API endpoint analysis: techniques
Web API Indicators
Be on the lookout for obvious URL naming schemes: #
https://target-name.com/api/v1https://api.target-name.com/v1https://target-name.com/docshttps://dev.target-name.com/rest
Look for API indicators within directory names like: #
_/api, /api/v1, /v1, /v2, /v3, /rest, /swagger, /swagger.json, /doc, /docs, /graphql, /graphiql, /altair, /playground
Subdomains can also be indicators of web APIs: #
- api.target-name.com
- uat.target-name.com
- dev.target-name.com
- developer.target-name.com
- test.target-name.com
Another indicator of web APIs is the HTTP request and response headers. #
The use of JSON or XML can be a good indicator that you have discovered an API. HTTP Request and Response Headers containing "Content-Type: application/json, application/xml"
Watch for HTTP Responses that include statements like: #
- {"message": "Missing Authorization token"}
One of the most obvious indicators of an API would be through information gathered using third-Party Sources like Github and API directories. #
- GitHub: https://github.com/
- Postman Explore: https://www.postman.com/explore/apis
- APIs Guru: https://apis.guru/
- Public APIs Github Project: https://github.com/public-apis/public-apis
- RapidAPI Hub: https://rapidapi.com/search/
Passive API Reconnaissance
Google Dorking #
| Google Dorking Query | Expected results |
|---|---|
| inurl:"/wp-json/wp/v2/users" | Finds all publicly available WordPress API user directories |
| intitle:"index.of" intext:"api.txt" | Finds publicly available API key files |
| inurl:"/api/v1" intext:"index of /" | Finds potentially interesting API directories |
| ext:php inurl:"api.php?action=" | Finds all sites with a XenAPI SQL injection vulnerability. (This query was posted in 2016. Four years later, there are currently 141,000 results.) |
| intitle:"index of" api_key OR "api key" OR apiKey -pool | It lists potentially exposed API keys |
GitDorking #
Search parameters examples:
- filename:swagger.json
- extension: .json
Search GitHub for your target organization’s name paired with potentially sensitive types of information, such as:
“api key,” "api keys", "apikey", "authorization: Bearer", "access_token", "secret", or “token.”Then investigate the various GitHub repository tabs to discover API endpoints and potential weaknesses.
Analyze the source code in the Code tab, find bugs in the Issues tab and review proposed changes in the Pull requests tab.Code contains the current source code, readme files and other files. #
This tab will provide you with the name of the last developer who committed to the given file, when that commit happened, contributors and the actual source code.
Using the Code tab, you can review the code in its current form or use ctrl-F to search for terms that may interest you (such as API, key and secret). Additionally, view historical commits to the code by using the History button.
If you came across an issue or comment that led you to believe there were once vulnerabilities associated with the code, you can look for historical commits to see if the vulnerabilities are still viewable.
When looking at a commit, use the Split button to see a side-by-side comparison of the file versions to find the exact place where a change to the code was made.
TruffleHog #
TruffleHog is a great tool for automatically discovering exposed secrets. You can simply use the following Docker run to initiate a TruffleHog scan of your target's Github.
sudo docker run -it -v "$PWD:/pwd" trufflesecurity/trufflehog:latest github --org=target-nameTruffleHog can also be used to search for secrets in other sources like Git, Gitlab, Amazon S3, filesystem and Syslog. To explore these other options use the "-h" flag.
For additional information check out https://github.com/trufflesecurity/trufflehog
Shodan #
| Shodan Queries | Purpose |
|---|---|
| hostname:"targetname.com" | Using hostname will perform a basic Shodan search for your target’s domain name. This should be combined with the following queries to get results specific to your target |
| "content-type: application/json" | APIs should have their content-type set to JSON or XML. This query will filter results that respond with JSON |
| "content-type: application/xml" | This query will filter results that respond with XML |
| "200 OK" | You can add "200 OK" to your search queries to get results that have had successful requests. However, if an API does not accept the format of Shodan’s request, it will likely issue a 300 or 400 response |
| "wp-json" | This will search for web applications using the WordPress API |
The Wayback Machine #
This is great for passive API reconnaissance because allows you to check out historical changes to your target. If, for example, the target once advertised a partner API on their landing page, but now hides it behind an authenticated portal, then you might be able to spot that change using the Wayback Machine.
Another use case would be to see changes to existing API documentation. If the API has not been managed well over time, then there is a chance that you could find retired endpoints that still exist even though the API provider believes them to be retired. These are known as Zombie APIs. Zombie APIs fall under the Improper Assets Management vulnerability on the OWASP API Security Top 10 list.
Finding and comparing historical snapshots of API documentation can simplify testing for Improper Assets Management.
Active API Reconnaissance
OWASP Amass #
Making the most of Amass with API Keys
amass enum -active -d target-name.com | grep apiThis scan could reveal many unique API subdomains, including legacy-api.target-name.com. An API endpoint named legacy could be of particular interest because it seems to indicate an improper asset management vulnerability.
Amass has several useful command-line options. Use the intel command to collect SSL certificates, search reverse Whois records and find ASN IDs associated with your target.
Start by providing the command with target IP addresses:
amass intel -addr [target IP addresses]If this scan is successful, it will provide you with domain names. These domains can then be passed to intel with the whois option to perform a reverse Whois lookup:
amass intel -d [target domain] –whoisThis could give you a ton of results. Focus on the interesting results that relate to your target organization. Once you have a list of interesting domains, upgrade to the enum subcommand to begin enumerating subdomains. If you specify the **-**passive option, Amass will refrain from directly interacting with your target:
amass enum -passive -d [target domain]The active enum scan will perform much of the same scan as the passive one, but it will add domain name resolution, attempt DNS zone transfers, and grab SSL certificate information:
amass enum -active -d [target domain]To up your game, add the -brute option to brute-force subdomains, -w to specify the API_superlist wordlist and then the -dir option to send the output to the directory of your choice:
amass enum -active -brute -w /usr/share/wordlists/API_superlist -d [target domain] -dir [directory name]Gobuster - Use APIs specific wordlists #
gobuster dir -u target-name.com:8000 -w /home/hapihacker/api/wordlists/common_apis_160
gobuster dir -u http://targetaddress/ -w /usr/share/wordlists/api_list/common_apis_160 -x 200,202,301 -b 302Kiterunner #
Kiterunner is another tool available for discovering API endpoints and resources. While directory brute force tools like Gobuster and Dirbuster work to discover URL paths, it typically relies on standard HTTP GET requests.
Kiterunner will not only use all HTTP request methods common with APIs (GET, POST, PUT and DELETE) but also mimic common API path structures.
In other words, instead of requesting GET /api/v1/user/create, Kiterunner will try POST /api/v1/user/create, mimicking a more realistic request.
Scan
kr scan HTTP://127.0.0.1 -w ~/api/wordlists/data/kiterunner/routes-large.kiteBrute
kr brute <target> -w ~/api/wordlists/data/automated/nameofwordlist.txtReplay request
kr kb replay "http://192.168.50.35:8888/api/privatisations/count 0cf6841b1e7ac8badc6e237ab300a90ca873d571" -w ~/api/wordlists/data/kiterunner/routes-large.kiteDevTools #
- You can use the filter tool to search for any term you would like, such as "API", "v1", or "graphql"
- Check out the request in the browser, edit the headers/request body and send it back to the API provider
- Once you have copied the desired request open Postman. Select Import and click on the "Raw text" tab. Paste in the cURL request and select import.
- Once the request has been imported it will have all of the necessary headers and the request body necessary to make additional requests in Postman.
- This is a great way to quickly interact with an API and interact with a single API request.
Automatic Documentation
First we will begin by proxying all web application traffic using mitmweb.
Simply use a terminal and run:
mitmwebThis will create a proxy listener using port 8080. You can then open a browser and use FoxyProxy to proxy your browser to port 8080 using our Burp Suite option.
- Once the proxy is set up, you can once again use the target web application as it was intended.
- Every request that is created from your actions will be captured by the mitmweb proxy. You can see the captured traffic by using a browser to visit the mitmweb web server located at http://127.0.0.1:8081
- Continue to explore the target web application until there is nothing left to do.
- Once you have exhausted what can be done with your target web app, return to the mitmweb web server and click File > Save to save the captured requests.
- Selecting Save will create a file called flows. We can use the "flows" file to create our own API documentation
mitmproxy2swagger #
We will be able to transform our captured traffic into an Open API 3.0 YAML file that can be viewed in a browser and imported as a collection into Postman.
First run the following:
sudo mitmproxy2swagger -i /Downloads/flows -o spec.yml -p http://crapi.apisec.api -f flowAfter running this you will need to edit the spec.yml file to see if mitmproxy2swagger has ignored too many endpoints. Update the YAML file so that "ignore:" is removed from the endpoints that you want to include (Make sure to only remove "ignore:". Removing spacing or the "-" can result in the script failing to work).
Once your docs ready, make sure to run the above command once more. This second run will correct the format and spacing. This time around you can add the "--examples" flag to the end to enhance your API documentation.
After running mitmproxy2swagger successfully a second time through, your reverse-engineered documentation should be ready. You can validate the documentation by visiting https://editor.swagger.io/ and by importing your spec file into the Swagger Editor. Use File>Import file and select your spec.yml file.