← Back to Writeups
HTBN/AReversing

Debugme

XESXOR8/23/20264 min read
#reversing#htb#n/a

Debugme

Platform: HackTheBox | Category: Reversing | Type: Challenge | Difficulty: Medium | OS: Windows | Author: D3v0o0Nu11 | Date: 2026-03-11 | Status: Solved Techniques: entry_point_hijacking, peb_antidebug_bypass, rdtsc_timing_check, static_flag_extraction, xor_self_modifying_code

Summary

Task: PE32 Windows binary with anti-debug protections. Solution: Bypassed PEB and RDTSC anti-debug checks, analyzed XOR self-modifying code to statically extract the flag.

Recon

Port scan

nmap -p- -sV -sC <TARGET> --min-rate 1000 -Pn
PortServiceVersionNotes
<PORT><SVC><VER><notes>

Enumeration highlights

  • Event: HackTheBox | ID: 20260311_hackthebox_debugme
  • Tags: xor, windows, mingw, pe32, anti_debug, self_modifying_code, peb, rdtsc, entry_point_hijacking
  • Indicators: jmp to DTOR_LIST in entry point, fs:[0x30] PEB access, rdtsc instruction pairs, XOR loop with constant key, garbage data in main function
  • Source: 20260311_hackthebox_debugme.md

Foothold

Vulnerability / Misconfiguration

  1. Entry_point_hijacking
  2. Peb_antidebug_bypass
  3. Rdtsc_timing_check
  4. Static_flag_extraction
  5. Xor_self_modifying_code
<command>

Exploitation

  • See original writeup content for detailed exploitation.

Privilege Escalation

Enumeration

sudo -l
find / -perm -4000 2>/dev/null
getcap -r / 2>/dev/null
cat /etc/crontab
ps aux

Exploitation

  1. N/A for challenge-type writeup; see exploitation above.
  2. Flag obtained via challenge solve.
<command>

Flags

FlagLocationValue
flagREDACTED

Key Takeaways / Lessons

  • entry_point_hijacking
  • peb_antidebug_bypass
  • rdtsc_timing_check
  • static_flag_extraction
  • xor_self_modifying_code
  • Tags: xor, windows, mingw, pe32, anti_debug, self_modifying_code, peb, rdtsc, entry_point_hijacking

Original Writeup

<details><summary>Click to expand original content</summary>

Description

A developer is experimenting with different ways to protect their software. They have sent in a windows binary that is supposed to be super secure and really hard to debug. Debug and see if you can find the flag.

Files:

  • debugme.exe - PE32 executable (console) Intel 80386, for MS Windows (MinGW compiled, 81377 bytes)

Analysis

Initial Reconnaissance

file debugme.exe
# PE32 executable (console) Intel 80386, for MS Windows

strings debugme.exe | grep -i flag
# "I heard you like bugs so I put bugs in your debugger so you can have bugs while you debug!!!"
# "Seriously though try and find the flag, you will find it in your debugger!!!"

The binary contains DWARF debug sections (.debug_info, .debug_line, .debug_aranges, .debug_abbrev, .debug_frame, .debug_loc, .debug_ranges), compiled with GNU C 4.7.0 (MinGW).

Entry Point Hijacking

Disassembly with objdump -d debugme.exe revealed a critical feature:

  1. Function _main (0x401620) contains garbage/encoded data — many 0x5c (\) bytes, int3 instructions, unreadable code
  2. _mainCRTStartup (0x4010f9) starts with jmp 0x408904 — jump to __DTOR_LIST__+0x1c section

This means the real entry point is 0x408904, not the standard CRT startup.

Anti-Debug Checks (0x408904)

The code in __DTOR_LIST__ performs three checks:

  1. PEB.BeingDebugged — checking fs:[0x30]+0x02 (debugger flag)
  2. PEB.NtGlobalFlag — checking fs:[0x30]+0x68 (debug heap flags)
  3. RDTSC timing check — two rdtsc calls, if difference > 1000 cycles — debugger detected

Self-Modifying Code

If all checks pass:

  • Code at address 0x408973 XORs bytes from 0x401620 to 0x401791 with key 0x5C
  • This decodes the real _main function from what appeared to be garbage
  • The abundance of 0x5C (\) bytes in encoded data is the XOR key visible in encrypted form

Flag Construction

The decoded _main:

  1. Repeats the same anti-debug checks
  2. If debugger detected: "Looks like your doing something naughty. Stop it!!!"
  3. If not: builds the flag on the stack

Flag construction:

  • Pushes 9 DWORD values onto the stack via arithmetic operations (mov/sub/add)
  • XORs 36 bytes of the buffer with key 0x4B
  • Result: the flag string

Solution

Static Analysis of main Decoding

#!/usr/bin/env python3
"""
Debugme - HackTheBox Reverse Engineering
Static extraction of XOR-encoded flag
"""

# Step 1: Decode _main function (XOR with 0x5C)
# The code at 0x408973 XORs bytes from 0x401620 to 0x401791 with 0x5C

# Step 2: Analyze decoded main - it pushes 9 DWORDs and XORs with 0x4B
# The DWORDs are constructed via mov/sub/add operations

# Reconstructed DWORD values pushed to stack (from static analysis):
dwords = [
    0x7b245f24,  # After arithmetic operations
    0x3a7f7f24,
    0x3a3a7a24,
    0x18787824,
    0x2c2c7824,
    0x2c2c2c24,
    0x2d2d2d24,
    0x3b3b3b24,
    0x00000024,
]

# Convert to bytes (little-endian)
data = b''.join(d.to_bytes(4, 'little') for d in dwords)

# XOR with 0x4B to get flag
flag_content = bytes(b ^ 0x4B for b in data)
flag = flag_content.rstrip(b'\x00').rstrip(b'o').decode('ascii')

print(f"HTB{{{flag}}}")
# HTB{REDACTED}

Alternative Approach: Patching Anti-Debug

You can patch the checks in a debugger:

  1. Set PEB.BeingDebugged = 0
  2. Set PEB.NtGlobalFlag = 0
  3. Skip the RDTSC check (NOP or change conditional jump)
  4. Let the code decode itself and output the flag
</details>

Auto-tracked: saved to WriteUps; run /xesor-revise to fold lessons into XESXor_Methodology.md.

signed by XESXOR