Medinova
Difficulty: Medium | OS: Linux

Walkthrough - Youtube Habemus Shell
Em breve.
Scanning

Services and Versions

Exploration
Port 80 - http
Quando colocamos o ip no navegador, ele redireciona para um nome chamado
medinova.hcentã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.

Vamos verificar o conteúdo desse JWT com a ferramenta jwt.io

O cookie JWT e formado exatamente como e exibido na sua forma decodada.
Um
header,payloade umaassinatura.Há uma misconfiguration se tratando no Algoritmo(
alg) no header do Jwt. Podemos definir esse algoritmo comonone, quando esse tipo de algoritmo e aceito pelo servidor, ele possibilita a aceitacao desse token sem a necessidade de uma assinatura.
WSTG - Latest | OWASP Foundation
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 CyberChef para podermos alterar e depois iremos retornar para o Jwt.io

Agora jogue essa parte decodada para o Input, altere o algoritmo(
alg) paranonee coloque para encodar em base64Observe 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.IO 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 → CookiesAltere 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
usernamepara 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
usernamee 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
usernameele 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 Academy


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 sistemacallback= 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.sh 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árioTom, para poder ler essa flag.

Enumerando o sistema encontramos na pasta
/optum script.sh

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-dirna pasta home do usuáriotomque não temos permissão de acessar.Porém, nesse mesmo script temos a flag
--work-treeque 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/htmle como somos o usuáriowww-dataentã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 permissions

baixamos no alvo.

Da permissão de execução
Após executarmos o pspy, conseguimos verificar que o usuário com
UID=1001executava o script que encontramos em/opt.

Se analisarmos o arquivo
/etc/passwddo alvo, conseguimos descobrir que o uid1001é do usuárioTom

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
$verifypor um comando linux.Lembrando que podemos executar comandos no linux colocando entre
$()ou``

E como o
teegera um novo arquivo com a saída do comando anterior, criamos o arquivo chamado teste.txt com o conteúdo do comandoid.Então realmente conseguimos confirmar que da para executarmos comando aqui.
Bom, precisamos inicializar o
gitno diretório/var/www/htmlque esta comowork-treeno script.Então ele sempre pega o novo arquivo e coloca na última linha substituindo a variável
$verifySe 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
curlcom 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 -lencontramos o binário
read_pickle_filesque roda com qualquer usuário, inclusive root sem precisar de senha.

Bom, o nome do binário já traz uma dica. Ele lê arquivos
pickleCom 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.15
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 bibliotecapicklepois 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