[Dreamhack] Hidden (Level 1) forensics

2026. 3. 22. 20:30·디지털 포렌식/워게임 풀이
문제 설명

The image looks mediocre but there seems to be something hidden

( 이미지는 평범해 보이지만 숨겨진 무언가가 있는 것 같습니다)


flag format DH{...}


 

압축 해제하면 이렇게 2개의 파일이 있음.

file.png는 그냥 이렇게 까만 사진 파일이고,

flag.py는 이런 python 코드가 들어있다.

 

gemini에게 맡겨서 해석해보면,

1.  데이터 암호화 및 압축 단계

가장 먼저 숨기고자 하는 텍스트(d)를 처리합니다.

 

  • XOR 암호화: DH{Fake_Flags?}라는 문자열의 각 문자를 16진수 0x55(K)와 XOR 연산합니다. 
  • Base64 인코딩: 암호화된 바이트 데이터를 읽기 쉬운 텍스트 형태인 Base64로 변환합니다.
  • zlib 압축: 변환된 데이터를 zlib 라이브러리를 사용해 압축하여 크기를 줄입니다.

2. LSB 스테가노그래피 (이미지에 데이터 심기)

압축된 데이터(c)를 100x100 크기의 새로운 검은색 이미지(flag.png)에 저장합니다.

  • 비트 추출: 압축된 데이터를 2진수 비트(0과 1)의 나열로 바꿉니다.
  • LSB(Least Significant Bit) 변조: 이미지의 각 픽셀(R, G, B 값)의 가장 낮은 자리 비트를 데이터 비트로 교체합니다.
    • 예를 들어 빨간색 수치가 254(11111110)인데 데이터 비트가 1이라면 255(11111111)로 바꿉니다.
    • 사람의 눈으로는 색상 차이를 거의 느낄 수 없지만, 컴퓨터는 이 미세한 차이에서 데이터를 읽어낼 수 있습니다.

3. 파일 결합 (Append)

마지막 부분은 생성된 flag.png를 다른 이미지 파일(testfile.png) 뒤에 물리적으로 붙이는 작업입니다.

  • a.find(b'IEND')+12: 원본 PNG 파일의 끝을 알리는 청크인 IEND를 찾아 그 위치를 계산합니다.
  • a[:j] + h: 원본 이미지 데이터 바로 뒤에, 방금 만든 데이터가 숨겨진 이미지(h)를 이어 붙여 base.png라는 결과물을 만듭니다.

근데 제공받은 파일은 flag.png 랑 flag.py 밖에 없었으니까 아마 2번과정까지 하고난 후인듯?

 

그럼 저 과정을 역행하면 될 듯 하다.

gemini에게 설명해서 저 flag.png 파일을 decode할 수 있는 코드를 짜달라고 부탁했다.

import zlib as z
import base64 as b
from PIL import Image as I

try:
    # 1. 이미지 로드
    im = I.open("flag.png")
    px = im.load()
    width, height = im.size

    # 2. LSB 비트 추출
    bit_list = []
    for y in range(height):
        for x in range(width):
            r, g, b_val = px[x, y]
            # 각 채널의 LSB를 리스트에 추가
            bit_list.append(str(r & 1))
            bit_list.append(str(g & 1))
            bit_list.append(str(b_val & 1))
    
    bits = "".join(bit_list)

    # 3. 비트를 바이트 객체로 변환
    byte_arr = bytearray()
    for i in range(0, len(bits), 8):
        byte_str = bits[i:i+8]
        if len(byte_str) < 8: break
        byte_arr.append(int(byte_str, 2))
    
    extracted_bytes = bytes(byte_arr)

    # 4. zlib 데이터 찾기 (PNG 내부에 숨겨진 압축 데이터 시작점)
    # zlib 헤더는 보통 0x78 0x9C로 시작합니다.
    idx = extracted_bytes.find(b'\x78\x9c')
    
    if idx != -1:
        # 압축 해제
        decompressed = z.decompress(extracted_bytes[idx:])
        # Base64 디코딩
        decoded_b64 = b.b64decode(decompressed)
        
        # 5. XOR 복호화 (Key: 0x55)
        k = 0x55
        flag = "".join([chr(x ^ k) for x in decoded_b64])
        
        print("-" * 30)
        print("찾은 플래그: " + flag)
        print("-" * 30)
    else:
        print("이미지에서 유효한 zlib 데이터를 찾을 수 없습니다.")

except Exception as e:
    print(f"오류 발생: {e}")

 

그리고 이걸 cmd 창에서 돌려보면~~ 이렇게 flag가 나오게 된다.

플래그는 : DH{Supe3r_Dupe3r_H0td0g}

 

'디지털 포렌식 > 워게임 풀이' 카테고리의 다른 글

[Dreamhack] My Nervous PPT (Level 1) misc, forensics  (0) 2026.03.31
[Dreamhack] Gyul Box (Level 1) - forensics  (0) 2026.03.29
[Dreamhack] Hefty Image (Level 1) forensics  (0) 2026.03.22
[Dreamhack] Take Your Glasses (Level 2) misc, forensics  (0) 2026.03.22
2026 INCOGNITO CTF, The Missing Image Fragment 문제 풀이  (0) 2026.02.17
'디지털 포렌식/워게임 풀이' 카테고리의 다른 글
  • [Dreamhack] My Nervous PPT (Level 1) misc, forensics
  • [Dreamhack] Gyul Box (Level 1) - forensics
  • [Dreamhack] Hefty Image (Level 1) forensics
  • [Dreamhack] Take Your Glasses (Level 2) misc, forensics
maysokuli
maysokuli
성실히 열심히 꾸준히 / 디지털 포렌식 공부 중
  • maysokuli
    정보보호 소쿠리
    maysokuli
  • 공지사항

    • 분류 전체보기
      • 디지털 포렌식
        • 기술 스터디
        • 인프런 [기초부터 따라하는 디지털포렌식]
        • 드림핵 [Digital Forensics Basi..
        • 디스크포렌식(이별)
        • 심화팀 - 클라우드
        • 워게임 풀이
        • 기타 추가 공부
      • 개인정보보호
        • 기술 스터디
        • 개인정보보호 강의 수강
        • 동향 스터디
        • 기타 추가 공부
  • 최근 글

  • 전체
    오늘
    어제
  • hELLO· Designed By정상우.v4.10.6
maysokuli
[Dreamhack] Hidden (Level 1) forensics
상단으로

티스토리툴바