History
Smurf.c(by TFreak) hit the spotlight 20 years ago this month(Oct 1997). To give you an idea of the times, this was before social media was even a thing. This was a time when the internet was still cool. IRC, ICQ, and later AIM were really the only avenues of communication worth using. Unlike today, back then a “report” button was not nearly as common. So when conflicts erupted, people got creative. As a result, you would find people used Denial of Service to express their anger. Someone talks some trash, another guy responds, and then someone’s connection times out for 10-15 minutes.
But this attack was different. This was the first legitimate Distributed Denial of Service attack tool. It had not occurred to me until writing this, that I have never seen him credited for this. Thinking back, I can’t think of anything that existed to do this prior. Mstream, TFN2k, Stachel, etc. all came out after 2000. Sure there were DoS tools, and people ran them manually from multiple machines, but nothing on this level.
How it works
When you subnet a network, you lose three IPs: Network, Gateway, and Broadcast. To get directly to the point, the broadcast address is an IP that will send what it receives to ALL hosts on its subnet. There really is no reason for this traffic to leave your network, nor for your broadcast to accept traffic from outside of your network. So, it is fairly common for this to be restricted these days. But back then, this attack didn’t exist yet.
What if I were to send an ICMP(ping) packet to that broadcast address? The broadcast will pass that ICMP request on to every host on the subnet, and they will all respond. This doesn’t normally make a difference, unless there are hundreds or thousands of hosts on those subnets. In that case, we would get hundreds or thousands of responses just by pinging one address.
Ok, so doesn’t that flood us instead of our victim? Because we made the request? Yes. But the trick here is we spoof the victims IP as the source. So all of thoses hosts respond to our target, instead of us. Then, instead of sending one packet, we send as many as we can. Then we effectively create a DDoS attack.
This doesn’t still exist right?
[root@b08s02ur ~]# ping 212.1.45.255
PING 212.1.45.255 (212.1.45.255) 56(84) bytes of data.
64 bytes from 212.1.45.129: icmp_seq=1 ttl=54 time=112 ms
64 bytes from 212.1.45.203: icmp_seq=1 ttl=55 time=112 ms (DUP!)
64 bytes from 212.1.45.154: icmp_seq=1 ttl=54 time=112 ms (DUP!)
64 bytes from 212.1.45.93: icmp_seq=1 ttl=54 time=112 ms (DUP!)
64 bytes from 212.1.45.126: icmp_seq=1 ttl=54 time=112 ms (DUP!)
64 bytes from 212.1.45.80: icmp_seq=1 ttl=55 time=112 ms (DUP!)
64 bytes from 212.1.45.72: icmp_seq=1 ttl=55 time=113 ms (DUP!)
64 bytes from 212.1.45.32: icmp_seq=1 ttl=54 time=113 ms (DUP!)
64 bytes from 212.1.45.151: icmp_seq=1 ttl=54 time=113 ms (DUP!)
64 bytes from 212.1.45.131: icmp_seq=1 ttl=55 time=113 ms (DUP!)
64 bytes from 212.1.45.237: icmp_seq=1 ttl=54 time=113 ms (DUP!)
64 bytes from 212.1.45.117: icmp_seq=1 ttl=54 time=113 ms (DUP!)
64 bytes from 212.1.45.90: icmp_seq=1 ttl=54 time=114 ms (DUP!)
64 bytes from 212.1.45.87: icmp_seq=1 ttl=54 time=114 ms (DUP!)
64 bytes from 212.1.45.86: icmp_seq=1 ttl=55 time=114 ms (DUP!)
64 bytes from 212.1.45.94: icmp_seq=1 ttl=55 time=114 ms (DUP!)
64 bytes from 212.1.45.128: icmp_seq=1 ttl=54 time=114 ms (DUP!)
64 bytes from 212.1.45.88: icmp_seq=1 ttl=55 time=114 ms (DUP!)
64 bytes from 212.1.45.47: icmp_seq=1 ttl=55 time=114 ms (DUP!)
64 bytes from 212.1.45.59: icmp_seq=1 ttl=54 time=114 ms (DUP!)
64 bytes from 212.1.45.85: icmp_seq=1 ttl=55 time=114 ms (DUP!)
64 bytes from 212.1.45.181: icmp_seq=1 ttl=54 time=117 ms (DUP!)
64 bytes from 212.1.45.58: icmp_seq=1 ttl=54 time=118 ms (DUP!)
64 bytes from 212.1.45.49: icmp_seq=1 ttl=54 time=118 ms (DUP!)
64 bytes from 212.1.45.39: icmp_seq=1 ttl=53 time=129 ms (DUP!)
64 bytes from 212.1.45.111: icmp_seq=1 ttl=52 time=129 ms (DUP!)
64 bytes from 212.1.45.251: icmp_seq=1 ttl=52 time=130 ms (DUP!)
64 bytes from 212.1.45.156: icmp_seq=1 ttl=52 time=130 ms (DUP!)
64 bytes from 212.1.45.202: icmp_seq=1 ttl=244 time=130 ms (DUP!)
64 bytes from 212.1.45.146: icmp_seq=1 ttl=53 time=133 ms (DUP!)
64 bytes from 212.1.45.132: icmp_seq=1 ttl=53 time=133 ms (DUP!)
64 bytes from 212.1.45.6: icmp_seq=1 ttl=245 time=150 ms (DUP!)
c^C
--- 212.1.45.255 ping statistics ---
2 packets transmitted, 1 received, +31 duplicates, 50% packet loss, time 1001ms
rtt min/avg/max/mdev = 112.814/118.956/150.128/9.072 ms
[root@b08s02ur ~]#
It does in fact still exist. Not nearly to the extent that it once did, but one could still pull off a decent 30x amplified DDoS attack. After this attack, it became common practice for Network Administrators to use “no ip directed-broadcast”, or to use ACLs to prevent their broadcast addresses from being exposed externally. While this takes the bite away from smurf.c, it doesn’t solve the problem as a whole.
The bigger problem.
Years later the concept evolved to be more broadly referred to as a Reflection Attack. At this point a decent Reflection Attack can be achieved with DNS/NTP/PORTMAP/SNMP/LDAP/CHARGEN services. Anything that does not require acknowledgement, can be used to pull off a reflection attack. A TCP service cannot be used, because of how the TCP 3-way handshake works. We can spoof the SYN packet, but the SYN_ACK, would never reach us(In order to send the ACK). Sure, we could cause a syn_ack flood, but that does not provide us with any amplification. As such, you will find most of the things exploited these days for reflection/amplification attacks will be UDP. The goal being for the response to be bigger than the request.
How is this being resolved?
The responsibility to prevent this type of attack has fallen to the ISPs. ISPs now use ACLs to block spoofing entirely. This prevents people from changing the source IP in the packet before it gets routed. If you can’t spoof the source, you can’t cause a Reflection Attack.
To get an idea of how far along the project is, check out the spoofer project by CAIDA.
The Code
The version of smurf.c we find most often is version 4 based on TFreak’s comments. However, there was a later rendition he put together called papasmurf.c.
As a tribute to the 20th anniversary, I went ahead and wrote a shitty smurf broadcast scanner
A little extra
While writing this post, I was curious about who TFreak was and where he is now. Unfortunately it appears I am seven years too late. It looks like TFreak suffered from epilepsy and died in 2010. Thank you TFreak. As a kid on EFNet in the 90’s, in some weird way, you helped shape my childhood.