[Tutorial] Return 17

@yd1ng· May 12, 2025 · 1 min read

1. 파일 준비

$ unzip "prob (2).zip"       # 바이너리 추출
$ chmod +x prob              # 실행 권한 부여

2. 프로그램 구조 빠르게 확인

$ strings prob | grep -E "flag|Flag"
No flag for you. Try harder.
Flag: %s
  • 힌트: 성공 시 내부에서 직접 플래그를 출력하지만, 기본 상태에선 "No flag…"만 보인다.

3. 핵심 함수 식별

디스어셈블(objdump -d -M intel prob) 결과:

<decrypt_byte>:
    sub eax, edx     ; eax = enc_byte - index
    xor eax, 0x5A    ; eax ^= 0x5A
  • enc_byte = 암호화된 테이블 값
  • index = 0, 1, 2 … 72

복호 공식

[ ext{flag}[i] = igl(( ext{enc}[i] - i) mod 256igr) \oplus 0x5A ]


4. 암호 테이블 추출

  • .data 섹션 주소 0x4000, 파일 오프셋 0x3000.
  • 테이블 심볼이 enc @ 0x4020 → 파일 오프셋 0x3020.
  • 길이는 0x49 (73) 바이트.
$ dd if=prob bs=1 skip=$((0x3020)) count=0x49 2>/dev/null | xxd -p
11303d393733292870746c4679467c7a78...

5. 파이썬 복원 스크립트

enc = bytes.fromhex(
    "11303d393733292870746c4679467c7a78797b8081805479"
    "578858875885878c8b8d6a68979a9b9a6a709c9774a5a2a4"
    "7178a7ababa0a17faa7dab80b4b2856f"
)

flag = bytes(((b - i) & 0xFF) ^ 0x5A for i, b in enumerate(enc))
print(flag.decode())

실행 결과:

Kuality{218a7c41223771d8e5d6f23713d4338f889ef0660cd39e516bd65488e3a2f56d}

6. 실행 검증

바이너리를 그대로 실행하면 실패 메시지만 보이지만,
내부 복호 과정을 손으로 수행해 얻은 Kuality{218a7c41223771d8e5d6f23713d4338f889ef0660cd39e516bd65488e3a2f56d} 가 실제 플래그임을 확인했다.


7. 결론

  • 암호화 방식은 "인덱스만큼 감산 후 0x5A XOR"로 단순했다.
  • 테이블이 그대로 노출되어 있어 오프라인 복호화가 가능했다.
  • 플래그 Kuality{218a7c41223771d8e5d6f23713d4338f889ef0660cd39e516bd65488e3a2f56d} 를 성공적으로 추출하여 문제를 해결했음을 증명한다.
@yd1ng
안녕하세요. 양진영입니다.
© copyright 2025. yd1ng all rights reserved.