January 31st
2010
There are times you need to connect to ‘dirty’ networks such as public WiFi hotspots. Hopefully you’re ensuring that sensitive information is encapsulated in transport layer security enabled protocols such as SSL, because anyone on the same link (in the case of WiFi, that’s the air surrounding you. A vacuum will do, too, but that’s less common) can listen in on the traffic you’re sending. With SSL encapsulation such as HTTP over SSL (https://), your traffic can still be read — but for those who do it’s an extremely boring read because they don’t know the session key, only you and the other endpoint do. Hopefully.
One particularly nasty thing that can happen to you is when your machine is subverted into using the attacker’s machine as the router. That is known as ARP poison routing. The attacker can proceed to not only read the traffic coming from your machine (which, on a shared medium, could be done anyway), or read the traffic going into your machine (again: on a shared medium, that could be done anyway), but the attacker can now also modify the traffic between you and the rest of the non-local network, e.g., the internet, in both directions. And that’s when he can really go to town with your traffic. Injecting a javascript keylogger into all the webpages you visit. ‘Sidejacking‘ your sessions, so he does not even need to know your passwords, just your session cookies — which you happen to transmit with every page request.
All possible unless you use transport layer security, which is tamper-proof once properly set up. Once properly set up. But setting up can have problems of itself — there are ways of preventing you ever going from HTTP to HTTPS. If you know a thing or two about HTTP and SSL you’ll be delighted to learn about Moxie’s very evil but very clever ways of doing so.
Anyway, some level of security can be achieved if you tell your machine to ignore any messages sent to you from the other machines on the local network. That includes messages that will make your machine believe that the router has suddenly changed its physical address — which is quite unlikely to happen, but those messages are exactly the type of message an impersonator would send you. Of course we’d need to whitelist the routers of the network, otherwise we can’t get traffic out of it and onto other networks. DNS resolvers will need whitelisting too, unless you’re running one on your own machine (probably not).
Not openly announcing your presence may also be something you wish for. If you have ever been on a network with a Mac user you have probably seen them popping up in your Zeroconf service browser as “Firstname Lastname’s iSomething”. Let’s cut down on that kind of promiscuity, too. But you should understand now that you can not actually hide unless you turn off your WiFi. Shared medium, remember?
I prepared a simple script to accomplish the above. I’ve used ip from the iproute2 package instead of sticking to old-school route, ifconfig, arp & co. And I must say ip neigh flush nud stale has a poetic ring to it, wouldn’t you agree?
Take note: this will only protect you from some kind of attacks, and only partially. An attacker has a window of opportunity between your machine getting assigned a DHCP lease and you running this script, for instance. Or maybe the access point is rigged. Actually all protection other than end-to-end encryption combined with mutual authentication is pretty useless on shared networks ;-)
Here’s the script. Linux-only. If you want to use it, get the latest version from my public repository.
#!/bin/bash
# arpshield 0.2
# Protects against ARP poisoning and cloaks your machine for all
# local link devices but the router(s) and the DNS server(s).
# Whitelisting DHCP servers also works if you use the dhcpcd program
# to obtain DHCP leases.
# This program is of no help if your setup is already poisoned.
# Have a look at ArpON (http://arpon.sourceforge.net/manpage.html) if
# you need more extensive protection.
#
# Needs 'ip', 'awk', 'sed', 'arptables', and 'arping' and expects
# them on $PATH. Needs appropriate privileges (so use sudo).
# Takes a network interface as an argument. The network interface
# should be up and configured. If no argument is given, clear all
# rules. Obviously you should do that before connecting to a new
# network.
#
# Copyright 2010 Wicher Minnaard (wicher@gavagai.eu)
# License: Creative Commons Attribution-Share Alike 3.0
# Do you use dhcpcd for aquiring DHCP leases? And is it running?
dhcpcdLEASEFILE="/var/lib/dhcpcd-${1}.info"
dhcpcdPIDFILE="/var/run/dhcpcd-${1}.pid"
test -f ${dhcpcdLEASEFILE} && test -f ${dhcpcdPIDFILE} && source ${dhcpcdLEASEFILE}
# In case you lack the luxury of dhcpcd, where is your resolv.conf?
RESOLV="/etc/resolv.conf"
# No user-servicable parts below this line.
DEV="${1}"
# I know, I know. But if your routing table contains 0.333.456.789 you have bigger problems ;-)
IPREGEX="\([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}"
# Register
MACreg=""
# If not run as root, bail
[ "$(id -u)" != "0" ] && echo "You need root privileges to modify networking parameters. Exiting." 1>&2 && exit 2
getmac(){
# sets MAC register by IP. Sets to nil, if the MAC is not on the local link.
getMAC=$(ip neigh show ${1} | awk '{print $5}')
if [ -z "${getMAC}" ]; then
arping -c1 -I ${DEV} ${1} > /dev/null 2>&1
getMAC=$(ip neigh show ${1} | awk '{print $5}')
fi
MACreg=${getMAC}
}
allow(){
# Whitelists traffic to and from particular IP+MAC pairings and
# adds them to static ARP.
IP=${1}
MAC=${2}
if [[ -n "${IP}" && -n "${MAC}" ]]; then
arptables -A INPUT -s ${IP} --source-mac ${MAC} -j ACCEPT
arptables -A OUTPUT -d ${IP} --destination-mac ${MAC} -j ACCEPT
ip neigh replace ${IP} lladdr ${MAC} nud permanent dev ${DEV}
fi
}
if [ -n "${DEV}" ]; then
# whitelist the routers
test -z ${GATEWAYS} && GATEWAYS=$(ip route show dev ${DEV}| sed -n "s:.* via \(${IPREGEX}\).*:\1:p")
for GWIP in ${GATEWAYS}; do
MACreg=""
getmac ${GWIP}
allow ${GWIP} ${MACreg}
done
# whitelist the DNS servers
test -z ${DNSSERVERS} && DNSSERVERS=$(sed -n "s:^nameserver \(${IPREGEX}\):\1:p" ${RESOLV})
for DNS in ${DNSSERVERS}; do
MACreg=""
getmac ${DNS}
allow ${DNS} ${MACreg}
done
# if using dhcpcd, we can whitelist the DHCP server too
test -n ${DHCPSID} && getmac ${DHCPSID} && allow ${DHCPSID} ${MACreg}
# set default policy to DROP
arptables -P INPUT DROP
arptables -P OUTPUT DROP
# clear out non-hardcoded ARP cache entries
ip neigh flush nud reachable
ip neigh flush nud stale
else
# No argument given, so clean up.
arptables -F
arptables -P INPUT ACCEPT
arptables -P OUTPUT ACCEPT
ip neigh flush nud permanent
fi
Tags: arp spoofing, en_GB, security, wifi —

