DEV Community

Rocky
Rocky

Posted on

The SQL Injection That Never Showed Up in a Single Response

A pentester is testing an internal reporting endpoint: pass a customer ID, get back a PDF invoice. The ID parameter smells like SQLi, so the usual ladder starts. Error-based first: throw in a stray quote, look for a stack trace or a database error string in the response. Nothing. The app wraps every query in a try/catch and returns the same generic "report unavailable" page no matter what breaks on the backend.

Boolean-based blind is next: inject a condition that should flip the page's behavior between true and false. Except the ID parameter here feeds a subquery used only for an internal audit log write, not the query that actually decides what gets rendered. True or false, the customer sees the exact same PDF. No visible fork in the response means no oracle for boolean blind to read.

Time-based is the fallback for exactly this situation, so the tester tries it: inject a payload that should stall the query for five seconds if the condition is true, nothing if false. But there's a reverse proxy in front of this app enforcing a three-second upstream timeout, and it fires that timeout on every request once the backend takes too long, true condition or false. Both cases now return the same 504 at roughly the same three-second mark. The timing side channel that time-based blind depends on has been swallowed by infrastructure that has nothing to do with the vulnerability itself.

Three of the four classic techniques are dead, and none of them died because the SQLi isn't real. They died because nothing about this endpoint gives you a signal you can read back through the HTTP response.

That's the specific situation out-of-band SQL injection exists for: instead of trying to read the result of an injected query through the page, you make the database do something observable outside the response entirely, and you watch for it somewhere else. The classic version uses the database engine's own ability to make outbound network calls. On Microsoft SQL Server, procedures like xp_dirtree or xp_fileexist can be pointed at a UNC path such as \\<subdomain>.yourdomain.com\share, and the act of resolving that path triggers a DNS lookup against a name you control, one that can encode extracted data into the subdomain itself. On Oracle, functions like UTL_HTTP or UTL_INADDR can be chained inside a crafted injection to make the database originate an outbound HTTP request or DNS resolution the same way. Either way, you're not reading the answer in the response. You're reading it in your own DNS server's query log, or your own HTTP listener's access log, minutes after the request that triggered it already returned its identical, uninformative 504.

Sqlmap has a --dns-domain flag built around exactly this exchange: point it at a domain whose nameserver you control, and it automates the DNS-lookup exfiltration loop instead of you hand-crafting each xp_dirtree call.

The lesson underneath the technique matters more than any single payload: in-band, blind, and out-of-band aren't three unrelated tricks, they're the same methodology answering "how do I get data out of this database" under three different constraints on what's observable. In-band needs the response to leak the data directly. Blind needs the response to at least fork based on a condition. Out-of-band needs neither, because it uses a completely separate channel. Recognizing which constraint you're actually under, instead of retrying time-based blind for the tenth time against infrastructure that's eating your timing signal, is what turns this from guesswork into a methodology you can run consistently.

Codelivly's SQL Injection Notes PDF walks through in-band, blind, time-based and out-of-band SQLi as one connected methodology, with the database-specific payloads and sqlmap workflows for each, rather than treating OOB as an afterthought technique you only hear about when everything else has already failed.

If you want to drill the fundamentals hands-on first, the free SQLi Login Bypass lab and the NimbusPay SQL Injection CTF challenge on codelivly.com are a good place to build the pattern-recognition this methodology depends on.

Top comments (0)