Kong - Hard

Writeup da máquina Kong, da Hacking Club by Crowsec Edtech. Sinceramente essa máquina deveria estar como insane 😏

Essa é uma máquina de dificuldade Hard, feita pelo Carlos Vieira, queridão Kadu!

RECON

Iniciamos com um portscan na máquina e temos 3 portas disponíveis.

Podemos então, a partir disso, entrar na plataforma web e ver o que temos.

Apenas uma mensagem simples, mas algo interessante temos quando utilizamos a extensão Wappalyzer.

Rodamos então um fuzzing na página e ver se achamos, porém, em várias wordlists só é retornada a página de erro do Spring:

Depois de rodar algumas wordlists, uma retornou algo muito legal, a quickhits.

Pesquisando sobre, temos alguns artigos que podem nos ajudar a achar algo útil em algum desses diretórios. O que irei utilizar é este: https://0xn3va.gitbook.io/cheat-sheets/framework/spring/spring-boot-actuators. Então podemos ver o que há em /actuator/heapdump:

Temos um arquivo Java gigantesco aqui chamado heapdump. Segundo o artigo, tratasse de informações que podem ser confidenciais, como variáveis de ambiente, e até mesmo configurações da aplicação. Podemos utilizar o strings e o grep para capturar talvez senhas, usuários, qualquer coisa util. Vamos ver:

Ao utilizar esse comando, recebemos várias informações, mas nada muito útil:

strings heapdump | grep "password"

Vamos ser mais criativos então, vamos adaptar o comando e procurar tudo que tiver "hackingclub", e agora sim, temos melhores resultados:

strings heapdump | grep "hackingclub"

Temos um host, vamos adicioná-lo no nosso arquivo de hosts, mas também vamos adicionar o principal, então temos dois hosts para adicionar:

Vamos acessar então os dois hostsm no api-rest-admin temos um basic auth, e no kong.hackingclub temos a mesma aplicação de antes ao acessar apenas o IP:

EXPLORAÇÃO

Vimos antes que no primeiro hosts temos o actuator, podemos procurar na internet se temos alguma referência ou falha mais específica sobre ele mas não foi necessário procurar muito, no mesmo artigo que usei antes, existe o jolokia. Nesse caso em específico, rodei o nuclei para ver se acha algo com o jolokia, porém rodei com todos os templates, e filtrei os que são info e unknown.

Então passando:

echo "http://kong.hackingclub/" | nuclei -t ~/nuclei-templates/ -es info,unknown

Temos muita coisa, inclusive um LFI:

Vamos ver então o que é isso.

Que interessante. Porém, não temos muito o que fazer com isso. Lembrei que temos o host de api onde podemos fazer um login, então precisamos encontrar alguma credencial. Vamos começar a enumerar a configuração do kong utilizando a própria doc: https://docs.konghq.com/gateway/latest/production/running-kong/secure-admin-api/, porém nada de muito interessante. :/

Mas temos o heapdump, podemos ver se encontramos algo nele referente a admin

strings heapdump | grep "admin"

Aparentemente temos uma key, vamos usar o LFI para ver o que temos lá:

PÓS-EXPLORAÇÃO

Opa, então temos aqui as credenciais do admin e a primeira flag, não foi tão difícil. 👀 Vamos logar lá no admin então.

Ao acessar a api, podemos ver que na request ele passa um Authorization com um Basic em base64. Então podemos encondar as credenciais que conseguimos em base64 para ver se da certo:

Resultado:

Temos acesso! Então vamos adicionar esse Header nas nossas requests.

Passei muito tempo explorando, vendo as configurações que temos acesso a ver a página de admin. Porém nada útil.

Depois de algumas horas lendo e estudando sobre, descobri uma forma de nos comunicar com a api, utilizando um projeto chamado Konga: https://github.com/codeedu/apigateway-kong, e usando esse vídeo como base, podemos aprender a utilizá-lo: https://www.youtube.com/watch?v=_2GRXgYswhI&t=34s.

Podemos só seguir o tutorial a risca para termos o seguinte resultado:

