Blog
Previous Posts
January 2007| 01/26/2007 | Company Information Leakage and Web Search » |
| 01/23/2007 | What's In A Link » |
| 01/12/2007 | New MySpace Phish using CSS. » |
| 01/04/2007 | Multi-hack...defaced site hosting Phish. » |
| 01/02/2007 | MOTW: "Skype" Trojan Analysis » |
+ December 2006
+ November 2006
+ October 2006
+ September 2006
+ August 2006
"Skype" Trojan Analysis
Last week, we received a sample that was spammed to a Skype user through a message containing a link. The user clicked on the URL and downloaded a file named sp.exe that was executed. This trojan, is not to be confused with the Chatosky malware which also propagates through skype chat messages.
This week i will present the analysis of sp.exe because it is an interesting case study. This trojan uses interesting techniques such as encrypted data, obfuscated function loading, delta based data addressing (for injected code), its own IAT-like array that get injected into the remote processes, the offsets made up to call various subfunctions (no direct cross references), the download of payloads from a remote website for execution on the heap, and etc.
The file was protected with "NTkrnl Secure Suite", a commercial protection system using anti-cracking techniques, polymorphic engines, and other interesting features.
Unpacking
I won't provide too much details on how I unpacked the sample because it uses a commercial product, but I feel comfortable talking about the copy pasted code.
The main protection scheme I faced was the copy pasted from my Honeynet Scan of The month 33 Challenge. The breakpoint detection was 100% identical, even the numbers I had generated randomly. More importantly, the technique I had written based on SEH + cpuid/rdtsc was also copied. The only difference was that they used the EDX register to compare the timing.
Copy pasting protection code without even changing it a little, provides no security at all and allowed me to unpack it even quicker. (gotta love looking at code you wrote 2 years ago)
It apparently included some other tricks, that made it a little harder to unpack, and the file looked like it was corrupted at some point. In order to debug it and comment my disassembly in a readable way, I opted to use a userland debugger, and thus had to write a little shellcode for injection into the packed malware. Basically, it entailed abusing Windows Exception Handling (using a hook), to get past every check. After that, one could attach his favorite userland debugger to the malware and eventually find the Original Entry Point. Although the imports rebuilding for this protector isn't hard at all, it wasn't mandatory in this executable as it only imported one function: ExitProcess
The malcode is resolving its own imports whenever it needs to call some Windows functions, without any function (emulated GetProcAddress), which rendered one of the protection features useless.
Getting an unpacked sample wasn't all that hard in the end.
Unpacked Sample Analysis
Encrypted data
We did not see any strings when disassembling the unpacked sample. However a very obvious decrypting loop is right after a few instructions. Here, you can see encrypted strings and the "XOR" used to decrypt them:

Once decrypted, you can see some interesting strings such as CLSID and host address:
API Functions Resolution
Analyzing this sample takes quite some time because there is no imported functions beside ExitProcess, and a big amount of code is injected in different processes. Every time the trojan needs to call a function, it will resolve it dynamically using some shellcode like functions:

Every time it needs to call or load a function, a 32-bit hash is pushed onto the stack. (eg: push 0DB5DAD8Ch). The EDI register holds the address of the GetAPI function, which is basically a GetProcAddress emulation routine. The address of the HASH calculation routine is also passed onto the stack, in order to make it a little harder for the analyst to understand the GetAPI function's code flow.
The hashing technique is very common in shellcode, where they are used mainly to make smaller code. In this trojan, there is no size limitation, the main purpose is obfuscation. To identify the function called/resolved, you need to get the function corresponding to the Hash passed as a parameter. There are no plain text API function name in this sample.
All resolved functions are then saved in an IAT-like array, and will be injected in remote processes later on. This way the injected code won't need to resolve any already used functions.
In order to analyze the code, I had to create structures (for the IAT array), rename dwords and other things. Here is an example of code before and after modification in IDA:

Explorer.exe Injection
The trojan scans for running processes and looks for "explorer.exe". The function tasked to do it takes two parameters:
- The string to scan for "explorer.exe"
- The array / structure used to hold API function addresses.

