Dissecting the (Linux) Worm

What follows is an article on the Linux Worm (ADMw0rm), that I originally wrote in July 1999 for the IBM Developers Portal; they did not publish it in the end, but they paid me, so they hold the publishing rights. But I am allowed to publish it on my personal website.

Of course it's quite old, but I think it still makes a reasonably interesting reading.

Dissecting the (Linux) Worm

On this page... (hide)

  1. 1. Structure
  2. 2. Considerations
  3. 3. Thanks to:
  4. 4. Glossary

A "worm" is a piece of software whose primary aim is to replicate itself, like a virus. But its peculiarity is that it tries to copy itself onto remote computers directly trough network connections, exploiting holes in system security. Therefore a worm doesn't need to wait for user action, like booting from an infected diskette, or executing an infected program. The famous Internet Worm, released in 1988 by Robert Morris, is the most widely known example.

The Linux Worm or, more correctly, ADMw0rm, is a pretty simple example of a worm. It has been first reported by CERT, in May 1998 Summary, but it recently came back to the attention of the Linux community, in consequence of a mail to the BUGTRAQ mailing list, and of the related thread that appeared also on the "linux-security" list.

While not particularly intriguing from a programmer's point of view, it is instead interesting from a "social" point of view. This because it doesn't seem the product of a single developer, but it appears to have been built from pre-existing tools, contributed by different people. And the result is something that should be regarded as a toolkit for building a worm, rather than as a worm in itself.

1.  Structure

The main program (ADMw0rm) is a Bourne Shell script, whose flow is pretty linear:

  1. find the IP address of the network interface which is used for the default route
  2. generate a file containing a secondary shell script, used later
  3. generate a random IP address
  4. generate a sequence of (consecutive) IPs starting from the random one.
  5. on each address of the sequence,
    1. test for the accessibility of the port usually assigned to the vulnerable service
      (for the known ADMw0rm, this is port 53 - DNS service)
    2. if accessible, test for the vulnerability of the daemon
    3. if vulnerable,
      1. exploit the bug, issuing (to the remote system) shell commands that
        1. create a password-less account
        2. create a suid copy of /bin/sh
      2. telnet into the password-less account, and execute the secondary script that
        1. checks whether the worm is already on the host,
          and in case, deletes the logs and the suid shell, and aborts.
        2. transfers (via ftp, from the IP found in step 1) ) a tar.gz file that contains the worm
        3. unpack the tar.gz file in a directory
        4. start the worm in a separate background process, with superuser privileges
        5. mail the IP to a given address
        6. erase the suid shell
        7. erase the logs
        8. do some damage
          (in the current version, overwrites all the "index.html" files)

Steps 3) , A), B) and i) and are executed by C programs, which are pre-compiled and packaged, together with the ADMw0rm script, in the tar.gz file.

The code is quite naive, in many senses :

  • it only takes care of removing logs and the suid shell;
  • nothing is done to hide
    • the files that compose the worm,
    • the mail address to which the IPs are sent,
    • the password-less user,
    • the executing processes or
    • the outgoing network connections;
  • the names of the directories and of the executables do not change from one host to the next;
  • no special technique is applied to optimize the IP address scan: it is simply a flat, sequential scan;
  • it relies on the availability of telnetd and ftpd
  • it assumes that deleting one of the tcpd configuration files (/etc/hosts.deny) will suffice to "open the doors."

But, at the end, this simple structure gives it flexibility, and makes it a dangerous beast:

  • The simple scanning method makes it extremely difficult to recognize that a host has undergone a scan, since it only the specific port is "probed."
  • The fact that the scanner doesn't try to hide (it uses no "stealth" technique to identify the open port) makes it virtually invisible to packet loggers, that are usually configured to warn only about "strange" packets.
  • The fact that it scans complete IP ranges has another advantage: the dedicated servers (DNS servers, in this case) are usually kept up-to-date and managed by experienced people; a flat scan can find systems that might be not actively maintained.
  • With the current version, it's easy to detect an infected host by watching the IP traffic on the LAN or on a gateway, because it can saturate the network with a relatively high number of concurrent connections (20) to consecutive IP addresses. The worm could be made harder to trace just by introducing some randomness in delays and IP addresses (this is a technique already applied for "slow scans" - see this http://www.cert.org/incident_notes/IN-98.04.htmlCERT Incident Note)
  • Since it is, for the most part, a shell script, it's easy to change, for example to use filenames different from those reported by the CERT advisory, to make different damages, etc.
  • The test and exploit programs are external, simple C programs, trivially derived from a publicly available exploit. In the known version, it is an exploit for the bind DNS server. It would be extremely easy, for anybody, to produce a "new" worm, given any other root compromising remote exploit code. And exploit code is often easily available.
  • As C compilers are commonly available on Unix hosts, the simple C exploit programs could be distributed as source code, obtaining a quite portable worm.

