๋ฌธ์ : DreamHack โ Simple Patch Me ๋ถ๋ฅ: Reversing ๋์ด๋: ๐ฅ Bronze 2 FLAG:
DH{6ad0f80a0448aee5e8615fbdea9c2775}
"1๋
๋ค์ flag๋ฅผ ๋ณด์ฌ์ค๊ฒ :p"๋ผ๋ฉฐ ํ ์๊ฐ์ฉ sleepํ๋ ๋ฐ์ด๋๋ฆฌ๋ค. ์ค์ ๋ก 8760์๊ฐ(=1๋
)์ ์ธ์ผ flag๊ฐ ๋์จ๋ค. ์ด๋ฆ์ด "Patch Me"์ธ ๋งํผ, ๊ทธ ๋๊ธฐ ๋ฃจํ๋ฅผ ๊ฑด๋๋ฐ๋๋ก ๋ฐ์ด๋๋ฆฌ๋ฅผ ์ด์ง ๊ณ ์น๋ฉด ๋๋ค. ์นด์ดํฐ ์ด๊ธฐ๊ฐ ํ๋๋ง ๋๊ฐ์ผ๋ก ๋ฐ๊พธ๋ฉด ๋ฃจํ๊ฐ ํต์งธ๋ก ์คํต๋๋ค.
์ด ๊ธ์ ๋ช ๋ น์ ๋ชจ๋
extracted/์์ ์คํํ๋ค.
file simple_patch_me ; echo "--- strings ---" ; strings simple_patch_me | grep -iE "year|hour|day|flag|passed"
๋ฌธ์ ๊ฐ์
| ํญ๋ชฉ | ๋ด์ฉ |
|---|---|
| ๋ฌธ์ ๋ช | Simple Patch Me |
| ๋์ด๋ | ๐ฅ Bronze 2 |
| ๋ถ๋ฅ | Reversing (x86-64 ELF, stripped) |
| ์ ๊ณต ํ์ผ | simple_patch_me |
| ํต์ฌ ์ทจ์ฝ์ / ๊ธฐ๋ฒ | ๋๊ธฐ ๋ฃจํ ์ฐํ ๋ฐ์ด๋๋ฆฌ ํจ์น + ์นด์ดํฐ ๊ธฐ๋ฐ XOR ๋ณตํธ |
ํ์ด๋ ๋ ๊ฐ๋๋ค. ํ๋๋ ์ด๋ฆ๋๋ก ํจ์น โ 1๋ ๋๊ธฐ ๋ฃจํ๋ฅผ ๊ฑด๋๋ฐ๊ฒ ๋ฐ์ด๋๋ฆฌ๋ฅผ ๊ณ ์ณ ๊ทธ๋ฅ ์คํํ๋ค. ๋ค๋ฅธ ํ๋๋ flag๋ฅผ ๋ง๋๋ ๊ณ์ฐ์ด ๊ณ ์ ๋ ์นด์ดํฐ ๊ฐ์๋ง ์์กดํ๋ค๋ ๊ฑธ ์๊ณ ์ ์ ์ผ๋ก ์ฌํํ๋ ๊ฒ์ด๋ค. ๋ ๋ค ๊ฐ์ flag๋ก ์๋ ดํ๋ค.
๐ฌ ์ ์ฐฐ โ ์๊ฐ์ด ํ๋ฅด๋ ์ฒํ๋ ํ๋ก๊ทธ๋จ
strings๋ง ๋ด๋ ์ปจ์
์ด ๋๋ฌ๋๋ค. "I will show you the flag after 1 year :p", "%u hours passed", "%u days have passed.", "Great xD 1 year has passed! The flag is: ". sleep์ importํ๊ณ , ์๊ฐ์ด ํ๋ฅธ ์ฒ ๋ฉ์์ง๋ฅผ ์ฐ๋ค๊ฐ 1๋
์ด ์ง๋๋ฉด flag๋ฅผ ๋ณด์ฌ์ค๋ค.
ํ์ดํ๋ก ์คํํ๋ฉด ์๋ฌด ์ถ๋ ฅ ์์ด ๋ฉ์ถฐ ์๋ ๊ฒ์ฒ๋ผ ๋ณด์ด๋๋ฐ, ์ฒซ ๋ฐ๋ณต์์ sleep์ ๊ฑธ๋ ค ๋ฒํผ๊ฐ flush๋์ง ์๊ธฐ ๋๋ฌธ์ด๋ค. ์ค์ ๋ก ๊ธฐ๋ค๋ฆด ์๋ ์์ผ๋ main์ ์ด์ด ๋๊ธฐ ๋ฃจํ๋ฅผ ์ฐพ๋๋ค.
๐ฃ 1๋ ์ ๋ฒฝ โ sleep ๋ฃจํ
main์ ํต์ฌ์ ์นด์ดํฐ ํ๋(0x40404c, ์๊ฐ ๋จ์)๋ฅผ ๋๊ณ ๋๋ ๋ฃจํ๋ค. ๋งค ๋ฐ๋ณต sleep(3600)(=1์๊ฐ)์ ๊ฑธ๊ณ ์นด์ดํฐ๋ฅผ 1 ์ฌ๋ฆฐ๋ค. ์นด์ดํฐ๊ฐ 8759 ์ดํ์ธ ๋์ ๋ฐ๋ณตํ๋, 8760๋ฒ(=365ร24) ๋์์ผ ๋ฃจํ๋ฅผ ๋น ์ ธ๋์จ๋ค.
echo "[์นด์ดํฐ ์ด๊ธฐํ @0x401292 โ ํจ์น ๋์ imm32]" ; \
objdump -d -M intel simple_patch_me --start-address=0x401292 --stop-address=0x40129c | grep "401292" ; \
echo "[๋ฃจํ: sleep 3600 + t++]" ; \
objdump -d -M intel simple_patch_me --start-address=0x4012a1 --stop-address=0x4012b5 | grep -E "^ 40" \
| sed -E -e "s/(edi,0xe10)/\1 ; 3600s=1h/" -e "s/(add +eax,0x1)/\1 ; t++/" ; \
echo "[์ข
๋ฃ: t <= 8759 ์ด๋ฉด ๋ฐ๋ณต, ์๋๋ฉด flag]" ; \
objdump -d -M intel simple_patch_me --start-address=0x401376 --stop-address=0x401387 | grep -E "^ 40" \
| sed -E -e "s/(cmp +eax,0x2237)/\1 ; 8759=365*24-1/"
; 0x401292 ์นด์ดํฐ ์ด๊ธฐํ (ํจ์น ๋์)
mov dword [0x40404c], 0 ; t = 0
; 0x4012a1 ๋ฃจํ ๋ณธ๋ฌธ
mov edi, 0xe10 ; sleep ์ธ์ = 3600์ด(1์๊ฐ)
call sleep
add [0x40404c], 1 ; t++
; 0x40137c ์ข
๋ฃ ์กฐ๊ฑด
cmp eax, 0x2237 ; t <= 8759 (=365*24-1) ?
jbe 0x4012a1 ; ์ฐธ์ด๋ฉด ๋ฃจํ, ๊ฑฐ์ง(=8760)์ด๋ฉด flag ๋ก๋ฃจํ๋ฅผ ์ ์์ ์ผ๋ก ํต๊ณผํ๋ ค๋ฉด 8760์๊ฐ์ ๊ธฐ๋ค๋ ค์ผ ํ๋ค. ํ์ง๋ง ๋ฃจํ๊ฐ ๋๋๋ ์๊ฐ ์นด์ดํฐ ๊ฐ์ ํญ์ 8760์ผ๋ก ๊ณ ์ ์ด๋ค. ์ด ์ ์ด ๋ ๊ฐ์ง ํ์ด์ ์ด์ ๋ค.
๐ฉน ํจ์น โ ์นด์ดํฐ๋ฅผ ๋๊ฐ์ผ๋ก
๊ฐ์ฅ ๊ณง์ ๊ธธ์ ์นด์ดํฐ ์ด๊ธฐ๊ฐ์ 0 ๋์ 8760์ผ๋ก ๋ง๋๋ ๊ฒ์ด๋ค. ๊ทธ๋ฌ๋ฉด ๋ฃจํ ์กฐ๊ฑด t <= 8759๊ฐ ์ฒ์๋ถํฐ ๊ฑฐ์ง์ด๋ผ, sleep ๋ฃจํ๋ฅผ ํต์งธ๋ก ๊ฑด๋๋ฐ๊ณ ๋ฐ๋ก flag ๊ณ์ฐ์ผ๋ก ๊ฐ๋ค.

