ret2libc

hexo

什么样的题是ret2libc,这类题该怎么做?

程序的特征是:
进行栈溢出,没有system函数,也没有"/bin/sh"参数
无法进行常规的ret2text
ret2libc的关键是获取libc的版本,所以需要获得libc.so中函数的偏移量,
所以需要一个输出函数.got.plt中需要有libc中的函数,我们才能获取到libc中函数的真实地址

从而利用LibcSearcher确定libc版本


LibcSearcher原理?
基地址范围?


前置知识:
libc中有system函数,而libc.so动态偏移链接库中的函数之间的相对偏移是固定的

ALSR保护不会随机内存地址的后12位(后3个字节)

pwntools基本语法:
elf.got()返回的是.got中函数 相对plt基地址的偏移量
elf.plt()返回的是.plt中函数 相对got基地址的偏移量


常用函数

write()函数是C标准库(libc)中的一个系统调用,常用于向文件描述符写入数据:

1
ssize_t write(int fd, const void *buf, size_t count);
参数
  1. fd :目标文件描述符
    常见:
  • 0:标准输入
  • 1:标准输出
  • 2:标准错误输出
  • open系统调用获取文件描述符
  1. buf:源数据缓冲区
  2. count:要写入的字节数
返回值
  • 成功 返回写入的字节数
  • 失败 返回-1

LibcSearcher

Usage

原版接口

1
2
3
4
from LibcSearcher import *
obj = LibcSearcher("fgets",0x7ff39014bd90) # 使用一个已知符号地址作为初始约束,初始化LibcSearcher
obj.add_condition("atoi", 218528) # 添加一个约束条件
obj.dump("printf") # 根据已有约束条件,查询某个符号在Libc中的地址(偏移量)

新增接口

1
2
3
4
5
6
7
8
len(obj)  # 返回在当前约束条件下,可能的Libc数量
print(obj) # 若Libc已被唯一确定,打印其详细信息

for libc in obj:
print(libc) # 实现了迭代器,打印(或其他操作)当前所有可能的Libc

obj.select_libc() # 打印可能的Libc列表,手动选择一个认为正确的Libc
obj.select_libc(2) # 手动选择2号Libc作为正确的Libc

如果未知libc版本,在本地泄漏libc版本和在远程泄漏libc版本是不同的!
因为在本地程序运行时加载的是本地的libc版本!
LibcSearcher找到的也是本地的libc版本!

找不到正确的libc可以add_condition添加限制条件

经典例题:ctfshow pwn107


ret2libc
http://example.com/2024/11/04/ret2libc/
作者
yvyvSunlight
发布于
2024年11月4日
许可协议