2025. 07. 19 ํ ์์ผ ์์ฃผ๋ํ๊ต์์ ์งํ๋ COSS CTF ๋ณธ์ ์ ์ฐธ์ฌํ์๋ค


๋์ผํ๊ฒ ์ถ์ ํ๊ณ , ์ต์ข ๊ฒฐ๊ณผ 4์๋ก ๋ง๋ฌด๋ฆฌ ํ๋ค


์์งํ ๋ณธ์ ์ ๋ชฉํ๋ก ๋๊ฐ๊ฑฐ์๊ณ , ์์์ ์๊ฐ๋ ๋ชปํ๋๋ฐ, ์์ํ๋๊น ์ผ๋จ๋จํ๊ณ ๋๋ฌด ์ข๋ค
์ฒซ ๋ณธ์ ์ ์ฒซ ์์์ธ ๋งํผ ๋ํ ํ๋ฃจ์ ์ผ์ ์ ์ ๋ฆฌํด๋ณด๋ ค๊ณ ํ๋ค
08:10 - ๊ธฐ์
์๋ 8์์ ์ผ์ด๋๋ ค๋ค๊ฐ ์กฐ๊ธ ๋ฆ์๋ค
์ฒ๋ฅ ๋ฒ๊ฐ๊ฐ ์ณ์ ๋ฆ๊ฒ ์ ๋ค์๋๋, ์๋์ ๋ชป ๋ค์๋ค
๊ทธ๋๋ ๋ฆ์ง๋ ์์๋ค
08:30 ~ 09:30 - ์ด๋
๋ํ์ฅ๊น์ง๋ 40๋ถ ์ ๋ ๊ฑธ๋ ธ๋ค
์ป๊ณ ๋์ถฉ ๋นต ๋จน๊ณ ๋ฐ๋ก ์ถ๋ฐํด์ ํ์ดํธํ๊ฒ ๋์ฐฉํ๋ค
401ํธ์๋? ๊ฑฐ๊ธฐ์ ์ธ์ ์ฒดํฌ๋ฅผ ํ๋๋ฐ, ์๋ง ๋ด๊ฐ ๊ฐ์ฅ ๋ง์ง๋ง์ผ๋ก ์จ ๊ฒ ๊ฐ์๋ค
09:30 ~ 09:50 - ๋ํ์ฅ ์ด๋ ๋ฐ ์ค๋น
์ฐ ๋ํ์ฅ์ 1์ธต์ ์์๋ค
์์งํ ๋น์ค๊ณ ๊ทธ๋์ ๊ทธ๋ฌ๋์ง๋ ๋ชจ๋ฅด๊ฒ ๋๋ฐ, ๊ฑด๋ฌผ์ด ์คํํ ๋๋์ด ์์๋ค
๊ทผ๋ฐ ๋ํ์ฅ์ ์์ฒญ ๊น๋ํ๊ณ ์ธ๋ จ๋์ด ์์๋ค
๊ทธ๋ฆฌ๊ณ ์ธํ ๋ฆฌ์ด๊ฐ ์ด๋ปค๋ค


๊ฐ๋๊น ํฐ์ ์ธ ๋ ๋๋ ์ฃผ์ จ๋ค
๋ ๋ค๊ณผ๋ ์์๋๋ฐ, ๊ฐ์๋ค์ด ์์ฒญ ๋ง์๋ค
์ง์ง ์ข์๋ค


๋ํ ํ์ด์ง ๋ก๊ทธ์ธ ํ๊ณ , ์ค๋ช ๊ฐ๋ตํ๊ฒ ๋ฃ๊ณ , ์์ดํ์ด ์ก๊ณ , ๋ฑ ์ธํ ํด๋๋ ์์ํ ์๊ฐ์ด ๋์๋ค
10:00 ~ 15:30 - ๋ณธ์ ๋ํ
์์ํ์๋ง์ ๋ฐ๋ก misc๋ก ๋ฌ๋ ค๊ฐ๋ค
mic check ๊ฐ์๊ฑฐ ์์ ์ค ์์๋๋ฐ ์์๊ณ , give me flag๋ฅผ ๊ทธ๋ฆฌ๋ฉด ํ๋๊ทธ๋ฅผ ์ฃผ๋ ๋ฌธ์ ๊ฐ ์์๋ค

