EC-Council LPT Master study materials
EC-Council LPT Master study resources

Weaponising a stack overflow on a warehouse pick-line service

EC-Council LPT Master · Put your knowledge to work in context.

All case studies

Weaponising a stack overflow on a warehouse pick-line service

During an internal test at Helios Logistics you find a custom 32-bit Windows service, WHSE-SYNC.EXE, listening on TCP 7402 on 46 warehouse workstations. There is no source code and no test environment. The service synchronises barcode scans, and a crash stalls the pick line for roughly 20 minutes. Sending 5,000 A bytes over the socket crashes it; you determine a 268-byte offset to EIP with roughly 200 bytes of writable space before the end of the buffer. The hosts run Windows 10 with system-wide DEP and ASLR enabled, but dumpbin /headers shows the binary was linked without /DYNAMICBASE and without /SAFESEH. The maintenance window is Sunday 02:00-04:00, and you have written authorisation for exploitation. The operations manager's only instruction is "do not take the line down".

1. How do you develop and validate this exploit without stalling the pick line? Lay out the sequence and the controls.

Read the worked answer

Move the crash off the production floor before writing a single byte of exploit.

Phase 1 - replicate (days before Sunday):

  • With written permission, copy the service binary, its DLLs, and the registry/service configuration from one workstation. Record SHA-256 hashes so your lab matches the field build.
  • Build a Win10 32-bit VM (and a 64-bit one, in case of WoW64 quirks) matching patch level and installed redistributables. Run the service under a debugger locally.
  • Derive the offset from your own crashing input using a generated cyclic pattern, not by re-crashing the workstation. Confirm 268, then map exactly which bytes land on EIP and what sits after it.

Phase 2 - enumerate mitigations before designing the payload: check /DEP, /GS, SEHOP state, loaded DLLs and their ASLR status, and whether the service is single- or multi-threaded. A single-threaded service means one connection at a time - relevant to reliability and to the client's availability.

Phase 3 - validate on one host, in the window, with controls:

  • Pre-agreed rollback: a scheduled task or documented service restart procedure, tested beforehand, that restores normal operation in under two minutes.
  • Warehouse supervisor on the call; a named person who can stop the test.
  • First validation proves only EIP control (e.g. EIP = 0x41414141) with a debugger attached - no shellcode, no payload. That single attempt yields the evidence and takes the service down for seconds, not 20 minutes.

What I would not do: iterate payloads against a live pick-line host because "it restarts itself". A 20-minute outage times 46 workstations is a business interruption the report cannot justify.

2. Given system-wide DEP and ASLR but a binary built without /DYNAMICBASE and /SAFESEH, is reliable code execution realistic? What drives the answer?

Read the worked answer

The two missing flags help enormously, but DEP is the real gate.

What no /DYNAMICBASE gives you: the executable's own image base is fixed, so every gadget inside WHSE-SYNC.EXE is at a static, predictable address. That defeats ASLR for that module. Check the imported DLLs too - a legacy DLL loaded without ASLR (common with old vendor libraries) widens the useful gadget pool.

What DEP costs you: you cannot jump to the stack. You need a ROP chain to call VirtualProtect/VirtualAlloc with RWX, then pivot into it. With only ~200 bytes before the buffer end, the chain must be tight; a staged payload (ROP calls recv to read shellcode into a known writable region) is usually more practical than a full chain plus shellcode in one shot.

What no /SAFESEH gives you: the exception-handler chain is a candidate overwrite target, but do not assume it - Windows 10 enables SEHOP by default, which will reject a corrupted handler chain. Verify before betting the exploit on it.

Reliability drivers to test in the lab:

  • Stack layout stability across inputs (does the service copy fixed-length data before the vulnerable copy?)
  • Whether bad characters (0x00, 0x0a, 0x0d) corrupt the chain through the socket read
  • Threading: connection handling order
  • Restart behaviour and whether the service re-binds the port

Decision rule: run the exploit 30+ times in the lab and require near-100% success before touching a production host. If the chain is fragile, stop at EIP control and report a confirmed crash/DoS plus a clearly argued code-execution potential. 46 hosts means one reliable exploit becomes estate-wide, so reliability is not academic - it determines whether the report says "remote code execution" or "denial of service".

3. What artefacts do you deliver for this exploit, and what must not be in the package?

Read the worked answer

Deliver a reproducible proof, not a weapon.

Included:

  • PoC source (Python or C) in a clearly commented, single-purpose form, with the offset discovery script and the cyclic pattern used.
  • The tested binary's SHA-256 and version metadata, plus the matching service configuration.
  • Reproduction steps: lab host setup, debugger attach, expected register state at crash, and what success looks like at each stage (EIP control, ROP execution, staged payload).
  • A reliability statement: number of attempts, success rate, failure modes, and observed outage duration per attempt.
  • Mitigation guidance: rebuild with /GS, /DYNAMICBASE, /SAFESEH and modern compiler settings; add authentication to the 7402 protocol; segment warehouse VLANs so only sync servers reach the service; add an IPS signature for the oversized request; restrict the service account's privileges.
  • Vendor coordination note: the binary is custom, so responsible disclosure to the supplier runs in parallel with the client's fix.

Excluded:

  • Any payload or shellcode that persists, calls home, or is not strictly necessary to prove execution.
  • Credentials, customer or employee data extracted during testing.
  • A "production-ready" build handed over without handling instructions. If the weaponised version must exist, it is hashed, access-restricted, referenced in the report by hash, and retained or destroyed per the contract.
  • Copies of the client binary outside the agreed evidence repository.

Why the line matters: an exploit that works against 46 unpatched workstations is a loaded weapon if it leaks. The contract, the cyber-insurance position, and the client's own regulatory exposure all depend on you being able to say exactly which version existed and who held it - hence hashes, an evidence register, and a destruction certificate at engagement close.