September Scan Analysis

Ulrich Drepper drepper@redhat.com, 2001-9-6.


1. The attackers used rpc.statd attack to get into the system. What modifications did they make to the break in process to both automate and make the process faster?

It is not entirely clear when the actual attack started. Fact is that two series of probes of the rpc.statd ports of the machine on the target network happened. One from 203.111.78.182 (baccess-01-182.magna.com.au) in the time from 02:33:23 to 02:33:29 and another from 211.185.125.124 in the time from 18:21:23 to 18:21:24. Only the latter probe is directly followed by an attack.

But both probes show one common characteristic: a program is contacted the rpc.statd port of machines in entire subnets. The initial contacts of all machines happen within a few seconds only.

One conclusion of this is that the probes are unrelated and just performed by similar programs (the latter by a more sophisticated one which automatically mounts attacks, see below). The other possible conclusion is that the first contact is only scanning for vulnerabilities. But this would mean the attackers are quite unsophisticated since they are not using the fact that only the machines .103 and .108 responded to the rpc.statd probe.

Between the two probes of the rpc.statd ports a few more scans happened. The port 137 (netbios-ns) probes are most probably unrelated since they are directed at Windows machines and not Red Hat Linux 6.2. They also come from completely different addresses. Using different machines for different kind of attacks seems unlikely.

The other probes performed (on port 515, lpd) come from 211.180.229.190, yet another address. Which vulnerability is looked for cannot be seen since no attack happened. The Solaris machine (172.16.1.103, as can be seen in the package sent at 07:08:31.993785) attracts a bit more of attention and a telnet connection is opened. But after the login banner showed the machine type no further actions are recorded. This probing also seems unrelated since the fact the 172.16.1.103 is a Solaris machine isn't used in the final attack.

This all leads to the conclusion that the logs show 8 different attacks/probes (5 netbios-ns, 2 rpc.statd, 1 lpd) which are all unrelated. They simply reflect the automatic probing performed by the script kiddie tools of the day. The one successful attack used the most effective tool. It performs the probing of an entire subnet and automatically exploits the vulnerability. The time between the first contact and receiving the exploits is not even a second. The packages in question for the target system are:

  18:21:24.995382 211.185.125.124.790 > 172.16.1.108.sunrpc:  udp 56

  18:21:25.326967 211.185.125.124.791 > 172.16.1.108.931:  udp 1076

The time between the first contact of a machine in the subnet and receiving the exploit is not even two seconds. The exploit program doesn't try to find out what type the target machine is. As can be seen in the case of 172.16.1.103, the Solaris machine, the same exploit package is send to it although it will only work on the Linux machine.

Given a sufficiently fast network connection it is therefore possible to detect and exploit machines in entire networks within seconds. Even if we assume a conservative two seconds for every 8 machines this nevertheless means 14400 machines an hour, 115200 in eight hours. Since the probing runs automatically this is achievable.


2. What system/country did the badguys come in from?

The attack was mounted from the machine with the address 211.185.125.124. It has no DNS record but using traceroute it can be followed back to the kix.ne.kr network. Therefore the country is (most likely) South Korea.


3. What nationality are the badguys, and how were you able to determine this?

The only natural language in text the install script writes out and in the email send out by the script after the telnet connection (port 39168 on the target machine) was established. The install script is started using the package

  18:45:11.543572 211.185.125.124.4450 > 172.16.1.108.39168: P 96:106(10) ack 1233 win 32120 <nop,nop,timestamp 23821378 3021224> (DF)

and its output follows. A bit later the mail is sent to bidi_damm@yahoo.com and it contains further natural language. This all can be seen much easier from the rootkit sources (see below). Not recognizing the language I simply typed in a few of the words appearing in the text in a Google search and this turned up almost exclusively documents of Romanian origin.

There are other participants, though. Parts of the root package (especially the "cleaner" script) are of German origin, the person who compiled the root kit has the email address last@linuxmail.org which points to Hong Kong.

But Romania is most likely since the root kit was downloaded from s1.home.ro, user soane, password i2ttgcj1d.


4. What do the answers to questions #1 and #2 tell us about the tactics the badguys are using?

They run program probing for specific vulnerabilities on machines which have been cracked before in an effort to conceal the traces. Given the fast rate of connections the machines the attacks are mounted from are well connected and can easily handled the thousands of connections performed by the automatic probe and attack program.

