skip to primary navigationskip to content

Service detection on a Unix box


What's the Problem?

Do you know how the outside world can connect to your system? Even if you have secured all the system services that listen to the network how do you know if your users haven't started some of their own? The enemy outside might use a CGI script on a web server you didn't even know existed to get into your system after you had removed the CGI scripts from your "official" web server. Alternatively, if your system had been compromised, the enemy within may have set up an extra service to provide a long term backdoor.

What's the Answer?

There is an old adage from the earliest days of computers:

Don't try to solve technical problems with social solutions.

Don't try to solve social problems with technical solutions.

What this quotation means in these circumstances is that you need to listen to your users and find out why they are running network services. Find out if they are aware of the security implications, whether they have addressed them and whether it is something that the system should be doing for them anyway. If you alienate your users they will just hide their insecure activities better in future.

You do talk to your users, don't you?

However, you still need to know what to talk to them about, and what to say. You cannot do this from a position of ignorance. The rest of this document discusses the technical issues regarding determining what services are being run on your system. It will describe the natures of network listeners, demonstrate how to determine what network listeners you are running and what processes are responsible for them.

Network Listeners

A network listener is a process (usually a daemon) that controls a network port and ccepts incoming connections. A network port is identifies by the IP address(es) it listens on (while most Unix boxes have a single Internet address this is not required) and a "port number", a number between 1 and 65,356. It listens for either TCP data (streams of information) or UDP data (individual packets of information). The TCP port numbers and the UDP port numbers are completely separate. One program can listen to TCP port N completely unrelated to another program listening to UDP port N.

There are essentially two ways a daemon can be started up on a Unix box: directly or indirectly via the inetd, a super-server that starts up other daemons on demand.

There are also two ways a network listener can determine what port it should use. The first is that it knows in advance what port to use (a so-called "well-known service") and simply grabs it. The second is that it takes a request to another daemon, called the portmapper (or rpcbind on Solaris 2) which chooses a port to assign to the listener.

Well known services

A well known service is the association of a service with a port number that is agreed on between all machines. For example the telnet port is number 23 on all systems, the SMTP (mail transfer) port is number 25 and so on.

The association between services and port numbers is recorded in the file /etc/services. The file consists of a series of entries, one per service.

tcpmux          1/tcp                           # rfc-1078
echo            7/tcp
echo            7/udp
discard         9/tcp           sink null
discard         9/udp           sink null
systat          11/tcp          users
daytime         13/tcp
daytime         13/udp
netstat         15/tcp
qotd            17/tcp          quote
chargen         19/tcp          ttytst source
chargen         19/udp          ttytst source
ftp-data        20/tcp
ftp             21/tcp
telnet          23/tcp
smtp            25/tcp          mail
time            37/tcp          timserver
time            37/udp          timserver

The first column identifies a service name (e.g. telnet), the second (e.g. 23/tcp) identifies the port number and the protocol and the remaining columns up to the end of line or a comment are alias names for the service. The hash character introduces a comment which extends to the end of the line.

Note that the fact that a service is mentioned in this file does not imply that the service is running, not must a service be named in this file to be runnable. This is purely a convenience file.

The services maps must agree at both server and client ends. When a client wants to connect to a server it looks up the service port number locally and makes a connection to that port number on the server machine.

RPC services

The other sort of daemon uses the Remote Procedure Call (RPC) system. In this facility a listener starts up, knowing its RPC "program number", but not its port number. It connects to the portmapper daemon already running on a well-known port. The new listener asks the portmapper for a port. The portmapper selects an unused port and assigns it to the listener.

When a client wants to connect to this listener, it first connects to the portmapper on the remote machine and asks if the service (identifies by Program Nunber) is running at all. The portmapper responds by either disowning knowledge of the serice or by acknowledging it and passing pack the port number which the client then connects to.

The set of most commonly used RPC program numbers is held in a file called /etc/rpc on each system. The file consists of a series of entries, one per service.

portmapper      100000  portmap sunrpc
rstatd          100001  rstat rstat_svc rup perfmeter
rusersd         100002  rusers
nfs             100003  nfsprog
ypserv          100004  ypprog
mountd          100005  mount showmount
ypbind          100007
walld           100008  rwall shutdown
yppasswdd       100009  yppasswd
etherstatd      100010  etherstat
rquotad         100011  rquotaprog quota rquota
sprayd          100012  spray
3270_mapper     100013
rje_mapper      100014
selection_svc   100015  selnsvc
database_svc    100016

The first column gives the service name, the second its program number and the remaining columns give aliases. Again, this is a simple lookup file. The presence of an entry here does not mean that the service is provided by your system and programs can use numbers not included in this file.

Directly launched daemons

A directly launched daemon is started from a shell or a shell script. The system daemons of this form are typically launched from one or more start up scripts at boot time.

Your users can also start up daemons directly from their login shells in this way.

Indirectly launched daemons

The inetd is a "super-daemon" that listens on a variety of ports corresponding to various well-known services (ftp, telnet etc.). When it receives a request on one of these ports it starts up the appropriate daemon and passes it the connection.

The inetd is configured by a file /etc/inetd.conf. This consists of a series of lines, one per service handled. For example the line controlling the ident protocol is started by the following line:

auth  stream tcp  wait  root  /usr/sbin/in.identd  in.identd -w -t120

The first component, auth, identifies the service name. This must be a well known service.

The next two elements, stream tcp, identify what sort of service to expect. This example indicates that it is a TCP service.

The next field, wait, indicates that the inetd should wait for this instance of the daemon to pass before starting another instance. Any more incoming connections will be dealt with by the existing daemon.

The next field, root, indicates the user the daemon should run as. The group of the daemon will be the primary group of that user as specified in the password map.

The next field, /usr/sbin/in.identd, identifies the program to run to get the daemon.

The rest of the line, in.identd -w -t120, provides the arguments to the daemon, including the "zeroth" argument of the command name itself. Note that this need not be the same as the name of the file in the previous field. Serveral programs are written to modify their behaviour according to the name they are called by.

Every non-comment line in this file corresponds to a service provided by your computer. A good security policy is to go through this file and to leave uncommented only those services you actually need. If you are over-cautious your users will let you know. If you modify the /etc/inetd.conf file you must send a HUP signal to the inetd to get it to reread its configuration file.

# ps -ax | grep inetd
  138  ?  S    0:00 inetd 
  896  p1 R    0:00 grep inetd 
# kill -HUP 138

(Note that the options on ps vary between systems.)

Determining services

So let's cut to the chase: How do we determine what listeners are active on a system and what's responsible for them?

The best tool for this task (and for several others) is lsof, a program that lists open files. This has an option, -i to list open IP sockets.

There is an alternative on Linux systems where the netstat program has been extended to provide the extra information.