์์ฐ! ๋ณ๊ฑฐ ์๋ ๋ฌธ์ ๋ฐ ํผ๋ธ์ด๋ค
๊ฝค๋ ์ด๋ ค์์ ์~์ ๊ทธ๋ ค์ผ ํ๋ค
๊ทธ๋ฆฌ๊ณ ํ ๋ฌธ์ ๋ฅผ ๋ณด์๋ค
ํ์์ค ํ ๋ช ์ด ํฌ๋ฆฝํ ๋ฅผ ๋งก์์, ํฌ๋ฆฝํ ํ ๋ฌธ์ ๋ฅผ ํธ๋๋์์ ๋๋ ๋ค๋ฅธ ํฌ๋ฆฝํ ๋ฌธ์ ๋ฅผ ๋ณด๊ธฐ ์์ํ๋ค
Decrypt RSA ๋ผ๋ ๋ฌธ์ ๋ก ๋๊ฐ ๋ด๋ RSA ๋ฌธ์ ์ธ๊ฑธ ์ ์ ์๋ค
Franklin-Reiter Related Message Attack ๊ฐ์ด ์๊ฒจ์ ๊ทธ๋ฅ GPTํํ ์ฝ๋ ๋์ ์ฃผ๋๊น ๋ฐ๋ก ์๋ ค์คฌ๋ค
from Crypto.Util.number import long_to_bytes
n = 65756182677698595176310503281797205396723871448656240837096474734817334229057
c1 = 46677618784900339556238162525204951591280608902940779073106839725667571575750
c2 = 46210449457768784989069436594183693519377189857113615576663015891132602693402
k = 1
f = [(-c1) % n, 0, 0, 1]
g = [((k**3 - c2) % n), (3*k**2) % n, (3*k) % n, 1]
def poly_trim(p):
while p and p[-1] == 0:
p.pop()
return p
def poly_divmod(a, b):
a = a.copy()
poly_trim(a); poly_trim(b)
deg_b = len(b) - 1
inv_lc_b = pow(b[-1], -1, n)
q = [0] * (len(a) - len(b) + 1) if len(a) >= len(b) else []
while len(a) >= len(b) and a:
d = len(a) - len(b)
coeff = (a[-1] * inv_lc_b) % n
q[d] = coeff
for i, bi in enumerate(b):
a[d + i] = (a[d + i] - coeff * bi) % n
poly_trim(a)
return poly_trim(q), poly_trim(a)
def poly_gcd(a, b):
poly_trim(a); poly_trim(b)
while b:
_, r = poly_divmod(a, b)
a, b = b, r
# normalize leading coefficient to 1
if not a:
return a
inv_lc = pow(a[-1], -1, n)
return [(coeff * inv_lc) % n for coeff in a]
d = poly_gcd(f, g)
if len(d) != 2:
raise ValueError(f"unexpected gcd degree: {len(d)-1}")
d0, d1 = d
m = (-d0 * pow(d1, -1, n)) % n
flag = long_to_bytes(m)
print(flag.decode())
# flag{fr4nkl1n-r3173r_4774ck}
์ด๊ฒ๋ ํผ๋ธ์ด๋ค
์ฌ์ด๊ฑด ๋นจ๋ฆฌ ํ ์ ์๋๋ฐ, ์ด๋ ค์ด ๊ฑธ ๋ชปํผ๋ค ใ
๊ทธ ๋ค์์ผ๋ก๋ ๋ฆฌ๋ฒ์ฑ์ผ๋ก ๊ฐ๋ค
1ํ๋ ๋ฆฌ๋ฒ์ฑ ๊ณ ํธ๊ฐ ์์ด์, ์ฌ์ด ๋ฌธ์ ํ๋ ํ๊ณ ์๋๊ฑด ๊ทธ ์น๊ตฌ๊ฐ ๊ธ๋ฐฉ ํ ๊ฒ ๊ฐ์๊ณ , ๋๋ ๋ค๋ฅธ ๋ฌธ์ ๋ฅผ ๋ณด๊ธฐ ์์ํ๋ค
๋ฑ ๋ณด๋๊น ํ๋งํ๊ฒ Save the cat์ด๋ผ์ ๋ฐ๋ก ์๋ํด๋ดค๋ค
apk ํ์ผ ํ๋๊ฐ ์ฃผ์ด์ก๊ณ , ๋ง์นจ!! Hackquest์ ์๋๋ก์ด๋ ๋ฆฌ๋ฒ์ฑ ๋ด์ฉ์ด ์์ด์ ์ฐธ๊ณ ํ๋ฉด์ jadx๋ก ๋์ปดํ์ผํด์ ์์ค์ฝ๋ ์ถ์ถํ๋ค

