ECHO · Write-ups · ACE-T Core

The ACE-T Write-Ups

ACE-T Core is not a multiple-choice badge. Section one is the written exam, section two is five challenges of your choosing off the Antisyphon Cyber Range, and section three — the part the certification actually turns on — is report writing: two write-ups on your approach, your methodologies and your findings, delivered for the public to read. These are those two reports, published in full.

Take it with you

19 pages · this page, set for print — not the exam submission, and carrying none of its identity fields

Provenance

Submitted 20 June 2026 for the ACE-T Core certification, Antisyphon Training, as the ECHO Club Digital Forensics Examination Report, Volumes I and II. The challenges were solved on the MetaCTF Training Platform (the Antisyphon Cyber Range). Supervising writer: Digital Orukami.

This page is the club’s public setting of those two reports. The exam PDFs open on a cover block carrying the candidate’s legal name and student ID — not the identity this site publishes under, and the only thing left out here. The findings, evidence tables, methodology, code, flags and recommendations are the submitted text.

Disclaimer. This report documents challenge solutions completed on the MetaCTF Training Platform for educational purposes. All analysis was performed in a controlled CTF environment. ECHOClub is not responsible for the organization or administration of the MetaCTF platform.

Volume I

Forensics & Malware Analysis

Malware Procmon · FTP capture · Sysmon log · Process dump

Challenge 1 · Digital forensics / malware analysis · Threat level: critical

A Needle in a Needlestack

A Windows system was generating repeated crash popups for malware.exe. A Process Monitor (Procmon) capture log — Logfile.PML, 54 MB, 108,560 events — was provided. The objective was to identify the specific file responsible for launching malware.exe.

Evidence

ArtifactDescription
Logfile.PML54 MB Process Monitor binary log — 108,560 captured events
malware.exeCrashing process located at C:\malware.exe
netutils.dllMalicious DLL found at C:\Windows\netutils.dll
phHelper.exeProcess Hacker helper utility used as injector
WerFault.exeWindows Error Reporting — triggered by the malware.exe crashes

Methodology

Tool setup

The PML file was parsed using the Python procmon-parser library (v0.3.13), since version incompatibilities prevented opening it in the Procmon GUI.

pip install procmon-parser --break-system-packages
Process tree reconstruction

All Process Create events were extracted to reconstruct the full execution chain. The key discovery was phHelper.exe being launched by cmd.exe rather than ProcessHacker.exe.

ProcessParentCommand line
ProcessHacker.execmd.exeProcessHacker.exe
phHelper.execmd.exe (anomalous)phHelper.exe 1016 phLib.dll
notepad.exeProcessHacker.exenotepad.exe
explorer.exe (2528)cmd.exeexplorer.exe
malware.exe (2104)explorer.exe (2528)"C:\malware.exe"
DLL load order analysis

Examining the events between the shacct.dll COM object load and the malware.exe Process_Create at event [70855], a critical DLL load-order anomaly was identified.

Event 70824: CreateFile C:\Windows\netutils.dll           <- LOADED FIRST (malicious)
Event 70831: CreateFile C:\Windows\System32\netutils.dll  <- skipped

Windows DLL search order causes C:\Windows\ to be searched before C:\Windows\System32\ when it appears in the PATH environment variable. A malicious netutils.dll planted at C:\Windows\netutils.dll was loaded instead of the legitimate System32 version.

Full attack chain
  • Attacker planted a malicious netutils.dll at C:\Windows\netutils.dll
  • cmd.exe launched phHelper.exe with arguments targeting ProcessHacker.exe (PID 1016)
  • phHelper.exe opened ProcessHacker.exe with PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE (0x0000002a) — classic CreateRemoteThread injection
  • explorer.exe processed the Start Menu ProgramsCache, triggering COM CLSID {4F6BCD94-C2A5-42CE-8DBC-31E794BE4630}
  • shacct.dll (the legitimate Shell Computer Accounts DLL) loaded and attempted to import netutils.dll
  • The malicious netutils.dll in C:\Windows\ was loaded before the System32 version
  • The malicious DLL spawned C:\malware.exe (PID 2104)
  • malware.exe connected to 192.168.220.129:4444 — a Meterpreter reverse TCP shell

