Medinova

Difficulty: Medium | OS: Linux

Walkthrough - Youtube Habemus Shell


Em breve.

Scanning


image.png

Services and Versions


Exploration


Port 80 - http


  • Quando colocamos o ip no navegador, ele redireciona para um nome chamado medinova.hc então vamos colocar no /etc/hosts

  • Agora conseguimos acessar a página de forma correta

  • Navegando pela pagina web, chegamos na página "Consultation”

  • Essa página tinha um formulário de login e também nos dava a possibilidade de logar como usuário "guest”

  • Após realizar esse login com a conta guest, fomos redirecionados a uma página de marcação de consulta.

  • E vermos que temos um "Welcome Guest” demonstrando que estamos na conta do usuário Guest.

  • Quando logamos, normalmente temos um Cookie de sessão, analisando via burp, podemos comprovar pelo header inicial que se trata de um JWT.

  • O cookie JWT e formado exatamente como e exibido na sua forma decodada.

  • Um header, payload e uma assinatura.

  • Há uma misconfiguration se tratando no Algoritmo(alg) no header do Jwt. Podemos definir esse algoritmo como none , quando esse tipo de algoritmo e aceito pelo servidor, ele possibilita a aceitacao desse token sem a necessidade de uma assinatura.

WSTG - Latest | OWASP Foundationarrow-up-right

  • Como nao e necessario a assinatura com essa tecnica, podemos entao retirar a ultima parte do token jwt que corresponde a assinatura, deixando apenas o .

  • E agora podemos alterar o payload sem necessitar assinar o mesmo.

  • Vamos alterar o username para verificarmos se teremos sucesso na mensagem de boas vindas.

  • Normalmente o usuario administrativo vem como administrador ou admin, vamos tentar admin.

  • Antes disso, vale lembrar que esses campos do JWT se tratam de um encode base64, vamos jogar a assinatura no CyberChefarrow-up-right para podermos alterar e depois iremos retornar para o Jwt.io

  • Agora jogue essa parte decodada para o Input, altere o algoritmo(alg) para none e coloque para encodar em base64

  • Observe que ele colocou o caractere =, ele não e aceito na hora da formação do JWT, então pode retirá-lo.

  • Agora colamos o output no header do token.

  • E vai ficar assim o token final.

  • Poderíamos ter montado todo payload através do base64, já que e o encode do JWT. Mas dessa forma fica mais intuitiva e funcional.

  • Só mudei o header pelo base64 no CyberChef, pois se fizesse essa alteração o JWT.IOarrow-up-right iria deixar tudo branco, e um comportamento desse site, poderíamos usar outro que não tem esse compotamento, ou ate plugins para o burp suite para facilitar essa troca.

  • Agora podemos copiar o token final e alterar no navegador.

  • Podemos nos utilizar de plugins para facilitar essa troca de cookie, mas também podemos usar os recursos nativos do navegador.

  • Exemplo no firefox, aperte o F12 → Storage → Cookies

  • Altere o valor do token para o que alteramos e aperte enter.

  • Após isso só atualizar a página.

  • Observe que o username foi alterado para o que colocamos no token JWT, ou seja, temos aqui uma vulnerabilidade de JWT None Attack.

  • Como não temos mais nenhuma função que o admin possa executar, podemos tentar verificar se esse template pode ter alguma vulnerabilidade. Essa mentalidade surge, no momento que trocamos de usuario guest para admin e apenas isso faz com que o Welcome mude o nome do usuário.

  • Então caso manipulemos o username para forçar um XSS Reflected podemos confirmar que ele está colocando tudo que fica em username diretamente na página.

  • Alteramos o cookie novamente e atualizamos a página. Após a atualização, confirmamos que a página pega o username e coloca diretamente na página.

  • Com isso temos uma vulnerabilidade de XSS Reflected

  • E apos clicar em OK, fica sem nada do lado de Welcome.

  • Nessa hora você talvez estivesse pensando em um possível Stealer Cookie, já que a flag HTTP Only esta como false, para elevar para usuário administrativo, mas ja conseguimos mudar para usuário administrativo. E nao faz sentido, pois o usuario administrativo nao tem nenhuma funcao a mais que possamos aproveitar para um acesso ao servidor.

  • Bom, como trigamos o XSS e percebemos que tudo que colocamos no username ele coloca no template, podemos tentar agora uma falha de Server Side Template Injection (SSTI)

  • Verificando as tecnologias que temos nesse alvo, podemos observar que ele está rodando em PHP.

  • Temos uma tecnica para tentar descobrir qual template que esta rodando, conforme a imagem abaixo, iremos seguir esse fluxograma para poder encontrar qual payload triga essa vulnerabilidade.

