๋ฌธ์ : DreamHack โ baseball ๋ถ๋ฅ: Reversing ๋์ด๋: ๐ฅ ์ค๋ฒ 3 FLAG:
DH{Did_you_know_how_base64_works}
๋ฌธ์ ์ค๋ช ์ ์งง๋ค.
๋ฐ์ด๋๋ฆฌ๋ฅผ ๋ถ์ํ์ฌ ํ๋๊ทธ๋ฅผ ์ป์ด์ฃผ์ธ์. ์ป์ ํ๋๊ทธ๋
DH{<flag>}ํ์์ผ๋ก ์ธ์ฆํด์ฃผ์ธ์.
baseball ๋ฐ์ด๋๋ฆฌ์ text_in.txtยทtext_out.txtยทflag_out.txt ์ธ ํ
์คํธ ํ์ผ์ด ์ฃผ์ด์ง๋ค. ๋ฐ์ด๋๋ฆฌ๋ฅผ ๋ถ์ํด ๋ณด๋ฉด ์ด๊ฑด ์ปค์คํ
์ํ๋ฒณ base64 ์ธ์ฝ๋๋ค. ์ํ๋ฒณ(table)๋ง ์๋ฉด flag_out์ ๋ณตํธํ ์ ์๋๋ฐ, table์ ์ ์ค๋ค. ๋์ ํ๋ฌธ๊ณผ ๊ทธ ์ธ์ฝ๋ฉ ๊ฒฐ๊ณผ ํ ์์ด ์ฃผ์ด์ ธ์, ๊ทธ๊ฑธ๋ก ์ํ๋ฒณ์ ์ญ์ผ๋ก ์บ๋ผ ์ ์๋ค.

