Unicornscan

From SecurityForest


Original Test available at: http://www.dyadsecurity.com/unicornscan/getting_started.txt

This getting started guide is intended to cover some of the basics of using Unicornscan from the perspective of a security tester.

Unicornscan is licensed under the GNU General Public License (GPL) and can be downloaded free of charge from http://www.unicornscan.org. It comes as source code and should compile on Linux, Solaris, NetBSD, OSX and FreeBSD. The next release will also compile on HP-UX and AIX. We have also included assembly code to make it work with Sun, HP and IBM hardware. We are creating a web based front end for use with any modern browser. As of this writing, the current stable version, is 0.4.2. There is a php/html front end with a relational database back-end available (see the README.database for clues how to play with this now); however, this file will focus on using Unicornscan from the command-line.

Table of contents

Section 1 - using the tool

The usage syntax of Unicornscan can be fairly simple. To get help, use the command-line -h or --help options. Different types of modes of scanning are specified with the -m flag. A TCP SYN scan, for example, is "-mT", which coincidently is the default mode. Options are then specified, followed by the hosts or networks to be targeted.

Unicornscan must be run as root. For security reasons, we recommend using an OS that supports Mandatory Role Based Access Controls (RBAC), such as SE Linux (http://www.nsa.gov/selinux/index.cfm). In a non-rbac OS, shortly after execution Unicornscan will change effective UID to nobody inside of a chrooted environment. This is done to limit inherent risks in taking arbitrary user input off of the wire.

Unicornscan is meant for testing extremely large networks, and will take CIDR notation as target input. To scan a single IP you would specify 192.168.1.1/32. For a "class B" sized network, you would specify 172.16.0.0/16, etc. See http://public.pacbell.net/dedicated/cidr.html for more information on CIDR representation.

Unicornscan can be used as a very fast, very scalable port scanner. It uses CPU specific instructions to track the packets per second you specify as closely as possible. From a single Pentium system, it is typical to be able to generate up to 40,000 pps or more. The pps limit will scale with your architecture accordingly. This single system pps limit is an artificial limit however as we have also built in an InterProcess Communications (IPC) channel to allow for scaling between multiples of scanners working together. Because of the great speed and pps generation potential, an increased sophistication will be required to properly harness the power of Unicornscan.

If you follow the OSSTMM (www.osstmm.org) 2.1 methodology for security testing, Section C covers Internet Technology Security testing. The very first step is Logistics and controls into the target network.

For Unicornscan, proper logistics and controls involves calculating the bandwidth and packets per second limits you have from the network you are testing from and the bandwidth and packets per second limits on the target network. With Unicornscan the -r option will specify the rate at which we send packets. An ultra conservative number to start with is 150 pps or -r150. Other common speeds used are 250, 1000, 5000, 7500, and 10000. Warning, 10,000+ packets per second can crash many internetworking devices, even big expensive devices. Be careful :). This is especially true for local NAT devices. I have seen SOHO boxes run out of state table in as little as 100+ pps. Port scanning through NAT devices can really be painful. To get the full power, scan from a machine with as few networking devices in it's way as possible.

Because Unicornscan is forging packets for us independent of what the kernel is expecting to deal with, we have included a secondary program called fantaip. Fantaip is a "Phantom IP" program that listens on a secondary IP address that we will use to receive response information to without confusing the kernel. To use fantaip, type 'fantaip (interface) (ip)', Ex., 'fantaip eth0 192.168.140.53'.

For internal network testing, you may run into ARP issues when testing large networks. To counteract this, you may consider tweaking how the kernel handles ARP timeouts. In Linux:

echo 8192 > /proc/sys/net/ipv4/neigh/default/gc_thresh1
echo 32768 > /proc/sys/net/ipv4/neigh/default/gc_thresh2
echo 65536 > /proc/sys/net/ipv4/neigh/default/gc_thresh3

That is really more of a kludge than anything else... it helps you not run out of space in your ARP tables. We're going to completely rewrite how we handle ARP for use in internal networks. For now this is better used from an "external" perspective. Just make sure that the network you're trying to scan is on a separate segment than you and you'll be able to go full speed. Otherwise, you'll be slowed down by ARP storms.

Now that fantaip is running, and we've modified the ARP behavior, we're ready to start our first test. Let's say for example that you wanted to search the 192.168.142.0/24 space for DNS servers and we are scanning from the IP address of 192.168.140.53. We would type:

# unicornscan -r200 -mU 192.168.142.0/24:53 -s 192.168.140.53 -p
Added 192.168.142.2 src port 53 ttl 64
Added 192.168.142.3 src port 53 ttl 64
Added 192.168.142.4 src port 53 ttl 64
Added 192.168.142.159 src port 53 ttl 64
Added 192.168.142.252 src port 53 ttl 64
Added 192.168.142.66 src port 53 ttl 64
Added 192.168.142.95 src port 53 ttl 64
average `196.40' packets per second at end of run
Open              domain[   53]         From 192.168.142.2      ttl 64
Open              domain[   53]         From 192.168.142.3      ttl 64
Open              domain[   53]         From 192.168.142.4      ttl 64
Open              domain[   53]         From 192.168.142.66     ttl 64
Open              domain[   53]         From 192.168.142.95     ttl 64
Open              domain[   53]         From 192.168.142.159    ttl 64
Open              domain[   53]         From 192.168.142.252    ttl 64
[RECV][Verbose recv_udp.c:308] Packets received: 116 Packets Dropped: 0 Interface Drops: 0

Broken down, that calls the program, sets the pps rate to 200 pps, sets the mode to UDP, sets the target range to 192.168.142.0/24:53, sends the packets from the 192.168.140.53 IP address, sets the scanner to "impatient mode" which makes it print "added" for every response packet as it receives response data. We only see the Open ports for which we received a response from the stimulus we introduced.

To see all of the responses, we specify the -E option:

# unicornscan -r200 -mU 192.168.142.0/24:53 -s 192.168.140.53 -p -E
Closed            domain[   53]         From 192.168.142.1      ttl 255
Open              domain[   53]         From 192.168.142.2      ttl 64
Open              domain[   53]         From 192.168.142.3      ttl 64
Open              domain[   53]         From 192.168.142.4      ttl 64
Closed            domain[   53]         From 192.168.142.5      ttl 64
Closed            domain[   53]         From 192.168.142.6      ttl 64
Closed            domain[   53]         From 192.168.142.7      ttl 64
Closed            domain[   53]         From 192.168.142.8      ttl 64
Closed            domain[   53]         From 192.168.142.9      ttl 64
Closed            domain[   53]         From 192.168.142.10     ttl 128
Closed            domain[   53]         From 192.168.142.11     ttl 64
Closed            domain[   53]         From 192.168.142.15     ttl 128
Closed            domain[   53]         From 192.168.142.18     ttl 64
Closed            domain[   53]         From 192.168.142.21     ttl 64
Closed            domain[   53]         From 192.168.142.22     ttl 64
Closed            domain[   53]         From 192.168.142.23     ttl 64
Closed            domain[   53]         From 192.168.142.24     ttl 64
Closed            domain[   53]         From 192.168.142.25     ttl 64
Closed            domain[   53]         From 192.168.142.27     ttl 64
Closed            domain[   53]         From 192.168.142.34     ttl 128
Closed            domain[   53]         From 192.168.142.36     ttl 128
Closed            domain[   53]         From 192.168.142.45     ttl 64
Closed            domain[   53]         From 192.168.142.46     ttl 128
Closed            domain[   53]         From 192.168.142.53     ttl 64
Closed            domain[   53]         From 192.168.142.62     ttl 64
Open              domain[   53]         From 192.168.142.66     ttl 64
Closed            domain[   53]         From 192.168.142.67     ttl 64
Closed            domain[   53]         From 192.168.142.69     ttl 64
Closed            domain[   53]         From 192.168.142.70     ttl 64
Closed            domain[   53]         From 192.168.142.71     ttl 64
Closed            domain[   53]         From 192.168.142.74     ttl 64
Closed            domain[   53]         From 192.168.142.77     ttl 64
Closed            domain[   53]         From 192.168.142.79     ttl 64
Closed            domain[   53]         From 192.168.142.92     ttl 128
Closed            domain[   53]         From 192.168.142.93     ttl 128
Open              domain[   53]         From 192.168.142.95     ttl 64
Closed            domain[   53]         From 192.168.142.96     ttl 64
Closed            domain[   53]         From 192.168.142.103    ttl 128
Closed            domain[   53]         From 192.168.142.104    ttl 128
Closed            domain[   53]         From 192.168.142.105    ttl 64
Closed            domain[   53]         From 192.168.142.109    ttl 128
Closed            domain[   53]         From 192.168.142.123    ttl 64
Closed            domain[   53]         From 192.168.142.130    ttl 64
Closed            domain[   53]         From 192.168.142.136    ttl 64
Closed            domain[   53]         From 192.168.142.137    ttl 64
Closed            domain[   53]         From 192.168.142.138    ttl 64
Closed            domain[   53]         From 192.168.142.140    ttl 128
Closed            domain[   53]         From 192.168.142.142    ttl 64
Closed            domain[   53]         From 192.168.142.144    ttl 64
Closed            domain[   53]         From 192.168.142.151    ttl 64
Open              domain[   53]         From 192.168.142.159    ttl 64
Closed            domain[   53]         From 192.168.142.161    ttl 64
Closed            domain[   53]         From 192.168.142.188    ttl 64
Closed            domain[   53]         From 192.168.142.195    ttl 128
Closed            domain[   53]         From 192.168.142.197    ttl 128
Closed            domain[   53]         From 192.168.142.198    ttl 64
Closed            domain[   53]         From 192.168.142.213    ttl 64
Closed            domain[   53]         From 192.168.142.230    ttl 64
Closed            domain[   53]         From 192.168.142.231    ttl 64
Closed            domain[   53]         From 192.168.142.232    ttl 64
Closed            domain[   53]         From 192.168.142.233    ttl 64
Closed            domain[   53]         From 192.168.142.234    ttl 64
Closed            domain[   53]         From 192.168.142.235    ttl 64
Closed            domain[   53]         From 192.168.142.240    ttl 255
Closed            domain[   53]         From 192.168.142.242    ttl 64
Closed            domain[   53]         From 192.168.142.247    ttl 64
Closed            domain[   53]         From 192.168.142.248    ttl 64
Closed            domain[   53]         From 192.168.142.249    ttl 64
Closed            domain[   53]         From 192.168.142.251    ttl 64
Open              domain[   53]         From 192.168.142.252    ttl 64
Closed            domain[   53]         From 192.168.142.253    ttl 255
Closed            domain[   53]         From 192.168.142.254    ttl 255 

Closed here means we received an ICMP Type 3 code 3 packet from the IP listed in the From column. Any other ICMP response would come up with it's Type and Code listed in the T##C## format. Ex., if we got a Destination Unreachable, Communication Administratively Prohibited ICMP packet, it would be shown as T03C13. We also show the ttl value, as it is the unmolested value we saw on the packet we received.

It should be noted that using multiple pieces of software that pick up packets off of the wire you will diminish your accuracy in scanning. Also, you will see really strange results if you are performing a lot of other scans at the same time. If you can't get around that requirement, all of your scans will be tainted and less reliable.

(insert talk on forward vs reverse ttl values)

What is happening here with the UDP scan is very different than traditional UDP scanning. In traditional UDP scanning, the scanning machine will send a UDP packet with a blank datagram to the target IP. It hopes to receive an ICMP packet back telling the scanner what state the port is in. If it receives an ICMP T3C3 back from the IP it sent the packet to, the scanner will mark it closed. If it receives an ICMP T3C3 from any other IP, it will mark the packet firewalled (or filtered). If it receives an ICMP T3C13 from any IP, it will mark the packet firewalled (or filtered). If it gets nothing back, the scanner will mark the packet open.

Unicornscan supports the concept of actually speaking the protocol of the application you are trying to enumerate. In this case, DNS, we have 3 payloads that are tried on each host on UDP port 53 to enumerate a response. We watch for any response and only count a response from a source port source IP combination once. One of the payloads tries to do a "localhost A record" request. Another payload tries a chaos.txt request. The last payload is a dynamic payload that will insert the IP address that you are scanning into the packet to do a reverse lookup of the target IP.

We currently have over 54 such UDP payloads in the configuration file. We cover the most commonly used UDP based protocols, and can add any additional protocol handshake as they are submitted to us. The payload trigger is not the only important piece for UDP scanning. You also need to be mindful of which source port, dst port combinations are required for the protocol. There are some payloads which must be generated "just in time" to be effective.

For vanilla TCP SYN scanning we can use the -mT option:

# unicornscan -r200 -mT www.yahoo.com/29:80 -s 205.217.153.53 -p
Added 66.94.230.32 src port 80 ttl 52
Added 66.94.230.33 src port 80 ttl 52
Added 66.94.230.34 src port 80 ttl 52
Added 66.94.230.35 src port 80 ttl 52
Added 66.94.230.36 src port 80 ttl 52
Added 66.94.230.37 src port 80 ttl 52
average `196.25' packets per second at end of run
Open                http[   80]         From 66.94.230.32       ttl 52
Open                http[   80]         From 66.94.230.33       ttl 52
Open                http[   80]         From 66.94.230.34       ttl 52
Open                http[   80]         From 66.94.230.35       ttl 52
Open                http[   80]         From 66.94.230.36       ttl 52
Open                http[   80]         From 66.94.230.37       ttl 52
[RECV][Verbose recv_tcp.c:316] Packets received: 9 Packets Dropped: 0 Interface Drops: 0

