[๐Ÿฅ‡ Gold 4] RC4์ธ ์ค„ ์•Œ์•˜๋˜ ์•”ํ˜ธ์™€, ํŒŒ์ผ ํ•˜๋‚˜์— ์ˆจ์–ด ์žˆ๋˜ ์„ธ ์กฐ๊ฐ โ€” DreamHack Enc-JPG ํ’€์ด

2026-07-27ยท1๋ถ„ ์ฝ๊ธฐยท

[๐Ÿฅ‡ Gold 4] RC4์ธ ์ค„ ์•Œ์•˜๋˜ ์•”ํ˜ธ์™€, ํŒŒ์ผ ํ•˜๋‚˜์— ์ˆจ์–ด ์žˆ๋˜ ์„ธ ์กฐ๊ฐ โ€” DreamHack Enc-JPG ํ’€์ด

๋ฐฐํฌ๋ฌผ์€ ์œˆ๋„์šฐ ์‹คํ–‰ํŒŒ์ผ Enc ์™€ ๊นจ์ง„ flag.jpg ๋‘˜๋ฟ์ด๋‹ค. Enc ๋ฅผ ๋œฏ์–ด๋ณด๋ฉด RC4 ์ฒ˜๋Ÿผ ์ƒ๊ธด ๋ฃจํ‹ด์ด ๋‚˜์˜ค๋Š”๋ฐ ํ‘œ์ค€๊ณผ ์„ธ ๊ตฐ๋ฐ๊ฐ€ ๋‹ค๋ฅด๋‹ค โ€” ํ‚ค ํ™•์žฅ์ด ๋‚˜๋จธ์ง€๊ฐ€ ์•„๋‹ˆ๋ผ AND, ํ‚ค์ŠคํŠธ๋ฆผ์ด S ๋ฐ•์Šค๋ฅผ ํ•œ ๋ฒˆ ๋” ํƒ€๊ณ , ๋ฌด์—‡๋ณด๋‹ค 0x400 ์ฒญํฌ๋งˆ๋‹ค S ๋ฐ•์Šค๋ฅผ ์ƒˆ๋กœ ๋งŒ๋“ ๋‹ค. ๋งˆ์ง€๋ง‰ ํ•˜๋‚˜๋ฅผ ๋†“์น˜๋ฉด JPEG ํ—ค๋”๋งŒ ์‚ด์•„๋‚˜๊ณ  ๋‚˜๋จธ์ง€๊ฐ€ ์ „๋ถ€ ๊นจ์ง„๋‹ค. ์ œ๋Œ€๋กœ ๋ณตํ˜ธํ•˜๋ฉด ํŒŒ์ผ ํ•œ ๊ฐœ ์•ˆ์— JPEG ๋‘˜๊ณผ ํ‰๋ฌธ๊ณผ PNG ๊ฐ€ ์ด์–ด๋ถ™์–ด ์žˆ๊ณ , ํ”Œ๋ž˜๊ทธ๋Š” ๊ทธ ์…‹์— ๋‚˜๋‰˜์–ด ๋“ค์–ด ์žˆ๋‹ค. ๋งˆ์ง€๋ง‰ ์กฐ๊ฐ์€ PNG ์˜ IDAT ๊ธธ์ด ํ•„๋“œ ์ž๋ฆฌ์— ๋ฎ์—ฌ ์žˆ์–ด์„œ ๊ทธ๋ฆผ์œผ๋กœ๋Š” ์˜์˜ ์•ˆ ๋ณด์ธ๋‹ค.

๋ฌธ์ œ: DreamHack โ€” Enc-JPG ๋ถ„๋ฅ˜: Reversing + Forensics ๋‚œ์ด๋„: ๐Ÿฅ‡ Gold 4 FLAG: DH{How_ENc_ECrypt_yo}


๋ฌธ์ œ ๊ฐœ์š”

๋ฐฐํฌ๋ฌผEnc (PE32+ x86-64 ์ฝ˜์†”, 12KB), flag.jpg (7,415 B)
์„œ๋ฒ„์—†์Œ (needs_vm: false)
ํ•ต์‹ฌ ๊ธฐ๋ฒ•RC4 ๋ณ€ํ˜• ์—ญ์‚ฐ ยท ํŒŒ์ผ ์นด๋น™ ยท JPEG ํ—ค๋” ์ด์‹ ยท PNG ์ฒญํฌ ๋ณต๊ตฌ

๋ฌธ์ œ ์„ค๋ช…์ด ์งง์ง€๋งŒ ์ •๋ณด๊ฐ€ ๊ฝค ๋“ค์–ด ์žˆ๋‹ค.

๋“œ๋ฆผ์ด๊ฐ€ JPGํŒŒ์ผ ๋งŒ๋“œ๋Š” ์ค‘์— ๋ณ€์กฐ๊ฐ€ ๋˜์—ˆ์–ด์š”!! JPGํŒŒ์ผ์ด ๋‹จ๋‹จํžˆ ์ด์ƒํ•˜๋„ค์š”โ€ฆ?? ๋ฌธ์ œ ํŒŒ์ผ์ด ํ•˜๋‚˜ ์ž˜๋ชป์ƒ์„ฑ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ใ… -ใ…  ๋งˆ์ง€๋ง‰ ์‚ฌ์ง„ ํ”Œ๋ž˜๊ทธ ๊ธ€์ž์ˆ˜๋Š” 4๊ฐœ์ž…๋‹ˆ๋‹ค. DH{JPG_TXT_PNG}

๋งˆ์ง€๋ง‰ ์ค„์„ ๋‚˜๋Š” ์ฒ˜์Œ์— "ํ”Œ๋ž˜๊ทธ ํ˜•์‹์€ ์ด๋ ‡๊ฒŒ ์ƒ๊ฒผ๋‹ค"๋Š” ์˜ˆ์‹œ๋กœ ์ฝ์—ˆ๋‹ค. ๋‹ค ํ’€๊ณ  ๋‚˜์„œ์•ผ ์กฐ๊ฐ์ด JPGยทTXTยทPNG ์„ธ ๊ณณ์—์„œ ๋‚˜์˜จ๋‹ค๋Š” ๊ตฌ์„ฑ ์•ˆ๋‚ด์˜€๋‹ค๋Š” ๊ฑธ ์•Œ์•˜๋‹ค. ๊ทธ๋ฆฌ๊ณ  "์ž˜๋ชป์ƒ์„ฑ"๊ณผ "๋งˆ์ง€๋ง‰ ์‚ฌ์ง„ 4๊ธ€์ž"๋Š” ๋งˆ์ง€๋ง‰ ๋‹จ๊ณ„์—์„œ ์ •ํ™•ํžˆ ๋“ค์–ด๋งž๋Š”๋‹ค. ๋ฏธ๋ฆฌ ์•Œ๊ณ  ๋ดค์œผ๋ฉด ํ›จ์”ฌ ๋นจ๋ž์„ ํ…๋ฐ, ์ˆœ์„œ๋Œ€๋กœ ์ ์–ด ๋ณธ๋‹ค.

1. ์ •์ฐฐ

๋ฐ›์€ ๊ฒŒ ๋ญ”์ง€๋ถ€ํ„ฐ ๋ณธ๋‹ค.

cd extracted
ls -la && file Enc flag.jpg

ls ์™€ file ๋กœ ๋ฐฐํฌ๋ฌผ ํ™•์ธ โ€” Enc ๋Š” PE32+ x86-64 ์ฝ˜์†” ์‹คํ–‰ํŒŒ์ผ, flag.jpg ๋Š” JPEG ์ด ์•„๋‹ˆ๋ผ ๊ทธ๋ƒฅ data ๋กœ ์žกํžŒ๋‹ค
ls ์™€ file ๋กœ ๋ฐฐํฌ๋ฌผ ํ™•์ธ โ€” Enc ๋Š” PE32+ x86-64 ์ฝ˜์†” ์‹คํ–‰ํŒŒ์ผ, flag.jpg ๋Š” JPEG ์ด ์•„๋‹ˆ๋ผ ๊ทธ๋ƒฅ data ๋กœ ์žกํžŒ๋‹ค

flag.jpg๊ฐ€ data๋กœ ์žกํžŒ๋‹ค. ํ™•์žฅ์ž๋งŒ jpg ๊ณ  ๋‚ด์šฉ์€ JPEG ์ด ์•„๋‹ˆ๋ผ๋Š” ๋œป์ด๋‹ค. ์•ž 4๋ฐ”์ดํŠธ๊ฐ€ ff d8 ff e0์ด ์•„๋‹ˆ๋ผ๋Š” ์–˜๊ธฐ์ด๊ณ , ๊ทธ๋Ÿฌ๋‹ˆ Enc๊ฐ€ ์ด ํŒŒ์ผ์„ ๋ญ‰๊ฐ  ์žฅ๋ณธ์ธ์ผ ๊ฒƒ์ด๋‹ค.

์œˆ๋„์šฐ ๋ฐ”์ด๋„ˆ๋ฆฌ๋ผ ๋ฆฌ๋ˆ…์Šค์—์„œ ์‹คํ–‰ํ•  ์ˆ˜๋Š” ์—†๋‹ค. ์ •์  ๋ถ„์„์œผ๋กœ ๊ฐ„๋‹ค. ๋ฌธ์ž์—ด๋ถ€ํ„ฐ.

strings -n 5 Enc | grep -iE "funfun|flag|r\\+b|Project2"

strings ๋กœ ๋ฝ‘์€ ์˜๋ฏธ ์žˆ๋Š” ๋ฌธ์ž์—ด โ€” funfun, flag.jpg, r+b, ๊ทธ๋ฆฌ๊ณ  ๋นŒ๋“œ ๊ฒฝ๋กœ Project2.pdb
strings ๋กœ ๋ฝ‘์€ ์˜๋ฏธ ์žˆ๋Š” ๋ฌธ์ž์—ด โ€” funfun, flag.jpg, r+b, ๊ทธ๋ฆฌ๊ณ  ๋นŒ๋“œ ๊ฒฝ๋กœ Project2.pdb

funfun์ด ๋ˆˆ์— ๋ˆ๋‹ค. ๊ธธ์ด 6์งœ๋ฆฌ ์˜๋‹จ์–ด ๋ฐ˜๋ณต์ด๋ผ ํ‚ค์ผ ๊ฐ€๋Šฅ์„ฑ์ด ๋†’๋‹ค. flag.jpg์™€ r+b๊ฐ€ ๊ฐ™์ด ์žˆ๋Š” ๊ฒƒ๋„ ์ž์—ฐ์Šค๋Ÿฝ๋‹ค โ€” ํŒŒ์ผ์„ ์ฝ๊ธฐยท์“ฐ๊ธฐ ๊ฒธ์šฉ ๋ฐ”์ด๋„ˆ๋ฆฌ ๋ชจ๋“œ๋กœ ์—ฐ๋‹ค๋Š” ๊ฑด ์ œ์ž๋ฆฌ์—์„œ ๊ณ ์ณ ์“ด๋‹ค(in-place)๋Š” ๋œป์ด๋‹ค.

์„น์…˜ ๋ฐฐ์น˜๋„ ๋ด ๋‘”๋‹ค.

objdump -h Enc | sed -n "4,12p"

objdump -h ๋กœ ๋ณธ ์„น์…˜ โ€” .text 0x10fc, .rdata 0x1002, ์ด๋ฏธ์ง€ ๋ฒ ์ด์Šค 0x140000000
objdump -h ๋กœ ๋ณธ ์„น์…˜ โ€” .text 0x10fc, .rdata 0x1002, ์ด๋ฏธ์ง€ ๋ฒ ์ด์Šค 0x140000000

.text๊ฐ€ 4KB ๋‚จ์ง“์ด๋ผ ํ•จ์ˆ˜๊ฐ€ ๋ช‡ ๊ฐœ ์—†๋‹ค. ์ด ์ •๋„๋ฉด ์ „๋ถ€ ์ฝ์–ด๋„ ๋œ๋‹ค.