๋ฌธ์ ๊ฐ์
| ํญ๋ชฉ | ๋ด์ฉ |
|---|---|
| ๋ฌธ์ ๋ช | baseball |
| ๋์ด๋ | ๐ฅ ์ค๋ฒ 3 |
| ๋ถ๋ฅ | Reversing (x86-64 ELF, stripped) |
| ์ ๊ณต ํ์ผ | baseball, text_in.txt, text_out.txt, flag_out.txt |
| ๋ชฉํ | ์ปค์คํ base64 ์ํ๋ฒณ ๋ณต์ โ flag_out ๋ณตํธ |
| ํต์ฌ ๊ธฐ๋ฒ | known-plaintext๋ก ์ปค์คํ ์ํ๋ฒณ ์ถ์ถ |
table ํ์ผ์ด ์์ด๋, ํ๋ฌธ/์ํธ๋ฌธ ํ ์์ด๋ฉด ์ํ๋ฒณ์ ํต์งธ๋ก ๋์ด๋ฆด ์ ์๋ค.
๋ฐฐ๊ฒฝ โ ์ปค์คํ ์ํ๋ฒณ base64์ known-plaintext
base64๋ 3๋ฐ์ดํธ๋ฅผ 6๋นํธ์ฉ ๋์ด 4๊ธ์๋ก ๋ฐ๊พธ๋ ์ธ์ฝ๋ฉ์ด๋ค. ํ์ค ์ํ๋ฒณ์ A-Z a-z 0-9 + / 64๊ธ์๋ก ์ ํด์ ธ ์์ง๋ง, ๊ทธ 64๊ธ์๋ฅผ ๋ค๋ฅธ ์์(์ปค์คํ
์ํ๋ฒณ) ๋ก ๋ฐ๊ฟ์น๊ธฐํ๋ฉด ๊ฒ๋ชจ์ต๋ง ๋ค๋ฅธ base64๊ฐ ๋๋ค. ๋นํธ ๋ถํด ๋ฐฉ์์ ๊ทธ๋๋ก๊ณ , 6๋นํธ ๊ฐ์ ์ด๋ค ๊ธ์๋ก ํ๊ธฐํ๋๋๋ง ๋ฌ๋ผ์ง๋ค.
ํต์ฌ์ ์ฌ๊ธฐ ์๋ค. base64๋ ์์น๋ณ๋ก "๊ฐ โ ๊ธ์"๊ฐ ์ ํด์ง ์์น ๋ ๋ฆฝ์ ์ธ์ฝ๋ฉ์ด๋ผ, ๊ฐ์ ํ๋ฌธ์ ํ์ค base64์ ์ปค์คํ base64๋ก ๊ฐ๊ฐ ์ธ์ฝ๋ฉํ๋ฉด ๊ฐ์ ์์น์ ๊ฐ์ 6๋นํธ ๊ฐ์ด ์จ๋ค. ํ๊ธฐ ๊ธ์๋ง ๋ค๋ฅผ ๋ฟ์ด๋ค. ๊ทธ๋์ ํ๋ฌธ๊ณผ ์ปค์คํ ์ธ์ฝ๋ฉ ๊ฒฐ๊ณผ๋ฅผ ๋๋ํ ๋์ผ๋ฉด, ๊ฐ ์์น์์ "์ด 6๋นํธ ๊ฐ์ ์ด ์ปค์คํ ๊ธ์๋ก ํ๊ธฐ๋๋ค"๋ฅผ ํ๋์ฉ ์์๋ผ ์ ์๋ค. ์ด๊ฒ์ด known-plaintext ๊ณต๊ฒฉ์ด๋ค โ ์๋ ค์ง ํ๋ฌธ/์ํธ๋ฌธ ์์ผ๋ก ํค(์ฌ๊ธฐ์ ์ํ๋ฒณ)๋ฅผ ๋ณต์ํ๋ค.
๐ฌ ์ ์ฐฐ โ ์ธ ํ์ผ๊ณผ ๋ฐ์ด๋๋ฆฌ
๋จผ์ ์ธ ํ ์คํธ ํ์ผ์ ๋ณธ๋ค.
head -c 70 text_in.txt # ํ๋ฌธ (Pepero ์ค๋ช
)
head -c 70 text_out.txt # ์ปค์คํ
base64
cat flag_out.txt # flag ์ธ์ฝ๋ฉ
text_in.txt๋ ์ฝ์ ์ ์๋ ์์ด ๋ฌธ์ฅ์ด๊ณ , text_out.txt๋ base64์ฒ๋ผ ์๊ธด ๋ฌธ์์ด์ด๋ค(๊ธธ์ด๋ 149๋ฐ์ดํธ โ 200์๋ก base64 ๋น์จ๊ณผ ๋ง๋ค). flag_out.txt๋ ์งง์ ์ธ์ฝ๋ฉ ๋ฌธ์์ด์ด๋ค. ๋ฐ์ด๋๋ฆฌ๊ฐ ๋ฌด์์ ํ๋์ง ๋์ค์ด์
๋ธ๋ก ํ์ธํ๋ค.

usage๋ ./baseball <table filename> <input filename>์ด๊ณ , ์ธ์ฝ๋ฉ ํจ์(0x1289)๋ shr al, 0x2 ๊ฐ์ ํ์ค base64 ๋นํธ ๋ถํด๋ฅผ ํ ๋ค ๊ฒฐ๊ณผ 6๋นํธ ๊ฐ์ผ๋ก ์ ์ญ 0x4040์ table์ ์ธ๋ฑ์ฑํ๋ค. ์ฆ table ํ์ผ์ 64๊ธ์๊ฐ ๊ณง ์ถ๋ ฅ ์ํ๋ฒณ์ด๋ค. ๊ทธ๋ฐ๋ฐ ๊ทธ table ํ์ผ์ ์ฃผ์ด์ง์ง ์์๋ค โ ์ด๊ฒ ์ฌ์ค์ ๋น๋ฐ ํค๋ค.
๐ฃ ํต์ฌ โ ์๋ ค์ง ์์ผ๋ก ์ํ๋ฒณ ๋ณต์
text_in๊ณผ text_out์ด ๋ฐ๋ก ๊ทธ ์๋ ค์ง ์์ด๋ค. text_in์ ํ์ค base64๋ก ์ธ์ฝ๋ฉํ๋ฉด ์์น๋ณ 6๋นํธ ๊ฐ์ ์ ์ ์๊ณ , ๊ฐ์ ์์น์ text_out ๊ธ์๊ฐ ๊ทธ ๊ฐ์ ์ปค์คํ
ํ๊ธฐ๋ค.
import base64
STD = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
std_b64 = base64.b64encode(open("text_in.txt","rb").read()).decode()
ct = open("text_out.txt").read().strip()
custom = {}
for a, b in zip(std_b64, ct): # ๊ฐ์ ์์น๋ผ๋ฆฌ
if a == "=": continue
custom[STD.index(a)] = b # ๊ฐ STD.index(a) ๋ ์ปค์คํ
์์ b ๋ก ํ๊ธฐ
์ด๋ ๊ฒ ํ๋ฉด 200์ ํ
์คํธ์์ 64์นธ ์ํ๋ฒณ ์ค 53์นธ์ด ๋ณต์๋๋ค(๋๋จธ์ง 11์นธ์ ์ด ํ
์คํธ์ ์ ๋์จ ๊ฐ์ด๋ค). ๋ณต์์ด ์ ํํ์ง ํ์ธํ๋ ค๊ณ , ๋ณต์ํ ์ํ๋ฒณ์ผ๋ก text_in์ ๋ค์ ์ธ์ฝ๋ฉํด text_out๊ณผ ๊ฐ์์ง ๋์กฐํ๋ค.