docker-compose -d up db 
  • Aqui precisamos deixar a db subir completamente, para verificar isso é só usar docker-compose ps, e esperar a db atingir healthy:

E agora sim podemos subir o restante da aplicação

docker-compose up -d

Após seguir o passo-a-passo do vídeo, na porta 1337 no localhost podemos acessar o konga:

Criamos nossas credenciais, logamos e exploramos a aplicação. Dentro da aplicação, estudando ela, podemos adicionar conexões, plugins, usuários e etc. Porém, ao tentar nos comunicar com o host da api que estamos tentando explorar, aparentemente, não conseguimos.

Vamos aos passos:

  • Primeiro entramos em CONNECTIONS, e depois em NEW CONNECTIONS:

  • Ao clicar, temos algumas opções de comunicação, mas no nosso caso, utilizaremos Basic Auth, que é como estamos conseguindo acessar a api de admin. Configuramos então nossas infos e clicamos em CREATE CONNECTION:

  • Depois de criar, temos o resultado:

  • Ao clicar em ativar, não obtivemos acesso:

Isso dá a entender que não conseguimos nos comunicar por causa do host. Nós temos adicionado no nosso arquivo de hosts da nossa máquina, mas o konga está rodando em um container, e no container não está adicionado, então provavelmente precisamos adicionar lá. Para isso, acessamos o container, e adicionamos nele o ip e o host, assim como fizemos na nossa máquina:

  • Verificamos o id do container do konga, e utilizamos ele para acessar o container

docker ps
docker exec -it id_do_container bash

Agora sim, com ele adicionado no arquivo de hosts do container, vamos novamente tentar nos comunicar com a api:

Enfim, agora depois de ativado temos acesso a algumas opções utilizando a api e, depois de explorar bastante, vi que adicionando um plugin passando um código em Lua, podemos conseguir uma reverse shell. Segundo a doc, podemos adicionar plugins dessa forma: https://docs.konghq.com/hub/kong-inc/serverless-functions/, talvez consegamos executar código lua. Vamos tentar:

  • Primeiro clicamos em Plugins, em Pre Functions clicamos em Add Plugin:

  • Adicionamos nossa reverse shell com uma função lua:

  • E finalmente recebemos nossa shell, mas não entramos como root, então ainda precisamos de uma forma de conseguir nossa flag:

Escolhi direto baixar o linpeas na máquina para ver o que trazia e trouxe algo muito importante, e tive certeza que era por esse caminho assim que vi:

Podemos nos comunicar com o docker utilizando o docker.sock já que temos permissão. Então vou usar uma das tricks que encontrei para tentar explorá-lo: https://nosferatu.gitbook.io/nosferatu/notas/escalacao-de-privilegios/linux

Não temos curl na máquina, então preciso baixar o curl para lá também e seguir a risca os comandos citados no link.

1) curl -i -s -k  -X 'POST' -H 'Content-Type: application/json' --data-binary '{"Hostname": "","Domainname": "","User": "","AttachStdin": true,"AttachStdout": true,"AttachStderr": true,"Tty": true,"OpenStdin": true,"StdinOnce": true,"Entrypoint": "/bin/bash","Image": "kong-spring","Volumes": {"/hostos/": {}},"HostConfig": {"Binds": ["/:/hostos"]}}' http://localhost/containers/create --unix-socket /run/docker.sock
2) curl -XPOST --unix-socket /run/docker.sock http://localhost/containers/<container_id>/start
3) curl -i -s -X POST -H "Content-Type: application/json" --data-binary '{"AttachStdin": true,"AttachStdout": true,"AttachStderr": true,"Cmd": ["cat", "/hostos/root/root.txt"],"DetachKeys": "ctrl-p,ctrl-q","Privileged": true,"Tty": true}' http://localhost/containers/<container_id>/exec --unix-socket /run/docker.sock 
4) curl -i -s -X POST -H 'Content-Type: application/json' --data-binary '{"Detach": false,"Tty": false}' http://localhost/exec/<exec_id>/start --unix-socket /run/docker.sock 

Após isso, finalmente, conseguimos nossa flag de root:

Last updated