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 Anonymous on Thu, 07/07/2011 - 20:26.
#Perhaps something like this for the last lines... -A INPUT -p tcp -j REJECT --reject-with tcp-reset -A INPUT -j REJECT -A FORWARD -j REJECT
Submitted by Anonymous on Thu, 07/07/2011 - 20:06.
I tend to prefer the authors method. If a machine exists... one knows it is likely running certain things if it is a production server. Unless you are running out of band management or private backend services or servers or the like. However from the front I would prefer an unfirewalled appearance, partly for my own sanity and partly to avoid obscurity of services. For one, nmap is a tool. Not just for hackers, but for the sysadmins and sometimes internet people. It is rare I nmap a box that is not mine, but sometimes it can be helpful.... not harmful. Secondly, if I am accessing port 80 on a box, then I would only be more curious how many other obscured services are running if I know iptables is turned on. Iptables can often be a practice of apathy. From the front, I would just assume it look like the service isn't there. I certainly don't want it to be obscured. This appearance is less interesting and more useful in the real world. If ssh appears to be running along with apache, then I haven't given any thought to the exploits available on the other ports. If it were obscured.. .the release the hounds cause you know the packets are making it there and people can get there rules wrong or be lazy. I found myself running services that shouldn't have been on the net... I really just wanted them to go away, and not really being an iptables fan, I found this article useful. This is because my own nmaps were not just looking gone, but were looking filtered. In the end obscurity is bad. IMHO.
Submitted by Anonymous on Mon, 09/13/2010 - 06:16.
Very very good. Thanks!
Submitted by Anonymous on Tue, 07/14/2009 - 13:22.
The procedure I apply (is not my idea, I have seen it around in many guides :-) is to set the default policy to drop (in iptables you do so with the -P flag). If you do so, you don't need to close any ports, you only need to open the ones that are public (and to accept all output traffic). With this method, a port scanner also doesn't know which apps are listening but blocked, and it will take much more time to do a full scan, because you won't be sending any answer, so it will wait to a connection timeout for each port. In my servers, for example, I have moved the SSH to an strange port (and blocked it except for some IPs I owe), and blocked all new incoming connections (that includes ICMP echo) except port 80. This leave my machine save for a lot of random scans that only searchs for ping+ssh for a whole network, and slows down as much as possible a deep scan against my machine. (looked for some place to put who I am, didn't found it :-)
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 :)