์ด ํ์ผ 4๊ฐ๋ฅผ GPTํํ ๋์ ธ์ฃผ๊ณ "flag๋ฅผ ๋ณต๊ตฌํ๋ python ์ฝ๋ ์ง์ค" ํ๋๊น ์ฝ๋ ์ง์คฌ๋ค
expected = [
6, 102, 130, 179, 226, 146, 166, 20,
116, 112, 98, 210, 244, 166, 54, 0,
151, 66, 117, 7, 67, 36, 146, 51,
230, 87, 135, 85, 39, 50, 85, 182
]
# 1. Invert column rotations
arr = expected.copy()
for i in range(4):
for _ in range(i):
temp = arr[i]
arr[i] = arr[i + 12]
arr[i + 12] = arr[i + 8]
arr[i + 8] = arr[i + 4]
arr[i + 4] = temp
# 2. Invert row rotations
for i in range(4):
for _ in range(i):
base = i * 4
temp = arr[base]
arr[base] = arr[base + 3]
arr[base + 3] = arr[base + 2]
arr[base + 2] = arr[base + 1]
arr[base + 1] = temp
# 3. Invert XOR with "cat"
cat = [99, 97, 116]
for k in range(len(arr)):
arr[k] ^= cat[k % 3]
# 4. Invert nibble mixing to recover the two 16โchar strings
N = 16
orig1 = []
orig2 = []
for i in range(N):
lo1 = arr[i] >> 4
hi2 = arr[i] & 0xF
lo2 = arr[N + i] >> 4
hi1 = arr[N + i] & 0xF
orig1.append((hi1 << 4) | lo1)
orig2.append((hi2 << 4) | lo2)
flag1 = ''.join(chr(c) for c in orig1)
flag2 = ''.join(chr(c) for c in orig2)
print("var1:", flag1)
print("var2:", flag2)
# var1: flag{y0u_f1nally
# var2: _sav3d_th3_c4ts}
๋ฑ ์ด๊ฑฐ ํ๊ณ ๋๋๊น 1์๊ฐ์ด ์ง๋์์๋ค
์ด๋๊น์ง๋ ์ข ๋นจ๋ฆฌ ํ์๋? ์ถ์ด์ ๋์์ง ์์๋ ๊ฒ ๊ฐ๋ค
๊ทธ ์ดํ๋ก๋ ๋งํ๊ณ , ๋ญ ํ์ด์ผํ ์ง ๋ชฐ๋์๋ค
web ์ค์์ Download์ด๋ฐ๊ฑธ ๋ดค์๋๋ฐ, ์ด๋ค์์ผ๋ก ํด์ผํ ์ง๋ ๋์ถฉ ๋๋์ด ์๋๋ฐ, ์ ์๋์ ํ์์ด ๋ฐ๋ก ํ์ด์คฌ๋ค
ํฌ๋๋ธ ๋ฌธ์ ๋ฅผ ๋ณด๋ ์ฃ๋ค ํ์๋ค๊ฐ ํ๋๋ QEMU์๊ณ , ๋ด๊ฐ ํ ์์ ์ด ์์๋ค
๊ทธ๋์ ๊ทธ๋ ์ด์ง ๋ฐฉํฉ์ ํ๋ค
๋ฌธ์ ์ฅ์ฅ ๋ณด๋ค๊ฐ 12์๊ฐ ๋๊ณ ์ ์ฌ์ ์ฃผ์ จ๋ค
+) 12:00 - ์ ์ฌ
์ ์ฌ์ด ในใ GOAT์๋ค
๊ฑ ํ์ฅ ๋์๋ฝ์ ๋ ์ค ๊ฒ ๊ฐ์๋๋ฐ, ๋ญ ๋์๋ฝ์ ์์ฐ ํ๊น๊ณผ ์คํ ์ดํฌ์ ์ ๋ณต์ด ํ ๋ง๋ฆฌ ํต์ผ๋ก ์์๋ค
ํ์์ผ๋ก ์ปต ๊ณผ์ผ๋ ์ฃผ์ จ๋ค

