When assessing a web service or API for information disclosure, we should spend considerable time on fuzzing.
Information Disclosure through Fuzzing
Maybe there is a parameter that will reveal the API’s functionality. Let us perform parameter fuzzing using Ffuf 🐳 and the burp-parameter-names.txt list, as follows.
We notice a similar response size in every request. This is because supplying any parameter will return the same text, not an error like 404.
Let us filter out any responses having a size of 19, as follows.
It looks like id is a valid parameter. Let us check the response when specifying id as a parameter and a test value.
Find below a Python script that could automate retrieving all information that the API returns (save it as brute_api.py).
We import two modules requests and sys. requests allows us to make HTTP requests (GET, POST, etc.), and sys allows us to parse system arguments.
We define a function called brute, and then we define a variable called value which has a range of 10000. try and except help in exception handling.
url = sys.argv[1] receives the first argument.
r = requests.get(url + ’/?id=‘+str(val)) creates a response object called r which will allow us to get the response of our GET request. We are just appending /?id= to our request and then val follows, which will have a value in the specified range.
if “position” in r.text: looks for the position string in the response. If we enter a valid ID, it will return the position and other information. If we don’t, it will return [].
The above script can be run, as follows.
Tip
If there is a rate limit in place, you can always try to bypass it through headers such as X-Forwarded-For, X-Forwarded-IP, etc., or use proxies. These headers have to be compared with an IP most of the time. See an example below.
The issue here is that the code compares the HTTP_X_FORWARDED_FOR header to the possible whitelist values, and if the HTTP_X_FORWARDED_FOR is not set or is set without one of the IPs from the array, it’ll give a 401. A possible bypass could be setting the X-Forwarded-For header and the value to one of the IPs from the array.
Information Disclosure through SQL Injection
SQL injection vulnerabilities can affect APIs as well. Try to use Sqlmap 🪲
Arbitrary File Upload
PHP File Upload via API to RCE
Suppose we are assessing an application residing in http://<TARGET IP>:3001. When we browse the application, an anonymous file uploading functionality sticks out.
Let us create the below file (save it as backdoor.php) and try to upload it via the available functionality.
The above allows us to append the parameter cmd to our request (to backdoor.php), which will be executed using system(). This is if we can determine backdoor.php’s location, if backdoor.php will be rendered successfully and if no PHP function restrictions exist.
backdoor.php was successfully uploaded via a POST request to /api/upload/. An API seems to be handling the file uploading functionality of the application.
The content type has been automatically set to application/x-php, which means there is no protection in place. The content type would probably be set to application/octet-stream or text/plain if there was one.
Uploading a file with a .php extension is also allowed. If there was a limitation on the extensions, we could try extensions such as .jpg.php, .PHP, etc.
Using something like file_get_contents() to identify php code being uploaded seems not in place either.
We also receive the location where our file is stored, http://<TARGET IP>:3001/uploads/backdoor.php.
We can use the below Python script (save it as web_shell.py) to obtain a shell, leveraging the uploaded backdoor.php file.
Use the script as follows.
To obtain a more functional (reverse) shell, execute the below inside the shell gained through the Python script above. Ensure that an active listener (such as Netcat) is in place before executing the below.
Local File Inclusion
Local File Inclusion (LFI) is an attack that affects web applications and APIs alike. It allows an attacker to read internal files and sometimes execute code on the server via a series of ways, one being Apache Log Poisoning.
Suppose we are assessing such an API residing in http://<TARGET IP>:3000/api.
Let us first interact with it.
We don’t see anything helpful except the indication that the API is up and running. Let us perform API endpoint fuzzing using Ffuf 🐳 and the common-api-endpoints-mazen160.txt list, as follows.
It looks like /api/download is a valid API endpoint. Let us interact with it.
We need to specify a file, but we do not have any knowledge of stored files or their naming scheme. We can try mounting a Local File Inclusion (LFI) attack, though.
The API is indeed vulnerable to Local File Inclusion!
Cross Site Scripting (XSS)
Cross-Site Scripting (XSS) vulnerabilities affect web applications and APIs alike. An XSS vulnerability may allow an attacker to execute arbitrary JavaScript code within the target’s browser and result in complete web application compromise if chained together with other vulnerabilities.
Suppose we are having a better look at the API of the previous section, http://<TARGET IP>:3000/api/download.
Let us first interact with it through the browser by requesting the below.
http://<TARGET IP>:3000/api/download/test_value
test_value is reflected in the response.
Let us see what happens when we enter a payload such as the below (instead of test_value).
It looks like the application is encoding the submitted payload. We can try URL-encoding our payload once and submitting it again, as follows.
Now our submitted JavaScript payload is evaluated successfully. The API endpoint is vulnerable to XSS!
Server Side Request Forgery (SSRF)
Server-Side Request Forgery (SSRF) attacks, listed in the OWASP top 10, allow us to abuse server functionality to perform internal or external resource requests on behalf of the server. We usually need to supply or modify URLs used by the target application to read or submit data. Exploiting SSRF vulnerabilities can lead to:
Interacting with known internal systems
Discovering internal services via port scans
Disclosing local/sensitive data
Including files in the target application
Leaking NetNTLM hashes using UNC Paths (Windows)
Achieving remote code execution
Suppose we are assessing such an API residing in http://<TARGET IP>:3000/api/userinfo.
Let us first interact with it.
The API is expecting a parameter called id. Since we are interested in identifying SSRF vulnerabilities in this section, let us set up a Netcat listener first.
Then, let us specify http://<VPN/TUN Adapter IP>:<LISTENER PORT> as the value of the id parameter and make an API call.
We notice an error about the id parameter being invalid, and we also notice no connection being made to our listener.
In many cases, APIs expect parameter values in a specific format/encoding. Let us try Base64-encoding http://<VPN/TUN Adapter IP>:<LISTENER PORT> and making an API call again.
When you make the API call, you will notice a connection being made to your Netcat listener. The API is vulnerable to SSRF.
As time allows, try to provide APIs with input in various formats/encodings.