Section 2 - Other fun features

We included a -w option for unicornscan which works much like the -w option from tcpdump. This allows you to write all of the response data collected to a pcap file to parse later if you need to.

We noticed that sometimes in scanning you will see response data that you just don't care about. We included the -P option as a way to specify additional filters. For example if you wanted to exclude responses from the host 192.168.5.16, you would add '-P "not host 192.168.5.16"'. This can be really useful if you find yourself being overtaken by SNMP traps!

).

The -R option allows you to specify how many times to repeat sending a packet to the target range. -R3 is a sane number to start with as it will provide for 3 sweeps into the target range. Although the packets will go out 3 times, and you will likely get responses 3 times, the output will only show you the response once. Again, you can check the pcap file you wrote to with the -w option to validate what is seen. Also the -R option combined with the -r option can lead to DoS conditions. Also fun is specifying a source IP of r, for random. This would make a Windows host based firewall have fun as the entire Internet is now attacking them :) Be careful! :).

Different kernels have different implementations of the TCP/IP stack. These differences make up the "fingerprint" characteristics that tools like p0f, ids, firewalls, etc look at to determine the OS that created the packet. Because we are crafting the packets outside of the kernel, we can use what ever characteristics we want. We included 7 in the 0.4.2 release for fun, cisco, openbsd, WindowsXP, p0fsendsyn, FreeBSD, nmap, linux, and Crazy lint tcp header (use with p0f hopefully) The OpenBSD one is funny because some OpenBSD firewall bigots will make special rules that only allow you to talk to them if you're coming from the right OS (OpenBSD in most cases). You can specify which one to send as with the -W option.