๋ฌธ์ž์—ด์ด .rdata ์–ด๋””์— ์žˆ๋Š”์ง€ ํ™•์ธํ•ด ๋‘๋ฉด ์ฐธ์กฐ ์ง€์ ์„ ์ฐพ๊ธฐ ์‰ฝ๋‹ค.

objdump -s -j .rdata Enc | grep -iE "funfun|flag"

objdump -s ๋กœ .rdata ๋คํ”„ โ€” 0x140003280 ์— funfun, 0x140003288 ์— r+b, 0x140003290 ์— flag.jpg ๊ฐ€ ์—ฐ๋‹ฌ์•„ ์žˆ๋‹ค
objdump -s ๋กœ .rdata ๋คํ”„ โ€” 0x140003280 ์— funfun, 0x140003288 ์— r+b, 0x140003290 ์— flag.jpg ๊ฐ€ ์—ฐ๋‹ฌ์•„ ์žˆ๋‹ค

์ฃผ์†Œ๊ฐ€ ๋‚˜์™”๋‹ค. funfun์€ 0x140003280, flag.jpg๋Š” 0x140003290์ด๋‹ค. ์ด์ œ ์ด๊ฑธ ๊ฐ€๋ฆฌํ‚ค๋Š” lea ๋ฅผ ์ฐพ์œผ๋ฉด ๋œ๋‹ค. ๋‘ ๊ตฐ๋ฐ๊ฐ€ ๋‚˜์™”๋‹ค โ€” 0x140001043๊ณผ 0x140001277. ์ฆ‰ ํŒŒ์ผ์„ ์—ฌ๋Š” ํ•จ์ˆ˜๊ฐ€ ๋‘˜์ด๋‹ค. ํ•˜๋‚˜๋Š” sub_140001000, ๋‹ค๋ฅธ ํ•˜๋‚˜๋Š” ๊ทธ๊ฑธ ํ˜ธ์ถœํ•˜๋Š” main(0x140001240)์ด๋‹ค.

์ •๋ฆฌํ•˜๋ฉด ์ด ํ”„๋กœ๊ทธ๋žจ์€ flag.jpg๋ฅผ ๋‘ ๋ฒˆ ํ›‘๋Š”๋‹ค.

2. 1๋‹จ๊ณ„ โ€” RC4๋ฅผ ๋‹ฎ์•˜์ง€๋งŒ ์•„๋‹Œ ๊ฒƒ

sub_140001000๋ถ€ํ„ฐ ์ฝ๋Š”๋‹ค. ์•ž๋ถ€๋ถ„์€ ํ‰๋ฒ”ํ•˜๋‹ค. funfun\0 7๋ฐ”์ดํŠธ๋ฅผ ์Šคํƒ([rbp+0x28])์— ๋ณต์‚ฌํ•˜๊ณ , fopen_s(&f, "flag.jpg", "r+b")๋กœ ์—ด๊ณ , fread(buf, 1, 0x400, f)๋กœ 1024๋ฐ”์ดํŠธ๋ฅผ ์ฝ๋Š”๋‹ค. ๊ทธ ๋‹ค์Œ ํ‚ค ๊ธธ์ด๋ฅผ ๊ตฌํ•˜๋Š” ๋ฃจํ”„(or rdx,-1 โ†’ inc rdx โ†’ cmp byte[rax+rdx],0)๊ฐ€ ๋Œ์•„ rdx = 6์ด ๋œ๋‹ค.

์—ฌ๊ธฐ์„œ๋ถ€ํ„ฐ๊ฐ€ ๋ณธ๋ก ์ด๋‹ค.

์ฃผ์„์€ tools/annot_ksa.sed ๋กœ ์–น์—ˆ๋‹ค. ; ๋’ค๊ฐ€ ๋‚ด๊ฐ€ ๋ถ™์ธ ๊ฒƒ์ด๊ณ  ๋‚˜๋จธ์ง€๋Š” objdump ์›๋ฌธ์ด๋‹ค.

s|\(and    rax,rdx\)|\1              ; โ˜… i % 6 ์ด ์•„๋‹ˆ๋ผ i \& 6|
s|\(mov    al,BYTE PTR \[rbp+rax\*1+0x28\]\)|\1  ; K[i] = key[i \& 6]|
s|\(mov    BYTE PTR \[rbp+rcx\*1+0x30\],r8b\)|\1 ; S[i] = i|
objdump -d Enc -M intel --start-address=0x1400010d5 --stop-address=0x1400010f9 \
  | sed -n "8,20p" | sed -f ../tools/annot_ksa.sed

objdump ๋กœ ๋ณธ KSA ์ดˆ๊ธฐํ™” ๋ฃจํ”„์— sed ๋กœ ์ฃผ์„์„ ์–น์—ˆ๋‹ค โ€” S[i]=i ๋ฅผ ์ฑ„์šฐ๋ฉด์„œ K[i]=key[i & 6] ๋กœ ํ‚ค๋ฅผ ํ™•์žฅํ•œ๋‹ค
objdump ๋กœ ๋ณธ KSA ์ดˆ๊ธฐํ™” ๋ฃจํ”„์— sed ๋กœ ์ฃผ์„์„ ์–น์—ˆ๋‹ค โ€” S[i]=i ๋ฅผ ์ฑ„์šฐ๋ฉด์„œ K[i]=key[i & 6] ๋กœ ํ‚ค๋ฅผ ํ™•์žฅํ•œ๋‹ค

RC4 ์˜ ํ‚ค ์Šค์ผ€์ค„์ด ๋งž๋‹ค. S[i] = i๋กœ ์ฑ„์šฐ๊ณ  K[i]์— ํ‚ค๋ฅผ ๋ฐ˜๋ณตํ•ด ๋„ฃ๋Š”๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ๋ช…๋ น์ด and rax,rdx ๋‹ค. ํ‘œ์ค€ RC4 ๋Š” K[i] = key[i % keylen]์ธ๋ฐ ์ด๊ฑด key[i & 6]์ด๋‹ค.

i & 6์ด ๋‚ผ ์ˆ˜ ์žˆ๋Š” ๊ฐ’์€ {0, 2, 4, 6} ๋„ท๋ฟ์ด๋‹ค. ์ฆ‰ ์‹ค์ œ๋กœ ์“ฐ์ด๋Š” ํ‚ค ๋ฐ”์ดํŠธ๋Š”

i & 6ํ‚ค ๋ฐ”์ดํŠธ
0'f' (0x66)
2'n' (0x6e)
4'u' (0x75)
6'\0' (0x00) โ€” ๋ฌธ์ž์—ด ๋ ๋„

๋„ท์ด๊ณ , funfun์˜ ๋‘ ๋ฒˆ์งธยท๋„ค ๋ฒˆ์งธยท์—ฌ์„ฏ ๋ฒˆ์งธ ๊ธ€์ž(u, f, n)๋Š” ํ•œ ๋ฒˆ๋„ ์•ˆ ์“ฐ์ธ๋‹ค. ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ตœ์ ํ™”ํ•œ ๊ฒŒ ์•„๋‹ˆ๋ผ ์†Œ์Šค๊ฐ€ ์›๋ž˜ &์˜€์„ ๊ฒƒ์ด๋‹ค. ์–ด๋А ์ชฝ์ด๋“  ๊ทธ๋Œ€๋กœ ๋ฒ ๊ปด์•ผ ํ•œ๋‹ค.

KSA ๋ณธ์ฒด(0x1400010f9)๋Š” ํ‘œ์ค€ ๊ทธ๋Œ€๋กœ๋‹ค. j = (j + K[i] + S[i]) & 0xff ํ•˜๊ณ  S[i]์™€ S[j]๋ฅผ ๋งž๋ฐ”๊พผ๋‹ค. and edi,0x800000ff ๋’ค์— ๋ถ™์€ ๋ถ€ํ˜ธ ๋ณด์ • 3์ค„์€ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ๋ถ€ํ˜ธ ์žˆ๋Š” ์ •์ˆ˜๋กœ ๋‚˜๋จธ์ง€๋ฅผ ํ‰๋‚ด ๋‚ธ ๊ฒƒ์ด๋ผ ๊ฒฐ๊ณผ์ ์œผ๋กœ๋Š” & 0xff์™€ ๊ฐ™๋‹ค.

ํ‚ค์ŠคํŠธ๋ฆผ์„ ๋ฝ‘๋Š” PRGA ์—์„œ ๋‘ ๋ฒˆ์งธ ์ฐจ์ด๊ฐ€ ๋‚˜์˜จ๋‹ค.

์ฃผ์„์€ tools/annot_prga.sed ๋กœ ์–น์—ˆ๋‹ค. ; ๋’ค๊ฐ€ ๋‚ด๊ฐ€ ๋ถ™์ธ ๊ฒƒ์ด๊ณ  ๋‚˜๋จธ์ง€๋Š” objdump ์›๋ฌธ์ด๋‹ค.

s|\(movzx  ecx,BYTE PTR \[rbp+rax\*1+0x30\]\)|\1 ; S[t]|
s|\(mov    al,BYTE PTR \[rbp+rcx\*1+0x30\]\)|\1  ; โ˜… S[S[t]] โ€” ํ•œ ๋ฒˆ ๋” ์ธ๋ฑ์‹ฑ|
s|\(xor    BYTE PTR \[rbp+r8\*1+0x130\],al\)|\1 ; buf[n] ^= keystream|
objdump -d Enc -M intel --start-address=0x14000118d --stop-address=0x1400011b2 \
  | sed -n "8,16p" | sed -f ../tools/annot_prga.sed

objdump ๋กœ ๋ณธ PRGA ๋๋ถ€๋ถ„ โ€” S[(S[i]+S[j])&0xff] ๋ฅผ ๊ตฌํ•œ ๋’ค ๊ทธ ๊ฐ’์œผ๋กœ S ๋ฅผ ํ•œ ๋ฒˆ ๋” ์ธ๋ฑ์‹ฑํ•œ๋‹ค
objdump ๋กœ ๋ณธ PRGA ๋๋ถ€๋ถ„ โ€” S[(S[i]+S[j])&0xff] ๋ฅผ ๊ตฌํ•œ ๋’ค ๊ทธ ๊ฐ’์œผ๋กœ S ๋ฅผ ํ•œ ๋ฒˆ ๋” ์ธ๋ฑ์‹ฑํ•œ๋‹ค

t = (S[i] + S[j]) & 0xff๊นŒ์ง€๋Š” ๊ฐ™๋‹ค. ํ‘œ์ค€์ด๋ผ๋ฉด S[t]๊ฐ€ ํ‚ค์ŠคํŠธ๋ฆผ ๋ฐ”์ดํŠธ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์—ฌ๊ธฐ๋Š” movzx ecx, [rbp+rax+0x30]์œผ๋กœ S[t]๋ฅผ ๊บผ๋‚ธ ๋’ค, ๊ทธ ๊ฐ’์„ ๋‹ค์‹œ ์ธ๋ฑ์Šค๋กœ ์จ์„œ mov al, [rbp+rcx+0x30] ์„ ํ•œ ๋ฒˆ ๋” ํ•œ๋‹ค. ์ฆ‰ S[S[t]] ๋‹ค.

์ด๊ฒƒ๋งŒ์œผ๋กœ๋„ ํ‘œ์ค€ RC4 ๊ตฌํ˜„์„ ๊ฐ–๋‹ค ์“ฐ๋ฉด ์•ˆ ๋œ๋‹ค๋Š” ๊ฒŒ ํ™•์‹คํ•ด์ง„๋‹ค. ์—ฌ๊ธฐ๊นŒ์ง€ ์ฝ๊ณ  ๋‚˜๋Š” "ํ‚ค funfun, & ํ™•์žฅ, ์ด์ค‘ ์ธ๋ฑ์‹ฑ" ์„ธ ๊ฐ€์ง€๋ฅผ ๋ฐ˜์˜ํ•ด ๋ณตํ˜ธ๊ธฐ๋ฅผ ์งฐ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ํ‹€๋ ธ๋‹ค.

