[ Team LiB ] Previous Section Next Section

Recipe 9.13 Testing for Open Ports

9.13.1 Problem

You want a listing of open network ports on your system.

9.13.2 Solution

Probe your ports from a remote system.

To test a specific TCP port (e.g., SSH):

$ telnet target.example.com ssh
$ nc -v -z target.example.com ssh

To scan most of the interesting TCP ports:

# nmap -v target.example.com

To test a specific UDP port (e.g., 1024):

$ nc -v -z -u target.example.com 1024

To scan most of the interesting UDP ports (slowly!):

# nmap -v -sU target.example.com

To do host discovery (only) for a range of addresses, without port scanning:

# nmap -v -sP 10.12.104.200-222

To do operating system fingerprinting:

# nmap -v -O target.example.com

For a handy (but less flexible) GUI, run nmapfe instead of nmap.

9.13.3 Discussion

When attackers observe your systems from the outside, what do they see? Obviously, you want to present an image of an impenetrable fortress, not a vulnerable target. You've designed your defenses accordingly: a carefully constructed firewall, secure network services, etc. But how can you really be sure?

You don't need to wait passively to see what will happen next. Instead, actively test your own armor with the same tools the attackers will use.

Your vulnerability to attack is influenced by several interacting factors:

The vantage point of the attacker

Firewalls sometimes make decisions based on the source IP address (or the source port).

All intervening firewalls

You have your own, of course, but your ISP might impose additional restrictions on incoming or even outgoing traffic from your site.

The network configuration of your systems

Which servers listen for incoming connections and are willing to accept them?

Start by testing the last two subsystems in isolation. Verify your firewall operation by simulating the traversal of packets through ipchains. [Recipe 2.21] Examine the network state on your machines with netstat. [Recipe 9.14]

Next, the acid test is to probe from the outside. Use your own accounts on distant systems, if you have them (and if you have permission to do this kind of testing, of course). Alternatively, set up a temporary test system immediately outside your firewall, which might require cooperation from your ISP.

The nmap command is a powerful and widely used tool for network security testing. It gathers information about target systems in three distinct phases, in order:

Host discovery

Initial probes to determine which machines are responding within an address range

Port scanning

More exhaustive tests to find open ports that are not protected by firewalls, and are accepting connections

Operating system fingerprinting

An analysis of network behavioral idiosyncrasies can reveal a surprising amount of detailed information about the targets

Use nmap to test only systems that you maintain. Many system administrators consider port scanning to be hostile and antisocial. If you intend to use nmap's stealth features, obtain permission from third parties that you employ as decoys or proxies.

Inform your colleagues about your test plans, so they will not be alarmed by unexpected messages in system logs. Use the logger command [Recipe 9.31] to record the beginning and end of your tests.

Use caution when probing mission-critical, production systems. You should test these important systems, but nmap deliberately violates network protocols, and this behavior can occasionally confuse or even crash target applications and kernels.

To probe a single target, specify the hostname or address:

# nmap -v target.example.com
# nmap -v 10.12.104.200

We highly recommend the -v option, which provides a more informative report. Repeat the option (-v -v...) for even more details.

You can also scan a range of addresses, e.g., those protected by your firewall. For a class C network, which uses the first three bytes (24 bits) for the network part of each address, the following commands are all equivalent:

# nmap -v target.example.com/24
# nmap -v 10.12.104.0/24
# nmap -v 10.12.104.0-255
# nmap -v "10.12.104.*"

Lists of addresses (or address ranges) can be scanned as well:

# nmap -v 10.12.104.10,33,200-222,250

nmapfe is a graphical front end that runs nmap with appropriate command-line options and displays the results. nmapfe is designed to be easy to use, though it does not provide the full flexibility of all the nmap options.

By default, nmap uses both TCP and ICMP pings for host discovery. If these are blocked by an intervening firewall, the nmap -P options provide alternate ping strategies. Try these options when evaluating your firewall's policies for TCP or ICMP. The goal of host discovery is to avoid wasting time performing port scans for unused addresses (or machines that are down). If you know that your targets are up, you can disable host discovery with the -P0 (that's a zero) option.

The simplest way to test an individual TCP port is to try to connect with telnet. The port might be open:

