Skip to content

Commit 222d891

Browse files
committed
Participate 36C3 CTF
1 parent e5765a6 commit 222d891

38 files changed

+3254
-0
lines changed

C3CTF/2019 36C3/bacon/brute.py

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
#!/usr/bin/env python3
2+
import itertools
3+
import sys
4+
5+
MASK = 0xffffff
6+
7+
8+
def forward(key, blk):
9+
assert tuple(map(len, (key, blk))) == (9, 6)
10+
def S(j, v): return (v << j | (v & MASK) >> 24-j) & MASK
11+
ws = blk[:3], blk[3:], key[:3], key[3:6], key[6:]
12+
x, y, l1, l0, k0 = (int.from_bytes(w, 'big') for w in ws)
13+
l, k = [l0, l1], [k0]
14+
for i in range(21):
15+
l.append((S(16, l[i]) + k[i] ^ i) & MASK)
16+
k.append(S(3, k[i]) ^ l[-1])
17+
for i in range(22):
18+
x = (S(16, x) + y ^ k[i]) & MASK
19+
y = (S(3, y) ^ x) & MASK
20+
return b''.join(z.to_bytes(3, 'big') for z in (x, y))
21+
22+
23+
def backward(key, cipher):
24+
assert tuple(map(len, (key, cipher))) == (9, 6)
25+
def S(j, v): return (v << j | (v & MASK) >> 24-j) & MASK
26+
ws = cipher[:3], cipher[3:], key[:3], key[3:6], key[6:]
27+
x, y, l1, l0, k0 = (int.from_bytes(w, 'big') for w in ws)
28+
l, k = [l0, l1], [k0]
29+
for i in range(21):
30+
l.append((S(16, l[i]) + k[i] ^ i) & MASK)
31+
k.append(S(3, k[i]) ^ l[-1])
32+
for i in range(21, -1, -1):
33+
y = S(21, y ^ x)
34+
x = S(8, (x ^ k[i]) - y)
35+
x, y = (z & 0xffffff for z in (x, y))
36+
return b''.join(z.to_bytes(3, 'big') for z in (x, y))
37+
38+
39+
# did I implement this correctly?
40+
assert forward(*map(bytes.fromhex, ('1211100a0908020100',
41+
'20796c6c6172'))) == b'\xc0\x49\xa5\x38\x5a\xdc'
42+
43+
44+
def H(m):
45+
s = bytes(6)
46+
v = m + bytes(-len(m) % 9) + len(m).to_bytes(9, 'big')
47+
for i in range(0, len(v), 9):
48+
s = forward(v[i:i+9], s)
49+
return s
50+
51+
52+
if len(sys.argv) < 2:
53+
print(f"Usage: python3 {sys.argv[0]} <hex>")
54+
exit(1)
55+
56+
target = bytes.fromhex(sys.argv[1])
57+
58+
59+
key = (18).to_bytes(9, 'big')
60+
61+
start = bytes(6)
62+
end = backward(key, target)
63+
64+
assert(forward(key, end) == target)
65+
66+
forward_dict = {}
67+
backward_dict = {}
68+
69+
all_bytes = [i.to_bytes(1, 'big') for i in range(256)]
70+
for k in itertools.product(all_bytes, repeat=9):
71+
key = b''.join(k)
72+
f = forward(key, start)
73+
forward_dict[f] = key
74+
if f in backward_dict:
75+
ans = key + backward_dict[f]
76+
break
77+
b = backward(key, end)
78+
backward_dict[b] = key
79+
if b in forward_dict:
80+
ans = forward_dict[b] + key
81+
break
82+
83+
print(ans.hex())
84+
assert H(ans) == target

C3CTF/2019 36C3/bacon/solver.py

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import subprocess
2+
3+
from pwn import *
4+
5+
c = remote('78.47.89.248', 1952)
6+
7+
target = c.recvline().strip()
8+
print target
9+
10+
ans = subprocess.check_output(
11+
['../pypy3.6-v7.3.0-linux64/bin/pypy3', 'brute.py', target]).strip()
12+
print ans
13+
14+
c.sendline(ans)
15+
16+
print c.recvall()

