Filtered: NMAP Port Scanner Sees Through IPtables Firewall

Submitted by Hannes Schmidt on Thu, 02/23/2006 - 15:02.

Ever wondered why port scanners like nmap are able to tell that some of the ports on your server are protected by a firewall? Have a peek at this nmap transcript:

Starting nmap 3.75 ( http://www.insecure.org/nmap/ ) at 2006-02-23 22:54 CET
Interesting ports on doodah.com (12.34.56.78):
(The 1658 ports scanned but not shown below are in state: closed)
PORT     STATE    SERVICE
21/tcp   open     ftp
22/tcp   open     ssh
53/tcp   open     domain
80/tcp   open     http
3306/tcp filtered mysql

I'm quite sure my firewall blocks access to the mysql port. Yet it bugs me that it is possible to tell that I have MySQL installed on my system simply by performing a port scan. Assuming that I am sane and do not filter unused ports [Wait a minute! - This might be good idea, actually ...]

Anyway, how is that possible? The answer lies in the way the firewall (in my case that would be iptables) responds to connection requests. If the firewall rule's target is DROP, the packet will be ignored. Sounds good, doesn't it? Wait! When a connection request arrives at a port at which no application is listening, the operating system responds to that request with a TCP RST packet. This is different to what happens if a connection request is made at port that is filtered using DROP. Thus, a clever port scanner can conclude whether a port is simply unused (a RST response) or filtered (no response).

Right, you say, let's use REJECT instead of DROP. Wrong, I say, because REJECT issues an ICMP Port Unreachable response. Darn it!

So how do we conceal the port properly? Luckily, IPtables has the --reject-with tcp-reset option that can be used in conjunction with the REJECT target in order to specify that connection requests should be handled using TCP RST, just like a connection to an unused port would be treated. Simply end your firewall rules with

-j REJECT --reject-with tcp-reset

and port scans will report the filtered port as "closed":

Starting nmap 3.75 ( http://www.insecure.org/nmap/ ) at 2006-02-23 22:56 CET
Interesting ports on doodah.com (12.34.56.78):
(The 1659 ports scanned but not shown below are in state: closed)
PORT   STATE SERVICE
21/tcp open  ftp
22/tcp open  ssh
53/tcp open  domain
80/tcp open  http

Nmap run completed -- 1 IP address (1 host up) scanned in 1.374 seconds

Sweet!

( categories: Unix | Administrator )
Submitted by Hannes Schmidt on Thu, 07/13/2006 - 23:56.

I get your point. But this article is more about dedicated production servers than your machine at home. I think it's unrealistic to assume that one can move port numbers for every single application on a production server. At least SMTP, DNS and WWW have to be at their respective standard ports. And the first thing a hacker does is scan well-known ports under 1024 and do an ICMP ping. After that he/she knows that the machine exists. There is no way hiding that fact. In that case it's better to use RST since it blends with the other ports that are closed.

Actually, it would be ok to use DROP for ALL ports other than ones that are in use. In that case nmap will see either open or firewalled ports but no closed ones and it would be impossible to tell on which of the firewalled ports an application was listening and which of these were simply closed. BUT: You must firewall high ports as well. Assuming that a hacker will never scan those is a bad move. They may not test them when they are scanning entire subnets for live IPs but once they picked a target they will scan high ports too. Trust me ;-). Now if you firewall high ports using DROP you need to do something about passive FTP, most likely stateful inspection. I know, iptables does that but it's more complicated to setup and more overhead. This is why I think my solution is better suited for production servers.

-- Hannes

Submitted by Anonymous on Thu, 07/13/2006 - 20:38.

DROP is better than a RST. Say for example that you run a few or one service(filesharing ssh). As long as you use a non-wellknown ports like 45678 for example it is unlikly that anyone doing random scanning will scan your entire port range. They will most likely scan only well know ports, plus maybe a few others if they are smart like emule and default ports for common bittorrent clients. If you use RST then they will know you are there and maybe scan further. However, if they scan only known ports and you DROP, they will have no way of knowing that a host is at that IP at all and will move on. This is why almost every pre-writen iptables script you find will DROP not RST.

Submitted by Anonymous on Fri, 06/30/2006 - 06:11.

Thanks a lot! I've been searching for something like this for a long time :)