Description
rot128.py
는 flag.png
파일을 암호화하여 encfile
로 저장하는 프로그램의 소스 코드입니다. (풀이자가 프로그램을 직접 실행할 수는 없습니다.)
주어진 encfile
을 복호화하여 flag
파일 내용을 알아낸 뒤, flag.png
에서 플래그를 획득하세요!
플래그의 형식은 flag{…} 입니다.
Files
ubuntu@WSL2:~/CTF/whitehat$ tree ROT128 ROT128 ├── encfile └── rot128.py 0 directories, 2 files ubuntu@WSL2:~/CTF/whitehat$ file ./ROT128/encfile ./ROT128/encfile: ASCII text, with very long lines (65536), with no line terminators ubuntu@WSL2:~/CTF/whitehat$ file ./ROT128/rot128.py ./ROT128/rot128.py: Python script, ASCII text executable
암호화된 이미지 파일 하나와 암호화시키는 파이썬 스크립트 파일 하나.
분석
rot128.py
#!/usr/bin/env python3 hex_list = [(hex(i)[2:].zfill(2).upper()) for i in range(256)] with open('flag.png', 'rb') as f: plain_s = f.read() plain_list = [hex(i)[2:].zfill(2).upper() for i in plain_s] 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)] enc_list = ''.join(enc_list) with open('encfile', 'w', encoding='utf-8') as f: f.write(enc_list)
- [’00’, ’01’, ’02’, ’03’, ~ ‘FF’]와 같이 0~255가 담긴 hex_list를 생성한다.
- flag.png 파일을 바이너리 읽기 모드로 열어 plain_s에 지정한다.
- plain_list에 16진수 타입으로 리스트를 만든다.
이를 테면, flag.png 파일이 abcd가 들어있으면, plain_list에는 [’41’, ’42’, ’43’, ’44’]가 된다. - 파일에 있는 각 하나의 문자를 나타내는 아스키코드에 128을 더하고 len(hex_list)값인 256을 %연산한 값을 hex_list의 index값으로 지정한다. 그렇게 index 값을 지정한 hex_list의 하나의 값이 담겨 enc_list가 된다.
이를 테면, (0x41+128)%256=193, hex_list[193]=0xC1,
(0x42+128)%256=194, hex_list[194]=0xC2,
(0x43+128)%256=195, hex_list[195]=0xC3,
(0x44+128)%256=196, hex_list[196]=0xC4가 되어
[‘C1’, ‘C2’, ‘C3’, ‘C4’]가 담긴 enc_list가 된다. - enc_list 리스트를 다시 하나의 문자열로 만들어 encfile로 저장한다.
풀이
encfile 파일에 있는 2바이트의 Hex값을 하나의 배열 요소로 지정한다.
hex_list 인덱스는 역으로 128을 빼고, 256을 %연산한 값으로 해서
이미지 파일의 한 바이트씩 복원시키면 된다.
Solution
hex_list = [(hex(i)[2:].zfill(2).upper()) for i in range(256)] with open('encfile', 'rb') as f: enc_list = f.read() enc_list = [int(enc_list[i:i+2], 16) for i in range(0, len(enc_list), 2)] plain_list = [] for i in range(len(enc_list)): plain_list.append(hex_list[(enc_list[i] - 128) % len(hex_list)]) plain_list = ''.join(plain_list) plain_list = bytes.fromhex(plain_list) with open('flag.png', 'wb') as f: f.write(plain_list)
FLAG