FlagC:\Windows\netutils.dll

Threat assessment

This attack demonstrates a sophisticated multi-stage compromise combining DLL search-order hijacking (MITRE ATT&CK T1574.001) with COM object abuse for persistence. The attacker leveraged Windows Explorer’s own process to spawn the malware, making it appear as legitimate system activity.

  • Reverse shell active on port 4444 — the attacker had full remote access
  • Malware relaunched on every new Explorer session — persistent across logoffs
  • Attribution to ProcessHacker.exe masked the malicious DLL activity in most security logs

Recommendations

  • Delete C:\Windows\netutils.dll and verify the hash of C:\Windows\System32\netutils.dll
  • Terminate and quarantine malware.exe and all associated processes
  • Rotate all credentials for accounts active on this system — assume full compromise
  • Enable SafeDllSearchMode: HKLM\System\CurrentControlSet\Control\Session Manager\SafeDllSearchMode = 1
  • Audit the C:\Windows\ directory for unexpected DLLs — it should not contain netutils.dll
  • Block outbound TCP port 4444 at the perimeter firewall
  • Deploy EDR rules to alert on phHelper.exe launched by any process other than ProcessHacker.exe
  • Investigate the initial access vector — how did the attacker gain write access to C:\Windows\?

Challenge 2 · Network forensics / packet analysis · Threat level: high

Flags Over the Wire

A packet capture (capture.pcap, 233 KB) of an FTP session between two computers was provided. One machine downloaded a file from the other. The objective was to reconstruct the transferred file from the raw packet data and extract the flag contained within it.

Evidence

ArtifactDescription
capture.pcap83-packet network capture of an FTP session
flags.zip230,329 bytes — ZIP file reconstructed from the FTP data stream
flags.png1944×2844 pixel PNG extracted from the ZIP — contained the flag
FTP credentialsUsername hack0r / password Chiapet2 — cleartext

Methodology

Protocol identification

Packet analysis using Scapy revealed an FTP control channel on TCP port 21 and a data channel on port 55983 (FTP passive mode). The full FTP session command sequence was recovered.

Client commandServer response
USER hack0r331 Please specify the password.
PASS Chiapet2230 Login successful.
PASV227 Entering Passive Mode (10,0,0,215,218,175)
RETR flags.zip150 Opening BINARY mode data connection for flags.zip (230329 bytes). / 226 Transfer complete.
QUIT221 Goodbye.
Data channel port calculation

In FTP passive mode the data port is encoded in the PASV response as p1 * 256 + p2:

227 Entering Passive Mode (10,0,0,215,218,175)
Data port = 218 * 256 + 175 = 55983
File reconstruction

All TCP packets originating from port 55983 (server to client) were collected in sequence and their payloads concatenated to reconstruct the raw file.

data = b''
for p in pkts:
    if p.haslayer(TCP) and p.haslayer(Raw):
        if p[TCP].sport == 55983:
            data += p[Raw].load

The reconstructed 230,329 bytes carried magic bytes 504b0304 — the ZIP file signature. The ZIP contained flags.png, which displayed a checkered flag image and the flag text.

FlagRedactedCTF{...}

Threat assessment

FTP transmits all data — including credentials and file contents — in cleartext over TCP. Anyone with network access between client and server can intercept usernames, passwords and every transferred file using tools as simple as Wireshark or tcpdump.

  • Credentials exposed in plaintext: hack0r / Chiapet2
  • All transferred file content fully visible in the capture
  • No integrity protection — files could be modified in transit without detection

Recommendations

  • Replace FTP immediately with SFTP (SSH File Transfer Protocol) or FTPS (FTP over TLS)
  • Rotate the compromised credentials hack0r / Chiapet2 — assume these are fully compromised
  • Implement network monitoring to detect and block plaintext FTP sessions on port 21
  • Enforce file transfer encryption policies across the organization
  • Use key-based authentication for SFTP rather than password authentication

