Jump to content
Nytro

KINS malware: initialization and DNA paternity test

Recommended Posts

Posted

KINS malware: initialization and DNA paternity test

A new post about KINS, I don’t have anything interesting on my hands right now so I decided to go on with the analysis of it. This was my first idea, but someone (Thanks Michael) suggested to me something to add to the analysis. The idea comes from a simple question: is KINS a new myth or is it just born from the leaked Zeus source code? Well, I’ll start looking at KINS with an eye to Zeus trying to understand if there are some similarities or not.

Holidays are coming and I don’t have a lot of free time for a complete analysis of the entire malware, right now you have to be satisfied with just the ground of KINS and Zeus_leaked_source_code, the initialization part only. It’s generally an annoying job but from the ground you can understand a lot of information of the malware. Anyway, I’ll try to write something light and readable.

Reference KINS malware: md5 = 7b5ac02e80029ac05f04fa5881a911b2

Reference Zeus leaked source code: version 2.0.8.9

Encrypted strings

Strings are always a good starting point and like almost all the malwares out there every suspicious string has been crypted, most of the time a simple xor encryption would suffice. KINS doesn’t decrypt all the strings in a unique time, it decrypts a single string when it has to use it.

Inside the .text section there’s an array of _STRINGINFO structures, each structure contains the necessary data about a single encrypted string:

00000000 _STRINGINFO struc ; (sizeof=0x8)
00000000 key db ? ; xor key used to decrypt the encoded string
00000001 db ? ; undefined ; unused because xor key is 1 byte only
00000002 size dw ? ; size of the string to decrypt
00000004 encodedString dd ? ; string to decrypt
00000008 _STRINGINFO ends

When the malware needs a string it calls DecryptStringW passing an index to it, the index is the array index:

4231CA DecryptStringW proc near
4231CA movzx eax, ax ; Id of the string to decrypt
4231CD lea eax, STRINGINFO[eax*8] ; current _STRINGINFO identified by the index
4231D4 xor ecx, ecx
4231D6 xor edx, edx ; iterator index
4231D8 cmp cx, [eax+_STRINGINFO.size]
4231DC jnb short loc_423209
4231DE push ebx
4231DF push edi
4231E0 DecryptStringIterator:
4231E0 mov edi, [eax+_STRINGINFO.encodedString]
4231E3 movzx ebx, [eax+_STRINGINFO.key]
4231E6 movzx ecx, dx
4231E9 movsx di, byte ptr [edi+ecx]
4231EE xor di, bx ; xor with key
4231F1 xor di, dx ; xor with iterator index
4231F4 mov ebx, 0FFh
4231F9 and di, bx ; the result is a unicode string
4231FC inc edx ; increase iterator index
4231FD mov [esi+ecx*2], di ; decrypt byte by byte
423201 cmp dx, [eax+2]
423205 jb short DecryptStringIterator
423207 pop edi
423208 pop ebx
423209 loc_423209:
423209 movzx eax, [eax+_STRINGINFO.size]
42320D xor ecx, ecx
42320F mov [esi+eax*2], cx ; put NULL at the end of the string
423213 retn
423213 DecryptStringW endp

A double xor operation over every byte of the encrypted string. KINS uses the same structure (_STRINGINFO) and the same decryption method (DecryptStringW) used by Zeus_leaked_source_code. It’s a perfect copy&paste approach. There are a lot of strings declared inside the exe, a comparison of the decrypted string is necessary. To decrypt all the string inside KINS you can use this simple idc function script:

static ListStrings(address)

{

auto iString;

auto sInfo;

auto xorKey;

auto sLen;

auto crypted;

auto i;

Message("\nDecrypted string list:\n");

iString = 0;

while((address + iString) < 0x4026C8) {

sInfo = address + iString;

xorKey = Byte(sInfo);

if (xorKey != 0) {

sLen = Word(sInfo+2);

crypted = Dword(sInfo+4);

if (!((crypted MaxEA()))) {

Message("\"");

for(i=0;i<sLen;i++)

Message("%c", Byte(crypted+i) ^ xorKey ^ i);

Message("\"\n");

iString = iString + 7; // sizeof(_STRINGINFO) - 1

}

}

iString++;

}

}

The result list contains a lot of interesting strings but comparing this list with the original one provided by Zeus you can note a lot of equal strings. I have to admit that there are some new entries but the core remains the same.

Init

KINS initialization resides inside a snippet of code starting @407A25 and ending @407C73. It performs all the necessary tasks needed for a clear execution of itself.

Looking inside the code you’ll notice that Init procedure is referenced by two different places, one at the beginning of the malware and the other one during its execution.

Besides, Init has a lot of calls inside but not all are executed at the first time. That’s because KINS has 2 level of initialization, it has to sets some things now and some later. The first level of execution is performed at the very beginning of the code and the second level is executed when particular operation has to be done. I’ll tell you something more about this 2° level in the next blog post. I.e.: the process injection feature requires the execution of parts of the Init procedure that are not scheduled in the first execution of Init.