No knowledge whatsoever is needed to use the tools and it all can happen withing a few minutes. It's just brute force searching for vulnerable machines.


5. What did you learn from this challenge?
  1. Upgrade the machine.
  2. The time between the first contact of the subnet and the successful exploit is most probably too short for any IDS to react. Rules like

    if a given port on more than one machine is contacted within one second"

    are not generally successful. It can work on machines with slow connections but not otherwise. Looking forward to times with fast access for everyone such rules are next to useless.

  3. It is possible, though, to use such rules as a warning sign and have the sysadmin react. The first probe of the port happened at 02:33 while the actual exploit happened 18:21. This would have left some time to react but only because the first probing programs wasn't as sophisticated.

6. How long did this challenge take you?

5 hours, including this write-up and the program below.


Bonus Question:

Can you recover the blackhat's rootkit from the Snort binary log file? If so, how?

The data transmission for the FTP connection can be easily isolated:

  tcpdump -r snort-0315\@0005.log -x dst host 172.16.1.108 and dst port 1027

Port 1027 on the target machine is assigned by the ftp client for the data transmission. This can be deducted by looking at the log and recognizing the big chunks of data coming into this port from

  s1.home.ro.ftp-data

All that is left to do is writing a program which extracts the data and reconstructs the file. The -x option in the tcpdump command line above tells tcpdump to dump all the data as well. A possible program to do the conversion is appended.

/* Reconstruct file from tcpdump -x output of FTP data connection.
   Copyright (C) Ulrich Drepper <drepper@redhat.com>.  */
#define _GNU_SOURCE
#include <ctype.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>


#define hexcharval(Ch) \
  ({ char _ch = (Ch); \
     _ch >= '0' && _ch <= '9' ? _ch - '0' : 10 + tolower (_ch) - 'a'; })


int
main (int argc, char *argv[])
{
  char *line = NULL;
  size_t len = 0;
  int nr = 0;
  int skip = 0;
  int fd;
  char buffer[4096];
  size_t nbuf = 0;

  fd = open (argc > 1 ? argv[1] : "OUT", O_RDWR | O_CREAT | O_TRUNC, 0666);
  if (fd == -1)
    {
      perror ("open");
      exit (EXIT_FAILURE);
    }

  while (!feof_unlocked (stdin))
    {
      ssize_t n = getline (&line, &len, stdin);
      char *cp;

      if (n < 0)
	break;
      if (n == 0)
	continue;

      /* Handle next package.  tcpdump starts those lines in column 1
	 with the time.  */
      if (isdigit (line[0]))
	{
	  /* Account for packages arriving out-of-order.  Position the
	     output file appropriately.  The header tells us which
	     package it is.  */
	  write (fd, buffer, nbuf);
	  nbuf = 0;

	  cp = strstr (line, " P ");
	  if (cp != NULL)
	    lseek (fd, atol (cp + 3), SEEK_SET);
	  else
	    {
	      /* Check for the final package signature.  */
	      cp = strstr (line, " FP ");
	      if (cp != NULL)
		lseek (fd, atol (cp + 4), SEEK_SET);
	    }
	  nr = 1;
	  continue;
	}

      if (nr++ < 3)
	continue;

      cp = line;
      if (nr == 4)
	{
	  /* Parse parts of the TCP which tells how many words the
	     header consists of.  */
	  while (isspace (*cp))
	    ++cp;

	  /* At this point we already read 3 words.  And tcpdump emits
	     16-bit values so multiply by 2.  */
	  skip = (hexcharval (*cp) - 3) * 2;
	}

      /* Skip TCP header options.  */
      while (skip > 0)
	{
	  while (isspace (*cp))
	    ++cp;
	  if (*cp == '\0')
	    break;
	  while (*cp != '\0' && !isspace (*cp))
	    ++cp;
	  --skip;
	}

      while (*cp != '\0')
	{
	  if (isxdigit (*cp))
	    {
	      buffer[nbuf++] = hexcharval (cp[0]) * 16 + hexcharval (cp[1]);
	      if (nbuf == sizeof (buffer))
		{
		  write (fd, buffer, nbuf);
		  nbuf = 0;
		}
	      cp += 2;
	    }
	  else
	    ++cp;
	}
    }

  write (fd, buffer, nbuf);
  close (fd);
  free (line);

  return 0;
}

Last modified: Thu Sep 6 15:31:26 PDT 2001