Curly Fries

Medium
Miscellaneous
John Hammond

❗ Nota

Esse desafio eu peguei do vídeo do John Hammond para escrever um writeup, já que algumas técnicas podem aparecer em futuros desafios. Ele também tem um pequeno "erro", que conforme o writeup avance, você poderá notar.

Linux Hackers Become Root with CURL & Sudo - YouTube

💡 Há vários hyperlinks durante o texto. Eles te levarão a uma explicação sobre o comando ou ferramenta utilizado, vale a pena olha.

Writeup 📜

Logado na máquina como o usuário user, se você utilizar o comando sudo -l (lista as permissões de comandos que o usuário atual pode rodar com sudo), a saída mostra o seguinte:

(fry) NOPASSWD: /usr/bin/curl 127.0.0.1\:8000/health-check

Isso quer dizer que podemos usar o comando curl como o usuário fry, porém somente utilizando 127.0.0.1:8000/health-check como parâmetro. Nisso, ao dar o comando sudo -u fry curl 127.0.0.1:8000/health-check vemos que o servidor não está iniciado, já que dá falha na conexão, então como ele disse no vídeo, a ideia seria nós mesmos iniciar o servidor http, nesse caso utilizando o python3 com o módulo http.server:

python3 -m http.server

Esse comando faz ele criar um servidor http na porta 8000 e que irá servir os arquivos do diretório atual (tipo o padrão do Apache que vemos muito).

Apache Index

Então você consegue acessar os arquivos da pasta em que foi criado. Logo se eu tiver um alguma-coisa.txt e mandar uma requisição pra http://127.0.0.1:8000/alguma-coisa.txt, eu irei receber o conteúdo desse arquivo. Logo, um jeito de obter acesso ao usuário (no caso ao .bash_history que fica todo histórico de comandos do bash e que foi uma dica na descrição do ctf) ele poderia fazer um symlink/symbolic link na home do fry. Então ele cria um symlink de /home/fry/.bash_history para health-check, que é onde o nosso amigo fry consegue fazer a requisição usando o curl:

ln -s /home/fry/.bash_history health-check

Aí agora então ao fazer a requisição no servidor que estavamos rodando, conseguimos ver o histórico de comandos que nosso amigo deu previamente.

sudo -u fry curl http://127.0.0.1:8000/health-check

E lá temos uma sessão SSH em que ele coloca a senha dele em plaintext, usando o sshpass

sshpass -p iLoveCurlyFriesYumYumInMyTumTum ssh fry@localhost

Agora que temos a senha do fry, só logarmos nele pelo ssh.

Mas pera aí... 🤔

Você percebeu algo de errado nessa primeira parte? Eu na hora fiquei meio confuso, porque não fazia muito sentido algumas coisas, e aqui vou explicar:

Primeira pergunta: Quem tá rodando o servidor http?

  • Isso mesmo, nosso querido user, o qual logamos.

Agora, quem tá rodando o curl?

  • O fry, no qual temos acesso pelo user sem senha para esse comando

Certo, agora quem faz o acesso pra ler o arquivo e enviar pela requisição http? O servidor. E quem tá rodando o servidor? O user.

"Num entendi"

Vamos lá: cada usuário no sistema tem sua pasta no /home, o qual somente ele tem acesso. No caso, o nosso usuário user não teria acesso ao /home/fry por padrão, e isso quer dizer que a permissão foi mudada, já que o servidor http do python que tá usando o symlink para /home/fry/.bash_history é o nosso user, logo, o problema poderia ser simplesmente resolvido usando cat /home/fry/.bash_history, tirando meio que a graça do problema e não fazendo muito sentido.

A parte interessante 🚩

Após obtermos a senha e logarmos como o usuário fry, rodamos o comando sudo -l de novo e obtemos isso:

(root) NOPASSWD: /usr/bin/curl 127.0.0.1\:8000/healthcheck*

Temos algumas coisas interessantes

  • Podemos rodar um comando como root sem precisar de senha

  • Temos um wildcard (chamado de curinga ou metacaractere) após o /healthcheck, que significa que podemos colocar o que quiser depois disso

O curl tem uma flag interessante que é a -o, o qual podemos pegar o retorno e escrever em um arquivo, podemos usar isso ao nosso favor para obter acesso ao root.

Sabendo disso, podemos utilizar o nosso curl como um comando de copy-paste. Dito isso, temos vários jeitos de explorar:

  • Mudar o uid do usuário no /etc/passwd

  • Mudar a senha do root para a do nosso usuário

Mas vou falar da solução que o JH usou no vídeo dele: adicionar uma chave ssh de acesso no root

Então você pode criar uma nova chave ssh (não vou cobrir aqui, mas quem quiser saber como tá aqui)

Salvando nossa chave pública na onde o servidor está rodando como health-check

cp ~/.ssh/id_rsa.pub health-check

Agora podemos fazer a requisição como root e salvar no ~/.ssh/authorized_keys para acessarmos

sudo -u root curl http://127.0.0.1:8000/health-check -o /root/.ssh/authorized_keys

Agora podemos dar ssh root@localhost e boom, logamos como root

Atualizado