vAPI
Last updated
Last updated
vAPI (vulnerable Adversely Programmed Interface) is a self-hostable API that mimics OWASP top 10 API 2019 security risks scenarios through exercises.
The lab used to solve the exercise is composed of an Ubuntu 22.04.2 LTS (Jammy Jellyfish) server (IP address 10.1.1.11) hosting the vAPI application on port 8008, and a Kali attacking machine (IP address 10.1.1.22). The vAPI web site is available at http://10.1.1.11:8008, and the documentation at http://10.1.1.11:8008/vapi
The exercise has been solved using Postman, Burpsuite and ffuf
https://github.com/roottusk/vapi
https://owasp.org/API-Security/editions/2019/en/0x11-t10/
Similar to IDOR in the web applications context, BOLA vulnerabilities are related to API endpoints that receives an ID of an object, and fail to validate if the user is authorized to access or to perform the requested action on the requested object.
In Postman, create a new user user8:password
by sending a POST request to /vapi/api1/user
. The user ID is returned in case it is successfully created.
The user's data is retrieved by sending a GET request with user ID and an authentication token. According to vAPI documentation, the authentication token is generated encoding base64 the string username:password
In our case, the authentication token is:
Let's check if the authentication token works. Placing it in the request headers we successfully retrieve user details.
As said before, the application would be vulnerable to BOLA if we could retrieve any user data just by changing the user ID. We verify that if we try querying user ID 1 we retrieve data for user Michael Scott.
The flag appears in the returned data.
Broken authentication vulnerabilities are related to applications that fail to implement protection mechanisms against authentication attacks. Examples of vulnerable applications are those that allow credential stuffing or brute force attack on the same user account, those that fail to implement protection mechanisms such as captcha/account lockout, those that allow weak passwords, those that send authentication tokens and clear passwords in the URL or those that does not validate the authenticity of tokens and accepts unsigned/weakly signed JWT tokens ("alg":"none"
).
According to documentation, there is some useful information in the vapi/Resources
directory. In fact, in the location /vapi/Resources/API2_CredentialStuffing
there is a list of possible credential pairs username/password. We can create two separate wordlists of users and passwords from it.
In order to launch a credential stuffing attack, we could use Burpsuite's intruder or ffuf
(normally faster). To launch an attack with ffuf
, first we capture a POST request to endpoint /vapi/api2/user/login
and modify it adding a random credential of the list, we send it and let it fail (it returns 401 unauthorized login unsuccessful).
Right-click on the request and save to file request.txt
, then modify it with a text editor to mark the fields to be fuzzed FUZZEMAIL
and FUZZPASSWORD
Now launch a pitchfork attack (credential stuffing) with ffuf
. It combines first username with first password of each wordlist, second username with second password, third with third, and so on.
The attack reports 3 successful credentials (code: 200).
Next step is to test this credential on the /vapi/api2/user/login
endpoint using a POST request. Logging in with hauck.aletha@yahoo.com:kU-wDE7r
we receive a successful login message, along with a token.
Finally, we send this token to the /vapi/api2/user/details
endpoint.
The flag appears in the application response.
Sometimes, API's are designed in such a way that they return sensitive data to the client, trusting that the client side developers will implement appropriate filters when presenting information to the user. However, an attacker can easily sniff the traffic and see the sensitive data.
Download and install the APK. For this write-up an android-x86 virtual machine running on Virtual Box has been used, Android Studio could also be used. Once installed, run the application and configure your vAPI server.
Create a new user and login. An application to post comments and replies comes into view.
Following the OWASP premises for this vulnerability, the API should be leaking user parameters that APK developer is filtering when presenting the comments to the user.
There are 2 methods to discover the information leaked by the endpoint depending on the Android virtual machine configuration used:
If you use Android Studio Android, it can be configured to use Burpsuite as a proxy. Add a comment and capture the HTTP response.
If using Android-x86 + Virtual Box, Burpsuite cannot be configured as a proxy. The alternative is to discover the endpoint used by the android app to manage comments and interact directly with it.
Since we are using Android-x86, we will follow the second option. For this, we fuzz for hidden endpoints in API3 and discover a hidden endpoint called /vapi/api3/comment
Simulating what the android app does, we query it with a GET request and see what information is leaked.
The flag appears in one of the parameters returned, therefore, we verify the endpoint is leaking unnecessary information, which is later filtered by the app developers.
Applications that do not limit the resources (network, CPU, memory, and storage) assigned to each client request are vulnerable to attacks where the user can send many results in shorts periods of time, and containing payloads of arbitrary size.
Sending a POST request to the /vapi/api4/login
endpoint initiates an OTP-based login process. A 4-digit OTP is supposed to be sent to the indicated mobile phone.
Another endpoint /vapi/api4/login
is used to verify the OTP by means of a POST request containing the received code.
Notice the OTP's are only 4-digit, so in theory they could be bruteforced if the application does not block massive amounts of user requests. This could be done with Burpsuite's intruder or ffuf
(faster). Same as before, capture a request with Burpsuite, and save to a request.txt
file.
Using a text editor, mark the field to bruteforce with the text FUZZ
Next step is to generate a wordlist called seq
of 9999 OTP's and launch the attack.
The OTP found is 1872.
Next step is to verify the validity of the OTP by means of a GET request sent to the endpoint /vapi/api4/otp/verify
The bruteforced OTP is valid and an authentication token is received. Final step is to use the token to disclose user information on the /vapi/api4/user
endpoint.
The flag appears in the HTTP response.
Applications vulnerable to BFLA are those that fail to verify if the user is authorized to perform certain actions on specific endpoints. For example, regular authenticated users may have access to restricted actions by simply changing the HTTP method (e.g., from GET to DELETE) or by simply guessing the endpoint URL and parameters (e.g., guess the endpoint /api/v1/admin
from /api/v1/users
). Whereas BOLA is related to authorization at an object level (e.g. ID's), BFLA is related to authorization issues at a function level (e.g. PUT, DELETE, POST or just changing the URL endpoint from users
to admin
).
POST a request to /vapi/api5/user
to create a new user.
A GET request sent to /vapi/api5/user/10
allows us to retrieve the user details (10 is the ID we received when creating the user). This endpoint requires an authorization token, if we remember from API1, it is generated encoding base64 the string username:password
Using this token we can query the user we have just created.
Now, to exploit the BFLA vulnerability, we can either abuse a known endpoint using a method we are not supposed to have access to, or find hidden endpoints which are not supposed to be exposed to us (e.g. send requests to /v1/admin
when we are supposed to have access only to /v1/users
).
To find hidden endpoints, we use ffuf
again.
Which returns a hidden endpoint called /vapi/api5/users
This is a hidden endpoint we are not supposed to have access to, since it returns a list of all the users of the database. Moreover, if we send a GET request to it, the endpoint fails to perform function-level authorization checks, since just providing token for user3
the complete list of users is returned.
The flag appears in the HTTP response.
Vulnerable applications allow users to update critical parameters directly, they automatically converts client parameters into internal object properties without considering the sensitivity and the exposure level of these properties. For example, when creating an account, a client should be able to exclusively update the username and password by means of a POST request. On the other hand, the client shouldn't be able to manipulate other parameter such as isAdmin
or similar parameters which may be used by the application to determine the privilege level of the user.
Let's create a new user sending a post to endpoint /vapi/api6/user
This user can be queried later with a GET request to endpoint /vapi/api6/user/me
, just adding the authorization token in the header.
As always, this is generated encoding base64 the string username:password
Notice the application leaks all the parameters of the user, including a previously unknown parameter called credit
. A mass assignment vulnerability allows attackers to update all user parameters automatically and without considering the sensitivity of each one. Let's try to create a new user and assign him any credits we want; for example, 10000 credits.
It seems the application accepted the request. We will verify this by querying the new user data. First, generate the token for the new user.
Now, query the endpoint for user test2
and inspect the output.
In fact, the application updated all the parameter, including the credit
one. The flag appears in the HTTP response.
The API is vulnerable if appropriate security hardening is missing or improperly configured. Examples of security misconfigurations include: important security patches are missing, unnecessary features are enabled (e.g., HTTP verbs) or necessary ones are disabled (TLS, HTTPS, CORS policy).
POST a request to endpoint /vapi/api7/user
to create a new user.
Generate an authentication token.
Send a GET request to endpoint /vapi/api7/user/login
to login with this user.
Take note of the phpessid
cookie, it will be used in the next request. Notice the documentation says something about a CORS vulnerability, these are exploited abusing the Origin: header
We will prepare an HTTP request in Postman. For this, first add the phpessid
cookie.
Then, to exploit the CORS vulnerability we add a new Origin:
header with an URL, no matter which one, and send the request.
The flag appears in the HTTP response.
When the API does not sanitize, filter or validate the user's input, it may be vulnerable to injection.
After some trial and error, a functional injection is found in the endpoint /vapi/api8/user/login
A basic SQLi is enough to bypass login and receive an authentication token.
And using this token in a GET request to endpoint /vapi/api8/user/secret
, the application dumps the flag.
If you want to play a bit more with this vulnerability, you can intercept a request with Burpsuite, save to file, and pass it to sqlmap
. It will dump the entire application database (the API8 flag is in the table a_p_i8_users
).
This vulnerability is related to outdated features still running in production environments due to a misconfiguration or because there is no plan for retirement or patching. For example, if a new /V2
endpoint implementing new security features is already in production, it is advisable that older outdated /V1
endpoints are retired or patched, or at least there is a retirement plan to do so.
Test the /V2
endpoint with a post request to /vapi/api9/v2/user/login
A status code 200 is received; however, no authentication message is returned. It seems we need a valid PIN to login, since it is only 4-digits, we will try to bruteforce it with ffuf
. As in previous steps, intercept an save a POST request and save to a text file. In the request file, mark as FUZZ
the PIN field to be bruteforced by ffuf
Generate a wordlist of possible PIN codes (from 0000 to 9999) and save the file as seq
, then launch the ffuf
attack.
Shortly after, we begin receiving status 500 codes, meaning the server is somehow detecting and blocking bruteforce attacks.
It seems bruteforce protections have been implemented in the /V2
endpoint. However, maybe there is an outdated /V1
endpoint still in place which does not provide any protection. Check if /V1
endpoint is still present in the host.
We receive a status code 200, meaning the /V1
endpoint has not been retired after entry into service of /V2
. We will try to repeat the bruteforce process for the /V1
endpoint. Modify the request.txt
file to point to the /V1
endpoint.
And re-launch the attack with ffuf
, filtering requests with size 0.
This time we find a working PIN 1655 returning status 200. So it seems the bruteforce protection was not implemented in /V1
endpoint.
All that's left is logging in using PIN 1655.
The flag appears in the HTTP response.
Vulnerable applications does not produce any logs, or the logging level is not set correctly, or log messages do not include enough detail.
Just query the endpoint, the flag will be returned. Nothing was logged!