Dreamhack - ROT128 (crypto)

·2026년 1월 8일

Dreamhack-Writeups

목록 보기
49/52

ROT128 (crypto)

문제 링크

https://dreamhack.io/wargame/challenges/852

문제 설명

rot128.py는 flag.png 파일을 암호화하여 encfile로 저장하는 프로그램의 소스 코드입니다. (풀이자가 프로그램을 직접 실행할 수는 없습니다.)
주어진 encfile을 복호화하여 flag 파일 내용을 알아낸 뒤, flag.png에서 플래그를 획득하세요!
플래그의 형식은 DH{...} 입니다.

풀이과정

  1. 주어진 암호화 소스코드를 확인한다.
    이 코드는 문자 또는 데이터 값을 128만큼 이동시키는 ROT128 스크립트다.
hex_list = [(hex(i)[2:].zfill(2).upper()) for i in range(256)]
  • hex_list00,01,02, ... ,FF 형태의 256개의 대문자 16진수 문자열 리스트이다.
  • 인덱스 0은 00, 인덱스 255는 FF
with open('flag.png', 'rb') as f:
    plain_s = f.read()
  • flag.png 를 바이너리로 읽어서 전체 바이트를 plain_s 에 저장한다.
plain_list = [hex(i)[2:].zfill(2).upper() for i in plain_s]
  • 읽어온 바이트를 두 자리 16진 문자열로 바꿔 리스트에 담는다.
enc_list = list(range(len(plain_list)))
  • 암호화된 값을 저장하기 위한 리스트를 만든다. plain_list와 길이가 같다 (len)
for i in range(len(plain_list)):
  • 파일의 각 바이트마다 반복한다.
    index = hex_list.index(hex_b)
  • 현재 바이트의 16진 문자열을 꺼낸다. 예) 89
    index = hex_list.index(hex_b)
  • 89가 hex_list에서 몇번째인지 찾는다. 89는 정수 137이다.
 enc_list[i] = hex_list[(index + 128) % len(hex_list)]
  • index 값에서 128을 더하고, hex_list의 길이인 256으로 나눈 후 나머지를 취한다.
  • (137 + 128) % 26 = 9
  • 그 결과를 2자리 16진 문자열로 기록한다. (09)
enc_list = ''.join(enc_list)
  • 리스트에서 값들을 합친다.
with open('encfile', 'w', encoding='utf-8') as f:
  • 암호문을 저장할 encfile 을 텍스트 쓰기 모드로 연다.
    f.write(enc_list)
  • 문자열을 파일에 저장한다. > 사람이 열어보면 09…. 같은 문자열만 보인다.
  1. 이를 복호화 할 수 있는 코드를 작성한다. (챗지피티를 활용하였다)
# encfile 읽기 (2글자씩 HEX)
with open('encfile', 'r', encoding='utf-8') as f:
    enc = f.read().strip()

plain = bytearray()

# 2글자(=1바이트)씩 끊어서 처리
for i in range(0, len(enc), 2):
    val = int(enc[i:i+2], 16)      # 16진 문자열 → 숫자
    dec = (val + 128) % 256        # ROT128 복호화
    plain.append(dec)

# flag.png 복구
with open('flag_recovered.png', 'wb') as f:
    f.write(plain)

print("[+] 복호화 완료 → flag_recovered.png 생성됨")
  • dec = (val + 128) % 256 에서 계산 결과를 되돌리고, 되돌린 바이트들을 이용해 flag.png를 복호화 한다.
  1. 새로운 .png 파일이 생성되었고, 확인해보니 플래그를 획득할 수 있었다.
profile
CTF 풀이 및 실습 중심 학습을 기록합니다.

0개의 댓글