October 9, 2011 at 12:00 PM
At times you may find yourself on a public network, only to be subjugated to slower speeds because another user is taking up all the bandwidth downloading pr0n, music, games, etc. With no administrative rights to the network and your computer as your only weapon, what's a h4x0r to do? Fear not my friend, you have all you need and James is here to help you take back the net! To be more specific, I will be discussing how to cut off a leech's Internet access, how to block specific ports from a leech, and how to regulate the amount of bandwidth a leech can use. So put your boots on, it's time to squash some leeches!
--[ Prerequisites ]---
---[ Phase 1: ARP Spoofing ]---
Address Resolution Protocol (ARP) is a TCP/IP protocol used to map an IP address to a physical (MAC) address. In order to communicate with a device on a network, a host needs to know that device's MAC and IP address. In order to learn a devices MAC address, a host will send out a broadcast that in essence says, "Hey my IP address is 192.168.1.2 and my MAC address is AA:BB:CC:DD:EE:FF, what's the MAC address of 192.168.1.1?" Host 192.168.1.1 will make an entry in its ARP table that says, "192.168.1.2 is at AA:BB:CC:DD:EE:FF." It will then send a message to 192.168.1.2 that says, "I'm 192.168.1.1 and my MAC address is 00:11:22:33:44:55:66." Host 192.168.1.2 will then make an entry in its ARP table that says, "192.168.1.1 is at 00:11:22:33:44:55:66." The problem is, that when a host receives a 'who-has' ARP message, it will ALWAYS update it's ARP table with the IP and MAC address of whomever sent the broadcast. So sending a specially crafted 'who-has' message, makes it possible to map any IP address in a host's ARP table to any MAC address you want. How does all of this help stop bandwidth leeching? Well in order to communicate with the outside world, a host will send traffic destined for outside the network to the router. The router then takes that traffic and sends it along to its destination. Now if someone were to set the MAC address of the router on the leech machine to something bogus, then traffic destined for the outside world would never reach the router! So launch your python interpreter and let's try shall we? Use following excerpt from my python interpreter as a guide.
>>> import scapy, time >>> a = scapy.ARP() # creates an ARP message object >>> a.psrc = "192.168.1.1" # sets the 'from' IP address to the router's >>> a.pdst = "192.168.1.12" # the leech's IP address >>> a.hwsrc = "aa:bb:cc:dd:ee:ff" # sets the 'from' MAC address to a bogus one >>> while 1: ... scapy.send(a) ... time.sleep(90) # sleep for 90 seconds and then send again ... . Sent 1 packets.
---[ Phase 2: Owning with MITM ]---
Now spoofing the router entry within a leech's ARP table to something bogus may be effective, it's not very fun. So instead of having packets destined for the router sent to nowhere, have them sent to you! Why would you want to do that? Well because now you control their Internet connection, which allows you to control what they access and how much bandwidth they can use. So first thing's first, poison the leech's ARP table to point to you. Use following excerpt from my python interpreter as a guide.
>>> import scapy, time >>> a = scapy.ARP() # creates an ARP message object >>> a.psrc = "192.168.1.1" # sets the 'from' IP address to the router's >>> # by not setting the hwsrc, the 'from' MAC address is set to our own >>> a.pdst = "192.168.1.12" # the leech's IP address >>> while 1: ... scapy.send(a) ... time.sleep(90)
Just poisoning the leech's ARP table isn't enough this time though. You will need to setup some iptables rules to enable traffic forwarding. This is accomplished by entering the following commands as root.
echo 1 > /proc/sys/net/ipv4/ip_forward echo 0 > /proc/sys/net/ipv4/conf/eth0/send_redirects iptables --append FORWARD --in-interface eth0 --jump ACCEPT
The first two commands tell the kernel to enable packet forwarding, and not to send ICMP redirects. While the last command makes an iptables rule that allows packets that come in from eth0 to be forwarded to their destination. So now that traffic from the leech is being routed through your computer, let's block some ports!
iptables --insert FORWARD --protocol tcp --destination-port 80 --jump DROP
The command above tells iptables to drop all packets to be forwarded that have a destination port of 80 (HTTP). In other words, the leech is now blocked from using HTTP. The reason '--insert' is used instead of '--append', is because rules in an iptables chain are executed in order. So rules that drop packets, should come before rules that accept packets. I could go on and on about filtering network traffic, but there are plenty of papers about that subject already out there. So instead I'll give you a link to the iptables man page. http://linuxreviews.org/man/iptables
---[ Phase 3: Bandwidth Limiting ]---
Bandwidth limiting allows you to control how much bandwidth a leech can use. In other words you could throttle a leech's connection speed down to that of a 56k modem, oh the irony. This is accomplished through the creation of a special queuing disciple aka. qdisc. First though, a brief summary of what a qdisc is, brought to you by "The Traffic Control HOWTO" http://tldp.org/HOWTO/Traffic-Control-HOWTO
Simply put, a qdisc is a scheduler. Every output interface needs a scheduler of some kind, and the default scheduler is a FIFO (First In First Out). Other qdiscs available under Linux will rearrange the packets entering the scheduler's queue in accordance with that scheduler's rules.
There are several different qdiscs out there, each with their own way of handling traffic. However the qdisc we will be using is the Hierarchal Token Bucket qdisc, because HTB makes it easy to regulate bandwidth. To setup HTB, enter the following commands as root.
tc qdisc add dev eth0 parent root handle 1: htb default 10 tc class add dev eth0 parent 1: classid 1:10 htb rate 100mbit prio 0 tc class add dev eth0 parent 1: classid 1:11 htb rate 56kbit prio 1 tc filter add dev eth0 protocol ip parent 1:0 handle 1337 fw flowid 1:11
The first command creates a new HTB qdisc for eth0, and tells it to default traffic to class 1:10. The second command creates the 'default' bandwidth class (identified as 1:10) with a maximum transmission speed of 100 megabits per second. The third command creates the 'leech' bandwidth class (identified as 1:11) with a maximum transmission speed of 56 kilobits per second. The last command tells the qdisc that any packets marked as 1337 (discussed below) should be placed into the 'leech' class. Finally, there are three iptables rules that must be applied in order to make all of this work.
iptables --table nat --append POSTROUTING --out-interface eth0 --jump MASQUERADE iptables --table mangle --append FORWARD --in-interface eth0 --source 192.168.1.11 --jump MARK --set-mark 1337 iptables --table mangle --append FORWARD --in-interface eth0 --destination 192.168.1.11 --jump MARK --set-mark 1337
In order to control both upload and download speed of the leech, NAT (Called masquerading in Linux) is required. This is accomplished with the first command. The next two commands tell iptables to mark any packets from or to the leech's IP address as 1337. Those packets are then handled by the tc filter rule setup above. Game over, boom head shot, the end, no more leeching problem.
---[ Bonus! ]---
Below are two scripts to help make your leech squashing easier. The first is to poison the leech's ARP table, and the second handles setting up iptables, and HTB. Put both in the same directory, and run 'squashLeech.sh'.