robertdavidgraham / masscan

TCP port scanner, spews SYN packets asynchronously, scanning entire Internet in under 5 minutes.
GNU Affero General Public License v3.0
22.97k stars 3.02k forks source link

UDP scan returning less results than nmap - only one payload per port sent #764

Open Zaptho opened 4 months ago

Zaptho commented 4 months ago

The issue

I noticed that masscan often does not find ports that are found by nmap (reason: udp response)

$nmap -p 123 -sU 192.168.1.123 -vv
Starting Nmap 7.93 ( https://nmap.org ) at 2024-02-22 12:55 UTC
[...]
Discovered open port 123/udp on 216.115.143.83
[...]

PORT    STATE SERVICE REASON
123/udp open  ntp     udp-response ttl 119
[...]
$masscan -pU:123 192.168.1.123
Starting masscan 1.3.9-integration (http://bit.ly/14GZzcT) at 2024-02-22 12:54:35 GMT
Initiating SYN Stealth Scan
Scanning 1 hosts [1 port/host]

Current behaviour

Masscan currently only scans UDP ports by sending one UDP request with one payload for each port. In contrast, nmap sends a UDP request for each payload in the payloads file per port. This results in masscan missing some open ports that nmap finds because masscan will only send a UDP request with the last payload of each port from the payloads file. This also explains, why in other issues a switch to a different masscan version fixed the issue - the used payloads file changed over time adding more payloads for specific protocol versions, thereby rendering the old payloads useless.

This behaviour is also documented at one section of the man page:

       •   --pcap-payloads: read packets from a libpcap file containing packets and extract the UDP  payloads,  and  associate
           those payloads with the destination port. These payloads will then be used when sending UDP packets with the match‐
           ing destination port. Only one payload will be remembered per port. Similar to --nmap-payloads.

       •   --nmap-payloads <filename>: read in a file in the same format as the nmap file  nmap-payloads.  This  contains  UDP
           payload, so that we can send useful UDP packets instead of empty ones. Similar to --pcap-payloads.

I was also able to confirm this behaviour using tcpdump even when specifying the nmap payloads file with --nmap-payloads <payloads-file>. (e.g. nmap sending two requests for NTP and masscan sending only one request with the last payload from the payloads file)

nmap:
12:59:16.714090 IP 192.168.1.111.51369 > mytarget.mytarget.com.ntp: NTPv4, Client, length 48
12:59:16.714112 IP 192.168.1.111.51369 > mytarget.mytarget.com.ntp: NTPv3, symmetric active, length 48
masscan:
13:01:52.156252 IP 192.168.1.111.46911 > mytarget.mytarget.com.ntp: NTPv3, symmetric active, length 48

some people suggested to just use the payload relevant to you in your payloads file. However, this does not work for me, since there are instances both (or more) payloads are needed to reliably detect open ports (e.g. ntp port 123 - NTPv3 and NTPv4 request - each one can only be used for the corresponding protocol version, not vice versa)

Suggested solution

Therefore, my idea for a solution would send a UDP request not only once for each port, but once for each payload for each port. The results then need to be joined in a way that prefers the open state over the closed state.

Once this is implemented, masscan should produce the same results as nmap (at least when specifying the same payloads file using the --nmap-payloads option).

Other related issues

https://github.com/robertdavidgraham/masscan/issues/182 https://github.com/robertdavidgraham/masscan/issues/587 https://github.com/robertdavidgraham/masscan/issues/647 https://github.com/robertdavidgraham/masscan/issues/643 https://github.com/robertdavidgraham/masscan/issues/639

bogi788 commented 3 months ago

I've openened #772 to should this.