Disclaimer: You are free to use presented knowledge for educational purposes, with good intentions (securing web applications, penetration testing, ctf’s etc.), or not. I am not responsible for anything you do.
This article was originally written in May 2018 and is presented here in its original format. While the content is old, it remains relevant, although there are areas where I would make updates, such as covering local/session storage, JWT-based authentication, DOM XSS, and Content Security Policy, along with general code refactoring.
Despite these potential improvements, I have chosen to preserve the article in its original form, as it represents my first-ever article writing endeavor during high school.
The topics covered here include basic Man-in-the-Middle attacks and Cross-Site Scripting (XSS).
If you’re interested in further exploration and learning, I recommend visiting PortSwigger Academy, particularly their XSS section. It provides excellent, free training in web security. KUDOS for them.
Enjoy your reading.
K.
This article will explain some of the common HTTP state interception methods for beginners.
At the base of our actions we need a listener.
Due to mixed content restrictions in modern browsers you’ll often need to use HTTPS protocol capable web server.
You can write your own or use httpd like Apache.
If your target is outside the NAT then corresponding port forwarding will be needed too.
You can also use a web service similar to Requestbin (public hosting discontinued unfortunately, although there are self-hosted options for webhooks and bins).
Here is a very simple solution written in Python 3.
|
|
You can then connect to it and test if it works.
|
|
GET /?xss=PHPSESSID=ThisIsMySessionCookieForTesting HTTP/1.1
The request was captured.
Session theft concept
For the case of simplicity and illustrating the concepts, I’ve chosen to use simple built-in PHP http server as we are not interacting with SSL traffic for now.
Let’s create something quick in PHP language. index.php
|
|
Example above is saving the GET xss parameter from incoming requests into a file named xss.txt.
In shorter words it just saves the received cookie into a file.
Start the server with elevated privileges.
|
|
- -S 0.0.0.0:80 - Listen on all interfaces, port 80
- -f index.php - Specified file to parse
- -t . - Directory root (dot means current directory)
The main point for now is to make the client send a request into our listener.
Fake image
payload.js
|
|
Basically we are creating a new image object, source of which points to our listener at 192.168.1.101, and while the browser is requesting to load a fake image, the server captures the URL parameter containing the cookie.
At first let’s test it locally with help of the developer console and then we’ll move out to injecting a script in non-physical access based situations.
Open up the developer console (F12) and test the payload.
If you’ve had received the cookie, then you’ve done everything correctly. Congratulations 😀
The cookie we’ve sent can be used to become an authenticated user without logging in.
We can use a Cookie extension to import the captured cookies into a browser.
We can also set it with javascript.
|
|
We can also set it in the storage tab.
[
Setting the cookie in the storage tab
If you craft requests by hand, pass the cookie manually in the HTTP “Cookie” request header.
Putting the cookie into a proxied request using Burp Suite
After refreshing you can notice that we are logged in as another user.
Let’s move to the basic XSS topic.
Browsers’ javascript parsers allow for client side, cross site code execution. - Cross Site Scripting.
Stored XSS
The first XSS exploitation technique I will showcase is called stored XSS. We will be targeting a vulnerable input that allows us to add an unsanitized comment. The exploitation is persistent as the payload is being constantly red from the database.
Infographic showing stored XSS
For encoding I used one of the Jim Stiles’ javascript utilities.
I encoded the payload in char code and then used eval to run it on body load event.
|
|
- Once the user logs in and reads the comments, we get his cookie.
Reflected XSS
Another technique is called reflected XSS and this time we will need the user to click on a prepared link that injects the payload using an unsanitized input. Generally, if there is a field that loads a string from the URL and does not filter anything before rendering it, then Reflected XSS is possible.
There is a vulnerable search field on this web app, let’s exploit it and send our link to the user.
Encoding the payload with Burp Suite assistance
|
|
Unwary user clicks on a malicious link
A Man standing in the Middle
Last technique I will cover in this article does not need precision to succeed.
It involves sniffing on the network, redirecting HTTPS traffic into HTTP, proxying the packets and then injecting the payload in real time.
We will use a great framework made by Marcello Salvati.
Before running, let’s take a look at the source code.
As we can see, the framework takes care of most of the boring administrative tasks for us automatically. There is no need to manually set ipv4 forwarding or write iptables rules.
The framework can efficiently spoof the ARP cache of the whole subnet. I will explain in steps how it works. At first we need to resolve the MAC address of targeted devices. We send an ARP ‘who-has’ request.
Then we announce that we have the MAC address of a gateway (router in this case). By doing that, all the devices are being tricked to send the packets at us after being routed.
After we become a man-in-the-middle, we can process the packets and serve whatever we want to the victim devices. In this case, we will intercept HTTP responses and then include a malicious javascript code inside them. We can also sniff the cookies just by intercepting the requests at this point, but we will perform a javascript injection to make it even more sophisticated. The possibilities are endless after the web browser gets trojanized with injected code.
The injection module uses BeautifulSoup with simple html parser to find a document body and append the payload into it. If we’ve hosted our payload on some server, we could inject it automatically in an < iframe > tag after specifying the URL.
Let’s change the payload to a different port:
|
|
It is time for the framework to do the work for us.
|
|
- -i wlp2s0 - Use interface wlp2s0
- –inject –js-file /home/krystian/xss/payload.js - perform javascript injection on a stripped content
- –spoof - spoof the packets
- –hsts - try to strip SSL and HSTS
- –netmask 192.168.1.0/24 - set network mask
- –gateway 192.168.1.1 - set the gateway
After a while, we could notice that every single device on the network sends us cookies from most of the HTTP requests they’ve sent.
Successful MITM cookie sniffing
How to avoid losing cookies?
- Web devs - sanitize your inputs - do not trust any input.
- Use HttpOnly and Secure cookie flags.
- Use the Content Security Policy.
- Verify whether sites you own do not contain something unexpected in the source code or the database.
- Do not trust every email.
- Verify what links you click on.
- Ring a bell when your connection suddenly loses SSL. (Verify the padlock icon in a web browser)
- Connect only to trusted networks. (Open WiFis are not trusted)
- If you detect a Man in the Middle attack in your packet captures, do not ignore the threat.
- Turn off javascript. (When you are desperate… 😀)