Untangling Kovter's persistence methods

Untangling Kovter’s persistence methods

Kovter is a click-fraud malware famous from the unconventional tricks used for persistence. It hides malicious modules in PowerShell scripts as well as in registry keys to make detection and analysis difficult. In this post we will take a deep dive into the techniques used by it’s latest samples to see all the elements and how they cooperate together.

Analyzed samples

#1:

2#:

// special thanks to

@F_kZ_

  and @JAMESWT_MHT for sharing the samples

Behavioral analysis

Authors of Kovter put a lot of effort in making their malware stealth and hard to detect. During the initial assessment of some of the Kovter samples we could notice that it is signed by valid Comodo certificate (it got revoked later):

comodo_signed

After the sample gets deployed, Kovter runs PowerShell and install itself in the system

powershell_install

Observing it via Process Explorer we can find the command passed to PowerShell. It’s purpose is to execute a code stored in an environment variable (names are random, new on each run), i.e:

$env:nvwisqng
psh_val

Content of the variable is a base64 encoded PowerShell script:

env_val

After that initialization phase, we can see PowerShell deploying regsrv32.exe (via which Kovter runs  it’s modules):

regsrv

Examining the network activity we can notice many new connections with the regsrv32.exe that are appearing and disappearing:

kovter_activity

We can expect that it is related with the click-fraud activity, performed by the malware.

Inside

Unpacking

Kovter comes packed by a crypter/FUD. After unpacking it we get the loader that is another PE file. It comes with a binary data in the resources:

resource1

Content of the resource is a next PE file, encrypted and compressed with aPLib (we can easily recognize the algorithm by the typical way in which it modified MZ header):

aplib_packed

During the execution, this unpacked PE file is loaded into an newly allocated, continuous area in the memory (without dividing content into sections). The original (host) sample loads all the necessary DLLs and applies relocations on the new module. Then, the execution is redirected there (see below):

redirect_to_payload

Payload’s Entry Point:

new_EP

This executable turns out to be a final stage, containing the core malicious functions. Looking at it’s strings (that are not obfuscated) we can find that this is the module responsible for further steps of infection – writing the registry keys, dropping malicious scripts etc. The easiest way to proceed with the analysis would be to dump the payload and analyze it as a separate entity. However, authors of the malware added some tricks in order to prevent this executable from running independently. When we dump the unpacked payload and try to run it, it will crash:

crash1

Analyzing the point of crashing, we can see the reason – trying to read unaccessible memory:

crash_reason

As we can see in the above code, sample reads it’s own headers and find the end of the mapped module (ImageBase + VirtualSize). Then it tries to read from the address that is exactly after it. In case if the sample was loaded via the host application, this address is accessible and the content is filled with appropriate value – see the example below:

accessible_val1

The read value points to the address where some content has been written – including the path to the current sample:

read_part

However, it doesn’t work if the sample was executed independently. That’s why we encounter the crash. Anyways, the dump can be very useful for the static analysis.

Persistence

Kovter achieves persistence by adding a Run key in the Windows Registry. Access to this key via regedit is restricted:

cannot_display_key

But using Sysinternals‘s tool – autoruns still we can see where it leads:

autorun

It refers to the link that leads to a batch script, running a dropped file of an unknown format:

dropped

This file with the extension .d7e6b has unreadable content and it doesn’t make much sense until we notice how it is opened. Kovter’s executable, during the installation process, registered in the Windows Registry a special way to run this type of files.

Added extension .d7e6b is handled by a newly defined command df01:

added_extension

That command is defined in another registry key (…df01shellopencommand):

reg_command

It uses a system application mshta.exe in order to run the JavaScript that decrypts the content of the file in memory and loads it.

Content of the script:

jATFuw4="wQfAd"; ZF3=new ActiveXObject("WScript.Shell"); XZs6HOl="uE6"; gdV5K2=ZF3.RegRead("HKCU\software\nsem\tnxm"); a0ZRS="gBz"; eval(gdV5K2); CcsujQ6="N61cuVbU"; 

It refers to other dropped registry keys, saved under a different path (names are different for different samples – in the current sample it is: “HKCUsoftwarensem“):

other_keys

Inside the variable tnxm another obfuscated script is embedded:

https://gist.github.com/hasherezade/184b23a2a98831061fc4b18473078542#file-tnxm-js

