Hidden ports on Linux

If you ever had trouble with hidden ports on Linux (2.4 and 2.6), I may have figured out one of the possible causes today (and no, it is not a rootkit). To keep the story short: if you bind any TCP port, but do not listen on it, netstat will not show it at all (the same does not happen with UDP ports).

Here is the idea. If you get this simple C program, it will attempt to bind every TCP port from 1025 to 1050, but it will not listen on them. After it is done, if you do a netstat (or fuser or lsof) nothing will be shown. However, if you try to use the port, you will get an error saying that it is already in use.

To reproduce, download the bind_ports.c program, compile and execute it:

dcid@copacabana:~$ wget http://www.ossec.net/files/other/bind_ports.c
..
14:56:32 (309.92 KB/s) – `bind_ports.c’ saved [1371/1371]

dcid@copacabana:~$ gcc -o bind_ports bind_ports.c
dcid@copacabana:~$ ./bind_ports &
[1] 11332

Ports from 1025 to 1050 were bind..

After that, run netstat (or lsof or fuser) to see if the port is listed (it will not be):

dcid@copacabana:~$ netstat -tan
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 127.0.0.1:80 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:53 0.0.0.0:* LISTEN

However, if you try to use the port, you will receive the “already in use” error (if using nc, it takes up to 10 seconds to fail).

dcid@copacabana:~$ nc -l -p 1025
Can’t grab 0.0.0.0:1025 with bind
dcid@copacabana:~$ nc -l -p 1026
Can’t grab 0.0.0.0:1026 with bind
dcid@copacabana:~$ nc -p 1026 127.0.0.1 80
Can’t grab 0.0.0.0:1026 with bind

Anyone has ideas why this happens? If I try the same thing on OpenBSD, netstat lists all the ports correctly.

Leave a Reply

Your email address will not be published. Required fields are marked *