Simple Nomad
thegnome@razor.bindview.com
thegnome@nmrc.org
What It Is
A command-line anti-spoofing detection utility. The idea is simple -- if
you receive a packet that you suspect is spoofed, try to determine the
real TTL of the packet and compare it to the TTL of the packet you
received.
Installation and Usage
Make sure you have libpcap 0.4 and libnet 1.0 (later versions of these
programs may work, ymmv).
tar xvzf despoof*tgz
cd despoof*
gcc `libnet-config --defines` -o despoof despoof.c -lnet -lpcap
cp despoof /fave/dir/in/root's/path
Running despoof requires root access.
# ./despoof -h
USAGE:
./despoof [opts] [-d dev] [-i 0-3] [-l|p num ] [-s src] [-t sec] [-T TTL] target
opts are a h v
-a set ACK flag on TCP packets (does nothing on ICMP)
-h this help screen
-v verbose
-d device to grab local IP or sniff from, default is eth0
-l local port to bind to, default is 80
-p target port to send to, default is 80
-i inquery packet type to send/receive, types include the following:
1 tcp (default)
2 icmp echo
3 icmp timestamp
-s spoofed source address
-t time in seconds to wait for all replies (default 10)
-T TTL to test (required)
target (IP address or hostname)
While a lot of the options are self-explanatory, the rest of this README
covers most of the features and why they might be used.
Background
When an IP packet is sent on its merry way towards its destination, it is
assigned a Time To Live (TTL) value. This TTL number gets decremented at
each router or "hop" on the network along the way. If the number reachs
zero, the packet is discarded. This is a way to prevent packets from
staying out on the network lost in a routing loop looking for a destination
and wasting bandwidth.
In most implementations of TCP/IP, this number starts out fairly high,
and will typically have anywhere from a few hops (local network, or at
least to the ISP's gateway to the Internet) to two or three dozen hops to
reach the destination. Therefore there is usually an ample TTL number
assigned to handle possible routing changes between the source and
destination.
When an attacker is spoofing packets, the attacker is usually at a
different location than the address being spoofed, so it makes sense that
an attacker's TTL will be different from the spoofed address' real TTL.
If you check *immediately* after receiving the suspected spoofed packet,
odds are pretty good that the route between the source address and your
destination address have not changed, so it is a pretty good indication
that the packet has been spoofed if the TTL doesn't match.
Deployment
How would you go about deployment of despoof? If you have a firewall,
router, or Intrusion Detection System (IDS) that is capable of spawning
processes or issuing commands based upon certain events (and can trigger
off of the TTL), you can have it launch despoof. If your firewall,
router, or IDS can log information to a file with the TTL, you could
have a log watcher such as Swatch launch despoof to determine if a
packet is spoofed or not.
Most modern firewall, router, and IDS systems allow for fairly flexible
logging, and certainly any open-source system could be altered to ensure
that logs contain the proper info, such as the TTL.
While it is possible to use despoof for network forensics, the results
could be unreliable if enough time has past since you received the
packets.
Since despoof supports full IP spoofing itself (ironic but hey) it is
possible to send a packet to query the suspected spoofed address with
the original destination address as the source, and to match up the
proper source and destination ports. Optionally you can also set the
ACK flag (with a random sequence number).
Could a battle between IDS-triggered despoofs on different sites
happen? It is possible, but this is always a danger when implementing
any automated trigger response to a probe or attack. The best advice
I could give is to try and limit the amount of counterprobes to one
per suspect address.
Working with Scripts
Try running despoof manually to get a feel for the output. To ease in
integration into scripts, regular stdout will spit out messages with
one of three keywords -- NORMAL, WARNING, and ERROR. NORMAL means that
the TTL matched, WARNING means that the TTL did not match, and ERROR
means some error occurred trying to determine the TTL (such as a
timeout).
Spoofing Despoof
While I did try to make a fairly useful tool, despoof can be defeated in
a number of ways. For starters, a clever attacker could perhaps determine
the proper TTL for a site being spoofed, probably by sniffing near the
target or the forged source address. An attacker could also probe the
address being spoofed, and other addresses along the way, and perhaps
determine the TTL needed to make the final TTL at the target seem legit.
This would of course require a lot more networking skill than your
average script kid could muster, but is certainly not impossible.
An attacker could also *not* spoof the packets but adjust the TTL for
the attack packets only. Despoof would return a false positive.
Spoofing an address that is behind a firewall is another method that
would thwart despoof, if the firewall is blocking what we are sending,
which brings us to the next topic.
Firewalls, Routers, and Caveats
Despoof supports ICMP Echo, ICMP Timestamp, and TCP. Most scans and
floods will fall into the ICMP or TCP arena (I wish I could support
UDP, more on that in a minute). The reason both ICMP Echo and ICMP
Timestamp are both supported is because of firewalls and routers.
While it is common for ICMP Echo to be blocked, often ICMP Timestamp is
not. Therefore I included support for it for checking ICMP since both
will return the same TTL.
TCP packets can have both source and destination addresses as well as
port numbers adjusted, so filtering routers and some firewalls can be
bypassed if the proper parameters are set. It is recommended that if
you use full spoofing you set the ACK flag. Incoming SYN packets from
a port scan will get a false positive if you respond fast enough, but
it might be enough to get through a firewall on the remote end.
I wish I could add UDP support, but unsure how. The trick is to get a
UDP service on the target to send a packet, but since UDP is one-way,
how do you manage that? The typical scanning method for UDP is to send
a TCP ping to establish a RTT then send a UDP packet -- if you get an
ICMP UNREACH before the RTT expires then the port is closed. This in
itself is unreliable (hence the U in UDP, eh?) so getting the exact
service we need to cough up the goods is even harder. Firewalls and
routers complicate this issue as it is common to block most UDP ports.
Granted, if the TCP ping gets through it seems possible that a UDP
port *might*, but still.
TTL implementation is interesting. Typically a normal TCP session
starts with a TCP packet with a TTL of 64 (the same for UDP). If
the target TCP port is closed, the returned TCP RST packet will have
a TTL of 255. This means that using despoof without regards to the
ports being used could lead to some false positives.
In theory it should be possible to determine the delta hop count,
and adjust for the different between normal TCP and port closed
TCP (or even simply use ICMP). This is the next logical step for
despoof, although it will require more research. If UDP support
gets added, this is how it will be done. However there may be all
kinds of 'in the wild' nuances that will have to be uncovered,
*and* it assumes every vendor implements TTL the same.
Credits
Based on an idea first proposed by Donald McLachlan
[don@mainframe.dgrc.crc.ca]. His idea involved building a TTL map of
addresses around himself (network-wise), which could lead to some
interesting data in itself (similar to Bill Cheswick's mapping work).
Hopefully Don will publish a paper or put up a web page that explains what
he has in mind -- I'm not explaining it as fully as I probably should.
Todo
Add icmp unreachable support.
Add TCP sequence number support.
Add support for more TCP flags (such as SYN/ACK, ACK/FIN, etc).
Determine if a delta hop count can be used to check TTL.