Disclaimer

Monday, May 27, 2019

URSNIF: Interesting API harvesting, Anti-Memory-Forensic and Decryption routine as VectoredExceptionhandler function.


Ursnif are quite active malware now a days, It is known in spam e-mail campaign using malicious document and also by using Steganography to hide its actual payload (usually Powershell script) from detection, that downloads a copy of itself in its C&C or sometimes other malware.

In this post I will just focus on some interesting technique that this malware do to bypassed or evade memory forensic or detection. so let's start. :)

Generating Decryption Key:

 In this variant the URSNIF will decrypt the .bss section by generating decryption key out of the creation file stamp of its binary file that are translated to a string within its .rdata section. In this case its " Apr  3 2019".

figure 1: generating the initial decryption key


after having the initial decryption key out of the file stamp string it will do another process where it will ROL it once to generate the final decryption key.

figure 2: generating the Decryption Key

Decryption of .bss Section:

Before it generates the needed decryption key it register its decryption routine function to an ExceptionHandler by using "AddVectoredExceptionhandler. that will call the decryption routine when exceptions happen.

figure 3: registering decryption routine to exception handler

figure 4: decryption routine for .bss section

figure 5: decrypted .bss section


Interesting API Harvesting:

Dynamic API resolver is a normal thing to malware to evade AV detection based on IMPORT API and to make the static analysis more time consuming. This ursnif variant show a quite interesting way to parse the API it needs.

After having the ImageBase of the needed module using "GetModuleHandleA" to parse all its needed API, it will call a function that traverse the export table and locate the VA pointer to the address of function of the API function she wants to use.

figure 6 : locating the Export Table


This function has 3 parameters, where the 2nd one is the name of the API it needs to parse. If this parameter is null, it will use the API hasher function to compute the hash of each exported function name within that module and then compare it to the API hash value place to its code body. if API was found, it will save and return the VA pointer of the address of function of that API.

figure 7: checking the 2nd parameter if available or not.

figure 8: save and return the VA ptr. of the address of function of the needed API.


VA to File Offset Converter Function:

Then it will convert that VA pointer to file offset using its own function converter and then it will open and read the dll module (e. g. kernel32.dll) and set the file pointer to that file offset to read the RVA address of function of that API.



figure 9: the func_VAToFileOfs that convert VA to file offset
figure 10: open and read the file offset of computed earlier to read the RVA Address of function of needed API.

Deleted MZ & PE of its Payload DLL in Memory:

This ursnif variant will decrypt the loader and the dll payload in the memory. But one notable thing with the DLL payload it will try to inject is that it tries to evade the memory forensic by decrypting it first to "READ & WRITE" memory allocation and then transfer to another allocated memory with executable attribute but without the header of the file. It will just locate the entry point to the dll it wants to execute. This technique is one of the many approach to evade memory forensic tool that look for the first 2kb bytes of  executable memory page in a process VAD tree or looking for common PE headers.


figure 11: The Loader decrypted in memory.

figure 12: the DLL payload decrypted in READ and WRITE allocated memory


figure 13: the DLL payload ready for execution in EXECUTABLE memory page but no PE HEADERS.

Conclusion:

Sometimes analyzing the minor part or even the code before the interesting events may give us some hint how malware tries to hide itself from detection and forensic perspective.

IOC:

Upon decrypting the .bss section of the dll payload you can see right away some useful IOC that it will execute, the POST command ,the setup for its file less execution command in registry and many more. Aside from that, there are encrypted string in reloc section that composed of the C&C server it will used to download updated copy of itself or another malware.



figure 14: IOC in decrypted .BSS section

figure 15: C&C server it will used to download another payload or update URSNIF malware.


Sha1: 140ceb574737761fa50622fa967575466985db1c
md5: 92f77609f4dbb0833cb024a3e3a4c116
Sha256: 9abfb714de8fd134faa9c99f213d300e2c3d655f1f6df401c7c96a00d600648b


 YARA Rules:


import "pe"

rule ursnif_crypter_win32_ {
    meta:
        author =  "tcontre"
        description = "detecting ursnif crypter"
        date =  "2019-05-26"
        sha256 = "9abfb714de8fd134faa9c99f213d300e2c3d655f1f6df401c7c96a00d600648b"

    strings:
        $mz = { 4d 5a }
    
        $code1 = { 83 48 FB FF 66 C7 40 FF 00 0A 89 48 03 66 C7 40 1F 00 0A C6 40 21 0A }
        $code2 = { 8B 35 60 45 45 00 83 C0 40 8D 50 FB 81 C6 00 08 00 00 3B D6 72 CD }
  
    condition:
        ($mz at 0) and  1 of  ($code*)
    
    }



import "pe"

rule ursnif_loader_win32_ {
    meta:
        author =  "tcontre"
        description = "detecting ursnif loader"
        date =  "2019-05-26"
        sha256 = "dc37550986164ff2b81ba0d8b6bb46a6d2f249c6052766e87cb3b88f01852649"

    strings:
        $mz = { 4d 5a }
        $bss_check = { 81 39 2E 62 73 73 75 07 39 41 04 75 02 8B D1 }
        $code1 = { 8A 4C 24 10 D3 C0 83 C7 04 33 C6 33 C3 8B F0 89 32 83 C2 04 }
        $code2 = { 33 C3 33 45 0C 83 C7 04 FF 45 FC 8B D9 8A 4D FC D3 C8 89 06 83 C6 04}
       
  
    condition:
        ($mz at 0) and  $bss_check and 1 of  ($code*)
    
    }



import "pe"

rule ursnif_dll_payload_win32_ {
    meta:
        author =  "tcontre"
        description = "detecting ursnif dll payload in memory"
        date =  "2019-05-26"

    strings:
        $sig1 = "version=%u&soft=%u&user=%08x%08x%08x%08x&server=%u&id=%u&type=%u&name=%s" fullword
    $sig2 = "rundll32 shell32.dll,ShellExec_RunDLL" fullword wide
        $sig3 = "name=\"upload_file\"; filename=\"%.4u.%lu\"" fullword
        $sig4 = "IE8RunOnceLastShown_TIMESTAMP"

  
    condition:
        3 of  ($sig*)
    
    }





"Reg Restore" Odyssey: Journey to Persistence And Evasion

The Windows Registry, a fundamental component of the Windows Operating System, empowers users to fine-tune system policies and manipulate lo...