The ultimate network scanner nmap knows how to perform an UDP scan:
$ nmap -sU -p1-65535 <target>You can add useful options such as -sV (probe open ports to determine service/version info). The scan is much longer than a TCP scan, but sometimes it works. Yes, sometimes. Recently I started a simple UDP server (with socat) on a random port and challenged myself to find it within the whole 1-65535 range: I appeared to be unable to find it with nmap (I'm probably misusing nmap).
Let's go back to how UDP scanning works. The most common technique, well-described in nmap's Art of port Scanning, relies on ICMP port unreachable replies that the target may send after UDP packets sent to ports that are not opened. Thanks to these ICMP packets, we can deduce ports which can be opened. Note that the remote host has perfectly the right not to send these ICMP packets, so this technique could be useless in some situations (firewall?).
Let's see how ICMP port unreachable scanning works with this example: we try to send \n to UDP ports 1233,1234,1235 with socat, but only port 1234 is opened.
$ echo | socat - UDP:target:1233 socat E read(3, 0x80c3a68, 8192): Connection refused $ echo | socat - UDP:target:1234 $ echo | socat - UDP:target:1235 socat E read(3, 0x80c3a68, 8192): Connection refused
Here is the tcpdump display explaining what happened (C=Client, S=Server):
1. IP C > S.1233: UDP, length 1 2. IP S > C : ICMP A.B.C.D udp port 1233 unreachable, length 37 3. IP C > S.1234: UDP, length 1 4. IP C > S.1235: UDP, length 1 5. IP S > C : ICMP A.B.C.D udp port 1235 unreachable, length 37
You can see that the server did not reply any ICMP port unreachable for port 1234, giving us a hint that this port could be opened. Nmap should report this port as opened|filtered.
Ok then, why not spamming the target with many UDP packets and just see what are the replies? Because there is a throttle: the host will not reply to every packet. So we have to send our UDP packets not so fast - otherwise we'll miss some replies - and not so slow - otherwise the scan will last for days.
This is when we grab our favourite network packet manipulation tool scapy and with a single line, we can perform a very good UDP scan:
>>> ans,unans = sr(IP(dst='target')/UDP(dport=[(1,65535)]),inter=0.5,retry=10,timeout=1) .*..*.*..*. [...] Finished to send 65535 packets. Begin emission:..*..*.*..*. [...] Finished to send 500 packets. Begin emission:..*..*.*..*.. [...] Received 6553512 packets, got 65534 answers, remaining 1 packets (<Results: TCP:0 UDP:0 ICMP:65534 Other:0>, <Unanswered: TCP:0 UDP:1 ICMP:0 Other:0>) >>> unans.summary() IP / UDP source:sourceport > target:1234
Options to sr (send & receive packets at layer 3):
- inter: means the interval in seconds between packets sent
- retry: after all packets have been sent, those with no answer are sent once again
- timeout: maximum wait time after the last packet have been sent
see Scapy documentation for more information.