$ telnet target.example.com ssh
Trying 10.12.104.200...
Connected to target.example.com.
Escape character is '^]'.
SSH-1.99-OpenSSH_3.1p1

or closed (i.e., passed by the firewall, but having no server accepting connections on the target):

$ telnet target.example.com 33333
Trying 10.12.104.200...
telnet: connect to address 10.12.104.200: Connection refused

or blocked (filtered) by a firewall:

$ telnet target.example.com 137
Trying 10.12.104.200...
telnet: connect to address 10.12.104.200: Connection timed out

Although telnet's primary purpose is to implement the Telnet protocol, it is also a simple, generic TCP client that connects to arbitrary ports.

The nc command is an even better way to probe ports:

$ nc -z -vv target.example.com ssh 33333 137
target.example.com [10.12.104.200] 22 (ssh) open
target.example.com [10.12.104.200] 33333 (?) : Connection refused
target.example.com [10.12.104.200] 137 (netbios-ns) : Connection timed out

The -z option requests a probe, without transferring any data. The repeated -v options control the level of detail, as for nmap.

Port scans are a tour de force for nmap:

# nmap -v target.example.com
Starting nmap V. 3.00 ( www.insecure.org/nmap/ )
No tcp,udp, or ICMP scantype specified, assuming SYN Stealth scan.
Use -sP if you really don't want to portscan (and just want to see what hosts are up).
Host target.example.com (10.12.104.200) appears to be up ... good.
Initiating SYN Stealth Scan against target.example.com (10.12.104.200)
Adding open port 53/tcp
Adding open port 22/tcp
The SYN Stealth Scan took 21 seconds to scan 1601 ports.
Interesting ports on target.example.com (10.12.104.200):
(The 1595 ports scanned but not shown below are in state: closed)
Port       State       Service
22/tcp     open        ssh
53/tcp     open        domain
137/tcp    filtered    netbios-ns
138/tcp    filtered    netbios-dgm
139/tcp    filtered    netbios-ssn
1080/tcp   filtered    socks
Nmap run completed -- 1 IP address (1 host up) scanned in 24 seconds

In all of these cases, be aware that intervening firewalls can be configured to return TCP RST packets for blocked ports, which makes them appear closed rather than filtered. Caveat prober.

nmap can perform more sophisticated (and efficient) TCP probes than ordinary connection attempts, such as the SYN or "half-open" probes in the previous example, which don't bother to do the full initial TCP handshake for each connection. Different probe strategies can be selected with the -s options: these might be interesting if you are reviewing your firewall's TCP policies, or you want to see how your firewall logs different kinds of probes.

Run nmap as root if possible. Some of its more advanced tests intentionally violate IP protocols, and require raw sockets that only the superuser is allowed to access.

If nmap can't be run as root, it will still work, but it may run more slowly, and the results may be less informative.

UDP ports are harder to probe than TCP ports, because packet delivery is not guaranteed, so blocked ports can't be reliably distinguished from lost packets. Closed ports can be detected by ICMP responses, but scanning is often very slow because many systems limit the rate of ICMP messages. Nevertheless, your firewall's UDP policies are important, so testing is worthwhile. The nc -u and nmap -sU options perform UDP probes, typically by sending a zero-byte UDP packet and noting any responses.

By default, nmap scans all ports up to 1024, plus well-known ports in its extensive collection of services (used in place of the more limited /etc/services). Use the -F option to quickly scan only the well-known ports, or the -p option to select different, specific, numeric ranges of ports. If you want to exhaustively scan all ports, use -p 0-65535.

If you are interested only in host discovery, disable port scanning entirely with the nmap -sP option. This might be useful to determine which occasionally-connected laptops are up and running on an internal network.

Finally, the nmap -O option enables operating system fingerprinting and related tests that reveal information about the target:

# nmap -v -O target.example.com
...
For OSScan assuming that port 22 is open and port 1 is closed and neither are firewalled
...
Remote operating system guess: Linux Kernel 2.4.0 - 2.5.20
Uptime 3.167 days (since Mon Feb 21 12:22:21 2003)
TCP Sequence Prediction: Class=random positive increments
                         Difficulty=4917321 (Good luck!)
IPID Sequence Generation: All zeros

Nmap run completed -- 1 IP address (1 host up) scanned in 31 seconds

