Target
32-bit Windows FMLServer
Analysis
x32dbg and x86 stack layout
Exploit
Python TCP payload
Environment
Isolated Kali and Windows VMs

Scenario and boundaries

The target was FMLServer, compiled as a 32-bit Debug build and running on a Windows VM. I analyzed the process with x32dbg while a Kali Linux VM sent test data over TCP port 8421. Python handled payload delivery, and Metasploit tooling generated and received the final lab reverse connection.

This was an intentionally vulnerable environment. DEP, ASLR, stack protections, Windows Firewall, and real-time malware protection were disabled or relaxed so the exercise could isolate the mechanics of a classic stack overflow. The technique is not presented as representative of a normally hardened Windows system.

Root cause

The vulnerable isASCII() function accepted raw network input and copied it into char cmdToParse[500] with strcpy(). Because strcpy() copies until a null terminator and has no destination-length parameter, input longer than the buffer continued into local variables, the saved base pointer, and the saved return address.

Source code for the vulnerable isASCII function showing a 500-byte stack buffer followed by an unbounded strcpy call
The validation logic operated only after the unsafe copy. Checking whether bytes were ASCII did not protect the destination buffer from being overwritten first.

Establishing control of EIP

I first approximated the stack layout from the 500-byte buffer, two local integers, saved EBP, and saved EIP. I then sent marker-based payloads and observed register state in x32dbg. Seeing marker bytes appear in EIP proved that the network input controlled the saved return address; the final layout placed the replacement address after 512 padding bytes and four additional marker bytes.

To redirect execution, I searched the target module for a stable jmp esp instruction. The debugger identified address 0x561586B3, encoded in little-endian order inside the Python payload.

Debugger result listing a jmp esp instruction at address 0x561586B3
The selected instruction transferred control from the overwritten return address to the top of the attacker-controlled stack.

Payload construction

The final Python script opened a TCP socket to the server and assembled the payload in four parts. I excluded null and newline bytes from the generated x86 payload because either could terminate or disrupt the server’s string-processing path.

Component Purpose
Padding and markersReach the saved return address at the confirmed offset
JMP ESP addressReplace EIP and redirect execution to stack-controlled data
32-byte NOP sledProvide a tolerant landing region before the generated bytes
x86 reverse payloadEstablish the controlled callback to the Kali handler

Result

When the vulnerable function returned, the overwritten address was loaded into EIP. The selected instruction redirected execution to ESP, which advanced through the NOP sled and into the generated bytes. The reported result was a Meterpreter reverse TCP session from the Windows server process to the listener on the Kali VM, demonstrating remote code execution inside the lab.

Mitigation analysis

The direct fix is at the source: reject oversized input before copying and replace the unbounded copy with an explicitly bounded operation. Validation must occur before data enters the destination buffer, not after corruption has already happened.

  • Stack cookies (/GS) detect corruption before the function uses an overwritten return address.
  • DEP marks the stack non-executable, preventing this payload from running directly from injected stack bytes.
  • ASLR makes a fixed control-transfer address unreliable between executions.
  • Firewall, endpoint protection, and least exposure reduce access to the vulnerable service and improve detection.

Skills demonstrated

  • x86 stack analysis
  • Memory corruption
  • x32dbg
  • EIP control
  • Little-endian encoding
  • Python sockets
  • Payload construction
  • Bad-character handling
  • DEP, ASLR, and /GS
  • Secure coding analysis