I think KINS doesn’t want to spoil a lot in his first part of the code, and prefer to follow an exact time scheme. I said KINS but I should say Zeus because this particular code structure is the same used by Zeus. Moreover, there’s another piece of code taken by a copy&paste: to decide what to setup the first time and what later Init checks the dword value passed as a parameter, I call it “flags”. flags is checked inside some if statements, here is a practical example:

.text:00407A31 mov eax, [ebp+flags] // INITF_NORMAL_START the first time, (INITF_INJECT_START | INITF_HOOKS_FOR_USER) the next one
...
.text:00407A36 mov esi, eax
.text:00407A38 and esi, 1 // Check for INITF_INJECT_START flag bit
.text:00407A3B mov [esp+420h+flags_Core], esi
.text:00407A3F jnz short loc_407A4B
.text:00407A41 xor ebx, ebx // First time
.text:00407A43 mov processFlags, ebx
.text:00407A49 jmp short loc_407A4D
.text:00407A4B xor ebx, ebx // Second time
.text:00407A4D call InitLoadModules

flags represents the value passed to Init, the first time flags’s value is 0 (INIT_NORMAL_START) and the second time is 3 (INITF_INJECT_START | INITF_HOOKS_FOR_USER).

I have started the analysis right now but copy&paste method has been used a lot of times. For a better explanation I announce you that KINS is heavily based on Zeus_leaked_source_code. Some parts are really equals, some parts have minor changes only, some of them have interesting additions and some of them are from Zeus version above 2.0.8.9. Yes, KINS writers took something from more than one Zeus version.

Copy&paste

As far as I’ve seen the core of the malware is equal to Zeus’s core. It’s based on the same structures, variables and code design. Here is a list of things that are directly taken from Zeus.

- Global variables

Global variables is one of the first things I tried to understand, and I have to say that most of them are simple flags used to recognize a particular status or event. You can recognize them from the code looking at mov instructions:

407C34 mov ref_count, ebx
407C3A mov reportFile, ax
407C40 mov registryKey, ax
407C46 mov readWriteMutex_localconfig, ax
407C4C mov registryKey_localconfig, ax
407C52 mov readWriteMutex_localsetting, ax
407C58 mov registryKey_localsetting, ax

- Memory initialization

The malware will need dynamic allocated memory, you can find the initialization memory code starting from @407A5D. This time you can see a mix of flag/variable init:

407A5D push ebx
407A5E push 80000h
407A63 push ebx
407A64 call ds:HeapCreate
407A6A mov mainHeap, eax
407A6F cmp eax, ebx
407A71 jnz short HeapCreate_OK
407A73 call ds:GetProcessHeap
407A79 mov hHeap, eax
407A7E mov heapCreated, bl ; heapCreated = false;
407A84 jmp short loc_407A8D
407A86 HeapCreate_OK:
407A86 mov heapCreated, 1 ; heapCreated = true;

mainHeap is a global variable and heapCreated is just a flag used to set the success or not of the heap creation process.

- Crypt initialization

Crypto is used by KINS and like all the other functionalities it requires a small place inside Init.

407A9A mov _last_rand_tickcount, ebx ; _last_rand_tickcount = 0;
407AA0 mov crc32Intialized, bl ; crc32Intalized = false;

From the only two lines of code used to perform this init operation it’s hard to predict the meaning of them but, again, flag and var are used.

If you want to understand some more things about them you can try with xref IDA option. After some more investigations you can understand their real use:

_last_rand_tickcount is used in comparison between a value obtained by GetTickCount and the previous tick count value.

crc32Initialized is true if crc32 has been initialized, false otherwise.

- Winsock initialization

Another expected feature of the malicious program is the ability to communicate with the server. A malware should send something to the server, and to start this communication process it needs a call to a function like WSAStartup. The winsock part is all inside a single call instruction to WSAStartup. KINS and Zeus initiate a client-server communication in the same classical way.

- initHandles, initUserData, initPaths

The name of the 3 procedures used above are taken from Zeus_leaked_source_code, and I put them together because they initialize global variables only.

The procedures are not so interesting per se.. To sum-up I can say that KINS creates a manual reset event, it gets the security information of a logon access (it saves two values: the length of the logon security identifier (SID) and an Id which is calculated by crc32(SID)), and it gets the full path for KINS executable.

- initOsBasic

The last fully copy&paste code contains Os based tasks. It starts determining whether KINS is running under WOW64 or not. The status is saved inside a boolean flag and after that it tries to add a new full access security descriptor. Once again it saves the result of the operation, it’s not a flag variable but a structure with information about the security descriptor. An empty structure means an error during the task. If everything goes fine, KINS produces a 16 bytes long identifiers based on the volume GUID path:

41D9C0 push 64h ; cchBufferLength
41D9C2 lea eax, [ebp+74h+szVolumeName]
41D9C5 push eax ; lpszVolumeName
41D9C6 lea eax, [ebp+74h+szVolumeMountPoint]
41D9CC push eax ; lpszVolumeMountPoint
41D9CD call edi ; GetVolumeNameForVolumeMountPointW
41D9CF test eax, eax ; check the result
41D9D1 jz short GetVolumeNameForVolumeMountPointW_FAILS
41D9D3 cmp [ebp+74h+sz], '{' ; a minor check over the obtained string
41D9D8 jnz short ERROR
41D9DA push [ebp+74h+pclsid] ; pclsid
41D9DD xor eax, eax
41D9DF mov [ebp+74h+var_68], ax ; str[38] = 0;
41D9E3 lea eax, [ebp+74h+sz]
41D9E6 push eax ; lpsz
41D9E7 call ds:CLSIDFromString ; ottiene:

GetVolumeNameForVolumeMountPoint could fail, just in case the snippet above can be executed more than one time. The first lpszVolumeMountPoint value is obtained calling SHGetFolderPath. In case GetVolemeNameForVolumeMountPoint fails the new lpszVolumeMountPoint string is obtained cutting the last part of it (it uses PathRemoveFileSpec). I.e.: it tries “C:\WINDOWS\” and then with “C:\” only.

From the organization of the code and the large variety of flags/variables used seems like there’s a big focus to the details. If something goes wrong, or if KINS thinks that it doesn’t have the right condition to run it stops running. I.e.: KINS uses a variable to store a value obtained from the combination of the Os version and the integrity level. If the value is out from a range of specific acceptable values the malware stops.

That’s why Zeus was, from some points of views, a master-piece. Yes, I said Zeus and you know why.

Copy&paste with minor changes

It happens when the code structure of a procedure is the same of the original version but there are some changes or additions. It’s the case of the InitLoadModules function, basically it’s a sequence of DecryptString/GetProcAddress calls. The list of functions address to retrieve is slightly changed from Zeus. The new list is composed by: NtCreateThread, NtCreateUserProcess, NtQueryInformationProcess, NtQueryInformationThread, RtlUserThreadStart, NtMapViewOfSection, NtUnmapViewOfSection, NtSuspendProcess, NtResumeProcess, NtClose and LdrFindEntryForAddress.

I don’t know if it’s a KINS addition or it’s taken from a Zeus new version. I’m not a security expert and I can’t access all the possible Zeus versions but it’s a doubt I have: KINS takes some concept from other Zeus versions (over the one I’m referring to, 2.0.8.9).

Copy&paste from more recent Zeus version

Here’s a practical example of my doubt, the anti check routine! As I said before KINS runs under particular conditions, and his continuation depends on the values returned by the 8 calls called here. Every call performs a specific check:

- CheckForPopupKiller: look for “C:\popupkiller.exe” file, if it exists KINS aborts

- CheckForExecuteExe: another unwanted file on the system is “C:\TOOLS\execute.exe”

- CheckForSbieDll: it’s time for a dll check, it tries to load “SbieDll.dll” (Sandboxie related dll), it won’t that dll on the system

- CheckMutexFrz_State: the mutex under the observation is Frz_State which is from Deep Freeze software

- CheckForNPF_NdisWanIp: the network related tool check, KINS doesn’t want “\\.\NPF_NdisWanIp” on the system

- CheckForVMWareRelatedFiles: VmWare is strictly prohibited: “\\.\HGFS” and “\\.\vmci” are the file to look for

- CheckForVBoxGuest: even VirtualBox is prohibited (“\\.\VBoxGuest”)

- CheckForSoftwareWINERegKey: check the existence of the key “Software\WINE”

If one of the calls above fails KINS aborts his execution immediately.

There’s no trace of this code inside Zeus_leaked_source_code but I read some articles on the net talking about this specific snippet. You can read something here

Snippets based on Zeus with KINS specific features

That’s the most interesting part of the malware Init, the place where something new join the party! In this part of the code the malware tries to create some Id values, they are based on the machine components and properties (computer name, version information, install date, GUID, physical memory and volume serial number). Zeus does the same but it uses a simple xor decryption, crc32 and Rc4 in his calculations. KINS substitutes everything with the use of his personal virtual machine combined to crc32, Rc4, Sha1 hash algorithm and some brain blasting calculation. I won’t go in details right here but if you need it drop me a mail and I’ll tell you more.

Basically, the addition are strictly related to the use of the virtual machine only. I gave a description of the virtual machine here, but I didn’t talk about his usage inside the malware. The VM is called some times during the life time of the malware but every time the VM modifies DataBuffer in the same way (it means the algo produced by the VM is always the same). When the VM ends, a number of bytes from DataBuffer are taken for the specific usage; in this initialization process they are used as a key for Rc4 algo.

Imho, it’s quite strange approach. I don’t know why you have to call the same algo a lot of times, especially when the result is always the same. Maybe it’s just a way to confuse the job of the reversers out there or maybe I’m missing something…

Is KINS a new myth or is it just born from the leaked Zeus source code?

Well, I’m not a security expert and I can’t say it for sure but judging from what I’ve seen so far I think that KINS is strongly based on Zeus_leaked_source_code, they have the same DNA! It’s the same concept of the real life, KINS has something completely new, but the core comes from the father, Zeus. Anyway, this is only an introduction to the DNA paternity test. Now I would like to know if we can apply the same concept to all the features of both malwares. Maybe soon, now it’s holiday time!

Sursa: KINS malware: initialization and DNA paternity test | My infected computer

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...