Challenge 3 · Threat hunting / Windows forensics · Threat level: critical

Catch Me If You Can, Mon!

A Sysmon event log (sysmon_logfile.evtx, 2.1 MB) was provided from a Windows system exhibiting suspicious activity inside Process Hacker. Threat intelligence indicated the attacker was hiding inside legitimate security tools. The objective was to identify the specific DLL used for memory injection.

Evidence

ArtifactDescription
sysmon_logfile.evtx2.1 MB Windows Sysmon event log — 724 total events
Event ID 1 (×8)Process Create — revealed the anomalous phHelper.exe launch
Event ID 10 (×590)ProcessAccess — showed the DLL injection signature
Event ID 7 (×120)Image Loaded — DLL load activity
phHelper.exeProcess Hacker helper utility — launched anomalously from cmd.exe
phLib.dllMalicious DLL injected into ProcessHacker.exe via CreateRemoteThread

Methodology

Log parsing

The EVTX binary was parsed using the python-evtx library to extract and correlate events programmatically.

pip install python-evtx --break-system-packages
Parent process anomaly detection

Examination of all Process Create (Event ID 1) events revealed the critical anomaly: phHelper.exe was launched from cmd.exe instead of its expected parent ProcessHacker.exe.

ProcessParentCommand line
ProcessHacker.execmd.exeProcessHacker.exe
phHelper.execmd.exe (anomalous)phHelper.exe 1016 phLib.dll
phHelper.execmd.exe (anomalous)phHelper.exe 2156 phLib.dll
notepad.exeProcessHacker.exenotepad.exe
whoami.execmd.exewhoami
Access mask decoding

The ProcessAccess events from phHelper.exe to ProcessHacker.exe showed GrantedAccess mask 0x0000002a.

Flag valueConstantPurpose
0x0002PROCESS_CREATE_THREADCreate a thread in the target process
0x0008PROCESS_VM_OPERATIONPerform VirtualAllocEx in the target
0x0020PROCESS_VM_WRITEWrite memory via WriteProcessMemory

This exact combination (0x0000002a) is the classic CreateRemoteThread DLL injection signature. phHelper.exe was injecting phLib.dll into the ProcessHacker.exe process space.

Full path identification

Extracting full paths from all ProcessHacker-related call traces confirmed the malicious DLL location. That DLL was accessing notepad.exe with GrantedAccess 0x001fffff (PROCESS_ALL_ACCESS) — the maximum possible permission level. Once injected into the ProcessHacker.exe process space, all of its activity was attributed to the legitimate security tool.

FlagC:\Users\Administrator\Downloads\processhacker-2.39-bin\x64\phLib.dll

Threat assessment

This attack demonstrates a sophisticated Living-off-the-Land technique that abuses a legitimate security tool’s own helper utility as a DLL injector. By hiding inside Process Hacker, the malicious activity inherits the tool’s trusted reputation and bypasses security products that whitelist it.

  • Process injection into a security tool — effectively blinds defenders
  • PROCESS_ALL_ACCESS to notepad.exe — memory contents fully readable and writable
  • The attacker used cmd.exe to manually invoke phHelper.exe — indicating an interactive post-exploitation session
  • whoami.exe execution confirms active attacker presence performing reconnaissance

Recommendations

  • Terminate Process Hacker and quarantine the malicious phLib.dll
  • Assume notepad.exe memory contents were read — review what sensitive data was open
  • Investigate how the attacker gained access to the system — check for initial access vectors
  • Implement file integrity monitoring on Process Hacker’s installation directory
  • Configure Sysmon to alert on phHelper.exe launched by any process other than ProcessHacker.exe
  • Alert on ProcessAccess events with mask 0x0000002a from unexpected source processes
  • Restrict write access to security tool installation directories to SYSTEM only
  • Enable Windows Credential Guard to protect against memory-based credential theft
  • Adjust and reconfigure AppLocker policies to restrict execution of notepad.exe and other commonly abused legitimate Windows binaries to authorized users, or to none at all