์ฌ์ธ์ฝ๋ฉ ๊ฒฐ๊ณผ๊ฐ text_out๊ณผ ์ ํํ ์ผ์นํ๋ค โ ์ํ๋ฒณ์ด ๋ง๋ค๋ ๋ป์ด๋ค. ๊ทธ๋ฆฌ๊ณ flag_out์ ์ด 53์นธ ์์ ๊ธ์๋ง ์ฐ๊ณ ์์ด ๊ทธ๋๋ก ๋ณตํธ๋๋ค.
โถ ์ฝ์ง: ๋ณตํธ ๊ฒฐ๊ณผ๊ฐ DH ํ์์ด ์๋๋ผ ๋ฌธ์ฅ, ๊ณต๋ฐฑ์งธ ์ ์ถํ๋ค๊ฐ ์ค๋ต
flag_out์ ๋ณตํธํ๋ DH{...}๊ฐ ์๋๋ผ "Did you know how base64 works"๋ผ๋ ํ๋ฒํ ์์ด ๋ฌธ์ฅ์ด ๋์๋ค. ์ฒ์์ "flag_out์ด ์ง์ง ํ๋๊ทธ๊ฐ ์๋๋ผ ํํธ์ธ๊ฐ?" ์ถ์ด ๋ฐ์ด๋๋ฆฌ์ ์จ์ flag๊ฐ ์๋, table ์์ฒด๊ฐ flag์ธ๊ฐ ํ์ฐธ ๋ค์ก๋ค.
๊ฒฐ๊ตญ ์ด ๋ฌธ์ฅ์ด ๊ณง ํ๋๊ทธ ๋ด์ฉ์ด์๋ค. ๋ฌธ์ ์ค๋ช
์ด DH{<flag>} ํ์์ด๋ผ ํ์ผ๋ ๊ฐ์ธ๋ฉด ๋๋๋ฐ, ๊ณต๋ฐฑ์ด ๋ฌธ์ ์๋ค. DH{Did you know how base64 works}๋ก ๋๋๋ ์ค๋ต. DreamHack ํ๋๊ทธ๋ ๊ณต๋ฐฑ ๋์ ์ธ๋์ค์ฝ์ด๋ฅผ ์ฐ๋ ๊ด๋ก๋ผ, DH{Did_you_know_how_base64_works}๋ก ๋ฐ๊พธ๋ ํต๊ณผํ๋ค. ๋ณตํธ ๊ฒฐ๊ณผ๋ฅผ ๊ทธ๋๋ก ๋ด๊ธฐ ์ ์ ํ๋๊ทธ ํ์(๊ณต๋ฐฑยท๋์๋ฌธ์)์ ํ ๋ฒ ์ ๊ทํํ๋ ์ต๊ด์ด ํ์ํ๋ค.
๐ Full Exploit
๋ณต์ํ ์ํ๋ฒณ์ผ๋ก flag_out์ ์ปค์คํ
โํ์ค ๋ฌธ์๋ก ๋๋๋ฆฐ ๋ค ํ์ค base64 ๋์ฝ๋ํ๊ณ , ๊ณต๋ฐฑ์ ์ธ๋์ค์ฝ์ด๋ก ๋ฐ๊ฟ ํ๋๊ทธ ํ์์ ๋ง์ถ๋ค.
import base64
STD = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
std_b64 = base64.b64encode(open("text_in.txt","rb").read()).decode()
ct = open("text_out.txt").read().strip()
custom = {}
for a, b in zip(std_b64, ct):
if a != "=": custom[STD.index(a)] = b
inv = {b: STD[v] for v, b in custom.items()} # ์ปค์คํ
๊ธ์ โ ํ์ค ๊ธ์
flag_ct = open("flag_out.txt").read().strip()
std_flag = "".join("=" if c == "=" else inv[c] for c in flag_ct)
plain = base64.b64decode(std_flag).decode()
print("DH{" + plain.replace(" ", "_") + "}")
๋ณต์ํ ์ปค์คํ
์ํ๋ฒณ: 53/64 ์ํธ๋ฆฌ
flag_out ๋ณตํธ: 'Did you know how base64 works'
FLAG: DH{Did_you_know_how_base64_works}๐ ๊ฒฐ๋ก
์ปค์คํ ์ํ๋ฒณ์ ์๋ ค์ง ํ๋ฌธ ํ ์์ด๋ฉด ๋ฌด๋์ง๋ค.
table(์ํ๋ฒณ)์ ๋น๋ฐ๋ก ๊ฐ์ท์ง๋ง, ํ๋ฌธ๊ณผ ๊ทธ ์ธ์ฝ๋ฉ ๊ฒฐ๊ณผ๊ฐ ํจ๊ป ๋ ธ์ถ๋๋ ์๊ฐ ์ํ๋ฒณ์ ์์น๋ณ ๋์์ผ๋ก ๊ทธ๋๋ก ๋ณต์๋๋ค. base64์ฒ๋ผ ์์น ๋ ๋ฆฝ์ ์ธ ์ธ์ฝ๋ฉ์ ํนํ ์ทจ์ฝํ๋ค โ ํ ์์น์ ๋์์ด ๋ค๋ฅธ ์์น์ ๋ฌด๊ดํ๊ฒ ์ฑ๋ฆฝํ๋ฏ๋ก, ์ถฉ๋ถํ ๊ธด known-plaintext๋ง ์์ผ๋ฉด ์ํ๋ฒณ ๋๋ถ๋ถ์ด ๋๋ฌ๋๋ค. ์ํ๋ฒณ์ ๋ฐ๊พผ "์ปค์คํ " base64๋ ๋๋ ํ์ผ ๋ฟ ์ํธ๊ฐ ์๋๋ค.
๋ณตํธ ๊ฒฐ๊ณผ๋ ํ๋๊ทธ ํ์์ผ๋ก ์ ๊ทํํด์ ์ ์ถํ๋ค.
๋ณตํธ๋ก ์ป์ ์๋ฌธ์ด ๊ณง ๋ต์ด๋ผ๋, ๋ํ ํ๋๊ทธ ํ์(๊ณต๋ฐฑโ์ธ๋์ค์ฝ์ด, ๋์๋ฌธ์, ๊ฐ์ธ๋ DH{})์ ๋ง์ถ๋ ๋ง์ง๋ง ํ ๋จ๊ณ๊ฐ ํ์ํ๋ค. ์๋ฌธ์ ๊ทธ๋๋ก ๋ด์ ์ค๋ต์ด ๋์ค๋ฉด "ํ์ด๊ฐ ํ๋ ธ๋" ์์ฌํ๊ธฐ ์ฌ์ด๋ฐ, ํ์ ๋ฌธ์ ์ธ ๊ฒฝ์ฐ๊ฐ ๋ง๋ค. ๋ณตํธ โ ํ์ ์ ๊ทํ โ ์ ์ถ ์์๋ฅผ ๊ธฐ์ตํ๋ฉด ์ด๋ฐ ํ๋ฐ์ง์ ์ค์ผ ์ ์๋ค.
Comments
๋๊ธ
๋๊ธ์ ๋จ๊ธฐ๋ ค๋ฉด ๋ก๊ทธ์ธ์ด ํ์ํด์. (๋ค์ด๋ฒ ยท ๊ตฌ๊ธ ๊ณ์ )
๋๊ธ ๋ถ๋ฌ์ค๋ ์คโฆ