> For the complete documentation index, see [llms.txt](https://zeyad-abulaban.gitbook.io/notes/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://zeyad-abulaban.gitbook.io/notes/web-penetration-testing/web-vulns/sqli/mysql.md).

# MySQL

***

* [**Fingerprinting MySQL**](#fingerprinting-mysql)
* [**Attack Vectors**](#attack-vectors)

***

MySQL comes with at least four versions which are used in production worldwide, `3.23.x`, `4.0.x`, `4.1.x` and `5.0.x`. Every version has a set of features proportional to version number.

* From Version 4.0: UNION
* From Version 4.1: Subqueries
* From Version 5.0: Stored procedures, Stored functions and the view named `INFORMATION_SCHEMA`
* From Version 5.0.2: Triggers

It should be noted that for MySQL versions before 4.0.x, only Boolean or time-based Blind Injection attacks could be used, since the subquery functionality or `UNION` statements were not implemented.

## The Single Quotes Problem

#### Bypass the need of single quotes

Let’s suppose we want to know the value of a field named `password` in a record.

1. Password like `'A%'`
2. The ASCII values in a concatenated hex: `password LIKE 0x4125`
3. The char() function: `password LIKE CHAR(65,37)`

## Multiple Mixed Queries

MySQL library connectors do not support multiple queries separated by `;`

## Fingerprinting MySQL

When a comment block `'/**/'` contains an exclamation mark `'/*! sql here*/'` it is interpreted by MySQL.

Example:

```sql
1 /*! and 1=0 */
```

## Versions

using comment fingerprinting with a version number

```sql
/*!40110 and 1=0*/
```

which means

```txt
if(version >= 4.1.10)
   add 'and 1=0' to the query.
```

***These are equivalent as the result is the same.***

**In band injection:**

```sql
1 AND 1=0 UNION SELECT @@version /*
```

**Inferential injection:**

```sql
1 AND @@version like '4.0%'
```

## Attack Vectors

If the connected user has `FILE` privileges and single quotes are not escaped, the `into outfile` clause can be used to export query results in a file.

```sql
Select * from table into outfile '/tmp/file'
```

> Note: there is no way to bypass single quotes surrounding a filename. So if there’s some sanitization on single quotes like escape `\'` there will be no way to use the `into outfile` clause.

#### Write a payload to a file

```sql
1 limit 1 into outfile '/var/www/root/test.jsp' FIELDS ENCLOSED BY '//'  LINES TERMINATED BY '\n<%jsp code here%>';
```

* Results are stored in a file with `rw-rw-rw` privileges owned by MySQL user and group.
* Where `/var/www/root/test.jsp` will contain: `//field values// ] <%jsp code here%>`

#### Read from a File

```sql
load_file('filename')
```

## Blind SQL Injection

* String Length:
  * `LENGTH(str)`
* Extract a substring from a given string:
  * `SUBSTRING(string, offset, #chars_returned)`
* Time based Blind Injection:
  * BENCHMARK and SLEEP `BENCHMARK(#ofcycles,action_to_be_performed)` The benchmark function could be used to perform timing attacks when blind injection by boolean values does not yield any results. See. `SLEEP()` (MySQL > 5.0.x) for an alternative on benchmark.