Server-side template injection | Web Security Academyarrow-up-right

  • O primeiro payload ${7*7}, não funcionou, então podemos seguir para o {{7*7}}

  • O segundo payload, já funcionou, ele interpretou a expressão matemática e nos trouxe o resultado de 49.

  • Então possivelmente seja um template do tipo Twig, que é um template muito usado em PHP.

  • Para podermos explorar essa falha, precisamos registrar uma função de callback para funções indefinidas no php.

  • _self = objeto especial que representa o template atual.

  • env = instancia de Twig_environment, que gerencia a lógica principal do twig como funções registradas, etc.

  • registerUndefinedFunctionCallback() = não e uma função nativa do php, ela faz parte do ambiente Twig. Ela registra uma função de callback que será chamada sempre que o Twig encontrar uma funcao nao registrada (indefinida)

  • system = funcao do php que permite execução de comandos no sistema

  • callback = e uma chamada indireta em resposta a algum evento ou condição.

  • E precisamos agora chamar uma função que nao está registrada, ou seja indefinida, para que o motor do Twig chame a função de Callback que registramos anteriormente. Com isso, ele ira executar o comando do sistema que eu estou passando.

  • getFunction() = é um handler para funções registradas no Twig.

  • id= comando do linux, como não é uma função do twig, será chamado o callback para funções indefinidas que registramos anteriormente.

  • O payload final ficará assim:

  • Alterando agora o cookie no navegador e atualizando a página, conseguimos explorar o SSTI e conseguir uma execução remota de código (RCE).

  • Agora podemos tentar conseguir um reverse shell. Iremos usar o site reverse-shell.sharrow-up-right para criar diversos payloads de reverse shell, pois caso o alvo não tenha um, ele passa para outro.

  • Como o alvo não tem acesso à internet, vamos copiar o script para nossa máquina e vamos subir um servidor web em python para trigar com nosso alvo.

  • Altere o JWT com o payload para baixar e passar a saída para o comando bash .

  • Não esqueça de colocar um listener com netcat na porta que criamos o nosso script de reverse shell.

Initial Access


  • E com isso conseguimos o shell no alvo.

  • Vamos deixar o shell mais interativo para que possamos trabalhar melhor.

  • Não podemos ler a flag ainda, pois somos o usuário www-data, e precisamos fazer uma escalação de privilégio horizontal para o usuário Tom, para poder ler essa flag.

  • Esse script não tínhamos permissão de editar, mas podíamos executar.

  • lendo esse arquivo descobrimos que ele seta o diretório do repositório git com --git-dir na pasta home do usuário tom que não temos permissão de acessar.

  • Porém, nesse mesmo script temos a flag --work-tree que permite especificar um diretório de trabalho alternativo. Diretório de trabalho é onde os arquivos do repositório são extraídos e manipulados, e está apontando para /var/www/html e como somos o usuário www-data então temos permissão para alterar essa pasta.

  • E mais abaixo temos a chamada do /bin/bash -c, então temos um possível command injection aqui. Porém, como está entre aspas duplas, tudo que ficar entre eles é definido como string, então precisamos conseguir bypassar isso.

  • Mas precisamos saber se esse script é chamado por alguém, então podemos analisar os processos do alvo, para ver se algum usuário está chamando esse script através de uma tarefa agendada.

GitHub - DominicBreuker/pspy: Monitor linux processes without root permissionsarrow-up-right

  • baixamos no alvo.

  • Da permissão de execução

  • Após executarmos o pspy, conseguimos verificar que o usuário com UID=1001 executava o script que encontramos em /opt.

  • Se analisarmos o arquivo /etc/passwd do alvo, conseguimos descobrir que o uid 1001 é do usuário Tom

  • Então agora que já sabemos que é o usuário TOM que executa esse script, podemos tentar nos aproveitar da execução desse script que tem um possível command injection, para podermos escalar privilegio para o usuário TOM.

  • Vamos testar esse command injection então, o última comando do script, vamos copiar e alterar a variável $verify por um comando linux.

  • Lembrando que podemos executar comandos no linux colocando entre $() ou ``

  • E como o tee gera um novo arquivo com a saída do comando anterior, criamos o arquivo chamado teste.txt com o conteúdo do comando id.

  • Então realmente conseguimos confirmar que da para executarmos comando aqui.

  • Bom, precisamos inicializar o git no diretório /var/www/html que esta como work-tree no script.

  • Então ele sempre pega o novo arquivo e coloca na última linha substituindo a variável $verify

  • Se salvarmos um arquivo com um nome de comando, ele deve executar o comando que pedimos.

  • Observe que quando o usuário TOM executa o script, ele pega os arquivos novos e exibe, como colocamos um nome de arquivo como um comando do linux, ele executou o comando curl com sucesso.

  • Agora podemos criar um reverse shell para conseguir escalar para o usuário Tom.

  • Mas tem um problema nessa nossa Poc, não dá para colocar o caractere da barra / no nome do arquivo.

  • Uma boa estratégia é encodarmos em base64 do comando completo e fazer o decode.

  • E conseguimos agora confirmar nessa nova poc que dá para salvar em base64 o comando com barra e na hora do decode ele consegue executar.

  • Podemos tentar pegar um reverse shell agora.

  • E agora só basta encodar e criar o arquivo

  • Finalmente conseguimos acesso ao usuário Tom, e podemos agora ler a primeira flag.

Privilege Escalation


  • Agora precisamos escalar para usuário root.

  • Verificando direto no sudo -l

  • encontramos o binário read_pickle_files que roda com qualquer usuário, inclusive root sem precisar de senha.

  • Bom, o nome do binário já traz uma dica. Ele lê arquivos pickle

  • Com uma pesquisa na documentação do Python, podemos ver que o pickle é um módulo para serializar e deserializar um objeto python.

12.1. pickle — Serialização de objetos Python — documentação Python 3.6.15arrow-up-right

  • Vamos criar então um script para serializar com o pickle um objeto python

  • Observe que funcionou, com certeza esse script executa a função loads() da biblioteca pickle pois o objeto está sendo desserializado e executado.

  • Podemos então utilizar novamente um payload de reverse shell como fizemos anteriormente para conseguir escalar para root.

  • E conseguimos a última flag do alvo.

Last updated