The function simply uses CreateToolHelp32Snapshot functions to list running processes. The process is then opened with "PROCESS_ALL_ACCESS" and some memory is allocated. As usual, the authors passed everything as parameters to the "alloc_and_inject" function:
- Address of the code to inject in the remote process
- Process Handle
- Address of the API structure
Once injected, the trojan makes up offsets relative to the memalloc base address. To make the analysis harder, there won't be any cross references between routines. This also allows the downloaded payload to call functions that aren't present in the assembled routine. I calculated and renamed every offsets in order to be able to follow the code in the static disassembly:

The "alloc_and_inject" function is called yet another time, this time the IAT array like is injected in the remote process. This way, the injected code has its own Import Address Table. Finally, the trojan uses CreateRemoteThread to execute the code in explorer.exe context.
To follow the disassembly, we need to disassemble the code I renamed to
"Code_to_be_executed_in_remote_process". This is where the structure feature in IDA really shines:
Explorer Injected Stub Analysis

Simple "Stealth" trick
After that, the trojan keeps resolving interesting functions, some of them are part of a keylogger feature that we will see later on.
In order to fool infected users, the trojan copies itself into the system32 directory and use the hal.dll time stamp. This way, if someone tries to list newly created files, the trojan won't appear in the list. Indeed, its time stamp will be a lot older.

Auto Restart Technique
Inside Explorer context, the injected code will open the registry key "HKEY_CURRENT_USER\Software\Microsoft\Active Setup\Installed Components\" and delete the CLSID. Then, it will create the same key, but in: "HKEY_LOCAL_MACHINE\Software\Microsoft\Active Setup\Installed Components\{2D0CCE2D-2EEF-4432-0503-
020002010803}".
It sets the value to "C:\WINDOWS\system32\wmp.exe" in order to restart when the machine reboots.
Default Browser Injection
In order to bypass a few personal firewalls, another stub is injected in the default browser. The injection is made from explorer.exe and it might trick some monitoring tools trying to detect RemoteThreads. It first read the registry to get the default browser path:

The code is identical to explorer injection, the only difference is that it runs the browser itself to inject it. (process is hidden at creation too)

The injected code will be discussed later. Once the browser is injected, the explorer stub will install a keylogger.
Keylogger component
The trojan will then install a keylogger. First it will create a Mutex Object "_wmpkl_". The keylogger is installed using "SetWindowsHook" function:

The Call Back is very simple and uses standard functions for keyloggers:

The keylogger creates a log file (wmp) inside the System32 directory which looks pretty messy (buggy?). The author didn't spend much time on the log creation as you can see below:

Browser Injected Stub Analysis
This stub loads WS2_32.dll and begins resolving a lot of winsock API functions. Things start to get interesting in this part of the code. The stub will resolve "nsdf.no-ip.biz" and connect to it on port 1100. Using "recv", data are placed onto the heap.
The received data is actually another stub to be executed. Our trojan is thus getting code from a remote server for execution on the heap. This technique allow easy payload update, bug fix, and allow for payload removal at anytime, which can lead to missing code during analysis.
Here is where the stub starts to execute the downloaded binary data:

Thanks to IDA's load additional binary feature, I added the downloaded binary file in my IDB.
From there, I found that the stub allocates many pages where code from the remote server will be copied to. Then, it uses an undocumented API function to decompress data:

Data after decompression:

As you can see, these are very interesting DLL names. After that, a new thread is created in the browser. The primary thread will eventually ExitThread.
They are loaded using LoadLibraryA. Another thread is created. After that, the stub tries to set the SeDebugPrivilege.
From here on, I couldn't get much more, and the code seems to fail for some reason. People mentioned that this trojan might use the Skype SDK, but I haven't seen any references to RegisterWindowMessageA, and found no strings such as "SkypeControlAPIAttach" or "SkypeControlAPIDiscover".
Prior to this, the code will also get information on the local machine such as the computer name, the username, Windows version, and then start playing with ProcessPriorityClass.
The code seems to use a few more undocumented API calls, which might explain why it failed on my test
machines. It crashes with some access violation error.
Outro
This trojan was fun to analyze, a lot of threads, remotethreads, obfuscation, protected by a commercial protector and even code that gets downloaded from a remote server. I will continue my investigation and update this report should I find any references to Skype. From what I have seen, I believe the author is a rather good programmer, even though some of the written code appears to be useless.
Researcher: Nicolas Brulez, Websense Security Labs
Post a Comment:







