In a recent session with our team as part of our MDR Wednesdays program, we were discussing reconnaissance and the usage of port 0. Not surprisingly, quite a few persons were surprised to hear about port 0 and its usage in reconnaissance. This blog post is meant as an additional resource, to aid the understanding.
One of the first steps, any threat actor will perform in any attack, is reconnaissance. It is the first column in the MITRE ATT&CK Framework and similarly, it is the first task in the Cyber Kill Chain. That is how important this task is. This post is more around that "active" reconnaissance. To learn more about "passive" reconnaissance, see this link.
Additionally, to make this more realistic, we will use the world's most popular network scanning/mapping tool Nmap.
Now let's be clear, if you are in an enterprise, I expect you have a security team and firewalls deployed to prevent some of these reconnaissance measures. At the same time, it is quite possible you are in an enterprise but have misconfigured firewalls. Who knows! If you are in a small business with no security team, I would not be surprised if you have not mitigated these reconnaissance measures.
Enough talking and let's get going. Before getting to why a threat actor may target port 0, let's start off with the regular reconnaissance.
________________ _______________
| THREAT ACTOR | | TARGET |
| 10.0.0.110 | --------->>> | 10.0.0.100 |
|_______________| |______________|
Starting with the traditional "ping". Running Nmap with the -PE option, we see from Nmap
┌──(kali㉿securitynik)-[~] └─$ sudo Nmap --send-ip -n 10.0.0.100 -sn -PE Starting Nmap 7.94SVN ( https://Nmap.org ) at 2024-01-30 22:30 EST Nmap scan report for 10.0.0.100 Host is up (0.00091s latency). MAC Address: 00:0C:29:A2:BB:D7 (VMware) Nmap done: 1 IP address (1 host up) scanned in 0.26 seconds
How does Nmap knows the host is up? Well if we look at tcpdump, output on the TARGET we see the following.
securitynik@seruritynik-srv:~$ sudo tcpdump -nnti ens33 'host 10.0.0.110 and icmp' tcpdump: verbose output suppressed, use -v[v]... for full protocol decode listening on ens33, link-type EN10MB (Ethernet), snapshot length 262144 bytes IP 10.0.0.110 > 10.0.0.100: ICMP echo request, id 59426, seq 0, length 8 IP 10.0.0.100 > 10.0.0.110: ICMP echo reply, id 59426, seq 0, length 8
As you can see from above, the echo request had an echo reply. Let's now go ahead and block these ICMP echo request on the firewall to prevent this type of reconnaissance.
securitynik@seruritynik-srv:~$ sudo iptables --table filter --append INPUT --proto icmp --in-interface ens33 --icmp-type 8/0 --jump DROP
The command above DROPs the packet. Note this is specific to ICMP Echo Request. Hence, the system will not respond with an ICMP Echo Reply.
Let's run Nmap again.
┌──(kali㉿securitynik)-[~] └─$ sudo Nmap --send-ip -n 10.0.0.100 -sn -PE Starting Nmap 7.94SVN ( https://Nmap.org ) at 2024-01-30 22:47 EST Note: Host seems down. If it is really up, but blocking our ping probes, try -Pn Nmap done: 1 IP address (0 hosts up) scanned in 2.08 seconds
Now Nmap is reporting 0 host up. Let's see what was seen via tcpdump on the target.
securitynik@seruritynik-srv:~$ sudo tcpdump -nnti ens33 'host 10.0.0.110 and icmp' tcpdump: verbose output suppressed, use -v[v]... for full protocol decode listening on ens33, link-type EN10MB (Ethernet), snapshot length 262144 bytes IP 10.0.0.110 > 10.0.0.100: ICMP echo request, id 55102, seq 0, length 8 IP 10.0.0.110 > 10.0.0.100: ICMP echo request, id 16092, seq 0, length 8
Great, we see that even though the ICMP Echo Request came in, there was no ICMP Echo Reply. Hence the reason why Nmap reported the host is not up.
Confirming the firewall dropped this traffic.
securitynik@seruritynik-srv:~$ sudo iptables --list INPUT --numeric --verbose Chain INPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 2 56 DROP icmp -- ens33 * 0.0.0.0/0 0.0.0.0/0 icmptype 8 code 0
So we confirmed the firewall is now dropping this traffic. Great! But guess what, if you looked at Nmap manpage, you see there are other techniques available to target ICMP. Let's go ahead with another.
This time, we try the Timestamp Request method.
┌──(kali㉿securitynik)-[~] └─$ sudo Nmap --send-ip -n 10.0.0.100 -sn -PP Starting Nmap 7.94SVN ( https://Nmap.org ) at 2024-01-30 22:59 EST Nmap scan report for 10.0.0.100 Host is up (0.00072s latency). MAC Address: 00:0C:29:A2:BB:D7 (VMware) Nmap done: 1 IP address (1 host up) scanned in 0.14 seconds
We see that the host is once again reported as up. We can also verify what Nmap received by looking at the target.
securitynik@seruritynik-srv:~$ sudo tcpdump -nnti ens33 'host 10.0.0.110 and icmp' tcpdump: verbose output suppressed, use -v[v]... for full protocol decode listening on ens33, link-type EN10MB (Ethernet), snapshot length 262144 bytes IP 10.0.0.110 > 10.0.0.100: ICMP time stamp query id 7808 seq 0, length 20 IP 10.0.0.100 > 10.0.0.110: ICMP time stamp reply id 7808 seq 0: org 00:00:00.000, recv 03:59:38.965, xmit 03:59:38.965, length 20
Great, so the pings we blocked did not prevent the ICMP reconnaissance so far. Let's now go ahead and block the Timestamp Request.
securitynik@seruritynik-srv:~$ sudo iptables --table filter --append INPUT --proto icmp --in-interface ens33 --icmp-type 13/0 --jump DROP
Trying the Timestamp reconnaissance again.
┌──(kali㉿securitynik)-[~] └─$ sudo Nmap --send-ip -n 10.0.0.100 -sn -PP Starting Nmap 7.94SVN ( https://Nmap.org ) at 2024-01-30 23:03 EST Note: Host seems down. If it is really up, but blocking our ping probes, try -Pn Nmap done: 1 IP address (0 hosts up) scanned in 2.08 seconds
Great, we seem to block this one also, as Nmap is once again reporting 0 host up.
Let's confirm at our firewall.
securitynik@seruritynik-srv:~$ sudo iptables --list INPUT --numeric --verbose Chain INPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 2 56 DROP icmp -- ens33 * 0.0.0.0/0 0.0.0.0/0 icmptype 8 code 0 2 80 DROP icmp -- ens33 * 0.0.0.0/0 0.0.0.0/0 icmptype 13 code 0
Great we are now blocking the Timestamp request. But Nmap also have the netmask request discovery. Let's try the last of these Nmap methods.
┌──(kali㉿securitynik)-[~] └─$ sudo Nmap --send-ip -n 10.0.0.100 -sn -PM Starting Nmap 7.94SVN ( https://Nmap.org ) at 2024-01-30 23:07 EST Note: Host seems down. If it is really up, but blocking our ping probes, try -Pn Nmap done: 1 IP address (0 hosts up) scanned in 2.07 seconds
Ooops! Nmap is reporting 0 host up. How could this be? We did not block this traffic. Let us see what the target host sees.
securitynik@seruritynik-srv:~$ sudo tcpdump -nnti ens33 'host 10.0.0.110 and icmp' tcpdump: verbose output suppressed, use -v[v]... for full protocol decode listening on ens33, link-type EN10MB (Ethernet), snapshot length 262144 bytes IP 10.0.0.110 > 10.0.0.100: ICMP address mask request, length 12 IP 10.0.0.110 > 10.0.0.100: ICMP address mask request, length 12
Well the host sees the request but there is no response. Why is this so? Well fortunately, in this case, there is nothing for us to do as this method seems to have been deprecated based on RFC 6918 sections 2.4 and 2.5.
However, a threat actor can try other mechanisms, such as specifically crafting a packet using scapy. Do keep in mind, there are a lot of these ICMP types and codes that have been deprecated, but depending on the system being targeted (older system?, IoT device?) some of these techniques may still succeed.
Now just to be clear, I only went through blocking those individual types for learning experience. The reality is, we could have done one line to block all ICMP, such as below.
securitynik@seruritynik-srv:~$ sudo iptables --table filter --append INPUT --proto icmp --in-interface ens33 --jump DROP securitynik@seruritynik-srv:~$ sudo iptables --list INPUT --numeric --verbose Chain INPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 DROP icmp -- ens33 * 0.0.0.0/0 0.0.0.0/0
If we run the commands above again all should be blocked. You should then see something such as below in your firewall table.
securitynik@seruritynik-srv:~$ sudo iptables --list INPUT --numeric --verbose Chain INPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 6 200 DROP icmp -- ens33 * 0.0.0.0/0 0.0.0.0/0
Ok. Now we have completed the initial part of understanding why we need to get to port 0.
Here we go! The firewall is blocking all ICMP traffic. However, we are still interested in simply knowing if the host is up. Let's figure that out.
First things first, there should never be any service running on port 0. For example, if we run netstat or in my case below ss, we see on this host:
securitynik@seruritynik-srv:~$ sudo ss --numeric --listening --tcp State Recv-Q Send-Q Local Address:Port Peer Address:Port Process LISTEN 0 4096 0.0.0.0:27017 0.0.0.0:* LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* LISTEN 0 128 0.0.0.0:22 0.0.0.0:* LISTEN 0 244 0.0.0.0:5432 0.0.0.0:* LISTEN 0 128 [::]:22 [::]:* LISTEN 0 244 [::]:5432 [::]:*
There is no port 0. So once again, why would an attacker port 0? Let's run Nmap to figure it out.
┌──(kali㉿securitynik)-[~] └─$ sudo nmap --send-ip -n 10.0.0.100 -Pn -p 0 --reason Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-01-30 23:27 EST Nmap scan report for 10.0.0.100 Host is up, received user-set (0.00052s latency). PORT STATE SERVICE REASON 0/tcp closed unknown reset ttl 64 MAC Address: 00:0C:29:A2:BB:D7 (VMware) Nmap done: 1 IP address (1 host up) scanned in 0.20 seconds
We see above Nmap is reporting 1 host up. We also see the reason it knows the host is up, is because it got a "reset". We can confirm at the target host that it did send a reset message.
securitynik@seruritynik-srv:~$ sudo tcpdump -nnti ens33 'host 10.0.0.110 and port 0' tcpdump: verbose output suppressed, use -v[v]... for full protocol decode listening on ens33, link-type EN10MB (Ethernet), snapshot length 262144 bytes IP 10.0.0.110.61475 > 10.0.0.100.0: Flags [S], seq 1785192689, win 1024, options [mss 1460], length 0 IP 10.0.0.100.0 > 10.0.0.110.61475: Flags [R.], seq 0, ack 1785192690, win 0, length 0
So what was the objective above? Even though we block the ICMP messages, from a reconnaissance perspective, the threat actor could target port 0, just to illicit this [R.] message. This confirms the host is online and hence the threat actor would have achieved the same objective as if he or she had pinged the host and got a response.
Let's close this off by blocking traffic coming in to port 0.
securitynik@seruritynik-srv:~$ sudo iptables --table filter --append INPUT --proto tcp --dport 0 --in-interface ens33 --jump DROP
Run the scan again
┌──(kali㉿securitynik)-[~] └─$ sudo nmap --send-ip -n 10.0.0.100 -Pn -p 0 --reason Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-01-30 23:32 EST Nmap scan report for 10.0.0.100 Host is up, received user-set. PORT STATE SERVICE REASON 0/tcp filtered unknown no-response Nmap done: 1 IP address (1 host up) scanned in 2.10 seconds
Now I find it strange above, that the REASON given is no-response but yet still Nmap is reporting 1 host is up. I take it this has to do with ARP. See the reference section for a discussion on this scenario. However, if you have a clearer answer, let me know.
If we look at the host, we can see the SYNs came in but no [R.] was sent.
securitynik@seruritynik-srv:~$ sudo tcpdump -nnti ens33 'host 10.0.0.110 and port 0' tcpdump: verbose output suppressed, use -v[v]... for full protocol decode listening on ens33, link-type EN10MB (Ethernet), snapshot length 262144 bytes IP 10.0.0.110.46295 > 10.0.0.100.0: Flags [S], seq 11534259, win 1024, options [mss 1460], length 0 IP 10.0.0.110.46297 > 10.0.0.100.0: Flags [S], seq 11403185, win 1024, options [mss 1460], length 0 IP 10.0.0.110.39645 > 10.0.0.100.0: Flags [S], seq 465318364, win 1024, options [mss 1460], length 0 IP 10.0.0.110.39647 > 10.0.0.100.0: Flags [S], seq 465449438, win 1024, options [mss 1460], length 0 IP 10.0.0.110.65137 > 10.0.0.100.0: Flags [S], seq 899162038, win 1024, options [mss 1460], length 0 IP 10.0.0.110.65139 > 10.0.0.100.0: Flags [S], seq 899293108, win 1024, options [mss 1460], length 0
We also see the firewall is dropping the Port 0 packets as while the SYN came in, there is no RST ACK.
I decided to try another trick, just in case for some strange reason the RST was being generated and I was not seeing it. This time, I configured the firewall to prevent the RST from leaving the device.
securitynik@seruritynik-srv:~$ sudo iptables --table filter --append OUTPUT --proto tcp --dport 0 --tcp-flags RST RST --out-interface ens33 --jump DROP
When I rerun the attack, targeting port 0, the output is basically the same. No RST. Which is what I expected because I blocked the port earlier.
securitynik@seruritynik-srv:~$ sudo tcpdump -nnti ens33 'host 10.0.0.110 and port 0' tcpdump: verbose output suppressed, use -v[v]... for full protocol decode listening on ens33, link-type EN10MB (Ethernet), snapshot length 262144 bytes IP 10.0.0.110.64965 > 10.0.0.100.0: Flags [S], seq 1541258948, win 1024, options [mss 1460], length 0 IP 10.0.0.110.64967 > 10.0.0.100.0: Flags [S], seq 1541390022, win 1024, options [mss 1460], length 0
Peaking into the firewall to see if any RST was generated and prevented from leaving, we see:
securitynik@seruritynik-srv:~$ sudo iptables --list OUTPUT --numeric --verbose Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 DROP tcp -- * ens33 0.0.0.0/0 0.0.0.0/0 tcp dpt:0 flags:0x04/0x04
Basically, the RST was not even generated and thus no opportunity to even be dropped.
Ok. I think we address the learnings for this example. No need to do anything else with this.
Main takeaway? Other than pings, threat actors can identify whether a host is live or not by using some seemingly simple reconnaissance techniques. We covered a few in this post. However, there are many more you can try on your own.
References:
Internet Control Message Protocol - Wikipedia
RFC 6918: Formally Deprecating Some ICMPv4 Message Types (rfc-editor.org)
Internet Control Message Protocol (ICMP) Parameters (iana.org)
Why I recived user-set on my Nmap analyze? - Information Security Stack Exchange
Learning by practicing: Stimulus and response revisited (securitynik.com)
MITRE ATT&CK®
Cyber Kill Chain® | Lockheed Martin
Learning by practicing: The importance of reconnaissance to the targeted threat actor (securitynik.com)
nmap(1) - Linux man page (die.net)
Learning by practicing: Building your own TCP 3-way handshake – Packet Crafting – The Scapy Way (securitynik.com)