๋ฌธ์ : DreamHack โ darimchal_001 ๋ถ๋ฅ: Crypto ๋์ด๋: ๐ฅ Bronze 3 FLAG:
pa55uc0
์น๊ตฌ ๋ค๋ฆฌ๋ฏธ๊ฐ ๋๋ฆผ์ด์ ์ปดํจํฐ์ XOR ๋์ฌ์จ์ด๋ฅผ ์ฌ์๋ค. ๋ณตํธํ ํค๋ฅผ ์ ๋ ฅํด์ ์ ๊ธ์ ํ์ด์ผ ํ๋ค๋, ์ฝ์ ํธ๊ฐ ๊ท์ฌ์ด ๋ฌธ์ ๋ค.
ํต์ฌ์ ๋จ ํ ์ค์ด๋ค. ์
๋ ฅํ ํค๋ฅผ ๊ณ ์ ๋ฌธ์์ด KEY์ ๋ฐ์ดํธ๋ณ๋ก XORํ ๋ค, ๋ฏธ๋ฆฌ ๋ฐํ ์๋ JOKER์ ๊ฐ์์ง๋ง ๋ณธ๋ค. XOR์ ๊ฐ์ ๊ฐ์ผ๋ก ๋ ๋ฒ ๊ฑธ๋ฉด ์๋๋๋ก ๋์์ค๋ ์๊ธฐ์ญ์(self-inverse) ์ฐ์ฐ์ด๋ผ, JOKER๋ฅผ KEY๋ก ํ ๋ฒ ๋ XORํ๋ฉด ํต๊ณผ ๋น๋ฐ๋ฒํธ๊ฐ ๊ทธ๋๋ก ํ์ด๋์จ๋ค.

