Great Lakes Security Conference CTF — Hackeando Apps NodeJS — Parte 4
Kevin
Esta é a parte 4 da Série Great Lakes Security Conference CTF — Hackeando Apps NodeJS.
Seguindo a linha dos outros dois desafios acima, o Kevin também começa com o código-fonte da aplicação disponível:
Resumo do Código
- Atende em /flag, via parâmetro name.
- Valida se o tipo do name é string (bloqueia ataques com tipo de dados diferentes, como arrays).
- Valida se o name, convertido pra maiúsculo, é diferente de ‘KEVIN’.
- Valida se o name maiúsculo gerado acima, convertido pra minúsculo, é igual a ‘kevin’.
Caso essa função de validação acima (isThisReallyKevin) retorne verdadeiro, envia a flag.
Novamente uma condição que parece impossível precisa ser verdadeira pra retornar a flag: o nome enviado, maiúsculo, não pode ser KEVIN, mas convertido de volta pra minúsculo, precisa ser igual a kevin. (WTF!)
Vulnerabilidade
Esse desafio tem uma pista não técnica: caso o nome não seja validado, ele retorna a mensagem “Kevin spells his name in an unusual way to honor his ancestor William Thomson”.
O William Thomson é o primeiro barão keLvin (nome que originou a unidade de medida de temperatura). Vamos guardar esse nome Kelvin.
Como o tipo de Input é string e as operações são de upper e lower, isso indica fortemente que o tipo de ataque possível envolve conversão de caracteres especiais Unicode.
Isso é possível porque algumas bibliotecas (em várias linguagens), têm uma fragilidade que é característica da arquitetura do Unicode para caracteres que só existe em uma determinada localidade.
Quando elas fazem a conversão de alguns caracteres para maiúsculo ou minúsculo, transformam um caractere em outro, perdendo informação! Com isso, a conversão de volta não transforma o caractere no que era originalmente.
Um exemplo disso é o caractere ı (é um “i” turco, sem o ponto), que é o caractere \u0131. Quando convertido pra maiúsculo, ele vira um “I” normal. Se você converter de volta pra minúsculo, ele vira o nosso “i” normal. Demorei um tempinho aqui achando que o ataque seria em cima do i turco. O Github teve uma falha de segurança desse tipo, onde era possível recuperar a senha de contas de outros e-mails. Exemplo abaixo, validando o conceito com o node (que é o que vai rodar no ServerSide):
$ nodeWelcome to Node.js v14.15.0.Type ".help" for more information.> 'John@Gıthub.com'.toUpperCase()'JOHN@GITHUB.COM'> 'John@Gıthub.com'.toUpperCase() === 'John@Github.com'.toUpperCase()true
Após algumas análises, encontrei uma tabela interessante de caracteres que poderiam ser testados: https://websec.github.io/unicode-security-guide/character-transformations/
Tem mais itens nessa lista, mas o último chama a atenção: KELVIN SIGN! (Pista do William mais acima).
Isso quer dizer que o ‘K’ maiúsculo é o caractere Unicode \u004B, enquanto o Kelvin Sign, que é visualmente idêntico, é o caractere \u212A (diferente). O que ocorre é que o Kelvin Sign é maiúsculo, então é diferente de ‘K’, mas quando convertido para minúsculo, ele vira a nossa letra k minúscula.
Fazendo o mesmo teste com o Kelvin:
> Kelvin = '\u212A''K'> K_Normal = 'K''K'> Kelvin === K_Normalfalse> Kelvin.toUpperCase() === K_Normal.toUpperCase()false> Kelvin.toUpperCase().toLowerCase() === K_Normal.toUpperCase().toLowerCase()true
Resultado: Enviar Kevin no name, com Kelvin Sign no lugar do K causa o seguinte cenário:
- A comparação do item 3 (do resumo) retorna Falso, porque o Kelvin Sign é diferente do K maiúsculo.
- A comparação do item 4 retorna Verdadeiro, porque o Kelvin Sign, convertido pra minúsculo, fica igual ao k minúsculo.
Com isso, o Payload no parâmetro name fica da seguinte forma:
'\u212Aevin'
Convertendo com URLEncode, o exploit fica assim:
curl 'https://host/flag?name=%E2%84%AAevin' --compressed
Mais uma Flag encontrada!!
GLSC{un1c0d3_ch4r4c73r5_4r3_1n73r3571n9}
Parte 5
O 5° e último desafio da série é o Mr. Roboto, que tem um perfil mais Scavenger Hunt.
Referências
- Parte 1 da série: https://neptunian.medium.com/great-lakes-security-conference-ctf-hackeando-apps-nodejs-parte-1-6e0f90a6b9a3
- Perfil do CTF — no CTF Time: https://ctftime.org/event/1051
- Meu perfil no CTF Time: https://ctftime.org/team/122851
- Link Direto do Evento: https://glsc.tech/
- Hacking With Unicode: https://eng.getwisdom.io/hacking-github-with-unicode-dotless-i/
- Mapa de Caracteres Unicode com Transformação: https://websec.github.io/unicode-security-guide/character-transformations/
- Twitter: @NeptunianHacks