[ http://www.rootshell.com/ ] Playing redir games with ARP and ICMP by yuri volobuev [ -Intro- ] There're bugs and there're features. All too often the distinction between the two is in the eye of the beholder. I'd like to show how two legitimate protocols, ARP and ICMP, while properly implemented, can be used to achieve something which is, well, not desirable. While passive attacks (sniffing) that take advantage of the root access to LAN are extremely popular and every half-way decent root kit has some kind of a net sniffer, active attacks are not nearly as widespread. Yet, active participation in the life of your LAN may bring lots of fun and joy. You knew that already, it's just that technical details had been somewhat obscure. So, let there be more light. Possibilities outlined here include spoofing and DoS. While other means of spoofing, such as IP blind spoofing, are more general and powerful, in terms of who can use them, they require quite a lot of (guess)work and may be hard to implement. ARP spoofing, on contrary, is very easy and robust. While ARP spoofing is only possible on a local network, it may be a serious concern as a way to extend an already existing security breach. If somebody can break into one machine on a subnet, ARP spoofing can be used to compromise the rest of it. [ -Background on ARP- ] [well, originally i wrote few paragraphs outlining arp, but then i figured that if you didn't know how it works already, you'll need to learn it from a better source. I recommend "TCP/IP Illustrated" by W.Richard Stevens.] [ -What can be done- ] Let's consider a hypothetical network IP 10.0.0.1 10.0.0.2 10.0.0.3 10.0.0.4 hostname cat rat dog bat hw addr AA:AA BB:BB CC:CC DD:DD (for short) all connected by Ethernet in some simple way (i.e. no switches, no smart hubs). You're on cat, you have root and desire to break into dog. You know that dog trusts rat, so if you can successfully spoof rat, something can be gained. First thing that comes to mind (I think everybody was thinking about this at some point) is "why don't I set my IP to the IP of that other machine and..." That won't work, at least it won't work reliably. If you tell Ethernet driver on cat that it's IP is 10.0.0.2, it'll start answering ARP requests to that IP. But so will rat. It's a pure race condition, and there's no winner. However, you can easily be the loser, because this particular situation happens quite often when some box is misconfigured to use somebody's else's IP, so many implmentations immedeately notice that and loudly complain. Many network traffic analyzers flag that, too. Seeing a syslog message saying something nasty (mentioning cat's Ethernet address) on the LAN admin's console is not quite what you want. And what you want you won't necessarily get, that is getting anything remotely close to a working connection. This of course can be helped. The attached program, send_arp.c, can be a useful tool. Just as its name says, it sends an ARP packet [ARP reply, to be exact: since the protocol is stateless, reply will be happily accepted even if no one ever asked for it. Request would do just as well, though, because of the ARP caching logic] to the net, and you can make this packet to be what you want. What you want is an ability to specify source and target IP and hardware addresses. First, you don't want your Ethernet driver to talk too much, and it's easy to accomplish with ifconfig -arp. Of course, it'll need ARP info anyway, so you'll have to feed it to the kernel manually with arp(8). The critical part is convincing your neighbours. In the case being described here, you want dog to believe that rat's hardware address is that of cat (AA:AA), so you send ARP reply with source IP 10.0.0.2, source hw address AA:AA, target IP address 10.0.0.3 and target hardware address CC:CC. Now, for all dog knows, rat is at AA:AA. Cache entry would expire, of course, so it needs to be updated (request needs to be resent). How often depends on the particular system, but every 40 sec or so should be sufficient for most cases. Send it more often if you want, it won't hurt. A complication here could come from an ARP caching implementation feature. Some systems (e.g. Linux) would try to update their cache entries by sending a unicast ARP request to the cached address (like your wife calling you just to make sure you're there). Such a request can screw things up, because it could change victim's ARP entry that we just faked, so it must be prevented. This can be accomplished by feeding the "wife" system with replies so that it never has to ask for it. Prevention is the best cure, as always. This time, a real packet from dog to rat should be sent, it's just that cat will be sending it, not dog, but for rat there's no way to tell. Again, doing it about every 40 sec is usually OK. So the procedure is simple. Bring up an alias interface, e.g. eth0:1 (or use your current one, whatever), with rat's IP and ARP on -- you need to set up some cache entries first, and it won't work on non-arp interface. Set up a host route entry for dog through the right interface. Set up a cache entry for dog, turn off arp, and it's all set. Now, inject the venom with send_arp (hitting both dog and rat) and for all dog knows, you're on rat. Just remember to keep sending those ARP packets to dog and rat. This attack only works on the local network, of course (in general, it can reach as far as ARP packets can get, usually not too far because ARP packets are almost never routed). But an interesting extension here is taking this outside by replacing dog's hardware address in the above plan with the router's. If it works (I'm not sure it always will, router's ARP implementation may be tougher to fool, and since I don't want to try it on real routers, I don't know, but there's no simple reason why not) you can easily impersonate any machine on the local network to the rest of the world. So the target machine could really be anywhere, but the machine you're impersonating must be on the same LAN. [ -What else can be done- ] Aside from spoofing, there's range of other things you can do with ARP. The sky is really the limit here. DoS is the most obvious application. Feeding victim wrong hardware address is a powerful way to make it mute. You can prevent it from talking to any particular machine (and ARP cache size usually allows for the whole network to fit in, so effectively you can stop it from talking to everybody for some time). Obvious target would be the router. Cache poisoning again should be two-way: both the victim system and the system you don't want victim to talk to should be fed. The simplest case would be feeding a non-existant address. It's not the most efficient, though, as the system will quickly realize that it's talking to nobody and send out an ARP request. Of course, your next drop of poison will nullify this, but you have to do it quite often. A more efficient approach here is feeding the victim with the hardware address of the wrong machine, which itself is alive and well. Again, it depends on a particular situation, but very often what happens is that victim keeps sending out packets of various types that arrive to the wrong destination, and destination system will promptly send ICMP Xxx Unreachable messages back, thus emulating a connection in some perverted way. This pseudo-conection can easily postpone cache expiry. On Linux, for example, pseudo-connection raises cache expiry from usual 1 min to about 10 min. By that time, most or all TCP connections are screw up. Could be quite annoying. This way, one ARP packet can screw someone. An interesting twist here is so-called "gratuitous ARP". It's when the source and target IPs in the ARP request are the same, and it usually appears in a form of an Ethernet broadcast. Some implementations recognize it as a special case, that of a system sending out updated information about itself to everybody, and cache that request. This way one packet could screw up the entire network. It must be admitted, though, that gratuitous ARP is not really defined as a part of ARP, so it's up to vendor to (not) implement it, and it's becoming increasingly less popular. ARP is a serious tool for professional practical jokes, too. Just imagine somebody setting up a relay, or tunnel, in a form of own machine that convinced two neighbours to send their packets intended for each other to relay's Ethernet. If relay just forwards packets to their real destinations, no one would even notice. However, some simple data stream modifications could have quite a spectacular effect on one's mental health. A simple, CPU-inexpensive "filter" could be swapping random two bytes at irregular long intervals. If it hits the data portion, most of the checksums won't change, i.e. data stream would seem to be intact, yet strange and unexplicable things _will_ happen for no apparent reason. [ -ICMP redirects- ] An effect somewhat similar to ARP cache poisoning can be achieved in a different way, again using a legitimate protocol feature, ICMP route redirects. Such a redirect is normally sent by the default router to the system to indicate that there's a shorter route to some particular destination. Originally, both network and host route redirects were proposed, but later net redirects were deprecated and now are usually treated as host redirects. Properly constructed ICMP packet that passes all sanity checks (it must come from the default router for the destination it's redirecting, new router should be on a directly connected network, etc.) it causes a host-route entry be added to the system routing table. The concept is just as secure as ICMP itself, i.e. (security)NULL. Spoofing routers IP address is simple, and attached icmp_redir.c does just that. Host Requirements RFC states that system MUST follow ICMP redirects unless it's a router. And indeed all the systems I've tried happily accept it (except vanilla Linux 2.0.30, where it's broken, it works in 2.0.29 and 2.0.31pre9, according to Alan Cox). ICMP redirects present a rather potent DoS. Unlike ARP cache entries, those host routes won't expire with time. And of course no access to local network is required, attack can be launched from anywhere. So if the target system does accept ICMP redirects (and packets can actually reach it) that system can be stopped from talking to any particular address on the net (well, not all, but those that aren't on the same subnet with the target). Nameservers would be an obvious target. [ -What can be done about it- ] ARP is low level protocol and as such is usually hidden from normal people. LAN admins may be concerned with it at times, but if all goes well no one pays attention. One can always inspect contents of ARP cache using arp(8), especially if there's some misterious network problem, but again it's not the first thing that comes to mind. Even W95 has arp command, and remembering about it may be helpful in certain situations. However, if you're the target of the attack originating from another network via gateway arp spoofing, there's no way to tell. Similarly, host routing table could be examined to spot ICMP-generated entries (in most versions of route(1) they are marked with D letter in flags field). Just be aware. The above ARP attack scheme work perfectly for plain old 10Base2 Ethernet. However, if machines are interconnected in some more advanced way, particularly using some smart hubs or switches, attack can be more visible or even impossible (same goes for passive attacks). So there's yet another reason to invest in a goo