Challenge 4 · Memory forensics / malware analysis · Threat level: high

CreateRemoteFlag()

A Windows Minidump file (notepad.exe_200310_020705.dmp, 143 MB) was provided, captured from a notepad.exe process suspected of having malicious code injected into it by KoVCxCjx.exe via CreateRemoteThread. The objective was to identify the DLL responsible for the injection by analyzing the process memory dump.

Evidence

ArtifactDescription
notepad.exe_200310_020705.dmp143 MB Windows Minidump — captured 2020-03-10 02:07:05
18 streamsMinidump stream count — a full memory snapshot
KoVCxCjx.exeAttacker-controlled process — name chosen to evade casual inspection
Injected DLLC:\temp\finding_a_dynamicly_linked_flag_for_some_cold_hard_points.dll
PDB pathC:\Users\Administrator\Documents\Payload\x64\Debug\...pdb

Methodology

Dump parsing

The Minidump was parsed using the Python minidump library to enumerate all loaded modules, memory segments and thread information.

pip install minidump --break-system-packages

from minidump.minidumpfile import MinidumpFile
mf = MinidumpFile.parse('notepad.exe_200310_020705.dmp')
Module enumeration

Enumerating all modules loaded into the notepad.exe process space revealed 80+ legitimate Windows DLLs and one highly suspicious entry.

ModuleBase addressAssessment
C:\Windows\System32\notepad.exe0x7ff6e8b80000Legitimate
C:\Windows\System32\ntdll.dll0x7fff71440000Legitimate
C:\Windows\System32\netutils.dll0x7fff6cf90000Legitimate
C:\temp\finding_a_dynamicly_linked_flag_for_some_cold_hard_points.dll0x7fff61ca0000Malicious
C:\Windows\System32\VCRUNTIME140D.dll0x7fff618f0000Debug runtime

The DLL in C:\temp\ stands out immediately — it sits in a writable directory rather than a system directory, it is loaded into a notepad.exe process, and it has a name that describes its own purpose. Its associated PDB debug path confirmed it was compiled by the attacker: C:\Users\Administrator\Documents\Payload\x64\Debug\finding_a_dynamicly_linked_flag_for_some_cold_hard_points.pdb

Memory region analysis

The injected DLL occupied memory segments from 0x7fff61ca0000 to 0x7fff61cc4000 (0x24000 bytes). String extraction from these segments revealed:

  • MessageBoxA import — the DLL displays a popup message
  • RegOpenKeyExW / RegQueryValueExW — it reads from the Windows registry
  • Hey you! — message box caption text, obviously suspicious
  • notepad_bonus_flags_are_the_best_of_flags — a hidden window class name

The full path of the injected DLL, as loaded in the process module list, provides the flag.

FlagC:\temp\finding_a_dynamicly_linked_flag_for_some_cold_hard_points.dll

Threat assessment

CreateRemoteThread DLL injection is a well-established process injection technique that allows an attacker to execute arbitrary code within the context of another process. By targeting notepad.exe — a commonly whitelisted application — the attacker’s malicious DLL inherits the process’s trust level and evades many security controls.

  • Full code execution within the notepad.exe process context
  • Registry access from an injected DLL — potential credential or configuration theft
  • A debug build (VCRUNTIME140D.dll) suggests this was a development/testing payload
  • C:\temp\ is a world-writable directory — low privilege required to plant the DLL

Recommendations

  • Remove C:\temp\finding_a_dynamicly_linked_flag_for_some_cold_hard_points.dll and terminate any affected processes
  • Audit C:\temp\ and all other world-writable directories for unauthorized DLLs
  • Investigate KoVCxCjx.exe — identify its origin, persistence mechanism and full capabilities
  • Review registry keys accessed by the injected DLL for signs of data exfiltration or persistence
  • Implement application whitelisting to prevent unauthorized DLLs from loading
  • Configure EDR to alert on DLL loads from C:\temp\ or other non-system directories
  • Restrict write access to C:\temp\ — only authorized processes should write there
  • Deploy memory scanning to detect injected code regions in running processes