The script contains simple obfuscation – variables have meaningless names and some unused strings are added in between to create a noise. After renaming variables and removing junk the same code looks much more readable:

https://gist.github.com/hasherezade/184b23a2a98831061fc4b18473078542#file-tnxm_deobfuscated-js

The hex_string contains hexadecimal representation of an encrypted code. It is processed by the following two loops. First loop converts it from the text representation into a binary. Second one – performs XOR decryption (the XOR key is random, generated newly on each run). Then, the result is executed by eval function.

Decrypted content: https://gist.github.com/hasherezade/184b23a2a98831061fc4b18473078542#file-txnm_deobfuscated_decoded2-ps1 The base64 content is the same like the one we encountered during behavioral analysis – (it was set in in the environment variable).

https://gist.github.com/hasherezade/184b23a2a98831061fc4b18473078542#file-nvwisqng-txt

After decoding it turns out to be a PowerShell Script:

https://gist.github.com/hasherezade/184b23a2a98831061fc4b18473078542#file-nvwisqng_decoded-ps1

It’s role is to load and execute the code hidden in the variable $sc32. It contains position-independent 32bit code (it will be referred as a shellcode). Content is loaded to the newly allocated memory page and executed in a new thread. Pointer to the allocated memory is passed to the  thread as a parameter (it is very important, because this address is further used for resolving pointers to variables).

Below you can see the beginning of this code, converted to binary:

implant_code

Every shellcode must be self-sufficient in loading all the required imports. For this purpose, this one uses a trick known from from ReflectiveLoader and shellcodes generated by Metasploit platform. At the beginning of the execution it tries to get the handle of kernel32.dll. To achieve this goal, it enumerates all the loaded modules, calculates checksums of their names and compares them with the hardcoded checksum (0x6A4ABC5B). Similarly, it uses checksums to get handles to the functions inside the kernel32.dll.

With their help, it loads other necessary modules and functions, i.e advapi32.dll:

loading_other_modules

Then, uses them to open registry keys dropped during installation.

In the analyzed samples the read registry paths are appropriately:

  • sample#1: HKCUsoftwarensem -> zorsuhg
  • sample #2: HKCUsoftwarewuuu -> vfkhxfak
key_dump_ends_on_zero

Note, that if you try to export this key, it will appear very shot, because it’s preview will be cut on the first zero byte – it’s not the full length! Example:

exported_key

The value that was stored in the registry is read into the memory and decrypted (also in this case, the encryption key is random, newly generated on each run of the installer):

reg_value_content

It turns out to be a PE file (the same payload that was loaded before – by the loader executable):

payload_unpacked_from_key

Just like at the first execution, all the dependencies of the payload are resolved by the external loader (this time it is inside the shellcode). Then, execution is redirected there:

redirect_to_new_pe

That’s how the original module has been redeployed. Now, Kovter can continue with it’s mission.

Conclusion

Thanks to the techniques employed by Kovter, no executable needs to be dropped on the disk – that’s why is known as “fileless”. Even the file to which the initial link leaded does not contain any code to be executed. Instead, it is used just for the flow obfuscation. Running it, in reality leads to running the code stored in the registry, that is sufficient to unpack and re-run the real payload.

Persistence used by this malware is creatively designed and exceptional in comparison to most of the malware. Not only it is scattered into several layers, but also obfuscated at every stage and containing tricks that slow down the analysis process.

Summary of the elements used for the persistence

Kovter’s persistence is composed of various tiny elements that executes each other, sometimes in an indirect way, like:

  1. Run key in the registry
  2. link
  3. batch script running the file with a new extension
  4. command in the registry handling the added extension (in fact it is a JavaScript reading other dropped registry key and running it)
  5. JavaScript with xor
  6. PowerShell script with Base64
  7. PowerShell script decoding and running the shellcode
  8. shellcode reading the dropped registry key, unpacking the PE file from it and loading it in the memory

Appendix

http://www.symantec.com/connect/blogs/kovter-malware-learns-poweliks-persistent-fileless-registry-update


This was a guest post written by Hasherezade, an independent researcher and programmer with a strong interest in InfoSec. She loves going in details about malware and sharing threat information with the community. Check her out on Twitter @hasherezade and her personal blog: https://hshrzd.wordpress.com.

ABOUT THE AUTHOR