The API Hacker’s Guide to Payload Injection with Postman
Postman is one of the most popular API development and testing tools in use today. It’s a powerful tool, and with the Collection Runner, you can automate some amazing things.
In this article, we’ll explore how to use the Collection Runner to do payload injection when hacking APIs. I’ll also show you some tips, tricks, and traps that will stop you from pulling your hair out when using Postman offensively like this. (no offense to bald people )
Stay tuned, it’s gonna be a wild ride!
What is the Postman Collection Runner?
The Postman Collection Runner enables you to run the API requests in a collection in a specified order. It logs your request test results and can use scripts to pass data between requests and alter the request workflow.
The Collection Runner is an extremely powerful tool for data-driven testing. Many QA teams swear by its ability to build a sequence of requests to test more complex scenarios that can take input from data files, usually in a CSV or JSON format. As API security testers, we can weaponize this same feature-set to feed malicious data through payload injection to our in-scope APIs under test.
What is Payload Injection in the context of APIs?
If you look at the top 10 classes of vulnerability as described in the OWASP API Security Top Ten, Injection flaws rank #8 on the list.
Injection flaws, such as SQL, NoSQL, Command Injection, etc., occur when untrusted data is sent to an API as part of a command or query. Your malicious data can trick the API into executing unintended commands or accessing data without proper authorization.
Through the PostMan Collection Runner, you can iterate through your specifically-crafted payload list and test API endpoints for injection vulnerabilities by injecting payloads into the requests.
Confused yet? What I am trying to say is you can look for vulnerabilities (not just Injection flaws) by injecting malicious data into your API requests, thanks to the Collection Runner.
Make more sense now? Good. Let’s move on.
Why use the Postman Collection Runner over Burp Intruder?
The whole Postman vs Burp is a great debate had by some. I say use the tool(s) you are most comfortable with. In the context of the Postman Collection Runner over Burp Intruder, there is one key reason you might want to use Postman… and that’s speed.
There is a reason why in the Beginner’s Guide to API Hacking I highly recommended you buy Burp Suite Professional. Portswigger has crippled Burp’s Intruder tool in the Community edition and only offers the full power of Intruder to those with a Professional (or higher) license. It’s just not feasible to iterate through large payload lists in a reasonable amount of time.
Postman doesn’t have such limits. So if you are using Burp Suite Community Edition, Postman Collection Runner is your best bet, unless you want to struggle with the free Turbo Intruder extension.
OK, with that out of the way, let’s actually use the Collection Runner and throw some malicious payloads at a target.
Real-world Example: Attacking crAPI datastore
So, if you have been practicing your API hacking tradecraft, you’ve probably come across crAPI by now. It’s the “completely ridiculous API“. It’s riddled with vulnerabilities described in the OWASP API Security Top Ten… including being vulnerable to NoSQL injection in its “coupon” feature.
Let’s go about testing for this.
Building a new collection from a request
To make this article simple, I am going to assume you don’t currently have a Postman Collection set up for crAPI. You can check out my article on how to build out your own collection using rogue API documents you craft yourself during recon if you want a full collection. For this case though, we will leverage your browser’s devtools to generate a cURL command you can import directly into Postman to build out a new collection for this endpoint we wanna attack.
So let’s go:
Launch DevTools
Open up your browser’s devtools, typically by hitting CTRL+ALT+I
, or by going to Menu → More Tools → Developer Tools
. Keep the tab open, and go back to your browser tab. Surf to the crAPI web application.
Go to the crAPI shop
Now visit the crAPI shop. If you have been using Corey’s hosted version of crAPI, you can get there at http://crapi.apisec.ai/shop. If you are running your own instance, just as good.
Now click the “+ Add Coupons” button on the top left.
Type in something like “test” and click the “Validate” button. You should see it returns an “Invalid Coupon Code“.
Generate cURL command
Now head back over to devtools. Right-click on the failed call to validate-coupon and select Copy → Copy as cURL
.
Create a new collection in Postman
Open up Postman. In the main menu select Workspaces → Create Workspace
:
Name the workspace something descriptive like “crAPI Coupons” and click Create workspace.
Now, within the new workspace, click the Import button (typically near the top left of the screen). When the dialog pops up, select the Raw text tab, and paste in your cURL command you collected from devtools. It will look something like this:
Hit the Continue button, and finally the Import button. You will now see a new request stored in your workspace. Click the Save button to save the request.
As you don’t have a collection yet, you will need to create one. Click the Create a collection button to do that. Name your collection something you will remember, make sure you select the new collection to put the request into, and then click Save.
Trap: Nuke the Content-Length
So, depending on how your request went, you might notice you have a Content-Length
in your POST request under the Headers tab. If you don’t have it, no biggy. But if you do see it, I want you to uncheck it, so it’s not sent.
Here’s why.
Later when we start injecting different malicious payloads the body size will change. If your Content-Length doesn’t match, the server MAY ignore anything past the size specified. This can really b0rk your testing. If the header isn’t there, Postman will take care of it on the way out for you, preventing this from screwing your injection attempts up.
Preparing your body for payload injection
Click on the Body tab for your request. Replace the value beside the coupon_code key with a Postman variable called {{payload}}
. Ensure you take out the quotes in the value too, as our payload will handle everything we want to test.
It might look something like this:
Make sure you hit Save to ensure the collection keeps the setting.
Creating a test for your request
When we execute our payload injection iterations in the Collection Runner, we want to know if something “works”. We can tell that invalid coupon codes return a 500
error. We can assume if something works, we will get a 200
HTTP response code.
So let’s build a test to validate that. Anything that “passes” can be considered a potentially valid malicious payload we can use for injection.
Click on the Tests tab of the request. To the right, there is a section called “Snippets“. Scroll down until you find the snippet named “Status code: Code is 200” and then click it. It will insert a test for you right in the Tests tab. It should look something like this:
Don’t forget to click Save.
Preparing your payload list
OK, with our Postman collection now setup we can start to prepare our payload list. If you read my article on how to detect the programming used by an API, you will know we detected that crAPI was written in Java. If you dug further, you might have learned the database behind it was based on NoSQL.
Using OWASP’s Web Application Security Testing framework, we know they document how to test for NoSQL injection. They point to a great injection payload wordlist we can use as a base for our malicious payloads.
I say “base”, as Postman doesn’t use straight textual wordlist like many hacking tools. It uses CSV and JSON files for its data-driven testing. And there are a few gotchas you gotta be concerned with.
Let’s talk about that.
Trap: CSV payloads
I love CSV files. They are so simple. Unfortunately for us though, that simplicity comes with a cost. Postman has trouble parsing CSVs with more interesting payloads in them. Things like double quotes, dash comments and commas blow up the payload import.
It get’s to be a real headache.
You can escape some thing like double quotes by double quoting around them. But then it goes crazy on other things, like dash comments. I say when it comes to malicious payloads just stay away from CSV. Postman’s CSV parser is just too ugly to want to fight with.
Which leaves us with JSON files.
Trick: JSON payloads
JSON is your friend. Heck, you’re an API hacker. JSON should be your jam. So let’s use it.
You can take the NoSQL injection wordlist and convert it to a JSON file. You need to remember to escape any double quotes with a backslash inside the value of the key/value pair for each of the payloads.
Tip: The key name for each JSON object property should match exactly whatever you set the Postman variable to in the Body of the request. Since I called mine {{payload}}
, I need to make sure the key is “payload” in the JSON file. When Postman Collection Runner loads a payload file, it will automatically update the variable’s value as they match for each iteration.
To save you time, I have done that already for you.
With your payload list in hand, it’s time to use it.
Setting up the Collection Runner
On the bottom left of Postman is the “Runner” icon. Click it.
When the Collection Runner comes up, you will see some options on how to run your collection. The first thing you will want to do is pull in the POST request we are going to test. This is one of those powerful features of the Postman Collection Runner. As an example, if you wanted to login to crAPI and get a new access token before calling the validate-coupon endpoint, you could bring that request in and order it to follow that sequence of activities and populate a variable for the bearer token. We don’t need to do that here as we actually have the token stored in our request.
With the request added to the Collection Runner, we now have to load up our payloads. Hit the Select File button under Data, and browse to find your JSON payloads file. You should see it load up 30 payloads, and automatically update the “Iterations” field to 30. You will also notice it automatically set the Data Type to application/json.
You can click the Preview button if you want to see how the payloads will look on each iteration.
Tip: Enable the option to Save Responses
Under Advanced settings there is a checkbox to Save Responses. I recommend you check that on. While the default is to have it off, you want to be able to inspect the responses during your test run so you can determine just how a malicious payload is interpreted by the API.
In the end, your setup might look something like this:
Execute test run
Time to test the endpoint for possible injection issues. Click the Run button. The button will be named after whatever you called your collection. Since I called my collection Injection Candidate, my run button says Run Injection Candidate.
The Collection Runner will now begin testing every one of your payloads. In each iteration, it will inject a new one in your {{payload}}
variable placeholder and see how the API responds. You will notice each time something went wrong, the test fails. However, in four cases, it passes.
Tip: Filter by test passes
So here is a tip. You will notice in the collection runner that by default it will show you the results of every test. You can click on any one of the failed tests, click Response Body and see how the API responded.
An even better way to filter results though is to click the Passed tab, then select on one of the test results and expand both Request Body and Response Body. Now you have a clear understanding of what malicious payload triggered a response… in our case of returning a valid coupon we shouldn’t know about.
NoSQL injection at its finest.
Bonus Exercise: So you know a payload of {"$ne":""}
will bring back a valid coupon. What happens if you send {"$ne":"TRAC075"}
? Could you craft a bash or Python script to download every coupon code in the database?
Conclusion
The Postman Collection Runner is an incredibly powerful tool for API testers and hackers. With it, you can easily load malicious payloads into your requests and see how the API responds. This allows you to quickly and easily find injection points in APIs. In this article, we looked at how to use the Collection Runner to do payload injection when hacking APIs.
As I re-read this article, I now realize I might have been better off showing you a different API vulnerability than Injection. Using payload injection in Postman, you can test for any of the OWASP API Security Top Ten, not just Injection. But I hope you can look past that and see the real potential here. Think about how you can build your own JSON payload files to test for just about anything.
Want to find more resources for different payload wordlists, along with other killer content for API hacking? Make sure you download my Ultimate Guide to API Hacking Resources.
Hack hard!
The post The API Hacker’s Guide to Payload Injection with Postman appeared first on Dana Epp's Blog.
*** This is a Security Bloggers Network syndicated blog from Dana Epp's Blog authored by Dana Epp. Read the original post at: https://danaepp.com/the-api-hackers-guide-to-payload-injection-with-postman