ํจ์นํ ๋ฐ์ดํธ๋ mov dword [0x40404c], 0 ๋ช
๋ น์ imm32๋ค. ๋ช
๋ น์ด c7 05 <disp32> 00 00 00 00 ์ด๋ฏ๋ก ๋ง์ง๋ง 4๋ฐ์ดํธ(ํ์ผ ์คํ์
0x1298)๋ฅผ 0x00000000์์ 0x00002238(=8760)๋ก ๋ฐ๊พผ๋ค.
import struct
OFF = 0x1298 # imm32 ํ์ผ ์คํ์
data = bytearray(open("simple_patch_me", "rb").read())
data[OFF:OFF+4] = struct.pack("<I", 0x2238) # t ์ด๊ธฐ๊ฐ 0 -> 8760
open("simple_patch_me_patched", "wb").write(data)ํจ์นํ ๋ฐ์ด๋๋ฆฌ๋ฅผ ์คํํ๋ฉด ๋๊ธฐ ์์ด ๊ณง์ฅ flag๊ฐ ๋ฌ๋ค.

Great xD 1 year has passed! The flag is: DH{6ad0f80a0448aee5e8615fbdea9c2775}๐ flag๋ ์ด๋ป๊ฒ ๋ง๋ค์ด์ง๋ โ ์นด์ดํฐ XOR ๋ณตํธ
ํจ์น๋ก flag๋ฅผ ์ป์์ง๋ง, ์ ์นด์ดํฐ ๊ฐ์ด ์ค์ํ์ง๋ ๋ณตํธ ํจ์(0x401196)๋ฅผ ๋ด์ผ ์๋ค. flag๋ ํต์งธ๋ก ๋ฐํ ์์ง ์๊ณ , ์นด์ดํฐ ๊ฐ์ผ๋ก ๋ง๋ ํค๋ก XOR ๋ณตํธ๋๋ค.
![ํด๋ฆญํ์ฌ ํ๋ objdump โ key = t ร 0x1337beef31337, enc[i+3] ^= key8[i mod 8]](/_next/image?url=%2Fimages%2Fblog%2Fdreamhack-simple-patch-me-writeup%2F03_disasm_decrypt.png&w=3840&q=75)
์ํธ๋ฌธ์ ์คํ์ movabs๋ก ์ฌ์ด๋ 37๋ฐ์ดํธ๋ค. ์ 3๋ฐ์ดํธ๋ DH{ ํ๋ฌธ, ๋์ }์ NUL, ๊ฐ์ด๋ฐ 32๋ฐ์ดํธ๊ฐ ์ํธ๋ฌธ์ด๋ค. ํค๋ ์นด์ดํฐ t๋ก ๋ง๋ ๋ค.
// key8 = 8๋ฐ์ดํธ (๋ฆฌํ์๋์ธ)
key8 = (t * 0x1337beef31337) mod 2^64; // t = 8760
// ์ 3๋ฐ์ดํธ("DH{")์ ๋์ ๊ทธ๋๋ก, ๊ฐ์ด๋ฐ 32๋ฐ์ดํธ๋ง XOR
for (int i = 0; i < 32; i++)
enc[i + 3] ^= key8[i % 8];ํค๊ฐ t์๋ง ์์กดํ๊ณ t๋ ๋ฃจํ๊ฐ ๋๋๋ฉด ์ธ์ ๋ 8760์ด๋ค. ๊ทธ๋์ flag๋ ์คํ ํ๊ฒฝ๊ณผ ๋ฌด๊ดํ๊ฒ ํ๋๋ก ์ ํด์ง๋ค.
๐ฏ ์ ์ ๋ณต์ โ solve.py
๋ฐ์ด๋๋ฆฌ๋ฅผ ๋๋ฆฌ์ง ์๊ณ ๋, ์ด์
๋ธ๋ฆฌ์์ ์ฝ์ ์ํธ๋ฌธ 37๋ฐ์ดํธ์ ์์ 0x1337beef31337, ๊ณ ์ ์นด์ดํฐ 8760๋ง ์์ผ๋ฉด flag๊ฐ ๋์จ๋ค.
import struct
t = 8760
key8 = struct.pack("<Q", (t * 0x1337beef31337) & 0xFFFFFFFFFFFFFFFF)
# movabs ๋ก ์ฌ์ด๋ ์ํธ๋ฌธ (๋ฆฌํ์๋์ธ ๋ฐ์ดํธ์ด)
enc = bytearray(
struct.pack("<Q", 0xbebddde33e7b4844) +
struct.pack("<Q", 0xb9b58db638482980) +
struct.pack("<Q", 0xedbc8fba6d1c7cdd) +
struct.pack("<Q", 0xeaee80e36d4d7bde) +
struct.pack("<I", 0x7d1c2e8f) + b"\x00"
)
for i in range(32):
enc[i + 3] ^= key8[i % 8]
print("[+] FLAG:", enc.split(b"\x00")[0].decode())ํจ์น ์คํ๊ณผ ์ ํํ ๊ฐ์ flag๊ฐ ๋์จ๋ค.