Fingerprinting requires an open and a closed port, which are chosen automatically (so a port scan is required). nmap then determines the operating system of the target by noticing details of its IP protocol implementation: Linux is readily recognized (even the version!). It guesses the uptime using the TCP timestamp option. The TCP and IPID Sequence tests measure vulnerability to forged connections and other advanced attacks, and Linux performs well here.

It is sobering to see how many details nmap can learn about a system, particularly by attackers with no authorized access. Expect that attacks on your Linux systems will focus on known Linux-specific vulnerabilities, especially if you are using an outdated kernel. To protect yourself, keep up to date with security patches.

nmap can test for other vulnerabilities of specific network services. If you run an open FTP server, try nmap -b to see if it can be exploited as a proxy. Similarly, if you allow access to an IDENT server, use nmap -I to determine if attackers can learn the username (especially root!) that owns other open ports. The -sR option displays information about open RPC services, even without direct access to your portmapper.

If your firewall makes decisions based on source addresses, run nmap on different remote machines to test variations in behavior. Similarly, if the source port is consulted by your firewall policies, use the nmap -g option to pick specific source ports.

The nmap -o options save results to log files in a variety of formats. The XML format (-oX) is ideal for parsing by scripts: try the XML::Simple Perl module for an especially easy way to read the structured data. Alternately, the -oG option produces results in a simplified format that is designed for searches using grep. The -oN option uses the same human-readable format that is printed to stdout, and -oA writes all three formats to separate files.

nmap supports several stealth options that attempt to disguise the source of attacks by using third-parties as proxies or decoys, or to escape detection by fragmenting packets, altering timing parameters, etc. These can occasionally be useful for testing your logging and intrusion detection mechanisms, like Snort. [Recipe 9.20]

9.13.4 See Also

nmap(1), nmapfe(1), nc(1), telnet(1). The nmap home page is http://www.insecure.org/nmap. The XML::Simple Perl module is found on CPAN, http://www.cpan.org.

The /proc Filesystem

Programs like ps, netstat, and lsof obtain information from the Linux kernel via the /proc filesystem. Although /proc looks like an ordinary file hierarchy (e.g., you can run /bin/ls for a directory listing), it actually contains simulated files. These files are like windows into the kernel, presenting its data structures in an easy-to-read manner for programs and users, generally in text format. For example, the file /proc/mounts contains the list of currently mounted filesystems:

$ cat /proc/mounts
/dev/root / ext2 rw 0 0
/proc /proc proc rw 0 0
/dev/hda9 /var ext2 rw 0 0
...

but if you examine the file listing:

$ ls -l /proc/mounts
-r--r--r--    1 root     root            0 Feb 23 17:07 /proc/mounts

you'll see several curious things. The file has zero size, yet it "contains" the mounted filesystem data, because it's a simulated file. Also its "last modified" timestamp is the current time. The permission bits are accurate: this file is world-readable but not writable.[4] The kernel enforces these access restrictions just as for ordinary files.

You can read /proc files directly, but it's usually more convenient to use programs like ps , netstat, and lsof because:

  • They combine data from a wide range of /proc files into an informative report.

  • They have options to control the output format or select specific information.

  • Their output format is usually more portable than the format of the corresponding /proc files, which are Linux-specific and can change between kernel versions (although considerable effort is expended to provide backward compatibility). For instance, the output of lsof -F is in a standardized format, and therefore easily parsed by other programs.

Nevertheless, /proc files are sometimes ideal for scripts or interactive use. The most important files for networking are /proc/net/tcp and /proc/net/udp, both consulted by netstat. Kernel parameters related to networking can be found in the /proc/sys/net directory.

Information for individual processes is located in /proc/<pid> directories, where <pid> is the process ID. For example, the file /proc/12345/cmdline contains the original command line that invoked the (currently running) process 12345. Programs like ps summarize the data in these files. Each process directory contains a /proc/<pid>/fd subdirectory with links for open files: this is used by the lsof command.

For more details about the format of files in the /proc filesystem, see the proc(5) manpage, and documentation in the Linux kernel source distribution, specifically:

/usr/src/linux*/Documentation/filesystems/proc.txt

[4] Imagine the havoc one could wreak by writing arbitrary text into a kernel data structure.

    [ Team LiB ] Previous Section Next Section