Some people like to do creative things with their TCP options in order to make wild and crazy variations in their scanning. They even give them cute names like maimon. We included the ability in the TCP options mode to specify what ever options you want. For example `-mTsFpU' would send tcp packets with NO SYN,FIN,NO Push,URG bits inside the tcp header. Quick cheat list here: If you want a SYN scan -mT If you want an ACK scan -mTsA If you want an Fin scan -mTsF If you want a Null scan -mTs If you want a nmap style Xmas scan -mTsFPU If you want a scan with all options on -mTFSRPAUEC If you want to create your own special type of scan, just play with the options and document the results. (see http://www.iana.org/assignments/tcp-header-flags for more info)

Different levels of -v, -vv, -vvv, -vvvv, etc may be helpful to troubleshoot what you are seeing. A single -v is nice to have the scanner report timing information from the scan.

Section 3 - The configuration file

I'll add more here very soon :)

Section 4 - Examples of how you can use unicornscan

unicornscan 172.16.0.0/24:a -r10000 -v
# The 172.16.0.0/24 says to scan 172.16.0.0-172.16.0.255
# The :a means scan ports 0-65535
# The -r says the packets per second rate, in this case 10000
unicornscan 172.16.19.0/24:69,123,161 -r1500 -p -v -mU
# The :69,123,161 means scan ports 69,123,161
# The -p says to show you partial output as the information is collected
# the -mU puts the scanner in UDP mode, which introduces protocol specific
# queries to the target systems.
unicornscan 10.23.0.0/22:161 -r1000 -p -v -mU -P "not port 162" -w snmp.pcap
# The -P allows you to specify additional PCAP filters, in this case we're
# saying to ignore all packets with a src/dst port of 162
# The -w allows you to specify a file to write the responses to a pcap file
unicornscan 10.0.0.0/16:53 -r5000 -p -v -w 10-dns.pcap -mU -P "net 10.0.0.0/16" -R3 -s 10.1.2.3
# The -R allows you to set the packet repeat option.  -R3 says 3 times.
# The -s allows you to set which IP to send from, in this case 10.1.2.3.
unicornscan 192.168.1.2/32:a -sr -R99999999 -r10000
# This is a silly command for fuzzing a box
# -sr means a source IP of random
# The high repeat (-R) just means send lots of packets
# The speed can be what ever you want, in this case 10000 pps
unicornscan www.yahoo.com/28:80 -e p0f
# Specifying a name will cause a gethostbyname call.  We will only use
# the 1st IP returned in the substitution.
# The -e allows you to specify output modules.  In this case p0f.
# The p0f module allows you to use the passive OS fingerprinting
# database provided by the p0f project.
# The p0f database is highly dependant upon how the initial SYN packets
# were created.  The -W option may be needed here in order to get all
# of the matches possible.  If the default results look wrong,
# try specifying -W3 (p0fsendsyn).

Section 5 - Final Thoughts

There are LOTS of other features included in this release that I'm not going to go into now, as we're still working on finishing 20-30 more fun features. If you want to be added to the distribution mailing list to be notified of unicornscan related announcements, send email to "unicornscan at dyadsecurity dot com" and we'll keep you up to date.

Advertisement