[*] t = 8760 key8 = 0882b98dd8b81929
[+] FLAG: DH{6ad0f80a0448aee5e8615fbdea9c2775}๐ ๊ฒฐ๋ก
"๊ธฐ๋ค๋ ค์ผ ํ๋ค"๋ ์กฐ๊ฑด์ ๋๊ฐ ์ซ์ ํ๋๋ก ์์ถ๋ผ ์๋ค.
1๋
๋๊ธฐ๋ผ๋ ๊ฑฐ์ฐฝํ ์ฅ๋ฒฝ๋ ์ค์ ๋ก๋ ์นด์ดํฐ์ cmp ํ ์ค์ด์๋ค. ๊ทธ ์นด์ดํฐ์ ์ด๊ธฐ๊ฐ์ ๋๊ฐ์ผ๋ก ๋ฐ๊พธ๋ 4๋ฐ์ดํธ ํจ์น๋ก ์กฐ๊ฑด์ด ์ฒ์๋ถํฐ ๋ง์กฑ๋ผ, ๋ฃจํ ์ ์ฒด๊ฐ ๋ฌด์๋ฏธํด์ก๋ค. ์๊ฐยทํ์ยทํ๋๊ทธ ๊ฒ์ฌ ๊ฐ์ ๊ฒ์ดํธ๋ ๊ทธ ํ์ ์ ๋ด๋ฆฌ๋ ๋ช
๋ น ํ๋ ๊ฐ๋ง ์ฐพ์ผ๋ฉด ์ฐํ ์ง์ ์ด ๋ณด์ธ๋ค.
ํจ์น๊ฐ ํตํด๋ "์ ํตํ๋์ง"๋ ๋ฐ๋ก ์ดํดํ๋ค.
์ฌ๊ธฐ์ ํจ์น๊ฐ ๋จนํ ์ด์ ๋ flag ํค๊ฐ ๋ฃจํ์ ์ต์ข ์นด์ดํฐ ๊ฐ(8760)์์ ๋์ค๊ธฐ ๋๋ฌธ์ด๋ค. ๋ง์ฝ flag๊ฐ ๋งค ๋ฐ๋ณต ์กฐ๊ธ์ฉ ๊ฐฑ์ ๋๋ ๊ฐ์ด์๋ค๋ฉด, ๋ฃจํ๋ฅผ ์คํตํ ํจ์น๋ ์๋ฑํ ๊ฐ์ ๋ฑ์์ ๊ฒ์ด๋ค. ๋ณตํธ ๋ก์ง์ ์ฝ์ด "์นด์ดํฐ๊ฐ 8760์ผ๋ก ๊ณ ์ "์์ ํ์ธํ๊ธฐ์ ํจ์น์ ์ ์ ๊ณ์ฐ์ด ๊ฐ์ ๋ต์ผ๋ก ๋ง๋ฌ๋ค.
์ ๋ ฅ์ ์์กดํ์ง ์๋ ๊ณ์ฐ์ ์คํ์ด ์ ํ์ง์ผ ๋ฟ์ด๋ค.
ํค๊ฐ ๊ณ ์ ์์์ ๊ณ ์ ์นด์ดํฐ๋ก๋ง ์ ํด์ง๋, ๋ฐ์ด๋๋ฆฌ๋ฅผ ๋๋ฆฌ์ง ์๊ณ ์ข ์ด ์์์ XOR์ ๋์ง์ด๋ flag๊ฐ ๋์จ๋ค. ํจ์น๋ ๋น ๋ฅด๊ณ ์ง๊ด์ ์ด๊ณ , ์ ์ ๊ณ์ฐ์ ํ๊ฒฝ ์์ด๋ ์ฌํ ๊ฐ๋ฅํ๋ค. ๋ ๊ธธ์ ๋ค ํ์ธํ๋ฉด ๋ต์ ๋ํ ํ์ ์ด ์๊ธด๋ค.
Comments
๋๊ธ
๋๊ธ์ ๋จ๊ธฐ๋ ค๋ฉด ๋ก๊ทธ์ธ์ด ํ์ํด์. (๋ค์ด๋ฒ ยท ๊ตฌ๊ธ ๊ณ์ )
๋๊ธ ๋ถ๋ฌ์ค๋ ์คโฆ