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 youn run it, 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 https://dcid.me/ossec-docs/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* LISTEN
tcp 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 with bind
dcid@copacabana:~$ nc -l -p 1026
Can’t grab with bind
dcid@copacabana:~$ nc -p 1026 80
Can’t grab with bind

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

Posted in   linux   c_dev     by Daniel Cid (dcid)

Coding for fun and profit. Often fun and little profit.