์บฌ
์ ๊ฑฐ ๋จน์ผ๋ฉด์ ์๋ผ๋งํฌ ํ๋ฆฌํฐ ๋บจ์น๋ ์ ์ฌ์ด๋ผ๊ณ ์ฐฌ์ํ๋ค
์ ๋ฐฐํ์์๋ ์๋ผ๋งํฌ์ด์ผ๊ธฐ๊ฐ ๋์๋ ๊ฒ ๊ฐ๋ค ใทใท
์ ์ฌ๋ ์ฌ์ ๋กญ์ง ์๊ณ , ๊ฑ ๋ ธํธ๋ถ ์์์ 10๋ถ ์ปท ํ๊ณ ๋ฐฅ ๋จน์๋ค
์ด๋์ฏค๋๋๊น ์ด์ง ๋ชฝ๋กฑํด์ง๋ฉด์ ์ ์ ์ด ๋๊ฐ๋ค
๊ทธ๋ฆฌ๊ณ ๋ค์ ๋ํ๋ฅผ ๋ฐ์๋ค
์ด ์ดํ๋ก๋ ํฌ๋๋ธ ํ ๋ฌธ์ ์ ๋ฆฌ๋ฒ์ฑ ํ ๋ฌธ์ ๋ฅผ ํ๊ธฐ ์์ํ๋ค
ํฌ๋๋ธ์ ํ์ด์๊ณ , "ํ"ํ์ง ์์ ๋๋ ํ์ง ๋ชปํ์๋ค
๋ฆฌ๋ฒ์ฑ base ๋ฌธ์ ๋ฅผ ์ฐ๋ฆฌ ํ์ด ๋ชป ํ์๋๋ฐ, ๋ค๋ฅธ ํ์์๋ ์ ๋ง์ด ํผ์ง๋ ๋ชจ๋ฅด๊ฒ ๋ค