Posted by
Wicher
Topic:
Rants
January 24th
2010
Ik ben kwaad. Sacha vertelt waarom:

Dus. We hebben een regering van gekozen volksvertegenwoordigers. Goede zaak zou je zeggen, want die maken beleid dat het algemeen belang dient. Het algemeen belang.
Maar wat doet je minister, Camiel Eurlings? Die gaat nog even exclusief aan de leden van één (1!) belangenvereniging vragen of het beleid hen wel kan bekoren, want zo niet, dan gaat-ie het natuurlijk niet uitvoeren. Maar het is potdorie een hamerstuk waar onze tweede kamer (die jou vertegenwoordigt) al achter staat.
Camiel houdt een privéreferendumpje. Waarmee wordt beslist of autorijden duur mag worden. En alle automobilisten zijn uitgenodigd! Moet je in Nederland een ANWB-partijkaart hebben om je stem uit te mogen brengen?
Die heeft niet iedereen. Marietje, die vanochtend op de fiets naar d’r werk nog door een Hummer de stoep op werd gedrukt, wil er niet eens een. En Camiel gaat dus niet aan oma Truus in d’r met vrachtwagenroet bedekte woning aan de Fijnstofallee vragen wat zij van auto’s vindt. En hij vraagt het ook niet aan kleine Kareltje die achter z’n Playstation kinderdiabetes zit krijgen omdat er buiten niks te spelen valt omdat z’n huis temidden parkeerplaatsen, blik, drukke wegen en andere automobielinfra staat.
Als je het deze mensen zou vragen mag het autorijden best ontmoedigd worden. Maar nee, er wordt een voorstel gedaan zodanig dat autorijders het mee eens zullen zijn — en dus zullen die er niet al te veel op achteruit gaan. Met andere woorden: dat is dus niet het voorstel worden dat er voor gaat zorgen dat jongere generaties een fijne leefomgeving tegemoet gaan.
Goed hee Camiel, draagvlak zoeken. Dat zouden we vaker moeten doen. Zo vind ik dus dat de regering aan de Vereniging Stinkrijke Bonusbankiers had moeten vragen of ze er eigenlijk wel mee akkoord gaan dat die pret aan banden gaat. En we zullen ook nog maar moeten zien of de Nederlandse Delinquentenbond instemt met beter toezicht op verlofregelingen. Ze mogen dan trouwens zelf dat privéreferendumpje organiseren en de stemmen tellen, net als de ANWB. Zo nauw nemen we het immers toch al niet met de integriteit van volksraadpleegmechanismen.
Camiel, als je e.e.a. wil toelichten (graag!), dan kan dat door hieronder je reactie toe te voegen.
Tags: kilometerheffing, politiek, rekeningrijden —

