Why do netcat scans for UDP ports always succeed?

nc may not be the best tool for testing port status. Have you tried nmap? It's actually a port scanner. I checked a file server on my home network and 127.0.0.1, both report that UDP port 40000 is closed.

nmap

# nmap -sU -p 40000 igor

Starting Nmap 7.01 ( https://nmap.org ) at 2016-08-18 18:27 EDT
Nmap scan report for igor (192.168.1.125)
Host is up (0.00027s latency).
rDNS record for 192.168.1.125: igor.swass
PORT      STATE  SERVICE
40000/udp closed unknown
MAC Address: 68:05:CA:3A:BF:B7 (Intel Corporate)

Nmap done: 1 IP address (1 host up) scanned in 0.53 seconds

Kernel + /dev

You can also use the kernel to do this like so. But nmap is probably better.

# timeout 3 cat < /dev/udp/example.com/40000

When I tried nc on the same server (igor) I was getting the same results as you. But I went back to try again, and now it returning no output (no succeeded message) and wireshark is showing "Destination unreachable" being sent back over ICMP. I don't understand any of this. But I'd switch to a different method of checking UDP port status.


UDP is a "connectionless" protocol. If you send a packet and you don't get a rejection (via ICMP), regardless of whether you get a reply or not, it's considered successful. Something quite common is a firewall blocking the target's ICMP rejection packets from being sent back to you (which is what netcat uses to know whether the port is closed, otherwise it thinks it's open).

Contrast this with TCP, which is statefull. A failure to receive a reply (ACK) is considered a failure within TCP (this usually shows up as "filtered"), as are negative replies (RST, which will show up as closed).

UDP: open|filtered closed TCP: open closed filtered