October 20, 2026
Blind OS Command Injection With Out-of-Band Interaction
Proving a command executed when the application never shows you the result

By Kaustubh Asthana
4 min read
The first two blind command injection labs in this series both left a trail I could watch directly. Time delays showed up as a slower response. Output redirection let me read the result back from a file I could request afterward. This lab takes both of those away. The response to my injected request looks identical to a normal one, there's no timing difference to measure, and there's no writable web directory to drop output into and fetch later. The only way to confirm a command actually ran on the server is to make that server reach out to something I control, somewhere else entirely.
That's what out-of-band, or OOB, interaction means in this context. Instead of looking for a signal inside the HTTP response, you plant a payload that forces the backend to make a completely separate network connection, usually a DNS lookup, to a domain you own. If that domain gets pinged, you've got proof of execution, independent of anything the application returns to your browser.
Setting Up the Listener
Burp Suite ships with a tool built exactly for this called Collaborator. It generates a unique, disposable subdomain on Burp's own infrastructure and then sits there logging every interaction that domain receives, DNS lookups, HTTP requests, even SMTP connections, along with the source IP and timestamp of each one.
The workflow is simple. You generate a payload domain from the Collaborator tab, drop that domain into wherever you suspect the injection point is, trigger the request, and then poll Collaborator to see if anything came back. If your injected command included a DNS lookup of that domain and the command actually executed, the server's own infrastructure performs the lookup, and Collaborator logs it. No lookup means either the injection didn't fire or the input never reached a shell at all.
Finding the Injection Point
The lab description for this one was direct about where the vulnerability sits: the email field on the feedback form. That saved me the trial-and-error of probing name, subject, and message individually, and let me go straight to building the payload instead of hunting for the right parameter.
I opened the feedback form and submitted it once with ordinary values first, just to see the baseline behavior.
Capturing the Baseline Request
With Burp's proxy running, I pulled that same submission up in the request history. It was a straightforward POST to the feedback submit endpoint, carrying name, email, subject, and message as standard URL-encoded form fields, nothing unusual in the request or the response.
Generating the Collaborator Payload
Next I switched to the Collaborator client inside Burp and generated a fresh payload domain. I copied that domain out so I'd have a clean record of exactly what I was about to inject, separate from the rest of the request.
Injecting the Payload
Back in the request, I rebuilt the email field. Instead of a normal address, I appended the test email, then two pipe characters, then an nslookup command pointing straight at the Collaborator domain, then two more pipe characters to close it out. The pipe is what chains the extra command onto whatever the backend was already going to run with that input, letting my nslookup execute alongside, or instead of, the application's own logic. I sent the request.
The response came back looking exactly like the baseline. No error, no delay, no sign anything unusual had happened. That's expected, and it's the entire point of this lab, the application was never going to tell me anything.
Checking Collaborator
So I went back to the Collaborator client and polled it.
Two separate DNS lookups had come in, logged a millisecond apart from two different source IP addresses. The server had resolved the domain I'd planted, which only happens if the nslookup command I injected actually ran. That was confirmation the injection point was real and the payload had executed, even though nothing in the HTTP response ever hinted at it.
Closing It Out
I went back to the lab and refreshed.
Why This Matters
Most writeups on command injection focus on the cases where you get something back, a time delay, a file you can read, output reflected directly into the page. Real-world applications are often less forgiving than that. A background job processing a feedback form, a webhook handler, an async worker, none of these are obligated to tell an attacker anything about what they did with the input they received. If the only thing a tester checks for is a visible change in the response, a vulnerability like this one passes every manual check and still ships.
Out-of-band techniques close that gap by moving the signal outside the request and response entirely. The server doesn't need to tell you it ran your command, it just needs to touch infrastructure you're watching. That's a meaningfully different detection model, and it's the same underlying technique used to confirm all sorts of blind vulnerabilities beyond command injection, blind SQL injection and blind SSRF both lean on the exact same idea of forcing an outbound signal to a listener you control.
Takeaways From This Lab
- When a response gives you nothing to measure, stop looking inside it. Look for a way to make the server reach outward instead.
- Burp Collaborator exists for exactly this gap, it hands you a disposable domain and logs every interaction it receives, with source IP and timestamp, so you can correlate a payload to a result that never touches the HTTP response.
- Chaining a command onto an existing parameter with a pipe doesn't require the original input to fail, it just needs to ride alongside whatever the backend was already going to execute.
- A clean 200 OK is not proof that nothing happened. It's only proof that nothing was reported back to you.