Logo
Overview
[H7CTF 2025] AppleMeowMeow writeup

[H7CTF 2025] AppleMeowMeow writeup

October 21, 2025
2 min read

TL;DR

Stage가 실행 직후 SHA-256으로 자기 무결성을 확인하고 지정 경로 문자열을 다시 해시해 AES-256 키를 만든다
키는 SHA256(“C:\Users\huynh\Favorites\Pumpkin.html”)이고 IV는 .vector 섹션의 고정 16바이트다
AES-256-CBC로 Pumpkin.html.enc를 복호화하면 플래그 HTML이 생성된다

Analysis

Stage 본체 stage_capture/meo_232_11726770.exe는 먼저 자신과 checksum.txt를 비교하고 실패하면 즉시 종료한다.

; stage_capture/meo_232_11726770.exe @0x140013ff3
140013ff3: e8 f8 f0 ff ff call 0x1400130f0 ; sha256_file(self_path)
140013fff: 41 b9 10 00 00 mov r9d, 0x10
140014005: lea r8, [rip+0x9fcc] ; "ERROR"
14001400c: lea rdx, [rip+0x9fed] ; "sha256_file(self) failed"
140014015: call qword ptr [MessageBoxA]

sha256_file 함수는 Bcrypt API를 통해 SHA-256 상태를 초기화하고 64 KiB 단위로 파일을 해시한다.

; stage_capture/meo_232_11726770.exe @0x1400128f1
1400128f1: e8 56 02 00 00 call 0x140012b4c ; BCryptOpenAlgorithmProvider("SHA256")
14001292a: e8 82 01 00 00 call 0x140012ab1 ; BCryptHashData(chunk, 0x10000)
140012946: e8 01 02 00 00 call 0x140012b4c ; BCryptFinishHash(result)

Wine 트레이스 stage_capture/wine_bcrypt.txt에서도 동일한 호출 흐름이 반복되고 마지막 5104바이트에서 종료된다. stage_capture/checksum.txt의 해시와 Stage 자체 해시가 일치함을 확인했다.

Terminal window
$ shasum -a 256 stage_capture/meo_232_11726770.exe
a95d161103aeeb2bbcb0e9e69b97f620d8cc2a829a5637427c36692913822247
$ cat stage_capture/checksum.txt
a95d161103aeeb2bbcb0e9e69b97f620d8cc2a829a5637427c36692913822247

무결성 검증이 끝나면 Stage는 C:\Users\huynh\Favorites\Pumpkin.html 문자열을 해시해 AES-256 키로 사용한다. 파일 접근 요청이 로그에 남아 경로를 확정할 수 있었다.

00ec:trace:file:CreateFileW L"C:\Users\huynh\Favorites\Pumpkin.html"

초기화 벡터는 .vector 섹션 오프셋 0x61000에서 고정 16바이트로 읽는다.

Terminal window
$ xxd -g 1 -l 16 -s 0x61000 stage_capture/meo_232_11726770.exe
00061000: de ad c0 de 13 37 de ad c0 de 13 37 de ad c0 de

Exploit

  1. 문자열 C:\Users\huynh\Favorites\Pumpkin.html을 SHA-256 해시해 32바이트 키를 생성한다
  2. .vector 섹션에서 읽은 deadc0de1337deadc0de1337deadc0de를 IV로 사용한다
  3. Pumpkin.html.enc를 AES-256-CBC로 복호화하고 결과 HTML에서 플래그를 확인한다

Stage는 BCryptGenerateSymmetricKeyBCryptEncrypt 조합으로 Pumpkin.html.enc를 복호화한다.

from pathlib import Path
from hashlib import sha256
from Crypto.Cipher import AES
def main() -> None:
base = Path(__file__).resolve().parent
cipher_path = base / "Pumpkin.html.enc"
output_path = base / "Pumpkin.html"
key_source = r"C:\Users\huynh\Favorites\Pumpkin.html".encode("utf-8")
key = sha256(key_source).digest()
iv = bytes.fromhex("deadc0de1337deadc0de1337deadc0de")
ciphertext = cipher_path.read_bytes()
plaintext = AES.new(key, AES.MODE_CBC, iv).decrypt(ciphertext)
output_path.write_bytes(plaintext)
print(f"[+] Decrypted {cipher_path.name} -> {output_path.name}")
if __name__ == "__main__":
main()

flag