C3CTF/2019 36C3/bacon/vuln.py

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#!/usr/bin/env python3
2+
import os, signal
3+
4+
def Speck(key, blk):
5+
assert tuple(map(len, (key, blk))) == (9,6)
6+
S = lambda j,v: (v << j | (v&0xffffff) >> 24-j)
7+
ws = blk[:3],blk[3:], key[:3],key[3:6],key[6:]
8+
x,y, l1,l0,k0 = (int.from_bytes(w,'big') for w in ws)
9+
l, k = [l0,l1], [k0]
10+
for i in range(21):
11+
l.append(S(16,l[i]) + k[i] ^ i)
12+
k.append(S( 3,k[i]) ^ l[-1])
13+
for i in range(22):
14+
x = S(16,x) + y ^ k[i]
15+
y = S( 3,y) ^ x
16+
x,y = (z&0xffffff for z in (x,y))
17+
return b''.join(z.to_bytes(3,'big') for z in (x,y))
18+
19+
# did I implement this correctly?
20+
assert Speck(*map(bytes.fromhex, ('1211100a0908020100', '20796c6c6172'))) == b'\xc0\x49\xa5\x38\x5a\xdc'
21+
22+
def H(m):
23+
s = bytes(6)
24+
v = m + bytes(-len(m) % 9) + len(m).to_bytes(9,'big')
25+
for i in range(0,len(v),9):
26+
s = Speck(v[i:i+9], s)
27+
return s
28+
29+
30+
signal.alarm(100)
31+
32+
h = os.urandom(6)
33+
print(h.hex())
34+
35+
s = bytes.fromhex(input())
36+
if H(s) == h:
37+
print('The flag is: {}'.format(open('flag.txt').read().strip()))
38+
else:
39+
print('Nope.')
40+

C3CTF/2019 36C3/catch_the_flag/map

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
.................................X...X..X........X
2+
................X.X.XX...................X........
3+
.........X.....X....X....................X...X....
4+
....................................X..X..X...X...
5+
.X......................X......X...........X.....X
6+
..X.....X......X.................X.X..X...........
7+
.X..........X......X...X......X.X......XX.XXXX....
8+
..X....X....XX...............XX......X............
9+
.......................X...........X.....X........
10+
.......X....X......X.............X.............X..
11+
......X..X........................................
12+
.....................X.X......X...................
13+
.........................X.X.X.............X..X...
14+
.....X....................X..X....................
15+
...........X.................X....................
16+
............................X.......X.XXX.X.......
17+
..............X...............................X...
18+
..X......................XX.X..X...........X......
19+
.............................X...................X
20+
......................X............X..............
21+
..X.XX............XX.....................XX....X..
22+
.X..................X..........X...X.X............
23+
....XX............................................
24+
.......X.......X..............X...................
25+
......................X...........X........X...X..
26+
..................................................
27+
..X.X........X.X..........X.........XX..X........X
28+
..........X.........X....................X........
29+
..................X..............X....X...........
30+
...............X..X.....XX..X.....X..X............
31+
...................X...X..........................
32+
..........X.X....X.......X........................
33+
.X.......X.....X................X........XX.......
34+
......X....X.........X......X......XX.........X...
35+
X..............X..................................
36+
......X.......X...X...............X..............X
37+
....X......X...X..................................
38+
..........X....X.X.......X.....................X..
39+
...........................................X......
40+
..................................................
41+
.........X............X..X..................X.....
42+
...................X........................X.XXX.
43+
.......X.......................X............X.....
44+
......X.....X........X.X...X.X....X..X............
45+
X.................X.......X...................X...
46+
X.X..X............X.....X............X.X..X.......
47+
...............X...X...X..............XXX.........
48+
.X.......X.........X.............XX.....X.X......X
49+
.....X...................X.................X......
50+
...X...........X.X..X...X..........X...........X..

C3CTF/2019 36C3/catch_the_flag/map.py

