----------------[ Netfilter and IP routing ]---------------- If you haven't yet, read the Netfilter.org HOWTOs, http://www.netfilter.org/documentation/ . Read the "NAT howto", and understand the concepts of DNAT and SNAT (http://www.netfilter.org/documentation/HOWTO//NAT-HOWTO-6.html#ss6.1) Recall that the NAT examples we've previously done used the Iptables/Netfilter MASQUERADING target, a special case of source NAT (SNAT): Debian +-----------+ +--- .100 (Mac) 129.170.212.0/22 | | 192.168.57.0/24 | ------------------|eth1 eth0|---------------- LAN switch --|--- .200 gw .212.1 |DHCP .1 | | +-----------+ +--- .225 iptables -t nat -A POSTROUTING -s 192.168.57.0/24 -o eth1 -j MASQUERADE Don't forget to turn on kernel's forwarding of packets: echo 1 > /proc/sys/net/ipv4/ip_forward Explore other files in the /proc/sys/net/ipv4/ directory -- all of these are variables that affect your kernel's TCP/IP behaviors! Read parts of "man 7 ip" where /sys/net appears; aslo "man 7 tcp". Note that "man ip" gives you ip(8) config tool man page instead (see below), not ip(7) and tcp(7); you have to ask for section (7) explicitly! MASQUERADE is used with dynamic addresses on the globally routable interface; should the address change in a DHCP exchange, the NAT would still continue working, rewriting to the new address. Reminder: turn off NetworkManager and kill its dhclient processes, otherwise _nothing_ will work! For placement of IPtables hooks, see slides 4--9 of http://events.ccc.de/congress/2004/fahrplan/files/319-passive-covert-channels-slides.pdf (all functions in blue boxes are actual function names in the Linux kernel; e.g., arp_rcv() is at http://lxr.free-electrons.com/source/net/ipv4/arp.c#L901 and so on). I tend to use the old-style Linux commands ifconfig and route to configure my networks; however, there is a newer more versatile package called IPRoute2, which uses one command "ip" for both. Read about it http://www.policyrouting.org/iproute2.doc.html and practice it. (Also have a look at http://lartc.org/howto/, Chapter 3) . That's what ip(8) man page is for. I mentioned the bandwidth management on Linux via queue disciplines. See Chapter 9 of http://lartc.org/howto/ (http://lartc.org/howto/lartc.qdisc.html) . My favorite is the "Token Bucket Filter". ------------------[ Practice IPtables filtering ]------------------ 1. Start a ping to a remote computer (say, Google's 8.8.8.8) from the router, see it succeed; do not stop it. Now insert rules to the INPUT chain dropping the ICMP echo response packets iptables -A INPUT ... -j DROP (you must fill in the tests instead of ...) You should see your ping start reporting no response. Now remove the rule; the pings should resume. Do the same for the outgoing echo requests via the OUTPUT chain. You should see no responses, because Google is not getting your requests. Do the ping from the client machine; drop requests or responses in the FORWARD chain on the router. When you drop the responses going to the client, you should still see them come back from Google to the router. Make sure your filter on the router drops only responses from Google; pings to other external hosts should succeed. 2. Write rules on the router's FORWARD chain to filter out TCP RST packets from an external host. Check that they really do get filtered: attempt connecting to a non-existing external host or service from the client, then see the difference in the client behavior. Without filtering TCP RSTs, your connection would terminate immediately (the client gets a RST), with it it will wait some time for a response before it times out. 3. On the router facing the client, produce RST packets with Scapy to break the client's existing SSH connection. You should see the client connection's dropping when you inject the packets. NOTE: You should make sure the SEQ and ACK numbers in the RST packet fall into the TCP window, or else such a packet will be ignored; you will need to sniff the connection to find what ACK numbers are used, because the initial SEQ and ACK numbers are chosen randomly at the TCP handshake time for every connection (observe this with Scapy's sniff() function, or with tcpdump). Now block RSTs on the client in the INPUT chain. You injected RST packets should not have no effect. See the SANS Scapy cheat sheet http://www.packetlevel.ch/html/scapy/docs/scapy_sans.pdf for a simple TCP handshake script. Another useful cheatsheet is http://packetlife.net/media/library/36/scapy.pdf. Peeking at the TCP packets diagrams in https://nmap.org/book/tcpip-ref.html is very handy. ===[ Stealing and re-inserting packets with IPTables IPQUEUE and NFQUEUE ]=== IPtables/Netfilter is an excellent tool for selecting packets out of the forwarded packet streams, modifying them, and putting them back in with changes. For example, any packets that cross the FORWARD chain in the above example of NAT can be matched, extracted from the kernel, rewritten with Scapy, and reinserted back into the kernel. IPQUEUE is an older Netfilter mechanism for stealing packets out of the kernel into a userland process (and returning them to the kernel, possibly modified by userland code). NFQUEUE is the newer one. You can interface with it via Python or Perl or with the C library http://www.netfilter.org/projects/libnetfilter_queue/ (harder, because you will need to write C code to handle IP packets; additional libraries like libnet and libdnet have been written for this, but now Scapy makes it much easier). ---------------[ IPQUEUE and NFQUEUE with Perl ]--------------- Have a look at the ipq-test.sh and ipq-test.pl in http://www.cs.dartmouth.edu/~sergey/netreads/mitmer.tgz pack of basic MITM scripts. ---------------[ IPQUEUE and NFQUEUE with Python ]--------------- IPQUEUE has been is easier to use, https://woozle.org/~neale/src/ipqueue/ . Note that QUEUE has been deprecated in favor of NFQUEUE (although kernels still support it). Read python-and-nfqueue.txt for more detail. To use the newer NFQUEUE target with python, get https://pypi.python.org/pypi/NetfilterQueue/ How to use Scapy with NFQUEUE to edit and re-inject ICMP and DNS packets: https://5d4a.wordpress.com/2011/08/25/having-fun-with-nfqueue-and-scapy/ A copy of another great tutorial is at http://lost-and-found-narihiro.blogspot.com/2015/02/python-scapy-nfqueue-bindings-python.html also http://archive.is/PVPmh and https://archive.is/y81LB (sadly, the original URL http://danmcinerney.org/reliable-dns-spoofing-with-python-scapy-nfqueue/ seems defunct) Exercises: 1. Think of how you could use Netfilter's QUEUE or NFQUEUE target to write the rules and packet-mangling script for your node to appear "invisible" from traceroute. 2. Use QUEUE or NFQUEUE to create a 1 second delay on ping packets, and to drop every 10th ping. 3. Use QUEUE or NFQUEUE to drop packets that contain a particular substring. Try this with DNS requests. Requests for a particular name should get dropped, requests for all others should succeed. Do this on the router's FORWARD chain, so that you can check from the client. 4. Use QUEUE or NFQUEUE to change the content of TCP packets. Substitute different strings of equal length into HTTP connections. You will need to recalculate TCP and IP checksums after the substitutions; set them to None in Scapy, then rebuild the packets (see examples). 5. Turn off forwarding in your Linux kernel (echo 0 > /proc/sys/net/ipv4/ip_forward). Then write a Scapy script that does equivalent packet forwarding. You can use it with either sniff() and sendp() (or, even easier, with send(), but that would be cheating, because send() would automatically make an Ethernet header for your IP packets and select the interface, too). 6. Implement some form of rewriting DNS responses on a Linux gateway machine you control to swap one site for another (say, google.com for bing.com, or vice versa).