How I fuzz and hack APIs?
Hello Hackers,
In this post, I will explain how I fuzz APIs for bugs. This blog is more about how to understand your API and then about what tools I use and where to fuzz?
- Understanding the API
- Where to fuzz and how to fuzz?
Understanding the API?
Before finding vulnerabilities and starting to fuzz anything with payloads, passwords, ids, etc. it is crucial to understand the API itself first.
Understand the following things about the API that you are testing:
- HTTP Headers and Cookies
- Content-Type
- Type of API
- UUIDs and numeric ids
- Responses and Error codes
HTTP Headers and Cookies?
In APIs, the authorization can be handled in the form of cookies or by headers.
When handled using cookies, there is a cookie/cookies like,
Cookie: SESSION-ID=123123123123ASDBUSD331231,auth=bUIBWD12313212+bbis7831BD;
When handling using HTTP headers, there are headers like,
X-API-ID: AUIB123712bDCUJJDIUD8182
TOKEN: 789812bihBSIUDBIBHUDU782
Authorization: Bearer 67823bjS78923jhsbvd69923hbdd
The token present in Authorization HTTP header is handling the session for the current user. Delete that Authorization header and the requests should give you 401 Unauthorized or 403 Forbidden errors.
It is the first step on how the API is handling the current user's session, whether using cookies, headers or by a token in the request URL or body?
Content-Type
Mostly the request body contains the data in JSON format today, but some developers also use urlencoded format.
If you will specify "Content-Type: text/html" for an application which is handling the body present in the request as JSON, then the request will hardly get some response from the server and will give 400 Bad Request error as it wants "Content-Type: application/json" in the request.
So, understand the data that is sent in the request and use the Content-Type value corresponding to it.
Type of API
Well, there are three types of APIs that are commonly found: REST, GraphQL and SOAP. SOAP API is very older and is used with Content-Type: application/xml, so the request body has so much XML when you will deal with SOAP APIs.
REST APIs are still in use and very popular. They can accept many Content-Type values, but mostly developers sent the data over urlencoded and json format. The request is sent over GET, POST, PUT, DELETE, etc. methods.
GraphQL API is also popular and is used by many companies today. The request is sent mostly over POST method, sometimes over GET as well. The two basic operations are queries and mutations. The endpoint used in graphql api is mostly /graphql, but could be /api/graphql, /api/voyager, /graph, or could be anything.
Understand the API that you are dealing with, because every API takes in a hacker's payload at different places.
UUIDs and Numeric IDs
When dealing with APIs, you will see parameters like user_id, profile_id, image_id, video_id, file_id, plan_id, isAdmin, invoice_id, etc.
These parameters requires values and there data type could be string, integer, boolean, UUIDs, etc.
Well, it is important to understand the format of numeric id. It's length, it is incrementing sequentially or randomly. Is it fixed or changing after some duration of time. These things are important to understand how easy it is to reproduce the vulnerability by an attacker and will affect the severity of your bug.
Many applications are using UUIDs today, because they are 32 characters long, random and non-sequential. This decreases the possibility of guessing these values easily. Still, there are versions of UUIDs with variations in randomness and anonymity. I would suggest an article to read to understand the format of UUIDs and the attacks possible.
Response and Error Codes
Response contains status codes and they reflect the success and failure of the request. 200 means OK, 403 means Forbidden, 401 means Unauthorized, 404 means Not Found, 500 means Server Error, etc. Read MDN guide on HTTP status codes to learn about every status code properly.
Many times there are error codes like ERROR-10032, ERROR-10035, etc. and these errors are made by the developer. Go through the documentation of the application or the API, and see the errors section to understand these special codes.
All of this is important because when we collect endpoints and do our fuzzing with various numeric IDs, and authorization tokens you will receive many different status codes. You got 200 (maybe you got a bypass), you get 403 (security is enforced properly), you got 401 (security is enforced properly).
Spend some time with your application and understand the behaviour.
Where to fuzz and how to fuzz?
Fuzz in various positions for IDORs, XSS, SQLi, SSRF, etc. vulnerabilities.
Found some strings – fuzz for XSS and check the response for reflection and if sanitization is present or not.
Found some ids – fuzz for BOLA, BFLA, and business logic bugs.
Found some URLs or parameters like url, redir, etc – fuzz for open redirection and SSRF bugs.
Found boolean values – change true to false, 0 to 1, -1, null and notice the application's behaviour.
How to Fuzz?
Create two accounts and use Burpsuite Repeater first. Take the request from your HTTP history or your interceptor and send it to Repeater. Manually test some values there and check the response codes, how data is formatted in the request, and various headers.
After understanding everything, you can fuzz for more values or list of values in Burpsuite Intruder. For very long wordlists which takes time in Burpsuite Intruder, I use ffuf –> command line web fuzzer written in Golang.
ffuf -w numeric-six-digit.txt -u https://api.redacted.com/v1/user/invoices/FUZZ -fc 401,403
ffuf -w passwords.txt -H 'Content-Type:application/json' -d '{"username:admin","password":FUZZ}' -X POST -u https://redacted.com/login -fc 401 -mc 200,302
You can fuzz anything with ffuf including subdomains, directories, http headers, methods, anything. Fuzzing starts at the place where you put FUZZ keyword.
ffuf -w users.txt:FUZZ1 -w passwords.txt:FUZZ2 -d username=FUZZ1&password=FUZZ2 -X POST -u https://redacted.com/signin -fc 401 -mc 200
Here, I am fuzzing with two wordlists and have changed the FUZZ keyword for both wordlists to FUZZ1 and FUZZ2. These keywords are user-defined and you can change them however you want.
I just wrote more than 1060 words, and I think I've covered what I wanted to give in this post about hacking APIs.
Thank You!
Author: Inderjeet Singh
Twitter: twitter.com/3nc0d3dGuY
LinkedIn: linkedin.com/in/encodedguy