In parts one and two we looked at the theory and practice that goes into port scans. In this post I’m going to cover off UDP scanning. As we covered the theory in part one, I’ll go through a (very) brief recap of the theory then I’ll do a deep dive into tools and techniques.
The relationship between UDP port scanning and ICMP
Unlike TCP, UDP is a stateless protocol. It was designed for speed in an era where reliability couldn’t always be guaranteed. Effectively, UDP is mostly designed to be used for applications that care more whether or not a packet is sent than whether or not it is received.
This presents a problem. If a host continuously sends UDP datagrams to a system that isn’t even listening, it could saturate a link. Without any congestion control all manner of bad things could happen. As a result, UDP has several features involving ICMP to assist.
When a datagram is sent to a host on a port that isn’t open, an ICMP Destination Port Unreachable message is sent back. This allows the system to know that a port is closed. There are many types of unreachable message, but they all use a Type of 3. The more common ICMP codes you may encounter when UDP scanning are:
- 0 – Network Unreachable
- 1 – Host Unreachable
- 3 – Port Unreachable
- 6 – Destination network unknown
- 7 – Destination host unknown
- 13 – Communication administratively prohibited
Codes 0, 1, 6 and 7 are typically sent from a router, while code 3 is normally sent from the host itself. Code 13 is usually sent from a misconfigured firewall or filtering router. Why does code 13 indicate the firewall is misconfigured? Because a firewall shouldn’t send anything to you.
So, when a port is closed we get an ICMP message. If there’s a problem accessing the network we get an ICMP message, if we get a poorly configured firewall or router between us and the target blocking us, we get an ICMP message. So far, so good, right?
UDP Port scans in the 21st century, or why we can’t have nice things
As the Internet became more popular, people started to realise that there were two problems with this approach:
- As UDP is stateless, it’s easy to spoof, using ICMP error messages to mask the source of a Distributed Denial of Service attack
- An assumption developed that UDP port scanning is bad, that it should be stopped and that it’s dependent on ICMP error messages
Both of these contributed to the primary ‘defence’ against UDP port scanning we see today, ICMP error rate limiting. I first encountered this on Solaris systems in the early 2000s, but it soon became popular on Linux. With 65,535 ports to scan and error rate limits of 1 ICMP message per second in some cases, it can take upwards of 9 to 18 hours to scan some hosts. While ICMP error rate limiting is a nuisance to the budding scanner, there are techniques we can use to make it less of an issue.
Firstly, we can scan multiple hosts at the same time. For larger networks, the more concurrent hosts you can scan, the less rate limiting will affect you. We can also try scanning popular ports first, and we can ignore ports that require us to speak specific protocols and scan those separately.
Packets sent to UDP ports will only solicit UDP responses when the underlying application receives a packet that causes it to respond. For example, scanning port 161 with blank UDP datagrams is a pointless and futile exercise if you want to determine if the port is open. However, brute forcing SNMP on port 161 is certainly worthwhile. Sending a blank datagram to UDP port 53 is pointless, but sending a correctly formed DNS query will solicit a response. As the cost (for want of a better term) of sending a probe with a valid port is the same as that of sending a blank datagram, we may as well send correctly formed probes for common ports.
When it comes to UDP services, quite often services in the IANA allocated port range are allocated both TCP and UDP ports with the same port number. A good example of this is DNS, which uses TCP port 53 for reliable communications such as zone transfers, and UDP port 53 for unreliable communications such as DNS queries and responses. If a TCP port is open, it’s a good candidate to scan. That’s not to say that you shouldn’t scan services where TCP ports aren’t open, it’s simply a reasonable indicator, especially for older protocols operating on IANA allocated ports.
Another way we can find open UDP ports is to query the RPC portmap service on Unix and Linux systems. If Sun RPC services are present, there will be a running portmap service that can tell us more about them. If we can query Windows DCE RPC services on TCP or UDP port 135, or over NetBIOS via the epmapper named pipe then we can ask the Windows system for a list of endpoint and registered ports. DCE RPC is a horrific trainwreck of a beast and I’ll cover that in another post. But the point is that there’s plenty of ways to enumerate services without enumerating services. As with Pokémon, you gotta catch ’em all.
There is one diversion from the standard UDP port scan approach. Older versions of Windows (and some configurations of current Windows systems) don’t implement ICMP error rate limiting. If you’re confident that you know which are Windows systems and which are not, you can split the scans out and scan Windows systems with a separate IP list. However, you should run the same scans across Windows and non-windows systems for consistency.
A strategy that I use is to split port scans by port. As with TCP port scans, I run low port scans first as this should be relatively quick, even with ICMP rate limiting. If you have to take your pentest equipment home overnight, expect to cover 10,000-25,000 ports per working day and split accordingly. If you can keep it running overnight, do so.
Some of you may notice that 10,000 ports at a rate limit of 1 per second implies under 3 hours of scanning time. While technically correct, it’s more or less impossible to distinguish between an open port and a filtered port (except in some cases, which I’ll talk about later). What will happen is that most port scanners will retry several times before giving up on a port, and this is what slows a scan down. More often than not you can’t significantly drop the amount of retries below 3 because ICMP error rate limiting is usually implemented as an increasing penalty, meaning that the error messages are dropped or limited by x milliseconds, then x+y milliseconds, so the scanner doesn’t know how much the rate limiting will be until the scan has settled, at which point you may have already gone through all the ports once.
Low UDP Port Scans
Bearing in mind what we know about assigned ports there are certain indicators that give away certain inferences about a system. For example, the presence of what are sometimes referred to as “Simple UDP Services” in Windows parlance, is often an indicator of a less than perfectly configured system from a security perspective. Likewise the most commonly identified low UDP ports are port 53 and 161, allocated for use by by DNS and SNMP respectively.
Unlike TCP, UDP’s stateless nature means that services (with the exception of portmapped services) are more likely to stick to common ports as a failed response is not indicative of a failed service at the other end of a connection. While it is possible to run a DNS server on an arbitrary port, most client DNS resolvers have a hard-coded target port of 53.
Nmap is particularly good at conducting accurate UDP scans. It’s not great at doing them quickly, but it is as accurate as you’re going to get. There are other port scanners that could provide quicker results but usually at the cost of accuracy compared to Nmap. Instead of using the SYN scan switch, we’ll use Nmap’s UDP scan switch, -sU. We’ll also use Nmap’s -sV switch, which tells nmap to send service/version probes. The full command line used is otherwise the same – nmap -sU -PN -n -iL $TARGETFILE -p 0-1024 -oA nmap/udp-lo -sV.
The first thing that you may find strange is that my scan took over 20 minutes. There’s no actual lag, it’s simply a product of rate limiting.
The second thing worth noticing is that nmap reports a lot of closed ports, and some as open|filtered. This simply means that nmap didn’t receive a response that could confirm whether or not the port was filtered or open. Usually this means that no response was received. In my results only 3 ports were listed as open – 53, 111 and 137, of which the first two were also present in the TCP port scan results.
Finally, nmap’s service detection information has incorrectly identified the target Linux system as running Microsoft Windows. This sometimes happens with UDP scans, as nmap will typically probe the netbios name service and look at responses to determine the OS. In most cases the netbios name service used in Samba will respond in a similar way to Microsoft’s implementation in Windows XP, sometimes fooling nmap.
Remaining UDP Port Scans
After seeing what we’ve seen, what do you think we might expect for the remainder of the ports? Is it significant that a very large number of open TCP ports were found? Will this have an impact on the number of open UDP ports? Lets take a look. The command line we’ll use for this is nmap -sU -PN -n -iL $TARGETFILE -p 1025-65535 -oA nmap/udp-full -sV.
As expected there were some high ports open, but if you look at the services in more detail you’ll find that these are almost exclusively used by Sun RPC services. On Windows systems you should expect to see some high ports in use by DCE RPC services, and other services such as 3rd-party backup utilities, or application services such as those found with SAP deployments.
Distinguishing between open, closed and filtered ports with UDP and IP
There are circumstances where it is possible to determine between open, closed and filtered ports. There are no guarantees, but we can use a combination of ICMP and IP to whittle things down. For example, we know that:
- An open port will respond to a correctly formed application message if the service is supposed to respond to that message
- A closed port will lead to an ICMP port unreachable from the device (or a similar destination unreachable message from a nearby device)
- A filtered port will occasionally result in a message, but more often than not, nothing
- If a packet’s TTL expires an ICMP TTL Expired In Transit message is sent from the router the datagram is currently passing through to the packet’s source
Knowing this, we can abuse the Time-To-Live (TTL) values in IP in order to determine information about the underlying network. If we know the TTL of the target host, firewall and upstream router and are able to solicit ICMP responses from each system, we can send datagrams to the target with TTLs set to expire at the router, firewall or host in order to determine where filtering occurs for a given port. The point where ICMP TTL expired messages stop coming back is usually the point where filtering takes place, as most filtering systems will drop ICMP entirely, or ICMP with the exception of echo reply messages.
UDP is an extremely simple protocol, but getting the most out of port scanning UDP requires a lot of flexibility. Although ICMP rate limiting is a royal pain to deal with, there are techniques you can use that minimise it’s impact. Understanding which protocols are likely to respond and which aren’t takes time and experience. Communicating with port mapping services, and looking at responsive TCP services can often provide an indicator of what open ports to expect.
In this post we looked at:
- The relationship between UDP port scanning and ICMP
- ICMP Rate limiting and ways to reduce it’s impact on port scans
- Low and remaining port scans
- Distinguishing between open, closed and filtered ports with UDP and IP
In the next installment of this guide, we’ll take a look at port mappers, what they are, how they’re useful from a port scanning perspective and how to interact with them to find running services. As always, feel free to send me your thoughts, comments or suggestions on twitter @stevelord. If you’d like to be notified of new Raw Hex posts and other pentesting tips, sign up to my mailing list below.