๐Ÿ”ง ์‚ฝ์งˆ โ€” ํ—ค๋”๋งŒ ์‚ด์•„๋‚˜๊ณ  ๋‚˜๋จธ์ง€๊ฐ€ ์ „๋ถ€ ๊นจ์กŒ๋‹ค

์ฒญํฌ๋งˆ๋‹ค S ๋ฐ•์Šค๋ฅผ ์ƒˆ๋กœ ๋งŒ๋“ ๋‹ค๋Š” ๊ฑธ ๋†“์น˜๊ณ  ์ŠคํŠธ๋ฆผ์„ ํŒŒ์ผ ์ „์ฒด์— ๊ณ„์† ์ด์–ด์„œ ๋Œ๋ฆฐ ๋ฒ„์ „์ด๋‹ค.

# โœ— ์ž˜๋ชป๋œ ๋ฒ„์ „ โ€” S ๋ฐ•์Šค๋ฅผ ํŒŒ์ผ ์ „์ฒด์— ํ•œ ๋ฒˆ๋งŒ ๋งŒ๋“ ๋‹ค
S, j = ksa(KEY), 0
out = bytearray(data)
for n in range(len(out)):
    out[n] ^= prga_next(S)          # ์ฒญํฌ ๊ฒฝ๊ณ„๋ฅผ ๋ฌด์‹œํ•˜๊ณ  ๊ณ„์† ์ด์–ด ๊ฐ„๋‹ค
open("wrong_stream.jpg", "wb").write(out)

์•ž 4๋ฐ”์ดํŠธ๊ฐ€ ff d8 ff e0์œผ๋กœ ์ •ํ™•ํžˆ ๋‚˜์˜ค๊ณ  file๋„ JPEG ์œผ๋กœ ์žก๋Š”๋ฐ, ์ •์ž‘ ๊ทธ๋ฆผ์€ ์œ„์ชฝ ๋ช‡ ์ค„๋งŒ ๋ฉ€์ฉกํ•˜๊ณ  ์•„๋ž˜๊ฐ€ ์ „๋ถ€ ๋…ธ์ด์ฆˆ์˜€๋‹ค. ์•„๋ž˜๋Š” ๊ทธ๋ ‡๊ฒŒ ๋‚˜์˜จ wrong_stream.jpg ๋ฅผ ์ด๋ฏธ์ง€ ๋ทฐ์–ด๋กœ ์—ฐ ํ™”๋ฉด์ด๋‹ค.

์ฒญํฌ ์žฌ์ดˆ๊ธฐํ™”๋ฅผ ๋†“์นœ ๋ณตํ˜ธ๋ณธ โ€” JPEG ํ—ค๋”์™€ ์ฒซ ๋ช‡ ์ค„๋งŒ ๋งž๊ณ  ๋‚˜๋จธ์ง€๋Š” ํšŒ์ƒ‰ ๋…ธ์ด์ฆˆ
์ฒญํฌ ์žฌ์ดˆ๊ธฐํ™”๋ฅผ ๋†“์นœ ๋ณตํ˜ธ๋ณธ โ€” JPEG ํ—ค๋”์™€ ์ฒซ ๋ช‡ ์ค„๋งŒ ๋งž๊ณ  ๋‚˜๋จธ์ง€๋Š” ํšŒ์ƒ‰ ๋…ธ์ด์ฆˆ

"ํ—ค๋”๋Š” ๋งž๋Š”๋ฐ ๋’ค๊ฐ€ ํ‹€๋ฆฌ๋‹ค"๋Š” ๊ฑด ์•ž 1024๋ฐ”์ดํŠธ๋งŒ ํ‚ค์ŠคํŠธ๋ฆผ์ด ๋งž์•˜๋‹ค๋Š” ๋œป์ด๋‹ค. 1024๋Š” ์•„๊นŒ fread์— ๋„˜๊ธด 0x400์ด๋‹ค. ์šฐ์—ฐ์ผ ๋ฆฌ๊ฐ€ ์—†๋‹ค.

๊ทธ๋ž˜์„œ ํ•จ์ˆ˜ ๋์„ ๋‹ค์‹œ ๋ดค๋‹ค.

์ฃผ์„์€ tools/annot_loop.sed ๋กœ ์–น์—ˆ๋‹ค. ; ๋’ค๊ฐ€ ๋‚ด๊ฐ€ ๋ถ™์ธ ๊ฒƒ์ด๊ณ  ๋‚˜๋จธ์ง€๋Š” objdump ์›๋ฌธ์ด๋‹ค.