Posted by
Wicher
Topic:
Howto
January 10th
2010
Access remote X11 servers that have their TCP socket disabled
This happens to me regularly. Someone brings a machine along and I want to display some app, running on my machine, on their display. Networked X11 to the rescue, you say? No, their X11 server is started with ‘-nolisten TCP’ wich is the default on most modern Linux distros. Sadly, the TCP socket can’t be enabled ‘in-flight’ — if you decide you do fancy a TCP socket after all, you’ll have to restart your X server which may be a pain if you’re in the middle of something (besides, restarting is just plain uncool).
But there is a way to expose the Unix domain socket as a TCP socket, with the help of socat. The following examples all use bash, so if you run a different shell (if you don’t know, you probably aren’t) you may need to define environment variables differently.
Braindead Proof of Concept (BPOC)
Situation: You want to display an application running on a machine called w00t on another machine, called bling. There’s an X11 server running on bling, but it’s not configured to listen on any TCP socket. DNS is properly setup, so if you ping w00t from bling, you get replies from bling’s IP, and vice versa.
- On bling, find the domain socket of bling’s X11 server. Have a look in
/tmp/.X11-unix/. The socket’s name usually reflects its X server display number (which you can determine by running echo $DISPLAY in an xterm).
- On bling, run something along the lines of
socat TCP-LISTEN:6066 UNIX-CONNECT:/tmp/.X11-unix/X0
This will open up TCP port 6066 on all of bling’s network interfaces, connecting it to the Unix domain socket of the X server.
- In an xterm on bling, run
xhost +. You have now opened up your X11 server to the whole wide world, a silly thing to do. Anyone with access to the TCP socket can now read your keystrokes, read your window contents, click your mouse buttons…
- In an xterm on w00t, run
DISPLAY="bling:66" xclock. You may have noticed that 66 = 6066 – 6000 and indeed, by convention the TCP port number for a certain display is its display number + 6000. Anyhow…. yay, a clock! It’s displayed on bling, but running on w00t.
Improvements
- You may have noticed that in the BPOC, you can use the display on bling only once.
socat will allow only one client, and will exit once that client exits. In some situations, you may consider that a feature (it’s a one-time access grant), but in others you may not. If you want a reusable TCP socket, run something along the lines of
socat TCP-listen:6066,fork,reuseaddr UNIX-CONNECT:/tmp/.X11-unix/X0 which forks off a socat process for every TCP connection.
- You may not want to expose a TCP socket on all interfaces. Maybe you only want to expose a socket on the LAN interface, or on the localhost interface (and wrap the packets in an SSH tunnel). Well, you can, using the ‘bind’ option:
socat TCP-LISTEN:6066,bind=localhost UNIX-CONNECT:/tmp/.X11-unix/X0
Now tunnel it over SSH. On w00t, run ssh -L 6011:localhost:6023 bling. Now localhost:6011 on woot is actually localhost:6023 on bling which is actually /tmp/.X11-unix/X0 on bling. So on w00t you can start an xclock with its display on bling by running DISPLAY="localhost:11" xclock.
xhost + from the BPOC is braindead indeed. There are a couple things you could have done instead, there are good ways of tightening up your authorization scheme.
- First off, you don’t really need to run
xhost + if you properly set up X11 cookies, which you should. Here are some examples on using the xauth scheme, but take note: xauth generate will probably not work on recent X11 releases since the XSECURITY extension is disabled by default. Just use the same cookies on the client and the server.
- Run
xhost +w00t. That’s host-based authentication, which is stupid, but not as stupid as no authorization at all. Any user on w00t can now connect.
- Suppose that on bling (of course!) you’d run
xhost +SI:localuser:theuser with ‘theuser’ being the userID of the unix-user running the socat instance. Now from the point of view of the X server, any client connecting through socat will be coming from ‘theuser’ and will therefore be allowed access. Entertaining, but not much different from just running xhost +. It is something to keep in mind though! Many distros by default add the unix-user that started the X server to the authorization list. That user does not need a cookie. If you run socat as that user you will have the effect of running xhost + even if you run xhost -.
- Just run a nested X11 server, such as Xnest or Xephyr. This way you put untrusted users in a sandbox, preventing them from snooping your keyboard and windows. It’s the X11 equivalent of a chroot.
Tags: en_GB, socat, X11, xauth, xhost —