Volume II

Network Reconnaissance & Forensics

SNMP enumeration · IP geolocation · Password cracking · Hexed PNG

Challenge 1 · Network reconnaissance / protocol analysis · Threat level: high

Taking a Walk

A server at host1.metaproblems.com was identified as running SNMP on its default port. The challenge demonstrated how SNMPv1 and SNMPv2c lack meaningful security controls, allowing any party with the community string to enumerate the full Management Information Base (MIB) of a device. The flag was hidden in one of the standard SNMP OID fields.

Evidence

ArtifactDescription
host1.metaproblems.comTarget host — SNMP service on UDP port 161
Community stringpublic — default read-only, unchanged from factory
sysContact.0 OID1.3.6.1.2.1.1.4.0 — contained the flag instead of an admin contact
sysName.090f7a1a0c6d3 — hostname of the target device
sysLocation.0metactf — device location field

Methodology

SNMP version security context
VersionAuthenticationEncryptionRisk
SNMPv1Community stringNoneHigh — cleartext
SNMPv2cCommunity stringNoneHigh — cleartext
SNMPv3Username + passwordAES/DESLow — encrypted
SNMP walk execution

Cloud infrastructure firewalls blocked outbound UDP from the analysis environment, so the SNMP walk was performed from a local Windows terminal using the pysnmp Python library.

pip install pysnmp

import asyncio
from pysnmp.hlapi.v3arch.asyncio import *

async def run():
    snmpEngine = SnmpEngine()
    async for errorIndication, errorStatus, errorIndex, varBinds in walk_cmd(
        snmpEngine,
        CommunityData('public'),
        await UdpTransportTarget.create(('host1.metaproblems.com', 161)),
        ContextData(),
        ObjectType(ObjectIdentity('1.3.6.1')),
        lexicographicMode=False
    ):
        for varBind in varBinds:
            print(varBind)

asyncio.run(run())

Note: pysnmp v7 uses snake_case function names (walk_cmd) rather than the camelCase names used in older versions. This is a common compatibility trap.

Results
OID / fieldValue
SNMPv2-MIB::sysObjectID.0SNMPv2-SMI::enterprises.8072.3.2.10
SNMPv2-MIB::sysUpTime.01047691385
SNMPv2-MIB::sysContact.0RedactedCTF{...}
SNMPv2-MIB::sysName.090f7a1a0c6d3
SNMPv2-MIB::sysLocation.0metactf

FlagRedactedCTF{...}

Threat assessment

SNMP with default community strings is one of the most commonly exploited network misconfigurations in enterprise environments. The sysContact field — normally used for administrator contact information — was repurposed to hide the flag, demonstrating how arbitrary data can be stored in SNMP fields and exfiltrated by any party that can enumerate the MIB.

  • Default community string public left unchanged — any device on the network can enumerate the full MIB
  • All SNMP data transmitted in cleartext over UDP — interceptable by network-level attackers
  • An SNMP MIB can reveal OS version, running services, network interfaces, routing tables and user accounts
  • A read-write community string (private) could allow remote configuration changes if similarly misconfigured

Recommendations

  • Upgrade to SNMPv3 with authentication (SHA) and encryption (AES-256) immediately
  • Change all community strings from their default values (public, private) to strong random strings
  • Apply ACLs to restrict SNMP access to authorized management hosts only
  • Disable SNMP entirely on devices that do not require remote monitoring
  • Block UDP port 161 at the network perimeter — SNMP should never be exposed to the internet
  • Audit all SNMP-enabled devices on the network for default configurations
  • Implement SNMP monitoring to detect excessive GET/WALK requests indicative of reconnaissance

Challenge 2 · OSINT / threat intelligence · Threat level: low

Threat Intel Team

