cgb - GoogleCTF 2025
ゲームボーイカラーの問題
Ghidraでデコンパイルした
CMP系の命令を眺めると、以下の二つが怪しい
code:txt
FUN_05b9
4D40 01 02 10 20 10 20 80 80 ... . ..
4D48 40 40 4F 4F 4F 4F 4F 4F @@OOOOOO
C001 08 00 00 00 00 00 00 00 ........
C009 00 00 00 00 00 00 00 00 ........
code:txt
FUN_02fc
52B7 1C 17 C7 11 C0 C6 C5 85 ..Ç.ÀÆÅ.
52BF A3 57 9D F1 B2 AE 01 51 £W.ñ²®.Q
52C7 E0 F5 18 B1 AF 7F 13 32 àõ.±¯..2
52CF 39 EB E6 26 96 26 8B AA 9ëæ&.&.ª
52D7 1F 23 00 37 86 7A 8D BC .#.7.z.¼
C029 00 00 00 00 00 00 00 00 ........
C031 00 00 00 00 00 00 00 00 ........
C039 00 00 00 00 00 00 00 00 ........
C041 00 00 00 00 00 00 00 00 ........
C049 00 00 00 00 00 00 00 00 ........
前者はコナミコマンドっぽい並びなので、タイトルでup up down down left right left right ctrl altを入力すると隠し画面に入れた
https://scrapbox.io/files/68752d242e15c2e0e3e96779.png
その後の処理を眺めるとFUN_5300がfeistelぽかった
デコードするプログラムを書いた
code:python
def decode(bs):
buf = ''
for b in bs:
if 0x09 <= b <= 0x22:
buf += chr(b - 0x09 + ord('A'))
elif 0x23 <= b <= 0x3c:
buf += chr(b - 0x23 + ord('a'))
elif 0x3d <= b <= 0x46:
buf += chr(b - 0x3d + ord('0'))
elif b == 0x47:
buf += '@'
elif b == 0x48:
buf += '_'
elif b == 0x49:
buf += '-'
elif b == 0x4a:
buf += '{'
elif b == 0x4b:
buf += '}'
elif b == 0x4c:
buf += '?'
else:
buf += '!' # invalid character
return buf
def rot_left(x): return ((x<<1)|(x>>7)) & 0xFF
def rot_right(x): return ((x>>1)|(x<<7)) & 0xFF
def feistel_round(L, R, key):
F = R
for _ in range(8):
if key & 1:
F = rot_left(F)
else:
F = rot_right(F)
key >>= 1
def feistel_inv(L, R, key):
F = L
for _ in range(8):
if key & 1:
F = rot_left(F)
else:
F = rot_right(F)
key >>= 1
return R ^ F, L
def subkey(p, round):
s = '6c 3a ca 63 79 61 7b 79 6e 4a 3c 24 79 11 37 79 10 64 c0 32 05 3f 71 28 6e 4a 3c 24 79 11 37 79 10 64 c0 32 05 3f 71 28 6e 4a 3c 24 79 11 37 79 10 64 c0 32 05 3f 71 28 6e 4a 3c 24 79 11 e7 79 10 64 c0 32 05 3f 71 28 6e 4a 3c 24 79 11 37 79'
s = '1C 17 C7 11 C0 C6 C5 85 A3 57 9D F1 B2 AE 01 51 E0 F5 18 B1 AF 7F 13 32 39 EB E6 26 96 26 8B AA 1F 23 00 37 86 7A 8D BC'
def encrypt(buf, n):
for r in range(16):
buf0, buf1 = feistel_round(buf0, buf1, key) return buf
def decrypt(buf, n):
for r in range(15, -1, -1):
buf0, buf1 = feistel_inv(buf0, buf1, key) return buf
encs = []
for i in range(0, len(DAT_52B7), 2):
enc = decrypt(DAT_52B7i:i+2, i//2) encs.extend(enc)
print(decode(encs))
CTF{i_H@d_fuN_L3aRniNG_cGB_h0wY!B0u7_u?}と出力されたが、CTF{i_H@d_fuN_L3aRniNG_cGB_h0w_@B0u7_u?}が正しかった 謎
akiymさんがdecode関数などを書いてくれた
詳しく書かれていて良い