CTF-BR: firstflask Write-Up

E aí, galera, beleza? Meu nick é v3ntur4X e eu vou explicar como eu resolvi a chall que o j3r3mias fez pro CTF-BR!

Eu entrei no link que eles disponibilizaram: http://142.93.73.149:1337

Index do site

Analisei, fui no robots.txt e não tinha.
Abri a source da página e vi um “/pagina” comentado no código:

Código fonte da index

Acessei o /pagina e apareceu a source de um arquivo (código do app.py):

Source do app.py

Não sabia muito o que fazer pois nunca tinha trabalhado com Flask, então fiquei um tempo analisando o código e mandei pra um editor para poder ter melhor manuseio do mesmo.

Quando eu consegui compreender parte do código, eu me liguei que precisava ter uma sessão para fazer a maioria das ações no servidor.

Então vi que conseguiria criar um usuário sem ter sessão usando o /add_user:

Parte do código, referente ao /add_user

Então criei uma requisição com o Burpsuite, copiando a requisição do /login (enviei algumas credenciais quaisquer apenas para gerar a requisição):

Criando um usuário (id=username, pw=password)

Como é possível ver, deu reposta 302, ou seja, o usuário foi criado!

É só logar!

Logado no usuário “wr1t3up”

Em “Imagem”, antes de logar era possível ver uma imagem do Pikachu:

Imagem do Pikachu

Depois de logado, é possível ver uma outra imagem, uma imagem do “‘Pickle’ Rick” da animação “Rick and Morty”:

Imagem do “Pickle” Rick

E isso era uma DICA da vulnerabilidade a ser explorada!

E em “Notas” é possível criar uma nota:

Página do “Notas”

Porém, para acessar uma nota, era necessário estar logado como ADMIN:

Parte do código, referente ao /note

Logo, não faria sentido criar uma nota com aquele usuário, pois teria que logar como ADMIN para acessar-lá, então era mais prático logar como ADMIN. Para isso, utilizei o /info para obter informação do ADMIN.

No código do /info é possível acessar informações de um usuário passando “?username=usuariodesejado” via GET:

Parte do código, referente ao /info

Obtendo, então, informação do usuário ADMIN:

Resultado do /info

É possível ver uma hash: 0a65b5cf991cc23229b63fa717373b0bc0475e2fa6710320357c4176eddcdb62

“Quebrando” ela, tem-se: hitmebab1mortym

Hash quebrada

Então, agora é só logar como ADMIN!

Logado como admin

Acessando “Notas” é possível ver que já tem uma nota cadastrada, usarei ela apenas para entender como acessar as notas (algo bem simples, na verdade).

Segundo o próprio código do /note, só é preciso passar o id da nota no parâmetro “ni”:

Parte do código, referente ao /note

ID da nota que já está cadastrada:

ID da nota pré-cadastrada

Acessando a nota:

Acessando a nota

Voltando ao “Notas”…

Agora, é necessário criar uma nota, porém é preciso entender algumas coisas antes:

- O código está usando um “object serialization”: pickle.
- O pickle é usado para serializar e desserializar uma estrutura de objetos Python, então para explorar o pickle nada melhor que criar um objeto que executa algum comando.
- Mas antes disso é preciso entender que mandar só o objeto serializado não fará com que o mesmo seja executado pelo servidor, é necessário encodar com base64, já que o código faz decode de base64, para ser executado.
- E para que a requisição aceite e faça o decode do base64, é necessário adicionar “usebase64” na mesma.

E sobre a exploração do pickle, irei deixar alguns links, no final do write-up, que eu li para entender como explorar a vulnerabilidade.

Parte do código, referente ao /write_note

Eu criei um objeto, instanciei ele no dump do pickle e encodei a saída do dump com base64:

Explorando o pickle

E enviei a requisição:

Enviando a requisição para tentar a exploração

Acessando a nota criada é possível ver um erro 500:

Erro 500, servidor possívelmente recusou o uso da biblioteca “os”

Eu pensei que poderia ser que o sistema não aceita o uso da biblioteca “os” e resolvi mudar a biblioteca para outra que tem o mesmo papel - “commands”:

Alterando a biblioteca usada

Enviando a requisição…

Enviando a requisição do base64 com a biblioteca alterada

E deu certo!

Resposta do servidor ao comando requerido (id)

A partir daí só foi necessário listar os diretórios e ir procurando a flag, que estava em “files/e7e7a4697554b5ae/flag”.

E era só dar um cat nela!

Cat na flag
Enviando a requisição do cat
Flag!

Bom, é isso galera.

Qualquer dúvida, crítica ou elogio ao write-up, fiquem à vontade para fazer!!

Links sobre a exploração do pickle:

https://blog.nelhage.com/2011/03/exploiting-pickle/

https://dan.lousqui.fr/explaining-and-exploiting-deserialization-vulnerability-with-python-en.html

https://medium.com/poka-techblog/rotten-pickles-a-quick-introduction-to-offensive-serialization-techniques-83fd4dd36edb