+137
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
from pwn import *
2+
3+
from Queue import Queue
4+
5+
WIDTH = 50
6+
HEIGHT = 50
7+
8+
9+
def recv(p):
10+
return p.recvline().strip().split("\x00")
11+
12+
13+
def expect_room(p):
14+
while True:
15+
data = recv(p)
16+
if data[0] == 'd':
17+
return False
18+
elif data[0] == 'i':
19+
return True
20+
21+
22+
"""
23+
0 --> W
24+
| w
25+
| a d
26+
v s
27+
H
28+
"""
29+
30+
DIR = (('w', -1, 0), ('a', 0, -1), ('s', +1, 0), ('d', 0, +1))
31+
32+
UNKNOWN = 'O'
33+
PENDING = '?'
34+
SAFE = '.'
35+
DANGER = 'X'
36+
37+
guess = [[UNKNOWN for _ in range(WIDTH)] for _ in range(HEIGHT)]
38+
39+
guess[0][0] = SAFE
40+
guess[0][1] = PENDING
41+
guess[1][0] = PENDING
42+
43+
targets = Queue()
44+
targets.put((0, 1))
45+
current_target = (1, 0)
46+
47+
48+
def print_map():
49+
print ''.join(['=' for _ in range(WIDTH)])
50+
for y in range(HEIGHT):
51+
print ''.join(guess[y])
52+
print ''.join(['=' for _ in range(WIDTH)])
53+
54+
55+
def safe_path():
56+
fill = [[None for _ in range(WIDTH)] for _ in range(HEIGHT)]
57+
sy, sx = current_pos
58+
fill[sy][sx] = (sy, sx)
59+
ty, tx = current_target
60+
61+
q = Queue()
62+
q.put((sy, sx))
63+
while fill[ty][tx] is None:
64+
cy, cx = q.get()
65+
for c, dy, dx in DIR:
66+
ny = cy + dy
67+
nx = cx + dx
68+
if 0 <= ny < HEIGHT and 0 <= nx < WIDTH and fill[ny][nx] is None:
69+
if (ny == ty and nx == tx) or guess[ny][nx] == SAFE:
70+
fill[ny][nx] = (c, cy, cx)
71+
q.put((ny, nx))
72+
73+
s = ''
74+
while True:
75+
c, ny, nx = fill[ty][tx]
76+
s += c
77+
if ny == sy and nx == sx:
78+
return s[::-1]
79+
ty, tx = ny, nx
80+
81+
82+
def explore(p):
83+
global current_pos, current_target
84+
85+
path = safe_path()
86+
for i in range(len(path) - 1):
87+
p.sendline(path[i])
88+
assert expect_room(p)
89+
p.sendline(path[len(path) - 1])
90+
91+
ty, tx = current_target
92+
if not expect_room(p):
93+
# died
94+
guess[ty][tx] = DANGER
95+
if targets.empty():
96+
# finished
97+
current_target = None
98+
else:
99+
current_target = targets.get()
100+
return False
101+
else:
102+
# safe
103+
guess[ty][tx] = SAFE
104+
105+
if targets.empty():
106+
# finished
107+
current_target = None
108+
return False
109+
110+
current_pos = (ty, tx)
111+
current_target = targets.get()
112+
113+
for _, dy, dx in DIR:
114+
ny = ty + dy
115+
nx = tx + dx
116+
if 0 <= ny < HEIGHT and 0 <= nx < WIDTH and guess[ny][nx] is UNKNOWN:
117+
guess[ny][nx] = PENDING
118+
targets.put((ny, nx))
119+
120+
return True
121+
122+
123+
while True:
124+
p = remote("78.47.17.200", 7888)
125+
recv(p) # remove first room
126+
127+
current_pos = (0, 0)
128+
129+
while explore(p):
130+
print_map()
131+
132+
p.close()
133+
134+
if current_target is None:
135+
# finished
136+
print_map()
137+
break
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# echo 'hxp{FLAG}' > flag.txt && python3 world_generator.py 20 10 && docker build -t catch_the_flag . && docker run --cap-add=SYS_ADMIN --security-opt apparmor=unconfined -ti -p 7888:1024 catch_the_flag
2+
# run with: ./client.py 127.0.0.1 7888
3+
4+
FROM debian:buster
5+
6+
RUN apt-get update && \
7+
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
8+
python3 && \
9+
rm -rf /var/lib/apt/lists/
10+
11+
COPY ynetd /sbin/
12+
13+
RUN useradd --create-home --shell /bin/bash ctf
14+
WORKDIR /home/ctf
15+
16+
COPY flag.txt /home/ctf/flag.txt
17+
COPY game.py flag_char.py map /home/ctf/
18+
19+
RUN chmod 555 /home/ctf && \
20+
chown -R root:root /home/ctf && \
21+
chmod -R 000 /home/ctf/* && \
22+
chmod 500 /sbin/ynetd
23+
24+
RUN chown root:root /home/ctf/flag.txt && \
25+
chmod 004 /home/ctf/flag.txt
26+
27+
RUN chmod 004 map flag_char.py && \
28+
chmod 005 game.py
29+
30+
USER ctf
31+
RUN ! find / -writable -or -user $(id -un) -or -group $(id -Gn|sed -e 's/ / -or -group /g') 2> /dev/null | grep -Ev -m 1 '^(/dev/|/run/|/proc/|/sys/|/tmp|/var/tmp|/var/lock)'
32+
33+
USER root
34+
EXPOSE 1024
35+
36+
CMD ynetd -lm -1 -lt 10 -t 300 -lpid 16 /home/ctf/game.py

0 commit comments

Comments
 (0)