detonator
detonator.exeReverse Engineering500MediumHACK10{}1. Challenge Overview
detonator.exe is a 64-bit Windows console PE binary. The challenge description hints at malware-style detonation and sandboxing, but the note explicitly says no brute forcing or scanning is required. The objective is to reverse the binary statically, identify the true flag generation logic, and recover the final flag in the format HACK10{...}.
2. Initial Reconnaissance
I started with basic triage to identify the file type, inspect obvious strings, and dump the binary header.
Command:
1ls -laOutput:
1total 3242drwxr-xr-x 4 nopalinto nopalinto 28672 Mar 27 10:03 .3drwxr-xr-x 14 nopalinto nopalinto 4096 Mar 27 10:03 ..4drwxrwxr-x 2 nopalinto nopalinto 4096 Feb 7 09:49 .codex5drwxrwxr-x 5 nopalinto nopalinto 4096 Feb 13 06:44 .venv6-rw-rw-r-- 1 nopalinto nopalinto 284430 Mar 27 10:03 detonator.exeCommand:
1file detonator.exeOutput:
1detonator.exe: PE32+ executable for MS Windows 5.02 (console), x86-64, 19 sectionsCommand:
1strings -a -n 6 detonator.exe | sed -n '1,220p'Output:
1!This program cannot be run in DOS mode.2`.data3.rdata4@.pdata5@.xdata6.idata7@.reloc8AWAVAUATUWVSH9X[^_]A\\A]A^A_108MZuEHcP<H11UAWAVAUATWVSH12[^_A\\A]A^A_]13([^_]H14@' t H15@$A9@(\~16AWAVAUATUWVSH17C$9C(\~18H[^_]A\\A]A^A_19S$9S(\~20S$9S(\~21UAWAVAUATWVSH22C$9C(\~23C$9C(\~24[^_A\\A]A^A_]25UAWAVAUATWVSH26C$9C(\~27C$9C(\~28[^_A\\A]A^A_]29UAVWVSH30C$9C(\~31[^_A^]32[^_A^]33=UUUUw34S$9S(\~35AUATUWVSH36X[^_]A\\A]37AWAVAUATUWVSH38[^_]A\\A]A^A_39AWAVAUATUWVSH408[^_]A\\A]A^A_41AWAVAUATUWVSH42[^_]A\\A]A^A_43[^_]A\\A]A^A_44D$L)D$`45T$8HcD$L;B46D$`+D$H47ATUWVSLcY48[^_]A\\49[^_]A\\50AWAVAUATUWVSH518[^_]A\\A]A^A_52AVAUATUWVSH53 [^_]A\\A]A^54AUATUWVSH55([^_]A\\A]56([^_]A\\A]57WVSHcA58H9E0sRH59%02x%02x%02x%02x60C:\\Users\\HACK10{f4k3_fl4g_bu7_y0u_4r3_in_7h3_righ7_7r4ck}\\Desktop\\local.txt61HACK10{f4k3_fl4g_bu7_y0u_4r3_in_7h3_righ7_7r4ck}62File not found. Keep looking...63Here is the flag: HACK10{64__pos <= size()65std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::reference std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::operator[](size_type) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>; reference = char\&; size_type = long long unsigned int]66C:/msys64/ucrt64/include/c++/15.2.0/bits/basic_string.h67basic_string: construction from null is not valid68basic_string::_M_create69Argument domain error (DOMAIN)70Argument singularity (SIGN)71Overflow range error (OVERFLOW)72Partial loss of significance (PLOSS)73Total loss of significance (TLOSS)74The result is too small to be represented (UNDERFLOW)75Unknown error76_matherr(): %s in %s(%g, %g) (retval=%g)77Mingw-w64 runtime failure:78Address %p has no image-section79 VirtualQuery failed for %d bytes at address %p80 VirtualProtect failed with code 0x%x81 Unknown pseudo relocation protocol version %d.82 Unknown pseudo relocation bit size %d.83%d bit pseudo relocation at %p out of range, targeting %p, yielding the value %p.84(null)85Infinity86runtime error %d87GCC: (Rev8, Built by MSYS2 project) 15.2.088GCC: (Rev8, Built by MSYS2 project) 15.2.089GCC: (Rev8, Built by MSYS2 project) 15.2.090GCC: (Rev8, Built by MSYS2 project) 15.2.091GCC: (Rev8, Built by MSYS2 project) 15.2.092GCC: (Rev8, Built by MSYS2 project) 15.2.093GCC: (Rev8, Built by MSYS2 project) 15.2.094GCC: (Rev8, Built by MSYS2 project) 15.2.095GCC: (Rev8, Built by MSYS2 project) 15.2.096GCC: (Rev8, Built by MSYS2 project) 15.2.097GCC: (Rev8, Built by MSYS2 project) 15.2.098GCC: (Rev8, Built by MSYS2 project) 15.2.099GCC: (Rev8, Built by MSYS2 project) 15.2.0100GCC: (Rev8, Built by MSYS2 project) 15.2.0101GCC: (Rev8, Built by MSYS2 project) 15.2.0102GCC: (Rev8, Built by MSYS2 project) 15.2.0103GCC: (Rev8, Built by MSYS2 project) 15.2.0104GCC: (Rev8, Built by MSYS2 project) 15.2.0105GCC: (Rev8, Built by MSYS2 project) 15.2.0106GCC: (Rev8, Built by MSYS2 project) 15.2.0107GCC: (Rev8, Built by MSYS2 project) 15.2.0108GCC: (Rev8, Built by MSYS2 project) 15.2.0109GCC: (Rev8, Built by MSYS2 project) 15.2.0110GCC: (Rev8, Built by MSYS2 project) 15.2.0111GCC: (Rev8, Built by MSYS2 project) 15.2.0112GCC: (Rev8, Built by MSYS2 project) 15.2.0113GCC: (Rev8, Built by MSYS2 project) 15.2.0114GCC: (Rev8, Built by MSYS2 project) 15.2.0115GCC: (Rev8, Built by MSYS2 project) 15.2.0116GCC: (Rev8, Built by MSYS2 project) 15.2.0117GCC: (Rev8, Built by MSYS2 project) 15.2.0118GCC: (Rev8, Built by MSYS2 project) 15.2.0119GCC: (Rev8, Built by MSYS2 project) 15.2.0120GCC: (Rev8, Built by MSYS2 project) 15.2.0121GCC: (Rev8, Built by MSYS2 project) 15.2.0122GCC: (Rev8, Built by MSYS2 project) 15.2.0123GCC: (Rev8, Built by MSYS2 project) 15.2.0124GCC: (Rev8, Built by MSYS2 project) 15.2.0125GCC: (Rev8, Built by MSYS2 project) 15.2.0126GCC: (Rev8, Built by MSYS2 project) 15.2.0127_Unwind_Resume128DeleteCriticalSection129EnterCriticalSection130GetLastError131InitializeCriticalSection132LeaveCriticalSection133SetUnhandledExceptionFilter134TlsGetValue135VirtualProtect136VirtualQuery137mbrtowc138wcrtomb139__p__environ140_stat64i32141_set_new_mode142calloc143malloc144_configthreadlocale145localeconv146__setusermatherr147__C_specific_handler148memcpy149__p___argc150__p___argv151_cexit152_configure_narrow_argv153_crt_atexit154_errno155_initialize_narrow_environment156_set_app_type157_initterm158_initterm_e159_set_invalid_parameter_handler160signal161strerror162__acrt_iob_func163__p__commode164__p__fmode165__stdio_common_vfprintf166strlen167strncmp168strnlen169wcslen170wcsnlen171_ZSt17__throw_bad_allocv172_ZSt19__throw_logic_errorPKc173_ZSt20__throw_length_errorPKc174_ZSt21__glibcxx_assert_failPKciS0_S0_175_ZSt4cout176_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc177_ZStlsIcSt11char_traitsIcESaIcEERSt13basic_ostreamIT_T0_ES7_RKNSt7__cxx1112basic_stringIS4_S5_T1_EE178_ZdlPvy179__gxx_personality_seh0180libgcc_s_seh-1.dll181KERNEL32.dll182api-ms-win-crt-convert-l1-1-0.dll183api-ms-win-crt-environment-l1-1-0.dll184api-ms-win-crt-filesystem-l1-1-0.dll185api-ms-win-crt-heap-l1-1-0.dll186api-ms-win-crt-locale-l1-1-0.dll187api-ms-win-crt-math-l1-1-0.dll188api-ms-win-crt-private-l1-1-0.dll189api-ms-win-crt-runtime-l1-1-0.dll190api-ms-win-crt-stdio-l1-1-0.dll191api-ms-win-crt-string-l1-1-0.dll192libstdc++-6.dll193<?xml version="1.0" encoding="UTF-8" standalone="yes"?>194<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">195 <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">196 <security>197 <requestedPrivileges>198 <requestedExecutionLevel level="asInvoker"/>199 </requestedPrivileges>200 </security>201 </trustInfo>Command:
1xxd -l 512 detonator.exeOutput:
100000000: 4d5a 9000 0300 0000 0400 0000 ffff 0000 MZ..............200000010: b800 0000 0000 0000 4000 0000 0000 0000 ........@.......300000020: 0000 0000 0000 0000 0000 0000 0000 0000 ................400000030: 0000 0000 0000 0000 8000 0000 0000 0000 ................500000040: 0e1f ba0e 00b4 09cd 21b8 014c cd21 5468 ........!..L.!Th600000050: 6973 2070 726f 6772 616d 2063 616e 6e6f is program canno700000060: 7420 6265 2072 756e 2069 6e20 444f 5320 t be run in DOS 800000070: 6d6f 6465 2e0d 0d0a 2400 0000 0000 0000 mode....$.......900000080: 5045 0000 6486 1300 451e c569 004a 0300 PE..d...E..i.J..1000000090: 5f0a 0000 f000 2600 0b02 022d 008a 0000 _.....\&....-....11000000a0: 0040 0000 000c 0000 0014 0000 0010 0000 .@..............12000000b0: 0000 0040 0100 0000 0010 0000 0002 0000 ...@............13000000c0: 0400 0000 0000 0000 0500 0200 0000 0000 ................14000000d0: 0000 0400 0006 0000 493d 0500 0300 6001 ........I=....`.15000000e0: 0000 2000 0000 0000 0010 0000 0000 0000 .. .............16000000f0: 0000 1000 0000 0000 0010 0000 0000 0000 ................1700000100: 0000 0000 1000 0000 0000 0000 0000 0000 ................1800000110: 0000 0100 a40c 0000 0020 0100 e804 0000 ......... ......1900000120: 00d0 0000 1806 0000 0000 0000 0000 0000 ................2000000130: 0030 0100 7000 0000 0000 0000 0000 0000 .0..p...........2100000140: 0000 0000 0000 0000 0000 0000 0000 0000 ................2200000150: c0b4 0000 2800 0000 0000 0000 0000 0000 ....(...........2300000160: 0000 0000 0000 0000 6003 0100 4802 0000 ........`...H...2400000170: 0000 0000 0000 0000 0000 0000 0000 0000 ................2500000180: 0000 0000 0000 0000 2e74 6578 7400 0000 .........text...2600000190: 9088 0000 0010 0000 008a 0000 0006 0000 ................27000001a0: 0000 0000 0000 0000 0000 0000 2000 0060 ............ ..`28000001b0: 2e64 6174 6100 0000 d000 0000 00a0 0000 .data...........29000001c0: 0002 0000 0090 0000 0000 0000 0000 0000 ................30000001d0: 0000 0000 4000 00c0 2e72 6461 7461 0000 ....@....rdata..31000001e0: 6015 0000 00b0 0000 0016 0000 0092 0000 `...............32000001f0: 0000 0000 0000 0000 0000 0000 4000 0040 ............@..@3. Analysis / Forensics Path
The first important clue in the string dump was that the binary contains both a fake flag and a Windows path that embeds that fake flag:
1C:\\Users\\HACK10{f4k3_fl4g_bu7_y0u_4r3_in_7h3_righ7_7r4ck}\\Desktop\\local.txt2HACK10{f4k3_fl4g_bu7_y0u_4r3_in_7h3_righ7_7r4ck}3File not found. Keep looking...4Here is the flag: HACK10{At this point the working hypothesis was that the fake flag is used as bait inside a filesystem path and the real flag is derived from that full path.
To confirm that, I inspected the PE symbol table and disassembled the named flag-checking function.
Command:
1objdump -t detonator.exe | grep -E ' main$|WinMain|flag|local|read|print|sub_' | sed -n '1,220p'Output:
1[ 35](sec 3)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x0000000000000c10 .rdata$.refptr.__globallocalestatus2[ 49](sec 1)(fl 0x00)(ty 20)(scl 2) (nx 1) 0x00000000000003e0 WinMainCRTStartup3[129](sec 1)(fl 0x00)(ty 20)(scl 2) (nx 1) 0x00000000000009cf _Z10check_flagv4[133](sec 1)(fl 0x00)(ty 20)(scl 2) (nx 1) 0x0000000000000b7e mainCommand:
1objdump -d -Mintel --disassemble=_Z10check_flagv detonator.exeOutput:
100000001400019cf <_Z10check_flagv>:2 1400019ee: 48 8d 15 23 98 00 00 lea rdx,[rip+0x9823] # 14000b218 <_ZL1S+0x118>3 1400019ff: e8 7c 7c 00 00 call 140009680 <_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1IS3_EEPKcRKS3_>4 140001a1f: 48 8d 15 42 98 00 00 lea rdx,[rip+0x9842] # 14000b268 <_ZL1S+0x168>5 140001a30: e8 4b 7c 00 00 call 140009680 <_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1IS3_EEPKcRKS3_>6 140001a5b: e8 d0 6e 00 00 call 140008930 <stat64i32>7 140001a60: 85 c0 test eax,eax8 140001a67: 74 1d je 140001a86 <_Z10check_flagv+0xb7>9 140001a69: 48 8d 15 30 98 00 00 lea rdx,[rip+0x9830] # 14000b2a0 <_ZL1S+0x1a0>10 140001a7a: e8 41 01 00 00 call 140001bc0 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc>11 140001a86: 48 8d 15 34 98 00 00 lea rdx,[rip+0x9834] # 14000b2c1 <_ZL1S+0x1c1>12 140001a97: e8 24 01 00 00 call 140001bc0 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc>13 140001aaa: e8 a1 f9 ff ff call 140001450 <_ZL3md5RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE>14 140001ab9: e8 fa 00 00 00 call 140001bb8 <_ZStlsIcSt11char_traitsIcESaIcEERSt13basic_ostreamIT_T0_ES7_RKNSt7__cxx1112basic_stringIS4_S5_T1_EE>15 140001ac1: 48 8d 05 13 98 00 00 lea rax,[rip+0x9813] # 14000b2db <_ZL1S+0x1db>This shows the exact logic:
Build a std::string from the hardcoded path at .rdata+0x218.
Check whether the path exists with _stat64i32.
If it exists, print Here is the flag: HACK10{.
Call the internal MD5 function on that path string.
Print the MD5 digest and append }.
The .rdata dump confirms the relevant literals:
114000b210 00000000 00000000 433a5c55 73657273 ........C:\\Users214000b220 5c484143 4b31307b 66346b33 5f666c34 \\HACK10{f4k3_fl4314000b230 675f6275 375f7930 755f3472 335f696e g_bu7_y0u_4r3_in414000b240 5f376833 5f726967 68375f37 7234636b _7h3_righ7_7r4ck514000b250 7d5c4465 736b746f 705c6c6f 63616c2e }\\Desktop\\local.614000b260 74787400 00000000 4841434b 31307b66 txt.....HACK10{f714000b270 346b335f 666c3467 5f627537 5f793075 4k3_fl4g_bu7_y0u814000b280 5f347233 5f696e5f 3768335f 72696768 _4r3_in_7h3_righ914000b290 375f3772 34636b7d 00000000 00000000 7_7r4ck}........1014000b2a0 46696c65 206e6f74 20666f75 6e642e20 File not found.1114000b2c0 00486572 65206973 20746865 20666c61 .Here is the fla1214000b2d0 673a2048 41434b31 307b007d 0a005f5f g: HACK10{.}..__4. Exploitation / Recovery
Since the binary computes MD5("C:\\\\Users\\\\HACK10{f4k3_fl4g_bu7_y0u_4r3_in_7h3_righ7_7r4ck}\\\\Desktop\\\\local.txt"), the recovery path is simply to reproduce that digest locally.
Exact solver script used:
1#!/usr/bin/env python32import hashlib3def main() -> None:4 path = r"C:\\Users\\HACK10{f4k3_fl4g_bu7_y0u_4r3_in_7h3_righ7_7r4ck}\\Desktop\\local.txt"5 digest = hashlib.md5(path.encode()).hexdigest()6 print(f"HACK10{{{digest}}}")7if __name__ == "__main__":8 main()Exact command used to execute the solver:
1python3 solve_detonator.pyOutput:
I also verified the digest directly against the byte string recovered from the binary:
Command:
1python3 - <<'PY'2from pathlib import Path3b = Path('detonator.exe').read_bytes()4needle = b'C:\\\\Users\\\\HACK10{f4k3_fl4g_bu7_y0u_4r3_in_7h3_righ7_7r4ck}\\\\Desktop\\\\local.txt\\x00'5off = b.find(needle)6print('offset:', hex(off))7print('slice :', b[off:off+len(needle)])8import hashlib9print('md5 :', hashlib.md5(needle[:-1]).hexdigest())10PYOutput:
1offset: 0x94182slice : b'C:\\\\Users\\\\HACK10{f4k3_fl4g_bu7_y0u_4r3_in_7h3_righ7_7r4ck}\\\\Desktop\\\\local.txt\\x00'3md5 : be029cf0e9f2eaa5f80489343630befb5. Flag
6. Summary of Approach & Key Takeaways
Triaged the sample as a 64-bit Windows PE compiled with MinGW.
Used strings to identify a fake embedded flag, a suspicious Windows path, and a partial flag-printing string.
Used the preserved symbol table to find _Z10check_flagv and disassembled it.
Confirmed that the program checks for the existence of the hardcoded path and, on success, prints HACK10{ plus the MD5 of that exact path string.
Reproduced the MD5 digest in Python and recovered the final flag.
Fake flags embedded in strings are often bait, not the real answer.
When symbols are present, go straight to named functions before doing deeper blind reversing.
A malware-themed description can still resolve to a simple static derivation path.
Rebuilding the program logic outside the binary is often faster and cleaner than emulating execution.