The present version of ADMw0rm is not anything you should fear, if your bind DNS daemon is up-to date; but i think we should expect to see other, more dangerous reincarnations of the ADMw0rm. And not only for linux-x86. Sadly, the CERT report failed short of stressing these points, only focusing on the samples that had been found "in the wild" (actually deployed on the net).

2.  Considerations

What is striking about the ADMw0rm, is its simplicity. This means that it relies on the standardization of the Linux/Unix world, and on the fact that the majority of the hosts don't adopt any special defence measure.
In particular, the common availability of ftp and telnet clients and servers, the fact of relaying only on tcpd for restriction of access by IP address, and the vulnerability of log files are the common weaknesses abused by this worm.

The ADMw0rm has been called "The Linux Worm". As I explained before, technically it is not so Linux-specific. A Linux system, kept up to date and well managed, is as secure as any other Unix, or more; but despite of this, Linux is, nowadays, surely the best target for a worm. Let me explain why.

Linux is facing an incredible growth. While, until some time ago, it was almost only used on servers, or by Unix aficionados, now it's being widely deployed also as a workstation OS. This often means leaving a Unix system in the hands of people who are just users, not experienced system administrators, and not willing to become ones.
These people are not security aware, and/or cannot dedicate too much time to security, therefore these systems end up not being updated for long periods, and/or not being protected in any way: no firewall, no tcpd, non-configured daemons. This creates a good environment for the growth and spreading of worms.

All of this happens despite the continuous and pretty successful efforts of the Linux community to build a secure OS. In some sense, it also happens because of these efforts, that too often turns into a constant flow of packages that need upgrading, at a pace that common users cannot keep up with.

My personal suggestions are:

  • Distributions should deliver daemons already configured for restricted access, and force the users to knowingly disable the restrictions if he/she needs to. For no reason clients and servers should be packaged together, for no reason the servers should be enabled by default. An example of this is the telnet package, under RedHat 5.2.
  • The use of security measures should be strongly encouraged, making available easier configuration tools for firewalls, tcpd, inetd, Pluggable Authentication Modules.
  • Users/system administrators should be strongly encouraged to subscribe to security mailing lists - possibly right away during the installation process.

The packagers of many distributions aimed at the ease of installation and readiness to use, trying to compete with Windows. In doing so they often lost sight of simplicity and transparency. This makes too easy, for an inexperienced user, to install also unwanted and, security-wise, dangerous programs. I think the Linux community should avoid making the same mistakes for which Microsoft has been blamed before.

3.  Thanks to:

  • Defiant for his article on the Morris Internet Worm.
  • CERT for the good work they're doing
  • everybody on BUGTRAQ, for the restless flow of security information
  • linux-security, for helping those who don't have time to read BUGTRAQ.

Sergio Ballestrero, for the IBM Developer's Portal

4.  Glossary

suid (Set-User-ID)
option for executable files on Unix systems that forces the program to run with the identity and rights of the owner of the file. Usually it is implied that, when not specified, the user is root, the system administrator.
a "wrapper" (by Vietse Venema) that constrains configurable checks on the incoming connections before allowing access to the actual server daemon.
stealth scanning
scans made using IP packets with a non-standard flags set, so that a TCP connection is never started by the kernel. These are not logged by tcpd or similar methods - only a low level packet logger (like iplogd) can get to see, and log, them.
is often used as short for "vulnerability exploitation (executable or code)". Sometimes it's spelt "sploit"
root compromise
when a vulnerability allows execution of code with superuser privileges.