๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
โœ’๏ธ Capture The Flag (CTF)

[Dreamhack CTF Season 3] ROT128 Write Up

by A Lim Han 2023. 11. 26.

๐Ÿชฎ ROT128 Write Up

1.  ๋ฌธ์ œ ์„ค๋ช… ํ™•์ธ ํ›„ ํŒŒ์ผ ๋‹ค์šด๋กœ๋“œ

2.  ๋‹ค์šด๋ฐ›์€ rot128.py ํŒŒ์ผ ์˜คํ”ˆ ํ›„ ์ฝ”๋“œ ๋ถ„์„


โ‘  hex_list ์ดˆ๊ธฐํ™”

hex_list = [(hex(i)[2:].zfill(2).upper()) for i in range(256)]

 

์ฝ”๋“œ ์„ค๋ช…
range(256) 0๋ถ€ํ„ฐ 255๊นŒ์ง€์˜ ์ˆซ์ž ์ƒ์„ฑ
hex(i) ์ •์ˆ˜ i๋ฅผ 16์ง„์ˆ˜ ๋ฌธ์ž์—ด๋กœ ๋ณ€ํ™˜
[2:] '0x' ์ œ๊ฑฐ  ๋‚˜๋จธ์ง€ ๋ถ€๋ถ„์„ ๊ฐ€์ ธ์˜ด
zfill(2) ๋ฌธ์ž์—ด์˜ ๊ธธ์ด๋ฅผ 2๋กœ ์„ค์ •
upper() ํ•ด๋‹น ๋‚ด์šฉ ๋Œ€๋ฌธ์ž๋กœ ๋ณ€ํ™˜

โ‘ก ์›๋ณธ flag.png ํŒŒ์ผ ์ฝ๊ธฐ

with open('flag.png', 'rb') as f:
ใ…คใ…คplain_s = f.read()

 

++  flag.png ํŒŒ์ผ์„ ์ด์ง„ ๋ชจ๋“œ('rb': read binary)๋กœ ์—ด์–ด์„œ ๋‚ด์šฉ์„ plain_s์— ์ €์žฅ


โ‘ข plain_list ์ดˆ๊ธฐํ™”

plain_list = [hex(i)[2:].zfill(2).upper() for i in plain_s]

 

++  plain_s์— ์žˆ๋Š” ๊ฐ ๋ฐ”์ดํŠธ๋ฅผ 16์ง„์ˆ˜๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ๋ฆฌ์ŠคํŠธ์— ์ €์žฅ


โ‘ฃ ์•”ํ˜ธํ™” ๋ฆฌ์ŠคํŠธ ์ƒ์„ฑ ๋ฐ ์ดˆ๊ธฐํ™”

enc_list = list(range(len(plain_list)))

โ‘ค ์•”ํ˜ธํ™” ๋ฃจํ”„ ์ˆ˜ํ–‰

for i in range(len(plain_list)):
ใ…คใ…คhex_b = plain_list[i]
ใ…คใ…คindex = hex_list.index(hex_b)
ใ…คใ…คenc_list[i] = hex_list[(index + 128) % len(hex_list)]

 