A threat intelligence scenario presented a suspicious IP address (45.126.128.11) and required identification of its geographic origin. This type of IP geolocation analysis is a fundamental OSINT technique used in incident response and threat intelligence workflows to attribute malicious activity to geographic regions and identify hosting infrastructure.

Evidence

ArtifactValue
Target IP45.126.128.11
Country codeNZ
CountryNew Zealand
CityAuckland
RegionAuckland
ASN / orgRetrieved via the ipinfo.io API

Methodology

IP lookup

The IP address was queried against the ipinfo.io geolocation API using PowerShell.

Invoke-RestMethod -Uri 'http://ipinfo.io/45.126.128.11/json' | Select-Object country, city, region, org

The API returned country code NZ, confirming the address is geographically registered to New Zealand.

FlagRedactedCTF{...}

Threat assessment

IP geolocation is an intelligence gathering technique rather than an attack in itself. However, understanding the geographic origin of suspicious IP addresses is critical for:

  • Attributing attacks to geographic regions or nation-state actors
  • Identifying hosting providers and cloud infrastructure used by threat actors
  • Supporting legal and law enforcement actions with geographic context
  • Configuring geo-blocking rules on firewalls and WAFs

Note: IP geolocation is not perfectly accurate — VPNs, Tor exit nodes and compromised systems can all cause an address to appear to originate from a different country than the actual attacker.

Recommendations

  • Cross-reference suspicious IPs against threat intelligence feeds (VirusTotal, Shodan, AbuseIPDB)
  • Implement geo-blocking for regions with no legitimate business relationship, where appropriate
  • Log and alert on connections from flagged IP ranges at the perimeter firewall
  • Never rely solely on IP geolocation for attribution — correlate with other indicators
  • Use multiple geolocation sources (ipinfo.io, MaxMind, ip-api.com) to cross-validate results

Challenge 3 · Cryptography / password security · Threat level: high

A Confident Hash

A bcrypt password hash was provided alongside a custom wordlist of 75 entries. The objective was to identify the plaintext password that produced the hash using a dictionary attack. This challenge demonstrates both the application of bcrypt as a password hashing algorithm and the risk of using predictable passwords regardless of the algorithm employed.

Evidence

ArtifactValue
Hash$2a$04$KMCaaiytS5OIsg2UZtthzugkZUPDqQ/Zyoys8XAY6AJVgirU/MWOS
Algorithmbcrypt ($2a$) with cost factor 4
Wordlistconfident_dict.txt — 75 entries, tech-themed compound words
Cracked passwordgalactica_hash
Attempts1 of 5 allowed — cracked on the first wordlist pass

Methodology

Hash analysis

The hash prefix $2a$04$ identifies it as bcrypt with a cost factor of 4 — a relatively low work factor, making it faster to crack than production bcrypt (typically cost 10–12). The hash was 60 characters, the standard bcrypt output length.

Dictionary attack

The Python bcrypt library was used to test each word in the provided wordlist against the target hash.

import bcrypt

hash_val = b'$2a$04$KMCaaiytS5OIsg2UZtthzugkZUPDqQ/Zyoys8XAY6AJVgirU/MWOS'

with open('confident_dict.txt', 'r') as f:
    words = [w.strip() for w in f.readlines()]

for word in words:
    if bcrypt.checkpw(word.encode(), hash_val):
        print(f'CRACKED: {word}')
        break

The word galactica_hash was found at position 53 of 75 in the wordlist. The entire crack took under two seconds, due to the low bcrypt cost factor of 4.

FlagRedactedCTF{...}

Threat assessment

bcrypt is a strong, deliberately slow hashing algorithm designed to resist brute force attacks. However, even bcrypt cannot protect predictable passwords when an attacker has access to the hash and a relevant wordlist. The combination of a low cost factor (4) and a password drawn from a finite, themed wordlist made this hash highly vulnerable.

  • Cost factor 4 is roughly 64× faster to crack than cost factor 10 — inadequate for production use
  • Password drawn from a themed wordlist of only 75 entries — a trivial dictionary attack
  • If this hash were obtained from a database breach, the plaintext would be recovered in seconds
  • bcrypt correctly prevents rainbow table attacks — but dictionary attacks with relevant wordlists remain effective

