Hack #8. Check for Listening Services

Find out whether unneeded services are listening and looking for possible backdoors.

One of the first things you should do after a fresh operating system install is see what services are running and remove any unneeded services from the system startup process. You could use a port scanner (such as Nmap [Hack #66]) and run it against the host, but if one didn’t come with the operating system install, you’ll likely have to connect your fresh (and possibly insecure) machine to the network to download one.

Also, Nmap can be fooled if the system is using firewall rules. With proper firewall rules, a service can be completely invisible to Nmap unless certain criteria (such as the source IP address) also match. When you have shell access to the server itself, it is usually more efficient to find open ports using programs that were installed with the operating system. One option is netstat, a program that will display various network-related information and statistics.

To get a list of listening ports and their owning processes under Linux, run this command:

# netstat -luntp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address  State   PID/Program name
tcp        0      0 0.0.0.0:22    0.0.0.0:*        LISTEN  1679/sshd
udp        0      0 0.0.0.0:68    0.0.0.0:*                1766/dhclient

From the output, you can see that this machine is probably a workstation, since it just has a DHCP client running along with an SSH daemon for remote access. The ports in use are listed after the colon in the Local Address column (22 for sshd and 68 for dhclient). The absence of any other listening processes means that this is probably a workstation, not a network server.

Unfortunately, the BSD version of netstat does not let us list the processes and the process IDs (PIDs) that own the listening port. Nevertheless, the BSD netstat command is still useful for listing the listening ports on your system.

To get a list of listening ports under FreeBSD, run this command:

# netstat -a -n | egrep 'Proto|LISTEN'
Proto Recv-Q Send-Q  Local Address          Foreign Address        (state)
tcp4       0      0  *.587                  *.*                    LISTEN
tcp4       0      0  *.25                   *.*                    LISTEN
tcp4       0      0  *.22                   *.*                    LISTEN
tcp4       0      0  *.993                  *.*                    LISTEN
tcp4       0      0  *.143                  *.*                    LISTEN
tcp4       0      0  *.53                   *.*                    LISTEN

Again, the ports in use are listed in the Local Address column. Many seasoned system administrators have memorized the common port numbers for popular services and will be able to see at a glance that this server is running SSHD, SMTP, DNS, IMAP, and IMAP+SSL services. If you are ever in doubt about which services typically run on a given port, either eliminate the -n switch from the netstat command (which tells netstat to use names but can take much longer to run when looking up DNS addresses) or manually grep the /etc/services file:

# grep -w 993 /etc/services
imaps           993/udp     # imap4 protocol over TLS/SSL
imaps           993/tcp     # imap4 protocol over TLS/SSL

The /etc/services file should only be used as a guide. If a process is listening on a port listed in the file, it doesn’t necessarily mean that the service listed in /etc/services is what it is providing.

Also notice that, unlike in the output of netstat on Linux, with the BSD version you don’t get the PIDs of the daemons themselves. You might also notice that no UDP ports were listed for DNS. This is because UDP sockets do not have a LISTEN state in the same sense that TCP sockets do. In order to display UDP sockets, you must add udp4 to the argument for egrep, thus making it 'Proto|LISTEN|udp4'. However, due to the way UDP works, not all UDP sockets will necessarily be associated with a daemon process.

Under FreeBSD, there is another command that will give us just what we want. The sockstat command performs only a small subset of what netstat can do and is limited to listing information on Unix domain sockets and Inet sockets, but it’s ideal for this hack’s purposes.

To get a list of listening ports and their owning processes with sockstat, run this command:

# sockstat -4 -l
USER     COMMAND    PID   FD PROTO  LOCAL ADDRESS        FOREIGN ADDRESS   
root     sendmail  1141    4 tcp4   *:25                 *:*
root     sendmail  1141    5 tcp4   *:587                *:*
root     sshd      1138    3 tcp4   *:22                 *:*
root     inetd     1133    4 tcp4   *:143                *:*
root     inetd     1133    5 tcp4   *:993                *:*
named    named     1127   20 tcp4   *:53                 *:*
named    named     1127   21 udp4   *:53                 *:*
named    named     1127   22 udp4   *:1351               *:*

Once again, you can see that SSHD, SMTP, DNS, IMAP, and IMAP+SSL services are running, but now you have the process that owns the socket plus its PID. You can now see that the IMAP services are being spawned from inetd instead of standalone daemons, and that sendmail and named are providing the SMTP and DNS services.

For most other Unix-like operating systems, you can use the lsof utility (http://ftp.cerias.purdue.edu/pub/tools/unix/sysutils/lsof/). lsof is short for “list open files” and, as the name implies, it allows you to list files that are open on a system, in addition to the processes and PIDs that have them open. Since sockets and files work the same way under Unix, lsof can also be used to list open sockets. This is done with the -i command-line option.

To get a list of listening ports and the processes that own them using lsof, run this command:

# lsof -i -n | egrep 'COMMAND|LISTEN'
COMMAND   PID   USER FD  TYPE     DEVICE SIZE/OFF NODE NAME
named    1127 named  20u IPv4 0xeb401dc0      0t0  TCP *:domain (LISTEN)
inetd    1133  root   4u IPv4 0xeb401ba0      0t0  TCP *:imap (LISTEN)
inetd    1133  root   5u IPv4 0xeb401980      0t0  TCP *:imaps (LISTEN)
sshd     1138  root   3u IPv4 0xeb401760      0t0  TCP *:ssh (LISTEN)
sendmail 1141  root   4u IPv4 0xeb41b7e0      0t0  TCP *:smtp (LISTEN)
sendmail 1141  root   5u IPv4 0xeb438fa0      0t0  TCP *:submission (LISTEN)

Again, you can change the argument to egrep to display UDP sockets. However, this time use UDP instead of udp4, which makes the argument 'COMMAND|LISTEN|UDP'. As mentioned earlier, not all UDP sockets will necessarily be associated with a daemon process.