Intro
This post is all about the vapi which is hosted on github and it has been created by Tushar Kulkarni.
The Plan
This vulnerable API has no Frontend like e.g., craPI, so i’ll just take documentation and import it to my Postman Instance as a collection.
I’ll be using Kali Linux and following tools:
- Burp Suite Community
- Postman
- ffuf
- wfuzz
- jwt_token
TOC
- Intro
- Vulnerabilities
- API1:2019 Broken Object Level Authorization<
- API2:2019 Broken User Authentication
- API3:2019 Excessive Data Exposure
- API4:2019 Lack of Resources \& Rate Limiting
- API5:2019 Broken Function Level Authorization
- API6:2019 Mass Assignment
- API7:2019 Security Misconfiguration
- API8:2019 Injection
- API9:2019 Improper Assets Management
- API10:2019 Insufficient Logging \& Monitoring
- ARENA - Server-Side Request Forgery
Vulnerabilities
After having imported API documentation into Postman, we’ll notice that documentation is very conviniently arranged.
Each API folder is for each API vulnerability type. We know what we have to do, so let’s begin…
API1:2019 Broken Object Level Authorization<
APIs tend to expose endpoints that handle object identifiers, creating a wide attack surface Level Access Control issue. Object level authorization checks should be considered in every function that accesses a data source using an input from the user.
Source: https://github.com/OWASP/API-Security/blob/master/2019/en/src/0xa1-broken-object-level-authorization.md
In order to even send a request in postman, we need to set variables. To get started we need host
variable. I’ve added vapi.local
to my /etc/hosts
file, just to make the requests more distingishable.
Now let’s go to API1
and use POST Create User
to create a user:
I’ve got an ID of 5
. This should be added to api1_id
environment variable, same as api1_auth
. Otherwise check Console!
If we issue GET Get User
request, we should see our data
If we change ID to 1
, we can read other users information, leading to BOLA vulnerability
1
2
3
4
5
6
{
"id": 1,
"username": "michaels",
"name": "Michael Scott",
"course": "flag{api1_d0cd9be2324cc237235b}"
}
Same happens with PUT method if we set an ID to some other users, like 2
.
We have now overwritten user that was stored under ID of 2
.
API2:2019 Broken User Authentication
Authentication mechanisms are often implemented incorrectly, allowing attackers to compromise authentication tokens or to exploit implementation flaws to assume other user’s identities temporarily or permanently. Compromising a system’s ability to identify the client/user, compromises API security overall.
Source: https://github.com/OWASP/API-Security/blob/master/2019/en/src/0xa2-broken-user-authentication.md
In this section, we have to check Resources
folder to get list of credentials:
This are credentials provided
1
2
3
4
5
6
7
luka@yokai ~/dckr/vapi/Resources/API2_CredentialStuffing master head -n 5 creds.csv
brown.grimes@hotmail.com,w_5yhfEN
reuben.heaney@hotmail.com,8JhcB_mH
dcronin@robel.com,V$qe{8+3
hcollier@veum.com,vVsU7/yN
vemard@gmail.com,gRfJ3$U7
There are 2 endpoints present:
I’ve set a proxy to Burp and sent a request to brute-force the credentials provided!
I’ve splited the creds.csv
into 2 separate files
1
2
3
4
# Users
cat creds.csv | awk -F"," '{print $1}' > users
# Passwords
cat creds.csv | awk -F"," '{print $1}' > passes
In Burp, we’ll use Pitchfork
mode.
Alternatively, we could process single file twice in Burp, usernames before the comma and passwords after the comma.
We can brute-force credentials using FFUF as well
1
ffuf -w users:USERS -w passes:PASS -u http://vapi.local/vapi/api2/user/login -d '{"email":"USERS","password":"PASS"}' -H "Content-Type: application/json" -mode pitchfork -mc all -fc 401
FFUF ended up with 3 working credentials:
1
2
3
4
5
6
7
8
9
10
11
[Status: 200, Size: 89, Words: 1, Lines: 1, Duration: 1769ms]
* USERS: savanna48@ortiz.com
* PASS: zTyBwV/9
[Status: 200, Size: 89, Words: 1, Lines: 1, Duration: 1971ms]
* USERS: hauck.aletha@yahoo.com
* PASS: kU-wDE7r
[Status: 200, Size: 89, Words: 1, Lines: 1, Duration: 1829ms]
* USERS: harber.leif@beatty.info
* PASS: kU-wDE7r
Authentication should work with one of the credentials and we should get a token back.
We can also see that we have Rate Limiting
problem here.
Using /vapi/api2/user/details
(GET) we’ll notice that we get information about every user out there.
API3:2019 Excessive Data Exposure
Looking forward to generic implementations, developers tend to expose all object properties without considering their individual sensitivity, relying on clients to perform the data filtering before displaying it to the user.
Source: https://github.com/OWASP/API-Security/blob/master/2019/en/src/0xa3-excessive-data-exposure.md
API3 only has only one Endpoint in documentation
We can create a new user but that’s it.
For API3
challenge we’ll need to check Resources that come with the app.
We’ll get an .apk
which we’ll have to reverse. I’ve used jadx-gui
for that!
See the endpoint there?
What if we send a get request to that endpoint?
Yes we get a flag and as we can notice, much more information that’s necessary.
API4:2019 Lack of Resources & Rate Limiting
Quite often, APIs do not impose any restrictions on the size or number of resources that can be requested by the client/user. Not only can this impact the API server performance, leading to Denial of Service (DoS), but also leaves the door open to authentication flaws such as brute force.
Source: https://github.com/OWASP/API-Security/blob/master/2019/en/src/0xa4-lack-of-resources-and-rate-limiting.md
The API4
has 3 documented Endpoints
We can use Mobile Login
, however this is only 1 part of the login process. We need to provide OTP as well and here is where vulnerability lies. Verify OTP
has no rate limiting set, making it easy for us to brute-force the OTP code. We can use Intrudr or WFUZZ
1
wfuzz -z range,0000-9999 -u http://vapi.local/vapi/api4/otp/verify -d '{"otp":"FUZZ"}' -H "Content-Type: application/json" --hc 403
If we provide the right OTP, key
will be returned and environment variable set, so we can retrieve the flag in Get Details
API5:2019 Broken Function Level Authorization
Complex access control policies with different hierarchies, groups, and roles, and an unclear separation between administrative and regular functions, tend to lead to authorization flaws. By exploiting these issues, attackers gain access to other users’ resources and/or administrative functions.
Source: https://github.com/OWASP/API-Security/blob/master/2019/en/src/0xa5-broken-function-level-authorization.md
We have to documented endpoints here for API5
. We can create user…
… and we can retrieve its information.
There is no BOLA, so we cannot ask information for other user by changing its ID.
We can however try to send request to different path that is not documented and sounds like it could be right ==> /vapi/api5/users
.
… and indeed, the endpoint does not check users credentials (or does not check authorization for it)
API6:2019 Mass Assignment
Binding client provided data (e.g., JSON) to data models, without proper properties filtering based on an allowlist, usually leads to Mass Assignment. Either guessing objects properties, exploring other API endpoints, reading the documentation, or providing additional object properties in request payloads, allows attackers to modify object properties they are not supposed to.
Source: https://github.com/OWASP/API-Security/blob/master/2019/en/src/0xa6-mass-assignment.md
With Mass Assignment vulnerability we can change values ob some object even when we’re not supposed to.
We can create user…
… and retrieve its parameters.
Can we assign credits to ourselves when we create a new user?
Let’s create a new user and add credit
parameter with some interger to it.
Parameter credit
does indeed reflect on ou users object
API7:2019 Security Misconfiguration
Security misconfiguration is commonly a result of unsecure default configurations, incomplete or ad-hoc configurations, open cloud storage, misconfigured HTTP headers, unnecessary HTTP methods, permissive Cross-Origin resource sharing (CORS), and verbose error messages containing sensitive information.
Source: https://github.com/OWASP/API-Security/blob/master/2019/en/src/0xa7-security-misconfiguration.md
For Security Misconfiguration vulnerability (API7) we have 7 documented endpoints available:
We’ve created user, now we should be able to log in (API7_auth
token should be saved automatically)
Perhaps irrelevant, we after login PHPSESSID
session cookie will be set!
We can now grab a key
Vulnerability here lies in missing CORS protection or in other words - CORS is to permisive and as such allows grabing keys from victim any location.
API8:2019 Injection
Injection flaws, such as SQL, NoSQL, Command Injection, etc., occur when untrusted data is sent to an interpreter as part of a command or query. The attacker’s malicious data can trick the interpreter into executing unintended commands or accessing data without proper authorization.
Source: https://github.com/OWASP/API-Security/blob/master/2019/en/src/0xa8-injection.md
I’ve sent a request to Burp and checked for SQL injection there.
We can use the key to get the flag:
API9:2019 Improper Assets Management
APIs tend to expose more endpoints than traditional web applications, making proper and updated documentation highly important. Proper hosts and deployed API versions inventory also play an important role to mitigate issues such as deprecated API versions and exposed debug endpoints.
Source: https://github.com/OWASP/API-Security/blob/master/2019/en/src/0xa9-improper-assets-management.md
We have a single endpoint available here which is login with provided user and we’re supposed to guess/brute-force PIN.
Now the problem is that we gate rate-limited after 5 attempts.
There is v1
instance available which has no rate-limiting enabled
Exploitation after finding the endpoint is the same as in API4.
API10:2019 Insufficient Logging & Monitoring
Insufficient logging and monitoring, coupled with missing or ineffective integration with incident response, allows attackers to further attack systems, maintain persistence, pivot to more systems to tamper with, extract, or destroy data. Most breach studies demonstrate the time to detect a breach is over 200 days, typically detected by external parties rather than internal processes or monitoring.
Source: https://github.com/OWASP/API-Security/blob/master/2019/en/src/0xaa-insufficient-logging-monitoring.md
Here we get a flag right away, but i guess we get and understand a message, right?
1
2
3
4
{
"message": "Hey! I didn't log and monitor all the requests you've been sending. That's on me...",
"flag": "flag{api10_5db611f7c1ffd747971f}"
}
ARENA - Server-Side Request Forgery
asd
is vulnerable to Server-Side Request Forgery and vulnerability is not hard to find.
Interestingly if we try to connect with http://localhost
or http://127.0.0.1
, we’ll get 403 response back.
We can however let the server connect with external resources like https://webhook.site
which will display that HTTP request.
Inband SSRF returns response BASE64 encoded.
We can e.g., use file://
to read files on the system.