์ด ํ ์คํธ ํ์ผ 3๊ฐ ์ฃผ์๊ณ , ๋์ ํ ๋ชจ๋ฅด๊ฒ ์ด์ ๊ฑ GPT๋ ์์ฒญ ๋๋ ธ๋ค
import base64
encode_data = (
"fniu3dQC3Wcimkeojn75nttmng3QQBxXMQ4cX9DkNMNbUCBhUY0e192zGHiFxwQYxVc7SPr0oPoW"
"DjXVTukyKWtJfW3t3kxqmn4KjdgTjgp3nBDnQQNHMtBUXMiPNCQ9NYc4U9e81M7aGwt+GV3gxbxl"
"SHRzojqFDunYDF67A+v="
)
alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
cipher = base64.b64decode(encode_data)
cand = "".join(
alphabet[(cipher[i] - i) & 0x3F]
for i in range(len(cipher))
)
pad = "=" * ((4 - len(cand) % 4) % 4)
flag_raw = base64.b64decode(cand + pad)
print(flag_raw.decode())
์์ง๋ ๋๋์ฒด ์ ์ด๋ ๊ฒ ํธ๋์ง๋ ๋ชจ๋ฅด๊ฒ ๋๋ฐ 1์ 40๋ถ์ฏค์ ํ์๋ค
์ด๊ฒ ๋ด๊ฐ ํผ ๋ง์ง๋ง ๋ฌธ์ ์๋ค
์ด๋์ฏค 7์์ฏค์ผ๋ก ์ถ๋ฝํ๊ณ , ์ข ๋ฌธ์ ๋ฅผ ์ง๊ฐํ๋ค
2์์ ์น ํ์์ด ํผ๋ธ์ ๋๊ณ , 2๋ฑ์ผ๋ก ์ฌ๋ผ์ฐ๋ค
๋ฐ๋ก ์ถ๊ฒฉ๋นํ๊ณ , ๋ง์ง๋ง์ผ๋ก 3์์ฏค ํ๋ฐฐ๊ฐ ๋ฆฌ๋ฒ์ฑ ๋ฌธ์ ๋ฅผ ํ๋ฉฐ 4์๋ก ๋ํ๋ฅผ ๋ง๋ฌด๋ฆฌ ํ๋ค
3์๋ถํฐ๋ ํฌ๋๋ธ์ ์๋ํด๋ดค์ง๋ง, ์คํจํ๋ค
๋ง์ด ํ์๋๋ฐ ์์งํ ์ฌ์ด ๋ฌธ์ ๋ ์๋ ๊ฒ ๊ฐ๋ค
์ด๋ ๊ฒ ๋ํ๊ฐ ๋์ด ๋ฌ๋ค
ในใ ใท์ธ๊ฑด 2์ TheFatCat์์ ๋๋๊ธฐ 5๋ถ์ QEMU ์ ์ ๋๊ฐ ๋ฌธ์ ๋ฅผ ํธ์ ์ 1๋ฑ์ ํ๋ค
TheKing์ด ์ค์๊ฐ์ผ๋ก ์๊ธ 60๋ง์์ด ์ฆ๋ฐํด๋ฒ๋ฆฐ๊ฑธ ๋ณด์๋ค
ใทใท
GOAT๋ค์ ๊ฒฝ์์ ๋ฌด์ญ๋ค
15:40 ~ 16:30 - ENKI ๊ฐ์ฐ
10๋ถ์ ๋ ์ฐธ๊ฐ์๋ค๊ณผ ์ด์ผ๊ธฐ ํ๊ณ , ์ถ์ ์ ์ํค์์ ๋กธ์ ์ ์๋ ค์คฌ๋ค
์น 2๊ฐ ํฌ๋๋ธ 2 ๋ฌธ์ ์๋ธ ํด์ฃผ์ จ๊ณ , ์์ง ํ๊ธฐ๊น์ง๋ ์ฐ์ต์ด ๋ ํ์ํ ๊ฒ ๊ฐ๋ค
๊ทธ๋ฆฌ๊ณ ์ํค ๋ถ์ฌ์ฅ๋๊ป์ ๊ฐ์ฐ์ ํด์ฃผ์ จ๋ค
์ด๊ฒ ๊ทธ๋ฅ ๋ณด์์ค๋ฆฌ ๋ ์ค๋ช ํ๋ฉด ์ข ์ง๋ฃจํด์ง ์๋ ์์๋๋ฐ, ์ค์ ๊ณต๊ณต๊ธฐ๊ด์ด ์ด๋ค ์๋ฆฌ๋ก ๊ณต๊ฒฉ์ ๋นํ๋๋ฐ ์๊ฐ๋ณด๋ค ์ธ์ธํ๊ณ , ์์ธํ๊ฒ ์ค๋ช ์ ํด์ฃผ์ จ๋ค
HackQuest์ฒ๋ผ ์ฌ๊ณ ์ ํ๋ฆ์ด ์ด๋ป๊ฒ ํ๋ฌ๊ฐ์ผํ๋์ง๋ฅผ ์ ์ง์ด์ฃผ์๋ฉด์ ์ค๋ช ํด์ฃผ์ ์ ์ดํด๊ฐ ์ ๋์๋ค
๊ทธ๋ฆฌ๊ณ "50%์ ํ๋ฅ ๋ก ์ ๋ ํ์ฌ๋ ๊ณผํ์ด๋ค" ๋ฅผ ์ฃผ์ฅํ์ จ๋ค
๋ญ ์ด๋ ๊ฒ ๊ฐ์ฐ ํด์ฃผ์๊ณ ์์์์ ํ๋ค
16:30 ~ 16:50 - ์์์ ๋ฐ ์ฌ์ง ์ดฌ์
๋๋์ด ์์์์ ํ๋ค

