Great Lakes Security Conference CTF — Hackeando Apps NodeJS — Parte 2

Neptunian
2 min readApr 19, 2021

--

Desafio: Express Puzzle

Esta é a parte 2 da Série Great Lakes Security Conference CTF — Hackeando Apps NodeJS.

Este desafio já começa mostrando o código-fonte da página principal (Framework Express.js):

Código-fonte do Express Puzzle

Resumo do Código

  • Ele responde na URL /flag,
  • Pega o valor da querystring value.
  • Verifica se é diferente de ‘itchy,knee’ (strict inequality ‘!==’)
  • Verifica se é igual a ‘itchy,knee’ (loose equality ‘==’)
  • Se passar nas duas condições acima, entrega a flag

Receber a flag depende exclusivamente de passar nas condições acima, pois a resposta está dentro do secret.js, que está bem protegido. O desafio aqui é passar uma string que seja “igual e ao mesmo tempo diferente” de ‘itchy,knee’. Confuso? :)

Strict vs. Loose Equality

O segredo aqui está na diferença do modo strict para o modo loose, nas comparações de igualdade do Javascript.

  • No modo strict da igualdade (==) ele valida o tipo de dados também.

Neste caso, ele vai considerar diferentes dados “iguais”, se tiverem tipos diferentes. Exemplo: (“1” == 1) será considerado false.

  • No modo loose da igualdade (==), ele não valida o tipo de dados.

Neste caso, ele vai considerar dados iguais, se eles tiverem o mesmo valor após conversão, mesmo sendo de tipos diferentes. Exemplo: (“1” == 1) será considerado verdadeiro.

Vulnerabilidade

No código acima, a igualdade no modo loose pode ser explorada a partir do uso de um tipo de dados diferente no input. O tipo que funciona neste caso é o array, conforme exemplo abaixo:

Welcome to Node.js v14.12.0.
Type ".help" for more information.
> ['itchy', 'knee'] == 'itchy,knee'
true

A mesma comparação não funciona com o strict. Como ele está testando desigualdade, também retorna verdadeiro:

> ['itchy', 'knee'] !== 'itchy,knee'
true

Agora, testando a comparação completa (com uma variável arr ao invés de req.query.value):

> arr = ['itchy', 'knee']
[ 'itchy', 'knee' ]
> arr !== 'itchy,knee' && arr == 'itchy,knee'
true

Ou seja, encontramos o valor da querystring value que gera a condição verdadeira. Mas como passar uma matriz na querystring? A resposta é simplesmente repetir o mesmo nome da querystring várias vezes que o Express.js vai interpretar o valor como um array.

Exploit final:

$ curl -g $URL'/flag?value=itchy&value=knee' --compressed
GLSC{7wo_p@r@m5_@re_6e77er_7h@n_one}

Parte 3

O próximo desafio da série é o Javascript Puzzle, que explora uma outra aplicação NodeJS que também utiliza o framework Express.js.

Referências

--

--