๋ฌธ์ ๊ฐ์
| ํญ๋ชฉ | ๋ด์ฉ |
|---|---|
| ๋ฌธ์ ๋ช | darimchal_001 |
| ๋์ด๋ | ๐ฅ Bronze 3 |
| ๋ถ๋ฅ | Crypto |
| ์ ๊ณต ํ์ผ | chall1 (Mach-O x86-64 PIE), chall1.c (์์ค ๋๋ด) |
| ํต์ฌ ๊ธฐ๋ฒ | XOR ์๊ธฐ์ญ์ โ JOKER โ KEY๋ก ํต๊ณผ ํค ์ญ์ฐ |
| ํจ์ | ํ๋๊ทธ๋ DH{} ๋ํผ ์์ด, ๋ ์ธ๋๋ฐ๋ฅผ ๋บ pa55uc0 |
ํ์ด ํ๋ฆ์ ์งง๋ค. ์์ค์์ ๊ฒ์ฆ ํ ์ค์ ์ฝ๊ณ โ JOKER โ KEY๋ฅผ ๊ณ์ฐํด ๋น๋ฐ๋ฒํธ pa55uc0_๋ฅผ ์ป๊ณ โ ์ค์ ๋ฐ์ด๋๋ฆฌ ๋์ค์ด์
๋ธ๋ก ๊ทธ XOR์ด ์ง์ง์ธ์ง ํ์ธํ ๋ค โ ํ๋๊ทธ ํ์๋ง ๋ง์ถฐ ์ ์ถํ๋ค.
๐งฉ ๋ฐฐ๊ฒฝ โ XOR์ ์ ์๋ฌผ์ ์ด์ ์ด์ ์ธ๊ฐ
XOR(^)์ ๋์นญ์ด๋ค. ์ด๋ค ๋ฐ์ดํธ p๋ฅผ ํค k๋ก ๊ฐ๋ฆฌ๋ฉด c = p ^ k๊ฐ ๋๊ณ , ๊ฐ์ ํค๋ก ํ ๋ฒ ๋ XORํ๋ฉด c ^ k = p ^ k ^ k = p๋ก ์๋ ๊ฐ์ด ๋ณต์๋๋ค. k ^ k = 0์ด๊ณ p ^ 0 = p์ด๊ธฐ ๋๋ฌธ์ด๋ค.
์ด ๋ฌธ์ ๋ ๊ทธ ์ฑ์ง์ ๊ทธ๋๋ก ์๋ฌผ์ ๋ก ์ด๋ค. ์ ๋ต ๋น๋ฐ๋ฒํธ p๋ฅผ KEY๋ก XORํ ๊ฒฐ๊ณผ JOKER = p ^ KEY๋ฅผ ๋ฐ์ด๋๋ฆฌ์ ๋ฐ์ ๋๊ณ , ์ฌ์ฉ์๊ฐ ๋ฃ์ ์
๋ ฅ x์ ๋ํด x ^ KEY == JOKER์ธ์ง ๊ฒ์ฌํ๋ค.
๊ทธ๋ฐ๋ฐ x ^ KEY == JOKER๊ฐ ์ฑ๋ฆฝํ๋ ค๋ฉด x == JOKER ^ KEY์ฌ์ผ ํ๋ค. ๊ณต๊ฒฉ์ ์
์ฅ์์๋ ๋ธ๋ฃจํธํฌ์ค๋, ๋ฐฉ์ ์ ํ์ด๋ ํ์ ์๋ค. JOKER์ KEY๊ฐ ๋ ๋ค ๋ฐ์ด๋๋ฆฌ ์์ ์์ผ๋ ๊ทธ๋ฅ ๋์ XORํ๋ฉด ํต๊ณผ ํค๊ฐ ๋์จ๋ค. ๊ฐ๋ฆฌ๋ ๋ฐ ์ด ์ฐ์ฐ์ด ๊ทธ๋๋ก ์ฌ๋ ์ด์ ๊ฐ ๋๋ค.
๐ฌ ์ ์ฐฐ โ Mach-O ๋ฐ์ด๋๋ฆฌ์ ๋ฐํ ์๋ ์์
๋จผ์ ํ์ผ ์ข
๋ฅ์, ๋ฐ์ด๋๋ฆฌ์ KEYยทJOKER๊ฐ ์ค์ ๋ก ๋ค์ด ์๋์ง ๋ณธ๋ค.
file chall1 && strings -a chall1 | grep -nE "023661dd4|CRT;|\.success"
macOS์ฉ Mach-O 64-bit x86_64 ์คํ ํ์ผ์ด๋ค. ๋ฆฌ๋
์ค์์ ๋ฐ๋ก ์คํ๋์ง ์์ง๋ง, ์์ค๊ฐ ๊ฐ์ด ์ฃผ์ด์ก๊ณ ์์๋ ๊ทธ๋๋ก ๋ฐํ ์์ด ๋ถ์์๋ ์ง์ฅ์ด ์๋ค. strings์ 023661dd4(= KEY)๊ฐ ๊ทธ๋๋ก ๋ณด์ด๊ณ , JOKER์ ์ธ์ ๊ฐ๋ฅํ ๊ผฌ๋ฆฌ์ธ CRT;(0x43 0x52 0x54 0x3b)๋ ์กํ๋ค. ์ฑ๊ณต ์ ๋ง๋๋ ./%s.success ํ๊ทธ ํ์ผ ์ด๋ฆ๋ ๋ณด์ธ๋ค.
๐ ์ฝ๋ ๋ถ์ โ ๊ฒ์ฆ์ ๋ฑ ํ ์ค
๋๋ด๋ chall1.c์์ ์์์ ๊ฒ์ฆ ๋ก์ง๋ง ์ถ๋ฆฌ๋ฉด ์ด๋ ๋ค.
#define JOKER "\x40\x53\x06\x03\x43\x52\x54\x3b" // ์ ๊ธด ๊ฐ (8๋ฐ์ดํธ)
#define KEY "023661dd4" // XOR ํค (9๋ฐ์ดํธ)
int __is_valid_pwd(char *pwd) {
// pwd ๋ฅผ KEY ๋ก XOR ํ ๊ฒฐ๊ณผ๊ฐ JOKER ์ ๊ฐ์ผ๋ฉด ํต๊ณผ
if (!strncmp(JOKER, __obfuscation(pwd, KEY), sizeof(JOKER)))
return TRUE;
return FALSE;
}
char *__obfuscation(char *pwd, char *key) {
for (int i = 0; i < strlen(pwd); i++) {
if (key[i] == '\0') break; // ํค ๊ธธ์ด(9)๊น์ง๋ง
pwd[i] = pwd[i] ^ key[i]; // ๋ฐ์ดํธ๋ณ XOR
}
return pwd;
}__obfuscation์ ์
๋ ฅ์ KEY๋ก ๋ฐ์ดํธ๋ณ XORํ๋ค. __is_valid_pwd๋ ๊ทธ ๊ฒฐ๊ณผ๋ฅผ JOKER์ strncmp๋ก ๋น๊ตํ๋ค. ํต๊ณผ ์กฐ๊ฑด์ ๋ชจ๋ i์ ๋ํด pwd[i] ^ KEY[i] == JOKER[i], ์ฆ pwd[i] == JOKER[i] ^ KEY[i]๋ค.
๋น๊ต ๊ธธ์ด sizeof(JOKER)๋ ๋ฌธ์์ด ๋ฆฌํฐ๋ด์ ๋ ์ข
๋จ๊น์ง ํฌํจํด 9๋ค. JOKER๋ 8๋ฐ์ดํธ๋ฟ์ด๋ผ 9๋ฒ์งธ ์๋ฆฌ๋ ๋(0x00)์ด๋ค. ๊ทธ๋์ ์
๋ ฅ์ด ์ ํํ 8๊ธ์๋ฉด ๊ทธ ๋ฌธ์์ด์ ๋ ์ข
๋จ์ด 9๋ฒ์งธ ์๋ฆฌ์์ JOKER์ ๋๊ณผ ๋ง์๋จ์ด์ ธ, ์ 8๋ฐ์ดํธ๋ง ์ผ์น์ํค๋ฉด ๊ฒ์ฆ์ ํต๊ณผํ๋ค.
์์ค๋ง ๋ฏฟ์ง ๋ง๊ณ , ์ค์ ๋ฐ์ด๋๋ฆฌ์์๋ ์ด XOR์ด ๋๋์ง radare2๋ก __obfuscation ๋ฃจํ ๋ณธ์ฒด๋ฅผ ๋ฏ์ด ๋ณธ๋ค.
r2 -q -c "pd 13 @ 0x100003d2f" chall1![ํด๋ฆญํ์ฌ ํ๋ radare2 ๋์ค์ด์
๋ธ โ pwd[i]์ key[i]๋ฅผ ๊ฐ๊ฐ ๋ก๋ํด xor edx, esi ๋ก XOR ํ ๋์ ์ฅ](/_next/image?url=%2Fimages%2Fblog%2Fdreamhack-darimchal-001-writeup%2F02_disasm_xor.png&w=3840&q=75)
๋ ๋ฒ์ movsx โฆ byte [rax + rcx]๋ก pwd[i]์ key[i]๋ฅผ ๊ฐ๊ฐ ์ฝ์ด ์จ ๋ค์, xor edx, esi ํ ์ค๋ก XORํ๊ณ mov byte [rax + rcx], dl๋ก ์ ์๋ฆฌ์ ๋ฎ์ด์ด๋ค. ๊ทธ ๋ค add eax, 1๋ก ์ธ๋ฑ์ค๋ฅผ ์ฌ๋ ค ๋ฃจํ๋ฅผ ๋๋ค. ์์ค์ pwd[i] ^= key[i]๊ฐ ๋ฐ์ด๋๋ฆฌ์์๋ ๊ทธ๋๋ก๋ค.
๐ฏ ํ์ด โ JOKER โ KEY ํ ๋ฒ
pwd[i] = JOKER[i] ^ KEY[i]๋ฅผ ๊ทธ๋๋ก ์ฝ๋๋ก ์ฎ๊ธฐ๋ฉด ๋์ด๋ค.
# solve.py โ JOKER โ KEY ์ญ์ฐ
JOKER = bytes.fromhex("40 53 06 03 43 52 54 3b".replace(" ", "")) # 8 bytes
KEY = b"023661dd4" # 9 bytes
pwd = bytes(j ^ k for j, k in zip(JOKER, KEY))
print("๋ณตํธํ ํค(pwd):", pwd.decode()) # -> pa55uc0_
# ๊ฒ์ฆ: ๋ค์ XOR ํด์ JOKER ์ ์ผ์นํ๋์ง
check = bytes(p ^ k for p, k in zip(pwd, KEY))
print("re-XOR :", check.hex(" "), "==JOKER?", check == JOKER)
JOKER โ KEY = pa55uc0_. ๋ค์ KEY๋ก XORํ ๊ฐ์ด ์๋ JOKER์ ์ ํํ ์ผ์น(==JOKER? True)ํ๋, ์ด ๋ฌธ์์ด์ด ๋ฐ์ด๋๋ฆฌ๋ฅผ ์ฌ๋ ๋น๋ฐ๋ฒํธ๊ฐ ๋ง๋ค. 8๊ธ์๋ผ strncmp 9๋ฐ์ดํธ ๋น๊ต๋ ๋ ์ข
๋จ์ผ๋ก ์์ฐํ ํต๊ณผํ๋ค.
๐ ์ฝ์ง โ ํต๊ณผ ํค๋ ์ฐพ์๋๋ฐ ํ๋๊ทธ๊ฐ ์๊พธ ์ค๋ต
์ฌ๊ธฐ์ ํ์ฐธ ํค๋งธ๋ค. ํต๊ณผ ๋น๋ฐ๋ฒํธ pa55uc0_๋ ํ์คํ๋ฐ, ๋๋ฆผํต์ ์ ์ถํ ํ๋๊ทธ ํ์์ด ์์๊ณผ ๋ฌ๋๋ค.
โถ๐ ์ฝ์ง โ DH ๋ํผ์ ์ธ๋๋ฐ ๋๋ฌธ์ ์ค๋ต ๋ ๋ฒ
๋๋ฆผํต ํ๋๊ทธ๋ ๋ณดํต DH{...} ๊ผด์ด๋ผ, ์์ฐ์ค๋ฝ๊ฒ ์ด๋ ๊ฒ ๋ฃ์๋ค.
DH{pa55uc0_}โ ์ค๋ต (Wrong flag)DH{pa55uc0_4}โ ์ค๋ต (ํน์ 9๋ฒ์งธ ๋ฐ์ดํธ๊น์ง ํฌํจ์ธ๊ฐ ์ถ์ด์)
๋ฐ์ด๋๋ฆฌ ๊ฒ์ฆ์ ํต๊ณผํ๋ ํค์ธ๋ฐ ์ ์ค๋ต์ผ๊น. ๋ฐ์ด๋๋ฆฌ๋ ์ 8๋ฐ์ดํธ ์ ๋์ฌ๋ง ๋ณด๋, ์๊ฐ๊ฐ ๋ฑ๋กํ ํ๋๊ทธ ๋ฌธ์์ด์ด ํ์๋ง ๋ค๋ฅผ ์ ์๋ค๊ณ ๋ดค๋ค. ๋ฌด์์ ๋ณํ์ ๋ฟ๋ฆฌ๋ ๋์ ์ฑ๋ฆฐ์ง ๋๊ธ์ ์ฝ์ด ๋ณด๋ ๋ต์ด ์์๋ค.
- "๋๋ง DH ์ ๋ฃ์ด๋ ํ๋ฆฌ๋?"
- "ใ ~ ์ด๊ฑฐ ์ธ๋๋ฐ ๋นผ์ผ ๋๋๊ตฌ๋"
- "์ธ๋๋ฐ๋ฅผ ๋นผ์ผ ํ๋ฉด ๋ฌธ์ ์ค๋ช ์ ์ข ์จ์ฃผ์ธ์... ๋ฌธ์ ๋ ์ ์ด๋ ค์ด๋ฐ ์ธ๋๋ฐ ์ ๋นผ์ ์ ์ค๋ต์ธ๊ฐ ํ์ฐธ ๋ดค๋ค์"
์ ๋ฆฌํ๋ฉด ์ด ๋ฌธ์ ์ ๋ฑ๋ก ํ๋๊ทธ๋ DH{} ๋ํผ ์์ด, ๋ ์ธ๋๋ฐ๊น์ง ๋บ ํํ์๋ค. ์ฆ pa55uc0_ โ pa55uc0.
๋๊ธ์ด ์๋ ค์ค ๋๋ก DH{}๋ฅผ ๋ผ๊ณ ๋ ์ธ๋๋ฐ๋ ๋บ **pa55uc0**๋ฅผ ์ ์ถํ๋ ์ ๋ต ์ฒ๋ฆฌ๋๋ค(์๊ฒ์ auth API HTTP 201, ๋ฌธ์ ์ํ is_completed: true).
๋ฐ์ด๋๋ฆฌ๋ฅผ ์ฌ๋ ๋น๋ฐ๋ฒํธ(pa55uc0_)์ ์ฑ์ ์ฉ ํ๋๊ทธ(pa55uc0)๊ฐ ๋ฏธ๋ฌํ๊ฒ ๋ค๋ฅธ, ํ์ ํจ์ ์ด ์๋ ๋ฌธ์ ์๋ค.
๐ ๊ฒฐ๋ก
XOR์ ๊ฐ๋ฆฐ ๋ฐฉ๋ฒ์ด ๊ณง ์ฌ๋ ๋ฐฉ๋ฒ์ด๋ค.
์ ๋ต์ KEY๋ก XORํด ์จ๊ฒจ ๋จ๋ค๋ฉด, ๊ทธ KEY์ ์จ๊ธด ๊ฐ์ด ๊ฐ์ ๋ฐ์ด๋๋ฆฌ ์์ ์๋ ํ XOR ํ ๋ฒ์ผ๋ก ๊ทธ๋๋ก ๋ณต์๋๋ค. ๋์นญํค๋ฅผ ํ๋ฌธ ์์ ํจ๊ป ๋๋ ์๊ฐ ๋๋
ํ๋ ์ฅ์์ผ ๋ฟ์ด๋ค.
์์ค๊ฐ ์์ด๋ ์ค์ ๋ฐ์ด๋๋ฆฌ๋ฅผ ํ ๋ฒ์ ํ์ธํ๋ค.
์ด๋ฒ์ ์์ค์ ๋ฐ์ด๋๋ฆฌ๊ฐ ์ผ์นํ์ง๋ง, ์ ๊ณต ์์ค๊ฐ ๋จ์ํํ์ด๊ฑฐ๋ ์์๊ฐ ๋ค๋ฅผ ์ ์๋ค. strings๋ก KEYยทJOKER๊ฐ ์ค์ ๋ก ๋ฐํ ์๋์ง, radare2๋ก ๊ทธ XOR ๋ฃจํ๊ฐ ์ ๋ง ๋๋์ง ๋์ผ๋ก ํ์ธํ๊ณ ๋์์ผ ๊ณ์ฐ์ ๋ฏฟ์ ์ ์์๋ค.
๋ง์ง๋ง ๊ด๋ฌธ์ ์ํธ๊ฐ ์๋๋ผ ํ์์ด์๋ค.
ํค๋ฅผ ๋ค ํ๊ณ ๋ DH{} ๋ํผ์ ์ธ๋๋ฐ ๋๋ฌธ์ ๋ ๋ฒ ์ค๋ต์ ๋ฐ์๋ค. ๊ฒ์ฆ์ ํต๊ณผํ๋ ํค์ ์ฑ์ ์ฉ ํ๋๊ทธ๊ฐ ํญ์ ๊ฐ์ง๋ ์๋ค๋ ๊ฒ โ ๋งํ๋ฉด ๋ฌธ์ ์ค๋ช
ยท๋๊ธ์ ํ์ ํํธ๋ถํฐ ๋ค์ ๋ณด๋ ๊ฒ ๋น ๋ฅด๋ค.
Comments
๋๊ธ
๋๊ธ์ ๋จ๊ธฐ๋ ค๋ฉด ๋ก๊ทธ์ธ์ด ํ์ํด์. (๋ค์ด๋ฒ ยท ๊ตฌ๊ธ ๊ณ์ )
๋๊ธ ๋ถ๋ฌ์ค๋ ์คโฆ