ํ์ ๋จ์ฒด ์ฌ์ง๋ ์๋๋ฐ, ๋ชจ์์ดํฌ ํ๋๊น ๋๋ฌด ๋ฒ์ฃ์ ๊ฐ์์ ๊ทธ๋ฅ ๋ถ๊ณ์ ์ฌ๋ ธ๋ค
์ฒซ ๋ํ ๋ณธ์ ์ธ๋ฐ, 10๋ฑ๋ง ํผํ์์๋๋ฐ, ์์์ ํด์ ๋๋ฌด ์ข์๋ค
17:30 ~ 19:30 - ํ์ in ์์๋ญ
๋๋ฏธ๊ณ 3ํ์ด์ ์นํจ์ง์ ๊ฐ๋ค

10๋ช ์ด์ ๊ฐ๋ค
5๋ง๋ฆฌ ์์ผ์ ์ด์ผ๊ธฐ๋ ํ๊ณ , ๋จน์ผ๋ฉด์ ๋์๋ค
์ธ๋น 15000์์ ์นํจ์ด๋ผ ์ ๋ง ์ข์๋ค
๋ ์์ฃผ๋์์ ๊ธฐ๋ ์ ํ๊ธฐ์ ํฐ์ ์ธ ๋ ์ฃผ์ จ๋ค
์ ๋ง ๊ฐ์ฌํ๋ค
์ฌํํผ ์ด๋ ๊ฒ ์์ฃผ๋ํ๊ต CTF๋ฅผ ๋ง์น๊ฒ ๋์๋ค
์ฒ์ ์์ ์ ๋๊ฐ๋๋, ๋ณธ์ ๋ง๋ณธ์ ๋ง!์ ์ธ์น๋ฉฐ ๋๊ฐ ๋ํ์๊ณ , ๋ด ์์ ์ฒ์์ผ๋ก ๋ณธ์ ์ ๋๊ฐ๋ค
๊ทธ ์ํฉ์์ ์ฒซ ์์์ ํด์ ๋๋ฌด ์ข๋ค
ํฌ๋๋ธ์ ๋ ๊ณต๋ถํด์ผ๊ฒ ๋ค
์ ๋ง ์ข์ ๊ฒฝํ์ด์๋ค!
'CTF' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| [ ์ 31ํ ํดํน ์บ ํ ํ๊ธฐ ] (8) | 2025.09.01 |
|---|---|
| [ 2025 ์ 1ํ ๊ฒฝ๊ธฐ๋ ์ฌ์ด๋ฒ ๋ณด์ ์บ ํ ํ๊ธฐ ] (2) | 2025.08.25 |
| [2025 COSS ์์ฃผ๋ CTF - ์์ ] - Write Up & ํ๊ธฐ (0) | 2025.06.23 |
| [2025 Codegate ์์ ] - Write Up & ํ๊ธฐ (0) | 2025.05.26 |
| [2025 DIMI CTF Write Up] - Prob by pandas. with ํ๊ธฐ (3) | 2025.03.25 |