s|\(je     0x14000108e\)|\1  ; โ˜… ๋ณต๊ท€์ ์ด ftell ์ง์ „ = S๋ฐ•์Šค ์ดˆ๊ธฐํ™”๊ฐ€ ๋ฃจํ”„ ์•ˆ|
s|\(call   QWORD PTR \[rip+0x1f82\)|\1 ; feof|
objdump -d Enc -M intel --start-address=0x1400011f4 --stop-address=0x140001210 \
  | sed -n "8,14p" | sed -f ../tools/annot_loop.sed

objdump ๋กœ ๋ณธ ํ•จ์ˆ˜ ๊ผฌ๋ฆฌ โ€” feof ํ˜ธ์ถœ ๊ฒฐ๊ณผ๊ฐ€ 0 ์ด๋ฉด je 0x14000108e ๋กœ ๋˜๋Œ์•„๊ฐ„๋‹ค. ๋ณต๊ท€์ ์ด ftell ์ง์ „์ด๋ผ S๋ฐ•์Šค ์ดˆ๊ธฐํ™”๊นŒ์ง€ ๋ฃจํ”„ ์•ˆ์— ๋“ค์–ด๊ฐ€ 1024๋ฐ”์ดํŠธ ๋ธ”๋ก๋งˆ๋‹ค ํ‚ค์ŠคํŠธ๋ฆผ์ด ์ฒ˜์Œ๋ถ€ํ„ฐ ๋‹ค์‹œ ์‹œ์ž‘๋œ๋‹ค
objdump ๋กœ ๋ณธ ํ•จ์ˆ˜ ๊ผฌ๋ฆฌ โ€” feof ํ˜ธ์ถœ ๊ฒฐ๊ณผ๊ฐ€ 0 ์ด๋ฉด je 0x14000108e ๋กœ ๋˜๋Œ์•„๊ฐ„๋‹ค. ๋ณต๊ท€์ ์ด ftell ์ง์ „์ด๋ผ S๋ฐ•์Šค ์ดˆ๊ธฐํ™”๊นŒ์ง€ ๋ฃจํ”„ ์•ˆ์— ๋“ค์–ด๊ฐ€ 1024๋ฐ”์ดํŠธ ๋ธ”๋ก๋งˆ๋‹ค ํ‚ค์ŠคํŠธ๋ฆผ์ด ์ฒ˜์Œ๋ถ€ํ„ฐ ๋‹ค์‹œ ์‹œ์ž‘๋œ๋‹ค

feof๊ฐ€ 0์ด๋ฉด je 0x14000108e๋กœ ์ ํ”„ํ•œ๋‹ค. 0x14000108e๋Š” ftell ์ง์ „, ์ฆ‰ S ๋ฐ•์Šค ์ดˆ๊ธฐํ™”๋ณด๋‹ค ์•ž์ด๋‹ค. ๋‹ค์‹œ ๋งํ•ด ์ด ํ•จ์ˆ˜๋Š” ํŒŒ์ผ ์ „์ฒด๋ฅผ 1024๋ฐ”์ดํŠธ์”ฉ ๋Œ๋ฉด์„œ ๋งค ์ฒญํฌ๋งˆ๋‹ค S ๋ฐ•์Šค๋ฅผ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋‹ค์‹œ ๋งŒ๋“ ๋‹ค. ํ‚ค์ŠคํŠธ๋ฆผ์ด ์ด์–ด์ง€์ง€ ์•Š๋Š”๋‹ค.

ํ•œ ๊ฐ€์ง€ ๋” ์žˆ๋‹ค. KSA ๊ฐ€ ์“ฐ๋Š” j(๋ ˆ์ง€์Šคํ„ฐ edi)๋Š” ๋ฃจํ”„ ๋ฐ– 0x140001059์—์„œ ๋”ฑ ํ•œ ๋ฒˆ๋งŒ 0์ด ๋œ๋‹ค. PRGA ์ง์ „(0x14000113d)์—์„œ ๋‹ค์‹œ 0์œผ๋กœ ์ดˆ๊ธฐํ™”๋˜๋‹ˆ, KSA ๋Š” ์•ž ์ฒญํฌ PRGA ๊ฐ€ ๋๋‚ฌ์„ ๋•Œ์˜ j ๊ฐ’์„ ์ด์–ด๋ฐ›์•„ ์‹œ์ž‘ํ•œ๋‹ค. ๊ทธ๋ž˜์„œ ์ฒญํฌ๋งˆ๋‹ค S ๋ฐ•์Šค๋Š” ์ƒˆ๋กœ ๋งŒ๋“ค์–ด์ง€๋˜ ๋งค๋ฒˆ ๋‹ค๋ฅธ ๋ฐฐ์—ด์ด ๋‚˜์˜จ๋‹ค.

์ด ๋‘ ์ค„์ด ๋น ์ ธ์„œ ๋‘ ์‹œ๊ฐ„์„ ๋‚ ๋ ธ๋‹ค. ๋””์Šค์–ด์…ˆ๋ธ”๋ฆฌ์—์„œ ๋ฃจํ”„์˜ ๋ณต๊ท€ ์ง€์ ์„ ํ™•์ธํ•˜์ง€ ์•Š๊ณ  "ํ•จ์ˆ˜ ํ•˜๋‚˜ = ์ŠคํŠธ๋ฆผ ํ•˜๋‚˜"๋ผ๊ณ  ๋„˜๊ฒจ์งš์€ ๊ฒŒ ์›์ธ์ด๋‹ค.

ํŒŒ์ผ์„ ์–ด๋–ป๊ฒŒ ํ›‘๋Š”๊ฐ€

์•”ํ˜ธ ์ž์ฒด์™€ ๋ณ„๊ฐœ๋กœ, ์ด ํ•จ์ˆ˜๊ฐ€ ํŒŒ์ผ์„ ๋‹ค๋ฃจ๋Š” ๊ณจ๊ฒฉ๋„ ๋ด ๋‘˜ ํ•„์š”๊ฐ€ ์žˆ๋‹ค. ์ž„ํฌํŠธ ์ฃผ์†Œ๋ฅผ ํ˜ธ์ถœ ์ธ์ž์™€ ๋งž์ถฐ ๋ณด๋ฉด ์ด๋ ‡๊ฒŒ ์ •๋ฆฌ๋œ๋‹ค.

IAT ์ฃผ์†Œํ•จ์ˆ˜๊ทผ๊ฑฐ
0x140003188fopen_s(&f, "flag.jpg", "r+b") 3์ธ์ž
0x140003180feof์ธ์ž๊ฐ€ FILE* ํ•˜๋‚˜, ๋ฐ˜ํ™˜ 0 ์ด๋ฉด ๋ฃจํ”„ ๊ณ„์†
0x1400031a8ftell์ธ์ž FILE* ํ•˜๋‚˜, ๋ฐ˜ํ™˜๊ฐ’์„ ๋‚˜์ค‘์— fseek ์˜คํ”„์…‹์œผ๋กœ ์”€
0x140003178fread(buf, 1, 0x400, f)
0x140003190fwrite(buf, 1, ์ฝ์€์ˆ˜, f)
0x1400031b0fseek(f, ์˜คํ”„์…‹, 0) โ€” ์„ธ ๋ฒˆ์งธ ์ธ์ž r8d = 0 = SEEK_SET

ํ•œ ๋ฐ”ํ€ด๋Š” ftell ๋กœ ํ˜„์žฌ ์œ„์น˜ ๊ธฐ์–ต โ†’ fread โ†’ ๋ณ€ํ™˜ โ†’ ๊ธฐ์–ตํ•œ ์œ„์น˜๋กœ fseek โ†’ fwrite โ†’ ์ฝ๊ธฐ ๋๋‚œ ์œ„์น˜๋กœ ๋‹ค์‹œ fseek ์ด๋‹ค. ์ œ์ž๋ฆฌ ๊ฐฑ์‹ ์ด๋ผ r+b ๋กœ ์—ฐ ์ด์œ ๊ฐ€ ์—ฌ๊ธฐ์„œ ๋“œ๋Ÿฌ๋‚œ๋‹ค. ์›๋ณธ์„ ๋‚จ๊ธฐ์ง€ ์•Š์œผ๋‹ˆ flag.jpg ๋Š” ์ด๋ฏธ ๋‘ ๋ฒˆ ๋ฎ์–ด์จ์ง„ ์ƒํƒœ๋กœ ๋ฐฐํฌ๋œ ๊ฒƒ์ด๋‹ค.

์ •๋ฆฌํ•˜๋ฉด 1๋‹จ๊ณ„๋Š” ์ด๋ ‡๋‹ค.

ํ‘œ์ค€ RC4Enc.exe
ํ‚ค ํ™•์žฅK[i] = key[i % keylen]K[i] = key[i & 6]
ํ‚ค์ŠคํŠธ๋ฆผS[(S[i]+S[j]) & 0xff]S[ S[(S[i]+S[j]) & 0xff] ]
์ฒญํฌ ๊ฒฝ๊ณ„์ŠคํŠธ๋ฆผ ์—ฐ์†์ฒญํฌ๋งˆ๋‹ค S ๋ฐ•์Šค ์žฌ์ƒ์„ฑ, KSA ์˜ j ๋งŒ ์ด์–ด๋ฐ›์Œ

3. 2๋‹จ๊ณ„ โ€” ์ธ๋ฑ์Šค ํ™€์ง XOR

main์€ 1๋‹จ๊ณ„ ํ•จ์ˆ˜๋ฅผ ๋ถ€๋ฅธ ๋’ค ํŒŒ์ผ์„ ๋‹ค์‹œ ์—ฐ๋‹ค. ์ด๋ฒˆ์—” ํ›จ์”ฌ ๋‹จ์ˆœํ•˜๋‹ค.

์ฃผ์„์€ tools/annot_st2.sed ๋กœ ์–น์—ˆ๋‹ค. ; ๋’ค๊ฐ€ ๋‚ด๊ฐ€ ๋ถ™์ธ ๊ฒƒ์ด๊ณ  ๋‚˜๋จธ์ง€๋Š” objdump ์›๋ฌธ์ด๋‹ค.

s|\(test   dl,0x1\)|\1                ; ์ธ๋ฑ์Šค ํ™€์ง ํŒ์ •|
s|\(xor    cl,0x85\)|\1               ; ์ง์ˆ˜|
s|\(xor    cl,0x44\)|\1               ; ํ™€์ˆ˜|
objdump -d Enc -M intel --start-address=0x1400012cb --stop-address=0x1400012ef \
  | sed -n "8,18p" | sed -f ../tools/annot_st2.sed

objdump ๋กœ ๋ณธ 2๋‹จ๊ณ„ ๋ฃจํ”„ โ€” test dl,1 ๋กœ ์ธ๋ฑ์Šค ํ™€์ง์„ ๊ฐˆ๋ผ ์ง์ˆ˜๋Š” 0x85, ํ™€์ˆ˜๋Š” 0x44 ๋กœ XOR ํ•œ๋‹ค
objdump ๋กœ ๋ณธ 2๋‹จ๊ณ„ ๋ฃจํ”„ โ€” test dl,1 ๋กœ ์ธ๋ฑ์Šค ํ™€์ง์„ ๊ฐˆ๋ผ ์ง์ˆ˜๋Š” 0x85, ํ™€์ˆ˜๋Š” 0x44 ๋กœ XOR ํ•œ๋‹ค

test dl,0x1๋กœ ์ธ๋ฑ์Šค์˜ ์ตœํ•˜์œ„ ๋น„ํŠธ๋ฅผ ๋ณด๊ณ  ์ง์ˆ˜๋ฉด ^0x85, ํ™€์ˆ˜๋ฉด ^0x44 ํ•œ๋‹ค. ์—ญ์‹œ 0x400์”ฉ ์ฝ์–ด ์ฒ˜๋ฆฌํ•˜๊ณ  ๋˜์“ด๋‹ค. ์ฒญํฌ ํฌ๊ธฐ๊ฐ€ ์ง์ˆ˜๋ผ ์ฒญํฌ๊ฐ€ ๋‚˜๋‰˜์–ด๋„ ์ „์—ญ ํ™€์ง์ด ์–ด๊ธ‹๋‚˜์ง€ ์•Š๋Š”๋‹ค. ๊ทธ๋ž˜์„œ ํŒŒ์ผ ์ „์ฒด๋ฅผ ํ•œ ๋ฒˆ์— ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฒฐ๊ณผ๊ฐ€ ๊ฐ™๋‹ค.

cmp rdx,rdi; jbe ๋ผ ์ฝ์€ ๋ฐ”์ดํŠธ ์ˆ˜๋ณด๋‹ค ํ•˜๋‚˜ ๋” XOR ํ•˜๋Š” ์˜คํ”„๋ฐ”์ด์›์ด ์žˆ๋Š”๋ฐ, fwrite๋Š” ์ฝ์€ ๋งŒํผ๋งŒ ์“ฐ๊ธฐ ๋•Œ๋ฌธ์— ์ถœ๋ ฅ์—๋Š” ์˜ํ–ฅ์ด ์—†๋‹ค. ์Šคํƒ ํ•œ ๋ฐ”์ดํŠธ๋ฅผ ๊ฑด๋“œ๋ฆฌ๊ณ  ๋ง ๋ฟ์ด๋‹ค.

๋‘ ๋‹จ๊ณ„ ๋ชจ๋‘ XOR ์ด๋ผ ๋ณตํ˜ธ๋Š” ๊ฐ™์€ ์—ฐ์‚ฐ์ด๊ณ , XOR ์€ ๊ตํ™˜๋ฒ•์น™์ด ์„ฑ๋ฆฝํ•˜๋‹ˆ ์ˆœ์„œ๋„ ์ƒ๊ด€์—†๋‹ค.

4. ๋ณตํ˜ธ๊ธฐ

์ฝ์€ ๊ทธ๋Œ€๋กœ ์˜ฎ๊ธด๋‹ค. ๋ณ„๋„ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ํ•„์š” ์—†๋‹ค.

KEY = b"funfun\x00"          # ๋ฐ”์ด๋„ˆ๋ฆฌ๊ฐ€ ์Šคํƒ์— ๋ณต์‚ฌํ•˜๋Š” 7๋ฐ”์ดํŠธ ๊ทธ๋Œ€๋กœ
CHUNK = 0x400                # fread/fwrite ๋‹จ์œ„. 1ยท2๋‹จ๊ณ„ ๋ชจ๋‘ ์ด ํฌ๊ธฐ๋กœ ๋ˆ๋‹ค
 
 
def rc4_variant(data, j_carry=0, key=KEY):
    """ํ•œ ์ฒญํฌ. ๋ฐ˜ํ™˜ (๊ฒฐ๊ณผ, ๋‹ค์Œ ์ฒญํฌ KSA ๋กœ ๋„˜๊ธธ j)."""
    klen = len(key) - 1                              # strlen("funfun") = 6
    K = bytes(key[i & klen] for i in range(256))     # โ‘  i % klen ์ด ์•„๋‹ˆ๋ผ i & klen
 
    S = list(range(256))
    j = j_carry                                      # โ‘ก KSA ์ „์— j ๋ฅผ 0 ์œผ๋กœ ์•ˆ ๋Œ๋ฆฐ๋‹ค
    for i in range(256):
        j = (j + K[i] + S[i]) & 0xFF
        S[i], S[j] = S[j], S[i]
 
    out = bytearray(data)
    i = j = 0                                        # PRGA ์ง์ „์—๋งŒ j = 0
    for n in range(len(data)):
        i = (i + 1) & 0xFF
        j = (j + S[i]) & 0xFF
        S[i], S[j] = S[j], S[i]
        t = (S[i] + S[j]) & 0xFF
        out[n] ^= S[S[t]]                            # โ‘ข S[t] ๊ฐ€ ์•„๋‹ˆ๋ผ S[S[t]]
    return bytes(out), j
 
 
def stage2(data):
    """์ธ๋ฑ์Šค ํ™€์ง XOR. ์ž๊ธฐ์—ญํ•จ์ˆ˜."""
    return bytes(b ^ (0x44 if n & 1 else 0x85) for n, b in enumerate(data))
 
 
def stage1(data):
    """์ฒญํฌ๋งˆ๋‹ค S ๋ฐ•์Šค๋ฅผ ์ƒˆ๋กœ ๋งŒ๋“ค๋˜ KSA ์˜ j ๋งŒ ์ด์–ด๋ฐ›๋Š”๋‹ค. ์ž๊ธฐ์—ญํ•จ์ˆ˜."""
    out, j = [], 0
    for o in range(0, len(data), CHUNK):
        blk, j = rc4_variant(data[o:o + CHUNK], j)
        out.append(blk)
    return b"".join(out)
 
 
def decrypt(enc):
    return stage1(stage2(enc))       # ์•”ํ˜ธํ™”๊ฐ€ 1โ†’2 ์˜€์œผ๋‹ˆ ๋ณตํ˜ธ๋Š” 2โ†’1

๋Œ๋ ค ๋ณด๋ฉด ์ด๋ ‡๊ฒŒ ๋‚˜์˜จ๋‹ค.

solve.py ์‹คํ–‰ โ€” ์ž…๋ ฅ ์•ž 4๋ฐ”์ดํŠธ 1ddadbb9 ๊ฐ€ ffd8ffe0 ์œผ๋กœ ๋ฐ”๋€Œ๊ณ  file ์ด 303x64 JPEG ์œผ๋กœ ์ธ์‹ํ•œ๋‹ค
solve.py ์‹คํ–‰ โ€” ์ž…๋ ฅ ์•ž 4๋ฐ”์ดํŠธ 1ddadbb9 ๊ฐ€ ffd8ffe0 ์œผ๋กœ ๋ฐ”๋€Œ๊ณ  file ์ด 303x64 JPEG ์œผ๋กœ ์ธ์‹ํ•œ๋‹ค

ff d8 ff e0์œผ๋กœ ์‹œ์ž‘ํ•˜๊ณ  file์ด 303x64 JPEG ์œผ๋กœ ์žก๋Š”๋‹ค. ๊ทธ๋ฆผ๋„ ๋ฉ€์ฉกํ•˜๋‹ค.

๋ณตํ˜ธ๋œ JPEG โ€” ๋ฉ”๋ชจ์žฅ ๋ฉ”๋‰ด๋ฐ” "ํŒŒ์ผ(F) ํŽธ์ง‘(E) ์„œ์‹(O) ๋ณด๊ธฐ(V) ๋„์›€๋ง(H)" ์ด ๋˜๋ ทํ•˜๊ฒŒ ๋ณด์ธ๋‹ค
๋ณตํ˜ธ๋œ JPEG โ€” ๋ฉ”๋ชจ์žฅ ๋ฉ”๋‰ด๋ฐ” "ํŒŒ์ผ(F) ํŽธ์ง‘(E) ์„œ์‹(O) ๋ณด๊ธฐ(V) ๋„์›€๋ง(H)" ์ด ๋˜๋ ทํ•˜๊ฒŒ ๋ณด์ธ๋‹ค

๋ฉ”๋ชจ์žฅ ๋ฉ”๋‰ด๋ฐ”๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ํ”Œ๋ž˜๊ทธ๊ฐ€ ์—†๋‹ค. 303ร—64๋ฉด ๋ฉ”๋‰ด๋ฐ” ๋”ฑ ํ•œ ์ค„ ๋†’์ด๋ผ ์•„๋ž˜๊ฐ€ ์•„์˜ˆ ์—†๋‹ค.

๋ณตํ˜ธ๊ฐ€ ๋งž๋Š”์ง€ ์–ด๋–ป๊ฒŒ ํ™•์‹ ํ–ˆ๋‚˜

"ํ—ค๋”๊ฐ€ ๋งž์œผ๋ฉด ๋ณตํ˜ธ๊ฐ€ ๋งž๋‹ค"๋Š” ๊ฑด ์•ž์—์„œ ์ด๋ฏธ ํ•œ ๋ฒˆ ํ‹€๋ ธ๋‹ค. ๊ทธ๋ž˜์„œ ์ด๋ฒˆ์—” ์„ธ ๊ฐ€์ง€๋กœ ๊ต์ฐจ ํ™•์ธํ–ˆ๋‹ค.

  1. JPEG ๊ตฌ์กฐ๊ฐ€ ๋๊นŒ์ง€ ํŒŒ์‹ฑ๋œ๋‹ค. SOI ๋ถ€ํ„ฐ EOI ๊นŒ์ง€ ๋งˆ์ปค ๊ธธ์ด๊ฐ€ ์ „๋ถ€ ๋งž๊ณ , ์ค‘๊ฐ„์— ์ •์˜๋˜์ง€ ์•Š์€ ๋งˆ์ปค๊ฐ€ ๋‚˜์˜ค์ง€ ์•Š๋Š”๋‹ค. ํ‚ค์ŠคํŠธ๋ฆผ์ด ์–ด๊ธ‹๋‚˜๋ฉด ์••์ถ• ๋ฐ์ดํ„ฐ๊ฐ€ ๊นจ์ ธ ๋””์ฝ”๋”๊ฐ€ ์ค‘๊ฐ„์— ๋ฉˆ์ถ˜๋‹ค.
  2. ๊ทธ๋ฆผ์ด ์˜๋ฏธ๋ฅผ ๊ฐ€์ง„๋‹ค. ๋…ธ์ด์ฆˆ๊ฐ€ ์•„๋‹ˆ๋ผ ์ฝ์„ ์ˆ˜ ์žˆ๋Š” ํ•œ๊ธ€ ๋ฉ”๋‰ด ๋ฌธ์ž์—ด์ด ๋‚˜์˜จ๋‹ค. ์ด๊ฑด ์šฐ์—ฐ์œผ๋กœ ๋‚˜์˜ฌ ์ˆ˜ ์—†๋‹ค.
  3. ๋’ค์ชฝ PNG ์˜ zlib ์ŠคํŠธ๋ฆผ์ด ํ•ด์ œ๋œ๋‹ค. ํŒŒ์ผ ๋๋ถ€๋ถ„(์˜คํ”„์…‹ 4845 ์ดํ›„)์€ ์™„์ „ํžˆ ๋‹ค๋ฅธ ์ฒญํฌ์— ์†ํ•˜๋Š”๋ฐ, ๊ฑฐ๊ธฐ ์žˆ๋Š” ์••์ถ• ๋ฐ์ดํ„ฐ๊ฐ€ ์ •์ƒ ํ•ด์ œ๋˜๊ณ  ํฌ๊ธฐ๊นŒ์ง€ 179 ร— (1 + 439ร—4) ๋กœ ๋”ฑ ๋งž๋Š”๋‹ค. ์•ž์ชฝ๋งŒ ๋งž๊ณ  ๋’ค๊ฐ€ ํ‹€๋ฆฐ ์ƒํ™ฉ์ด์—ˆ๋‹ค๋ฉด ์—ฌ๊ธฐ์„œ ๋ฐ˜๋“œ์‹œ ๊ฑธ๋ฆฐ๋‹ค.

์„ธ ๋ฒˆ์งธ๊ฐ€ ํŠนํžˆ ์ค‘์š”ํ•˜๋‹ค. ์‚ฝ์งˆ ๋•Œ๋Š” 1๋ฒˆ๊ณผ 2๋ฒˆ์ด ๋ถ€๋ถ„์ ์œผ๋กœ ํ†ต๊ณผํ•ด์„œ ์†์•˜๋Š”๋ฐ, ํŒŒ์ผ ๋์—์„œ ๋…๋ฆฝ์ ์œผ๋กœ ๊ฒ€์ฆ๋˜๋Š” ์ง€ํ‘œ๋ฅผ ํ•˜๋‚˜ ์žก์•„ ๋‘๋ฉด ๊ทธ๋Ÿฐ ์ฐฉ๊ฐ์„ ๊ฑธ๋Ÿฌ๋‚ผ ์ˆ˜ ์žˆ๋‹ค.

5. ํŒŒ์ผ ํ•˜๋‚˜์— ๋„ท์ด ๋“ค์–ด ์žˆ์—ˆ๋‹ค

file์ด JPEG ์ด๋ผ๊ณ  ํ•ด์„œ ํŒŒ์ผ ์ „์ฒด๊ฐ€ JPEG ์ธ ๊ฑด ์•„๋‹ˆ๋‹ค. 7,415๋ฐ”์ดํŠธ ์ค‘ ์ด ๊ทธ๋ฆผ์ด ๋ช‡ ๋ฐ”์ดํŠธ๋ฅผ ์“ฐ๋Š”์ง€ ํ™•์ธํ•ด ๋ด์•ผ ํ•œ๋‹ค. ๋งˆ์ปค๋ฅผ ํ›‘๋Š” ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์งฐ๋‹ค.

d = Path("decrypted.jpg").read_bytes()
NAMES = {0xD8: "SOI", 0xD9: "EOI", 0xDA: "SOS", 0xC0: "SOF0",
         0xC4: "DHT", 0xDB: "DQT", 0xE0: "APP0"}
 
i = 0
while i < len(d) - 1:
    if d[i] == 0xFF and d[i + 1] in NAMES:
        m = d[i + 1]
        ln = int.from_bytes(d[i + 2:i + 4], "big")
        print(f"  @{i:<6} FF{m:02X} {NAMES[m]:<5} len={ln}")
    i += 1

๋งˆ์ปค ์Šค์บ” ๊ฒฐ๊ณผ โ€” EOI ๊ฐ€ 3271 ๊ณผ 4806 ๋‘ ๊ณณ, PNG ์‹œ๊ทธ๋‹ˆ์ฒ˜๊ฐ€ 4845 ์— ์žˆ๋‹ค
๋งˆ์ปค ์Šค์บ” ๊ฒฐ๊ณผ โ€” EOI ๊ฐ€ 3271 ๊ณผ 4806 ๋‘ ๊ณณ, PNG ์‹œ๊ทธ๋‹ˆ์ฒ˜๊ฐ€ 4845 ์— ์žˆ๋‹ค

EOI(FFD9)๊ฐ€ ๋‘ ๊ฐœ๋‹ค. ๊ทธ๋ฆฌ๊ณ  4845 ์— PNG ์‹œ๊ทธ๋‹ˆ์ฒ˜๊ฐ€ ์žˆ๋‹ค. ํŒŒ์ผ์€ ์ด๋ ‡๊ฒŒ ์ƒ๊ฒผ๋‹ค.

๋ฒ”์œ„๋‚ด์šฉ
0 ~ 3272JPEG โ‘  โ€” 303ร—64, ๋ฉ”๋‰ด๋ฐ”. SOI ๋ถ€ํ„ฐ EOI ๊นŒ์ง€ ์˜จ์ „ํ•˜๋‹ค
3273 ~ 4807SOI ๋„ ํ—ค๋”๋„ ์—†์ด ์Šค์บ” ๋ฐ์ดํ„ฐ๋งŒ ์žˆ๊ณ  EOI ๋กœ ๋๋‚œ๋‹ค
4808 ~ 484437๋ฐ”์ดํŠธ, JPEG ๋„ PNG ๋„ ์•„๋‹ˆ๋‹ค
4845 ~ 7414PNG โ€” 439ร—179

๋‘ ๋ฒˆ์งธ ๋ฉ์–ด๋ฆฌ๊ฐ€ ์„ค๋ช…์— ๋‚˜์˜จ "์ž˜๋ชป์ƒ์„ฑ๋œ ํŒŒ์ผ"์ด๋‹ค. JPEG ์€ SOIยท์–‘์žํ™”ํ‘œ(DQT)ยทํ”„๋ ˆ์ž„ ํ—ค๋”(SOF0)ยท ํ—ˆํ”„๋งŒํ‘œ(DHT)ยท์Šค์บ” ์‹œ์ž‘(SOS)์ด ์žˆ์–ด์•ผ ๋””์ฝ”๋”ฉ๋˜๋Š”๋ฐ, ๊ทธ๊ฒŒ ํ†ต์งธ๋กœ ์—†๊ณ  ์••์ถ•๋œ ํ”ฝ์…€ ๋ฐ์ดํ„ฐ๋งŒ ๋‚จ์•„ ์žˆ๋‹ค.

6. ํ—ค๋” ์—†๋Š” JPEG ์„ ๋˜์‚ด๋ฆฌ๊ธฐ

์—†๋Š” ํ—ค๋”๋Š” ๋งŒ๋“ค์–ด ๋ถ™์ด๋ฉด ๋œ๋‹ค. ๋งˆ์นจ ๊ฐ™์€ ์ธ์ฝ”๋”๊ฐ€ ๋งŒ๋“  JPEG โ‘ ์ด ๋ฐ”๋กœ ์•ž์— ์žˆ๋‹ค. ์–‘์žํ™”ํ‘œ์™€ ํ—ˆํ”„๋งŒํ‘œ๊ฐ€ ๊ฐ™์„ ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์œผ๋‹ˆ โ‘ ์˜ ํ—ค๋”๋ฅผ ๊ทธ๋Œ€๋กœ ์ด์‹ํ•ด ๋ณธ๋‹ค.

JPEG โ‘ ์—์„œ SOS ์„ธ๊ทธ๋จผํŠธ๊ฐ€ ๋๋‚˜๋Š” ์ง€์ (609 + 2 + 12 = 623)๊นŒ์ง€๊ฐ€ ํ—ค๋”๋‹ค.

d    = Path("decrypted.jpg").read_bytes()
hdr  = d[0:623]        # JPEGโ‘  ์˜ SOI ~ SOS ์„ธ๊ทธ๋จผํŠธ ๋
scan = d[3273:4808]    # JPEGโ‘ก ์˜ ์Šค์บ” ๋ฐ์ดํ„ฐ + EOI
Path("part2_graft.jpg").write_bytes(hdr + scan)

ํฌ๊ธฐ(SOF0 ์˜ ๊ฐ€๋กœยท์„ธ๋กœ)๋Š” โ‘ ์˜ 303ร—64 ๊ทธ๋Œ€๋กœ๋‹ค. ๋‹น์—ฐํžˆ ํ‹€๋ ธ์„ ํ…๋ฐ, JPEG ์€ ํฌ๊ธฐ๊ฐ€ ์–ด๊ธ‹๋‚˜๋„ ๋””์ฝ”๋”๊ฐ€ ์žˆ๋Š” ๋ฐ๊นŒ์ง€๋Š” ๊ทธ๋ ค ์ค€๋‹ค.

JPEGโ‘  ํ—ค๋”๋ฅผ ์ด์‹ํ•œ JPEGโ‘ก โ€” ํ™”๋ฉด์€ ์–ด๊ธ‹๋‚ฌ์ง€๋งŒ ์˜ค๋ฅธ์ชฝ์— ํ”Œ๋ž˜๊ทธ ์•ž๋ถ€๋ถ„ ๊ธ€์ž๊ฐ€ ๋˜๋ ทํ•˜๋‹ค
JPEGโ‘  ํ—ค๋”๋ฅผ ์ด์‹ํ•œ JPEGโ‘ก โ€” ํ™”๋ฉด์€ ์–ด๊ธ‹๋‚ฌ์ง€๋งŒ ์˜ค๋ฅธ์ชฝ์— ํ”Œ๋ž˜๊ทธ ์•ž๋ถ€๋ถ„ ๊ธ€์ž๊ฐ€ ๋˜๋ ทํ•˜๋‹ค

๋‚˜์™”๋‹ค. ํ™”๋ฉด์ด ์–ด๊ธ‹๋‚œ ๊ฑด ๊ฐ€๋กœ ํฌ๊ธฐ๊ฐ€ ์‹ค์ œ์™€ ๋‹ฌ๋ผ์„œ ์ค„์ด ๋ฐ€๋ฆฐ ๊ฒƒ๋ฟ์ด๊ณ , ๊ธ€์ž๋Š” ์ฝํžŒ๋‹ค.

์ œ๋Œ€๋กœ ๋œ ๊ฐ€๋กœ ํฌ๊ธฐ๋ฅผ ์ฐพ์œผ๋ ค๊ณ  ํ›„๋ณด๋ฅผ ํ›‘์–ด ํ•œ ์žฅ์— ๋ชจ์•„ ๋ดค๋‹ค.

๊ฐ€๋กœ ํฌ๊ธฐ ํ›„๋ณด 12๊ฐœ๋ฅผ ์„ธ๋กœ๋กœ ์Œ“์€ ๋ชฝํƒ€์ฃผ โ€” ์–ด๋А ํญ์—์„œ๋„ ํ”Œ๋ž˜๊ทธ ๊ธ€์ž ๋’ค๋กœ๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์—†์–ด ํšŒ์ƒ‰์œผ๋กœ ๋๋‚œ๋‹ค
๊ฐ€๋กœ ํฌ๊ธฐ ํ›„๋ณด 12๊ฐœ๋ฅผ ์„ธ๋กœ๋กœ ์Œ“์€ ๋ชฝํƒ€์ฃผ โ€” ์–ด๋А ํญ์—์„œ๋„ ํ”Œ๋ž˜๊ทธ ๊ธ€์ž ๋’ค๋กœ๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์—†์–ด ํšŒ์ƒ‰์œผ๋กœ ๋๋‚œ๋‹ค

์–ด๋А ํญ์œผ๋กœ ๋งž์ถฐ๋„ DH{How ๋’ค๋Š” ํšŒ์ƒ‰์ด๋‹ค. ์Šค์บ” ๋ฐ์ดํ„ฐ๊ฐ€ ๋”ฑ ๊ฑฐ๊ธฐ๊นŒ์ง€๋ผ๋Š” ๋œป์ด๋‹ˆ, ์ด ๊ทธ๋ฆผ์ด ๊ฐ€์ง„ ๊ธ€์ž๋Š” ๊ทธ๊ฒŒ ์ „๋ถ€๋‹ค. ํ™•๋Œ€ํ•ด์„œ ์ •ํ™•ํžˆ ์ฝ๋Š”๋‹ค.

ํ”Œ๋ž˜๊ทธ ์•ž๋ถ€๋ถ„์„ 4๋ฐฐ๋กœ ํ™•๋Œ€ โ€” ๋Œ€๋ฌธ์ž H ๋’ค์— ์†Œ๋ฌธ์ž o, w ๊ฐ€ ๋ถ„๋ช…ํ•˜๋‹ค
ํ”Œ๋ž˜๊ทธ ์•ž๋ถ€๋ถ„์„ 4๋ฐฐ๋กœ ํ™•๋Œ€ โ€” ๋Œ€๋ฌธ์ž H ๋’ค์— ์†Œ๋ฌธ์ž o, w ๊ฐ€ ๋ถ„๋ช…ํ•˜๋‹ค

DH{HOW๊ฐ€ ์•„๋‹ˆ๋ผ DH{How ๋‹ค. ์ž‘๊ฒŒ ๋ณผ ๋•Œ๋Š” ์ „๋ถ€ ๋Œ€๋ฌธ์ž๋กœ ๋ณด์˜€๋Š”๋ฐ ํ™•๋Œ€ํ•˜๋‹ˆ ow๊ฐ€ ์†Œ๋ฌธ์ž๋‹ค. ํ”Œ๋ž˜๊ทธ๋Š” ๋Œ€์†Œ๋ฌธ์ž๋ฅผ ํ‹€๋ฆฌ๋ฉด ๊ทธ๋ƒฅ ์˜ค๋‹ต์ด๋‹ˆ ์ด๋Ÿฐ ๊ฑด ๊ผญ ํ™•๋Œ€ํ•ด์„œ ํ™•์ธํ•ด์•ผ ํ•œ๋‹ค.

7. ์‚ฌ์ด์— ๋‚€ 37๋ฐ”์ดํŠธ

JPEG โ‘ก์˜ EOI ์™€ PNG ์‹œ๊ทธ๋‹ˆ์ฒ˜ ์‚ฌ์ด 37๋ฐ”์ดํŠธ๊ฐ€ ๋‚จ์•„ ์žˆ๋‹ค. ๊ทธ๋ƒฅ ๋คํ”„ํ•ด ๋ณธ๋‹ค.

xxd ๋กœ ๋ณธ 4808 ์˜คํ”„์…‹ 37๋ฐ”์ดํŠธ โ€” Find\0the\0String\0"_ENc_ECrypt" ๊ฐ€ ๊ทธ๋Œ€๋กœ ๋ณด์ธ๋‹ค
xxd ๋กœ ๋ณธ 4808 ์˜คํ”„์…‹ 37๋ฐ”์ดํŠธ โ€” Find\0the\0String\0"_ENc_ECrypt" ๊ฐ€ ๊ทธ๋Œ€๋กœ ๋ณด์ธ๋‹ค

Find\0the\0String\0"_ENc_ECrypt"\0\0\0...

๋„๋กœ ๋Š๊ธด ํ‰๋ฌธ์ด๋‹ค. _ENc_ECrypt โ€” ๋‘ ๋ฒˆ์งธ ์กฐ๊ฐ์ด๊ณ , ๋ฌธ์ œ ์„ค๋ช…์˜ DH{JPG_TXT_PNG} ์—์„œ TXT ์ž๋ฆฌ๋‹ค. ์—ฌ๊ธฐ์„œ ๊ทธ ์ค„์ด ํ˜•์‹ ์˜ˆ์‹œ๊ฐ€ ์•„๋‹ˆ๋ผ ์กฐ๊ฐ ์ถœ์ฒ˜ ์•ˆ๋‚ด์˜€๋‹ค๋Š” ๊ฑธ ์•Œ์•˜๋‹ค.

8. ์•ˆ ์—ด๋ฆฌ๋Š” PNG

๋‚จ์€ ๊ฑด PNG ๋‹ค. file์€ 439ร—179 RGBA ๋ผ๊ณ  ์ž˜ ์ฝ๋Š”๋ฐ ์ •์ž‘ ์ด๋ฏธ์ง€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ๋ชป ์—ฐ๋‹ค. ์ฒญํฌ๋ฅผ ์ˆœํšŒํ•˜๋ฉฐ CRC ๋ฅผ ๊ฒ€์‚ฌํ•ด ๋ณธ๋‹ค.

off = 8
while off + 8 <= len(d):
    ln, typ = struct.unpack(">I4s", d[off:off + 8])
    data = d[off + 8:off + 8 + ln]
    crc  = d[off + 8 + ln:off + 12 + ln]
    ok = struct.pack(">I", zlib.crc32(typ + data) & 0xFFFFFFFF) == crc
    print(f"  @{off:<6} {typ.decode():<5} len={ln:<12} CRC {'OK' if ok else '*** ๋ถˆ์ผ์น˜'}")
    off += 12 + ln

PNG ์ฒญํฌ ๊ฒ€์‚ฌ โ€” IHDRยทsRGBยทgAMA ๋Š” CRC OK, pHYs ๋ถ€ํ„ฐ ๋ถˆ์ผ์น˜๊ฐ€ ๋‚˜๊ณ  IDAT ๊ธธ์ด๊ฐ€ 16์–ต์œผ๋กœ ์ฝํžŒ๋‹ค
PNG ์ฒญํฌ ๊ฒ€์‚ฌ โ€” IHDRยทsRGBยทgAMA ๋Š” CRC OK, pHYs ๋ถ€ํ„ฐ ๋ถˆ์ผ์น˜๊ฐ€ ๋‚˜๊ณ  IDAT ๊ธธ์ด๊ฐ€ 16์–ต์œผ๋กœ ์ฝํžŒ๋‹ค

IHDRยทsRGBยทgAMA๊นŒ์ง€๋Š” CRC ๊ฐ€ ๋งž๋Š”๋‹ค. pHYs๋ถ€ํ„ฐ ์–ด๊ธ‹๋‚˜๊ณ , ๊ทธ ๋‹ค์Œ IDAT์˜ ๊ธธ์ด ํ•„๋“œ๊ฐ€ 1,601,793,917๋กœ ์ฝํžŒ๋‹ค. ํŒŒ์ผ์ด 2,570๋ฐ”์ดํŠธ์ธ๋ฐ 16์–ต์ด๋ผ๋‹ˆ ๋ง์ด ์•ˆ ๋œ๋‹ค.

์—ฌ๊ธฐ์„œ ๋‘ ๊ฐˆ๋ž˜๊ฐ€ ์žˆ๋‹ค. "PNG ๋ฅผ ๊ณ ์ณ์„œ ๊ทธ๋ฆผ์„ ๋ณธ๋‹ค"์™€ "์™œ ์ € ์ˆซ์ž๊ฐ€ ๋‚˜์™”๋Š”์ง€ ๋ณธ๋‹ค"๋‹ค. ๋‘˜ ๋‹ค ํ•ด ๋ดค๋Š”๋ฐ ์ •๋‹ต์€ ํ›„์ž์˜€๋‹ค.

8-1. ๊ณ ์ณ์„œ ๋ณด๊ธฐ

๋ฐฐ์น˜ ์ž์ฒด๋Š” ๋ฉ€์ฉกํ•˜๋‹ค. IEND๊ฐ€ 2562 ์— ์ œ๋Œ€๋กœ ์žˆ์œผ๋‹ˆ IDAT ๋ฐ์ดํ„ฐ๋Š” [91:2554]์ผ ์ˆ˜๋ฐ–์— ์—†๋‹ค. ๊ธธ์ด์™€ CRC ๋งŒ ๋‹ค์‹œ ๊ณ„์‚ฐํ•˜๋ฉด ์‚ด์•„๋‚œ๋‹ค.

idat = d[91:2554]                 # IDAT ํƒ€์ž…(87)+4 ~ IEND ๊ธธ์ดํ•„๋“œ(2558)-4
raw  = zlib.decompress(idat)      # 314,503 bytes
assert len(raw) == 179 * (1 + 439 * 4)     # ๋†’์ด ร— (ํ•„ํ„ฐ๋ฐ”์ดํŠธ 1 + ๊ฐ€๋กœ ร— RGBA)

zlib ํ•ด์ œ ํฌ๊ธฐ๊ฐ€ 179 ร— (1 + 439ร—4) = 314,503๊ณผ ์ •ํ™•ํžˆ ๋งž๋Š”๋‹ค. IHDR ์ด ๋งํ•œ ํฌ๊ธฐ๊ฐ€ ์ง„์งœ๋ผ๋Š” ๋œป์ด๊ณ , ๋ฐ์ดํ„ฐ๋„ ์˜จ์ „ํ•˜๋‹ค๋Š” ๋œป์ด๋‹ค. ์ฒญํฌ๋ฅผ ๋‹ค์‹œ ์กฐ๋ฆฝํ•˜๋ฉด ์—ด๋ฆฐ๋‹ค.

๋ณต๊ตฌํ•œ PNG โ€” ๋ฉ”๋ชจ์žฅ ๋ฉ”๋‰ด๋ฐ”๋งŒ ์žˆ๊ณ  ๊ทธ ์•„๋ž˜๋Š” ์™„์ „ํ•œ ๋ฐฑ์ง€๋‹ค
๋ณต๊ตฌํ•œ PNG โ€” ๋ฉ”๋ชจ์žฅ ๋ฉ”๋‰ด๋ฐ”๋งŒ ์žˆ๊ณ  ๊ทธ ์•„๋ž˜๋Š” ์™„์ „ํ•œ ๋ฐฑ์ง€๋‹ค

๊ทธ๋Ÿฐ๋ฐ ๋ฐฑ์ง€๋‹ค. ๋ฉ”๋‰ด๋ฐ” ์•„๋ž˜ ํ”ฝ์…€์„ ์ „๋ถ€ ์„ธ์–ด ๋ณด๋ฉด #ffffff ํ•œ ์ƒ‰๋ฟ์ด๋‹ค. ๊ทธ๋ฆด ๊ธ€์ž๊ฐ€ ์• ์ดˆ์— ์—†์—ˆ๋‹ค. ์„ค๋ช…์˜ "๋ฌธ์ œ ํŒŒ์ผ์ด ํ•˜๋‚˜ ์ž˜๋ชป์ƒ์„ฑ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค"๊ฐ€ ์ด๊ฑธ ๋งํ•œ ๊ฑฐ์˜€๋‹ค.

8-2. ์™œ 16์–ต์ด ๋‚˜์™”๋Š”์ง€ ๋ณด๊ธฐ

๊ทธ๋Ÿผ ๊ทธ ์ด์ƒํ•œ ๊ธธ์ด ํ•„๋“œ๋Š” ๋ญ˜๊นŒ. ๋ฐ”์ดํŠธ๋ฅผ ๊ทธ๋Œ€๋กœ ๋ณด๋ฉด 5f 79 6f 7d ๋‹ค. ASCII ๋กœ ์ฝ์œผ๋ฉด _yo} ๋‹ค. ํ˜น์‹œ ๋ชฐ๋ผ ํŒŒ์ผ ์ „์ฒด์—์„œ ASCII ๋Ÿฐ์„ ํ›‘์—ˆ๋‹ค.

for m in re.finditer(rb"[\x20-\x7e]{6,}", d):
    print(f"  @{m.start():<6} {m.group().decode()!r}")

ASCII ๋Ÿฐ ์Šค์บ” โ€” ์˜คํ”„์…‹ 4824 ์˜ _ENc_ECrypt ์™€ 4928 ์˜ ๋งˆ์ง€๋ง‰ ์กฐ๊ฐ์ด IDAT ์•ž์— ๋‚˜๋ž€ํžˆ ์žกํžŒ๋‹ค
ASCII ๋Ÿฐ ์Šค์บ” โ€” ์˜คํ”„์…‹ 4824 ์˜ _ENc_ECrypt ์™€ 4928 ์˜ ๋งˆ์ง€๋ง‰ ์กฐ๊ฐ์ด IDAT ์•ž์— ๋‚˜๋ž€ํžˆ ์žกํžŒ๋‹ค

@4928 '_yo}IDATx^'. ํ”Œ๋ž˜๊ทธ ์กฐ๊ฐ์ด IDAT ์ฒญํฌ์˜ ๊ธธ์ด ํ•„๋“œ ์ž๋ฆฌ์— ๊ทธ๋Œ€๋กœ ๋ฎ์—ฌ ์žˆ์—ˆ๋‹ค. ๊ทธ๋ฆผ์— ๊ธ€์ž๋ฅผ ๊ทธ๋ฆฌ๋Š” ๋Œ€์‹  ํŒŒ์ผ ๊ตฌ์กฐ๋ฅผ ๋ฎ์–ด์“ด ๊ฒƒ์ด๊ณ , ๊ทธ๋ž˜์„œ PNG ๊ฐ€ ์•ˆ ์—ด๋ฆฌ๊ณ  ๋‚ด์šฉ๋„ ๋ฐฑ์ง€์˜€๋‹ค. "์ž˜๋ชป์ƒ์„ฑ"๊ณผ "๋งˆ์ง€๋ง‰ ์‚ฌ์ง„ ํ”Œ๋ž˜๊ทธ ๊ธ€์ž์ˆ˜๋Š” 4๊ฐœ"๊ฐ€ ์—ฌ๊ธฐ์„œ ๋™์‹œ์— ๋งž์•„๋–จ์–ด์ง„๋‹ค โ€” _yo} ๋Š” ์ •ํ™•ํžˆ 4๊ธ€์ž๋‹ค.

PNG ๋ฅผ ๊ณ ์ณ์„œ ๊ทธ๋ฆผ๋งŒ ๋ดค๋‹ค๋ฉด ๋ฐฑ์ง€๋ฅผ ๋ณด๊ณ  ๋ง‰ํ˜”์„ ๊ฒƒ์ด๋‹ค. ๊นจ์ง„ ๊ตฌ์กฐ ํ•„๋“œ ์ž์ฒด๊ฐ€ ๋ฐ์ดํ„ฐ์ผ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒŒ ์ด ๋ฌธ์ œ์˜ ์ง„์งœ ๊ตํ›ˆ์ด๋ผ๊ณ  ์ƒ๊ฐํ•œ๋‹ค.

9. ์กฐ๊ฐ ๋งž์ถ”๊ธฐ

p1 = "DH{How"       # JPEGโ‘ก ์— ๊ทธ๋ ค์ง„ ํ…์ŠคํŠธ (JPEGโ‘  ํ—ค๋”๋ฅผ ์ด์‹ํ•ด ๋ Œ๋”)
p2 = "_ENc_ECrypt"  # JPEGโ‘ก EOI ์™€ PNG ์‚ฌ์ด ํ‰๋ฌธ 37๋ฐ”์ดํŠธ
p3 = "_yo}"         # PNG ์˜ IDAT ๊ธธ์ด ํ•„๋“œ ์ž๋ฆฌ์— ๋ฎ์—ฌ ์žˆ๋˜ 4๊ธ€์ž
 
print("FLAG =", p1 + p2 + p3)

์„ธ ์กฐ๊ฐ์„ ํ•ฉ์น˜๋Š” ์Šคํฌ๋ฆฝํŠธ ์‹คํ–‰ โ€” ์กฐ๊ฐ ์ถœ์ฒ˜์™€ ์™„์„ฑ๋œ ํ”Œ๋ž˜๊ทธ๊ฐ€ ์ถœ๋ ฅ๋œ๋‹ค
์„ธ ์กฐ๊ฐ์„ ํ•ฉ์น˜๋Š” ์Šคํฌ๋ฆฝํŠธ ์‹คํ–‰ โ€” ์กฐ๊ฐ ์ถœ์ฒ˜์™€ ์™„์„ฑ๋œ ํ”Œ๋ž˜๊ทธ๊ฐ€ ์ถœ๋ ฅ๋œ๋‹ค

DH{How_ENc_ECrypt_yo}

์„ค๋ช…์ด ์ค€ DH{JPG_TXT_PNG} ๊ตฌ์กฐ์™€ ์ •ํ™•ํžˆ ๋Œ€์‘ํ•œ๋‹ค.

์ถœ์ฒ˜์กฐ๊ฐ์–ด๋–ป๊ฒŒ ๊บผ๋ƒˆ๋‚˜
JPG (JPEG โ‘ก)DH{Howํ—ค๋”๊ฐ€ ์—†์–ด JPEG โ‘ ์˜ SOI~SOS ๋ฅผ ์ด์‹ํ•ด ๋ Œ๋”
TXT (ํ‰๋ฌธ 37B)_ENc_ECrypt๋‘ ์ด๋ฏธ์ง€ ์‚ฌ์ด์— ๋„ ๊ตฌ๋ถ„ ๋ฌธ์ž์—ด๋กœ ๋ฐ•ํ˜€ ์žˆ์Œ
PNG_yo}IDAT ๊ธธ์ด ํ•„๋“œ ์ž๋ฆฌ์— ๋ฎ์—ฌ ์žˆ์Œ (๊ทธ๋ž˜์„œ ํŒŒ์ผ์ด ์•ˆ ์—ด๋ฆผ)

10. ๋ฐฉ์–ด ๊ด€์ ์—์„œ

๋ฌธ์ œ๋ฅผ ๋– ๋‚˜ ์‹ค๋ฌด๋กœ ์˜ฎ๊ฒจ ๋†“๊ณ  ๋ณด๋ฉด ๋ช‡ ๊ฐ€์ง€๊ฐ€ ๋‚จ๋Š”๋‹ค.

ํ•˜๋“œ์ฝ”๋”ฉ ํ‚ค๋Š” ํ‚ค๊ฐ€ ์•„๋‹ˆ๋‹ค. funfun์€ .rdata ์— ํ‰๋ฌธ์œผ๋กœ ์žˆ์—ˆ๊ณ  strings ํ•œ ๋ฒˆ์— ๋‚˜์™”๋‹ค. ์‹คํ–‰ํŒŒ์ผ ์•ˆ์— ์žˆ๋Š” ๊ฐ’์€ ์‚ฌ์šฉ์ž์—๊ฒŒ ์žˆ๋Š” ๊ฐ’์ด๋‹ค. ์—ฌ๊ธฐ์— ๋”ํ•ด ์ด ๊ตฌํ˜„์€ ํ‚ค 6๋ฐ”์ดํŠธ ์ค‘ 3๋ฐ”์ดํŠธ๋ฅผ ์‹ค์ œ๋กœ๋Š” ์“ฐ์ง€๋„ ์•Š์•˜๋‹ค โ€” i & 6 ๋•Œ๋ฌธ์— ์œ ํšจ ํ‚ค ๊ณต๊ฐ„์ด ์‚ฌ์‹ค์ƒ 3๋ฐ”์ดํŠธ๋กœ ์ค„์—ˆ๋‹ค.

์ง์ ‘ ๋งŒ๋“  RC4 ๋ณ€ํ˜•์€ RC4 ๋ณด๋‹ค ์•ฝํ•˜๋‹ค. %๋ฅผ &๋กœ ๋ฐ”๊พธ๊ณ  ์ธ๋ฑ์‹ฑ์„ ํ•œ ๋ฒˆ ๋” ํ•˜๋Š” ์‹์˜ ์ˆ˜์ •์€ ์•ˆ์ „์„ฑ์„ ๋†’์ด์ง€ ์•Š๋Š”๋‹ค. ์˜คํžˆ๋ ค ์ด ๊ฒฝ์šฐ์—” ์ฒญํฌ๋งˆ๋‹ค ์ƒํƒœ๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ๋ฐ”๋žŒ์— ๊ฐ™์€ ํ‚ค์ŠคํŠธ๋ฆผ ํŒจํ„ด์ด 1024๋ฐ”์ดํŠธ๋งˆ๋‹ค ๋ฐ˜๋ณต๋˜๋Š” ๊ตฌ์กฐ๊ฐ€ ๋๋‹ค. ์•Œ๋ ค์ง„ ํ‰๋ฌธ(JPEG ํ—ค๋” ff d8 ff e0)์ด ์žˆ์œผ๋ฉด ํ‚ค๋ฅผ ๋ชฐ๋ผ๋„ ๊ณต๊ฒฉํ•  ์—ฌ์ง€๊ฐ€ ์ƒ๊ธด๋‹ค.

XOR ๋งŒ์œผ๋กœ๋Š” ๋ฌด๊ฒฐ์„ฑ์ด ์—†๋‹ค. ๋ณตํ˜ธ ๊ฒฐ๊ณผ๊ฐ€ ๋งž๋Š”์ง€ ํ‹€๋ฆฐ์ง€ ํ”„๋กœ๊ทธ๋žจ์€ ์•Œ ์ˆ˜ ์—†๋‹ค. ์‹ค์ œ๋กœ ๋‚˜๋Š” ์ž˜๋ชป๋œ ๋ณตํ˜ธ๋ณธ์œผ๋กœ๋„ "์ •์ƒ JPEG"์„ ์–ป์—ˆ๋‹ค(ํ—ค๋” 1024๋ฐ”์ดํŠธ๊ฐ€ ๋งž์•˜์œผ๋‹ˆ๊นŒ). ์•”ํ˜ธํ™”ํ•œ ๋ฐ์ดํ„ฐ์—๋Š” MAC ์ด๋‚˜ AEAD ๋ฅผ ๋ถ™์—ฌ์•ผ ์ด๋Ÿฐ ์ƒํ™ฉ์—์„œ ์ฆ‰์‹œ ๊ฑธ๋Ÿฌ์ง„๋‹ค.

ํฌ๋ Œ์‹ ์ชฝ์œผ๋กœ๋Š”, ํ™•์žฅ์ž์™€ file ์ถœ๋ ฅ์€ ํŒŒ์ผ์˜ ์•ž๋ถ€๋ถ„๋งŒ ๋ณธ๋‹ค๋Š” ๊ฑธ ๊ธฐ์–ตํ•ด ๋‘˜ ๋งŒํ•˜๋‹ค. ์ด๋ฒˆ์ฒ˜๋Ÿผ ํ•œ ํŒŒ์ผ์— ๋„ค ๋ฉ์–ด๋ฆฌ๊ฐ€ ์ด์–ด๋ถ™์–ด ์žˆ์–ด๋„ file์€ "JPEG"์ด๋ผ๊ณ ๋งŒ ํ•œ๋‹ค. EOI ์ดํ›„๋ฅผ ํ™•์ธํ•˜๋Š” ์Šต๊ด€, ๊ทธ๋ฆฌ๊ณ  ๊ตฌ์กฐ ํ•„๋“œ์˜ ๊ฐ’์ด ๋น„์ƒ์‹์ ์ด๋ฉด ๊ทธ๊ฒŒ ์˜ค์—ผ์ด ์•„๋‹ˆ๋ผ ๋ฐ์ดํ„ฐ์ผ ์ˆ˜ ์žˆ๋‹ค๋Š” ์‹œ๊ฐ์ด ์ด ๋ฌธ์ œ์˜ ๋งˆ์ง€๋ง‰ ๊ด€๋ฌธ์ด์—ˆ๋‹ค.


์ •๋ฆฌ

  • Enc.exe๋Š” flag.jpg๋ฅผ ๋‘ ๋ฒˆ ๋ฎ์–ด์“ด๋‹ค. 1๋‹จ๊ณ„๋Š” RC4 ๋ณ€ํ˜•, 2๋‹จ๊ณ„๋Š” ์ธ๋ฑ์Šค ํ™€์ง XOR
  • RC4 ๋ณ€ํ˜•์˜ ํ•จ์ • ์…‹: key[i & 6], ํ‚ค์ŠคํŠธ๋ฆผ S[S[t]], 0x400 ์ฒญํฌ๋งˆ๋‹ค S ๋ฐ•์Šค ์žฌ์ƒ์„ฑ
  • ์…‹์งธ๋ฅผ ๋†“์น˜๋ฉด ์•ž 1024๋ฐ”์ดํŠธ๋งŒ ๋ณตํ˜ธ๋ผ "ํ—ค๋”๋Š” ๋งž๋Š”๋ฐ ๊ทธ๋ฆผ์ด ๊นจ์ง„" ์ƒํƒœ๊ฐ€ ๋œ๋‹ค
  • ๋ณตํ˜ธ๋ณธ์€ JPEG + ํ—ค๋” ์—†๋Š” JPEG + ํ‰๋ฌธ 37B + PNG ๊ฐ€ ์ด์–ด๋ถ™์€ ํ•œ ํŒŒ์ผ
  • ํ”Œ๋ž˜๊ทธ ์„ธ ์กฐ๊ฐ ์ค‘ ๋งˆ์ง€๋ง‰์€ PNG ์˜ IDAT ๊ธธ์ด ํ•„๋“œ ์ž๋ฆฌ์— ์žˆ์–ด ๊ทธ๋ฆผ์œผ๋กœ๋Š” ์•ˆ ๋ณด์ธ๋‹ค

์ด ๊ธ€์ด ๋„์›€์ด ๋๋‚˜์š”?

Comments

๋Œ“๊ธ€

0๊ฐœ

๋Œ“๊ธ€์„ ๋‚จ๊ธฐ๋ ค๋ฉด ๋กœ๊ทธ์ธ์ด ํ•„์š”ํ•ด์š”. (๋„ค์ด๋ฒ„ ยท ๊ตฌ๊ธ€ ๊ณ„์ •)

๋Œ“๊ธ€ ๋ถˆ๋Ÿฌ์˜ค๋Š” ์ค‘โ€ฆ

Related

๊ด€๋ จ ๊ธ€

3๊ฐœ
[๐Ÿฅˆ Silver 2] ํ•ดํ‚น๋‹นํ•œ VM ์ด๋ฏธ์ง€์—์„œ ์ฑ„๊ตด๊ธฐ๊ฐ€ ์‚ผํ‚จ ํ”Œ๋ž˜๊ทธ ๋˜์ฐพ๊ธฐ โ€” DreamHack Infested Terran ํ’€์ด
blog

[๐Ÿฅˆ Silver 2] ํ•ดํ‚น๋‹นํ•œ VM ์ด๋ฏธ์ง€์—์„œ ์ฑ„๊ตด๊ธฐ๊ฐ€ ์‚ผํ‚จ ํ”Œ๋ž˜๊ทธ ๋˜์ฐพ๊ธฐ โ€” DreamHack Infested Terran ํ’€์ด

bzImage + rootfs.ext2 ๋‘ ํŒŒ์ผ๋งŒ ์ฃผ๋Š” ๋ฌธ์ œ. ์ด๋ฏธ์ง€๋ฅผ ๋งˆ์šดํŠธํ•˜์ง€ ์•Š๊ณ  ์—ด์–ด๋ณด๋ฉด buildroot ๋ฐ”์ด๋„ˆ๋ฆฌ๋“ค ์‚ฌ์ด์— glibc๋กœ ๋นŒ๋“œ๋œ ๋‘ ๊ฐœ๊ฐ€ ์„ž์—ฌ ์žˆ๋‹ค. /home/ubuntu/.helper๋Š” ํ‘œ์ค€์ž…๋ ฅ์œผ๋กœ ๋ฐ›์€ ๊ฐ’์„ argv[0]="[kworker]"๋กœ ์œ„์žฅํ•ด /usr/bin/sl์— ๋„˜๊ธฐ๊ณ , sl์€ ์ž…๋ ฅ 36๊ธ€์ž๋ฅผ ํž™์— ํฉ๋ฟŒ๋ฆฐ ๋’ค ๋ˆ„์ ํ•ฉ์„ ํ•˜๋“œ์ฝ”๋”ฉ๋œ ๊ฐ’๊ณผ ๋น„๊ตํ•œ๋‹ค. ๊ฒ€์ฆ์‹์ด ์‚ผ๊ฐํ–‰๋ ฌ์ด๋ผ ์ด์›ƒํ•œ ๋‘ ํ•ญ์„ ๋นผ๋Š” ๊ฒƒ๋งŒ์œผ๋กœ ํ•œ ๊ธ€์ž์”ฉ ๊ทธ๋Œ€๋กœ ๋ณต์›๋œ๋‹ค.
#dreamhack#ctf#reversing+7
2026-07-25#dreamhack +5
[๐Ÿฅ‡ Gold 4] ํŒŒ์ผ ์ปค์„œ๋ฅผ 656๋ฒˆ ํฉ๋ฟŒ๋ฆฐ ๊ฒ€์ฆ๊ธฐ ๋˜๊ฐ๊ธฐ โ€” DreamHack fverify ํ’€์ด
blog

[๐Ÿฅ‡ Gold 4] ํŒŒ์ผ ์ปค์„œ๋ฅผ 656๋ฒˆ ํฉ๋ฟŒ๋ฆฐ ๊ฒ€์ฆ๊ธฐ ๋˜๊ฐ๊ธฐ โ€” DreamHack fverify ํ’€์ด

fverify ๋Š” fseek(SEEK_CUR) 4949๋ฒˆ๊ณผ 1๋ฐ”์ดํŠธ fread 656๋ฒˆ์œผ๋กœ๋งŒ ์ด๋ฃจ์–ด์ง„ ์ง์„  ์ฝ”๋“œ๋‹ค. ํŒŒ์ผ ์˜คํ”„์…‹์ด ์ฝ”๋“œ ์–ด๋””์—๋„ ์•ˆ ์ ํ˜€ ์žˆ์–ด objdump ์ถœ๋ ฅ๋งŒ์œผ๋กœ๋Š” ๋ฌด์—‡์„ ๊ฒ€์‚ฌํ•˜๋Š”์ง€ ์•Œ ์ˆ˜ ์—†๋‹ค. ์ปค์„œ ์ด๋™์„ ๊ทธ๋Œ€๋กœ ์žฌ์ƒํ•ด ์Šฌ๋กฏ๊ณผ ํŒŒ์ผ ์˜คํ”„์…‹์„ ๋‹ค์‹œ ์ด์–ด ๋ถ™์ด๋ฉด 656๋ฐ”์ดํŠธ ์ •๋‹ต ํŒŒ์ผ์ด ํ†ต์งธ๋กœ ๋ณต์›๋œ๋‹ค.
#dreamhack#ctf#reversing+5
2026-08-17#dreamhack +4
[๐Ÿฅ‡ Gold 4] ์ง€๊ทธ์žฌ๊ทธ๋กœ ์ ‘ํžŒ ํ”Œ๋ž˜๊ทธ โ€” DreamHack quilt ํ’€์ด
blog

[๐Ÿฅ‡ Gold 4] ์ง€๊ทธ์žฌ๊ทธ๋กœ ์ ‘ํžŒ ํ”Œ๋ž˜๊ทธ โ€” DreamHack quilt ํ’€์ด

๋ฐฐํฌ๋œ quilt๋Š” ํ”Œ๋ž˜๊ทธ๋ฅผ ๊ฒ€์‚ฌํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ์ด ์•„๋‹ˆ๋ผ ํ”Œ๋ž˜๊ทธ๋ฅผ ๊ทธ๋ฆผ์œผ๋กœ ๊ตฝ๋Š” ์ธ์ฝ”๋”์˜€๋‹ค. /dev/urandom 192๋ฐ”์ดํŠธ ํ•œ๋ณตํŒ์— ์ธ์ž๋ฅผ ๊ทธ๋Œ€๋กœ ์–น๊ณ , 6๋น„ํŠธ์”ฉ ์ž˜๋ผ 64์ƒ‰ ํŒ”๋ ˆํŠธ๋กœ 32ร—32 ๋ธ”๋ก์„ ์น ํ•œ๋‹ค. ๋˜๋Œ๋ฆฌ๋Š” ๊ธธ๋ชฉ์— ๋†“์ธ ํ•จ์ •์€ ํ™€์ˆ˜ ๊ฒฉ์žํ–‰์„ ์ขŒ์šฐ๋กœ ๋’ค์ง‘๋Š” ํ•œ ์ค„์ด๋‹ค.
#dreamhack#ctf#reversing+4
2026-08-20#dreamhack +4