์ฝ”๋“œ ์„ค๋ช…
hex_b = plain_list[i] ํ˜„์žฌ ๋ฐ”์ดํŠธ์˜ 16์ง„์ˆ˜ ํ‘œํ˜„
index = hex_list.index(hex_b) hex_b๊ฐ€ hex_list์—์„œ ์–ด๋””์— ์œ„์น˜ํ•˜๋Š”์ง€ ํƒ์ƒ‰
hex_list[(index + 128) % len(hex_list) hex_list์—์„œ index์— 128์„ ๋”ํ•จ
+
๋ฆฌ์ŠคํŠธ ๊ธธ์ด๋กœ ๋‚˜๋ˆˆ ๋‚˜๋จธ์ง€์— ํ•ด๋‹นํ•˜๋Š” ๊ฐ’ ์ €์žฅ

โ‘ฅ ์•”ํ˜ธํ™” ๋ฆฌ์ŠคํŠธ๋ฅผ ํ•˜๋‚˜์˜ ๋ฌธ์ž์—ด๋กœ ๋ณ€ํ™˜

enc_list = ''.join(enc_list)

โ‘ฆ ์•”ํ˜ธํ™”๋œ ํŒŒ์ผ ์“ฐ๊ธฐ

with open('encfile', 'w', encoding='utf-8') as f:
ใ…คใ…คf.write(enc_list)

 

++  'encfile' ํŒŒ์ผ์„ UTF-8 ์ธ์ฝ”๋”ฉ์œผ๋กœ ์—ด๊ณ , ์•”ํ˜ธํ™”๋œ ๊ฐ’์„ ํŒŒ์ผ์— ๊ธฐ๋ก

3.  FLAG๊ฐ€ ์žˆ๋Š” png ํŒŒ์ผ ์ƒ์„ฑ์„ ์œ„ํ•œ ์ฝ”๋“œ ์ž‘์„ฑ

def decrypt(hex_str):
ใ…คใ…คhex_list = [(hex(i)[2:].zfill(2).upper()) for i in range(256)]

ใ…คใ…ค# ๋ฌธ์ž์—ด์„ 2๊ฐœ์”ฉ ์ž˜๋ผ ๋ฆฌ์ŠคํŠธ๋กœ ๋ณ€ํ™˜
ใ…คใ…คenc_list = [hex_str[i:i+2] for i in range(0, len(hex_str), 2)]

ใ…คใ…ค# ๋ณตํ˜ธํ™”๋œ ๊ฐ’์„ ์ €์žฅํ•  ๋ฆฌ์ŠคํŠธ ์ดˆ๊ธฐํ™”
ใ…คใ…คdec_list = list(range(len(enc_list)))

ใ…คใ…ค# ์•”ํ˜ธํ™” ๊ณผ์ • ์—ญ์œผ๋กœ ์ˆ˜ํ–‰
ใ…คใ…คfor i in range(len(enc_list)):
ใ…คใ…คใ…คใ…คhex_b = enc_list[i]
ใ…คใ…คใ…คใ…คindex = hex_list.index(hex_b)
ใ…คใ…คใ…คใ…คdec_list[i] = hex_list[(index - 128) % len(hex_list)]

ใ…คใ…ค# ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ฌธ์ž์—ด๋กœ ๋ณ€ํ™˜
ใ…คใ…คdec_str = ''.join(dec_list)

ใ…คใ…ค# 16์ง„์ˆ˜ ๋ฌธ์ž์—ด์„ ๋ฐ”์ดํŠธ ๋ฐ์ดํ„ฐ๋กœ ๋ณ€ํ™˜
ใ…คใ…คdecoded_data = bytes.fromhex(dec_str)

ใ…คใ…คreturn decoded_data


def main():
ใ…คใ…ค# encfile ์ฝ๊ธฐ
ใ…คใ…คwith open('/content/encfile', 'r', encoding='utf-8') as f:
ใ…คใ…คใ…คใ…คenc_str = f.read()

ใ…คใ…ค# ์•”ํ˜ธํ™”๋œ ๋ฌธ์ž์—ด์„ ๋ณตํ˜ธํ™”ํ•˜์—ฌ ๋ฐ”์ดํŠธ ๋ฐ์ดํ„ฐ๋กœ ์–ป๊ธฐ
ใ…คใ…คdecrypted_data = decrypt(enc_str)

ใ…คใ…ค# ๋ฐ”์ดํŠธ ๋ฐ์ดํ„ฐ๋ฅผ 'flag.png' ํŒŒ์ผ๋กœ ์ €์žฅ
ใ…คใ…คwith open('/content/flag.png', 'wb') as f:
ใ…คใ…คใ…คใ…คf.write(decrypted_data)

if __name__ == "__main__":
ใ…คใ…คmain()

 

 

++ ์ฝ”๋“œ Flow ์ฐธ๊ณ 

-->  https://today-loui.tistory.com/64

 

[Dreamhack] ROT128

1. ๋ฌธ์ œ ์ฃผ์–ด์ง„ encfile์„ ๋ณตํ˜ธํ™”ํ•˜์—ฌ flag ํŒŒ์ผ ๋‚ด์šฉ์„ ์•Œ์•„๋‚ธ ๋’ค, flag.png์—์„œ ํ”Œ๋ž˜๊ทธ๋ฅผ ํš๋“ํ•˜๋Š” ๋ฌธ์ œ ์†Œ์Šค์ฝ”๋“œ #!/usr/bin/env python3 hex_list = [(hex(i)[2:].zfill(2).upper()) for i in range(256)] with open('flag.png', 'rb

today-loui.tistory.com

4.  Google Colab์—์„œ ์ž‘์„ฑํ•œ ์ฝ”๋“œ ์‹คํ–‰  -->  flag.png ํŒŒ์ผ์ด ์ƒ์„ฑ๋จ

์ขŒ์ธก์ด ์ฝ”๋“œ ์‹คํ–‰ ์ „, ์šฐ์ธก์ด ์‹คํ–‰ ํ›„

5.  flag.png ํŒŒ์ผ ์˜คํ”ˆ  -->  FLAG ๋ฐœ๊ฒฌ