Recommendations

  • Use bcrypt with a minimum cost factor of 12 for password hashing in production systems
  • Enforce password complexity requirements that make passwords resistant to domain-specific wordlists
  • Implement account lockout and rate limiting to prevent online brute force attacks
  • Use a password manager and ensure all passwords are randomly generated with high entropy
  • Consider upgrading to Argon2id (winner of the Password Hashing Competition) for new systems
  • Conduct regular password audits using offline cracking tools to identify weak hashes in your database
  • Never use a cost factor below 10 in production — the extra computation is negligible for legitimate users but exponentially costly for attackers

Challenge 4 · Digital forensics / file format analysis · Threat level: low

Hexed

A file named hexed.png was provided that appeared to be a cursed image — it could not be opened as a standard PNG. The file command identified it as ASCII text rather than a binary image. The objective was to identify what had been done to the file, reverse the transformation, and recover the original PNG image containing the flag.

Evidence

ArtifactDescription
hexed.pngASCII text file — 1,910 lines of xxd-format hex dump
file command outputhexed.png: ASCII text — not a binary PNG
Magic bytes in hex89 50 4E 47 0D 0A 1A 0A — a valid PNG signature
Recovered image611×248 pixel RGBA PNG containing the flag text
Reconstructed size30,547 bytes — a valid PNG binary

Methodology

File identification

The file command immediately identified the anomaly — the file was ASCII text, not binary PNG data. Reading the first few lines revealed an xxd-format hex dump.

00000000: 8950 4e47 0d0a 1a0a 0000 000d 4948 4452  .PNG........IHDR
00000010: 0000 0263 0000 00f8 0806 0000 00a0 f6e1  ...c............

The hex dump format is [file offset]: [hex bytes] [ASCII representation]. The magic bytes 8950 4e47 = .PNG confirmed this was originally a valid PNG file that had been converted to a hex dump — the curse.

Hex dump reconstruction

A Python script parsed each line of the hex dump, extracted the hex byte values, and reassembled the original binary.

with open('hexed.png', 'r') as f:
    content = f.read()

data = bytearray()
for line in content.strip().split('\n'):
    if ':' in line:
        hex_part = line.split(':')[1].split('  ')[0].strip()
        hex_bytes = hex_part.replace(' ', '')
        data.extend(bytes.fromhex(hex_bytes))

with open('hexed_fixed.png', 'wb') as f:
    f.write(data)

The script reconstructed exactly 30,547 bytes. The first eight bytes (89 50 4E 47 0D 0A 1A 0A) confirmed a valid PNG header. Opening the image revealed the flag displayed in green pixel text on a light background.

FlagRedactedCTF{...}

The flag text itself — h3xdump_15n7_4_cur53 — is a leetspeak rendering of “hexdump isn’t a curse”, confirming the intended solution.

Key concepts

File signatures / magic bytes

Every file format has a unique signature in its first few bytes that identifies its type regardless of the file extension. The file command reads these magic bytes to determine the true file type.

Magic bytes (hex)File typeASCII
89 50 4E 47 0D 0A 1A 0APNG image.PNG....
FF D8 FFJPEG image
50 4B 03 04ZIP archivePK..
4D 5AWindows EXE/DLLMZ
7F 45 4C 46Linux ELF binary.ELF

Recommendations

  • Never trust a file extension — verify the true type from its magic bytes before opening or processing it
  • Treat a text file carrying binary magic bytes as an encoding or exfiltration channel, not a corruption
  • Automate file-type verification in intake pipelines so mismatches are surfaced rather than silently accepted

ECHOClub Digital Forensics Examination Report — Volumes I and II

Supervising writer: Digital Orukami · MetaCTF · Antisyphon Training · educational use only.