Digging a Hole Through Obfuscated VBA Malware

02 July 2020 — Written by SYN

Hello there! How are you doing this fine day? Welcome to my blog post about a fascinating tool which can make your computer’s life hell if you’re not careful enough :P

Macro Malware are very common in the threat world, and it has been in use since Macros were introduced in various applications. The most common type of Macro Malwares is seen in Visual Basic as, Microsoft Introduced Visual Basic for Applications (commonly known as VBA) in their Office product line so users can automate a lot of their day to day work while dealing with office productivity.

Due to some function calls present in VBA, which can easily be used to download a payload from the internet and infect someone’s computer, this has resulted into VBA Macros to be weaponized due to this and little did we know, this thing will be the most used malware in Phishing Campaigns done by APTs all around the world.


Introducing vba-obfuscator, a tool which obfuscates VBA macros in a simple, yet very effective way. This tool was made by bonnetn (Github) as a 2018 School Project. Very neat python tool which takes a VBA script and obfuscates it with multiple methods involved. Here is a sample payload delivery macro malware obfuscated with this obfuscator.

Except for the Auto_Open subs, you can’t figure out what is going on because the function names and variable names have been obfuscated with what seems to be Base64. But if you try decoding a Base64 variable name, it returns random characters which again doesn’t make any sense.


Now let’s look at the VirusTotal Detection of this file:-

vba macro obfuscator analysis vt

This sample file’s detection has increased from 8 to 19 over all. But if we take a harmless obfuscated file which prints Hello World, it gives us 5 detections. While 19 detections (at the time of writing) is still good, but let’s see what Inquest Labs has to say about our sample file:-

vba macro obfuscator analysis inquest

If we read the comment, we see that most of the malicious traits and suspicions are based on the obfuscation. Not what the file does to the system. So now, what do we do? Well we figure out what the obfuscated code does!


DISCLAIMER: I am doing everything here for research purposes, this program is meant for research purposes and neither me or bonnetn are responsible for your actions. For the research, I take a sample Hello World VBA Macro and obfuscated it using the tool.


Sample Code:-

Sub HelloWorld()
MsgBox "Hello World"
End Sub

Obfuscated Code:-

DQdqmDHFAZsXlO       As Boolean
Private phLmzjBheZF((0 Xor 0) To (5 Xor 58))  As Byte
Private QKJZqUIcJuC((0+(0 Xor 0)) To (51 Xor 76)) As Byte
Sub nzOxchBVlT()
MsgBox hhWpOZVspDmEP(Array((2+7),(0 Xor 36),(190+(8 Xor 1)),((41 Xor 89)+131)),(0 Xor 0)) & hhWpOZVspDmEP(Array((134+57),133,((30 Xor 1)+162),(0+(64 Xor 213)),((61 Xor 122)+(0 Xor 29)),(50+134),237),(2+2))
End Sub
Public Function KWcnPHwXPA(ByVal WyGwDJjQmpPM As String) As Byte()
If Not DQdqmDHFAZsXlO Then VjSimTuxaHK
Dim YusDIhkwWF() As Byte: YusDIhkwWF = jIuArLmtySP(WyGwDJjQmpPM)
Dim eqmzXFGApJxQ As Long: eqmzXFGApJxQ = UBound(YusDIhkwWF) + (1+(0 Xor 0))
If eqmzXFGApJxQ Mod (1 Xor 5) <> 0 Then Err.Raise vbObjectError, , ""
Do While eqmzXFGApJxQ > 0
If YusDIhkwWF(eqmzXFGApJxQ - 1) <> Asc("=") Then Exit Do
eqmzXFGApJxQ = eqmzXFGApJxQ - (1 Xor 0)
Loop
Dim OqhxSKRyhLn As Long: OqhxSKRyhLn = (eqmzXFGApJxQ * (0+(3 Xor 0))) \ (3+(0 Xor 1))
Dim MTtJcOcfrKhv() As Byte
ReDim MTtJcOcfrKhv((0 Xor 0) To OqhxSKRyhLn - 1) As Byte
Dim EtCjywfjssUWc As Long
Dim XjDMeszHGiIFe As Long
Do While EtCjywfjssUWc < eqmzXFGApJxQ
Dim tkPecfFdocqqBt As Byte: tkPecfFdocqqBt = YusDIhkwWF(EtCjywfjssUWc): EtCjywfjssUWc = EtCjywfjssUWc + ((1 Xor 0)+0)
Dim CAWpFwggkrrZh As Byte: CAWpFwggkrrZh = YusDIhkwWF(EtCjywfjssUWc): EtCjywfjssUWc = EtCjywfjssUWc + 1
Dim ujzMwVqMml As Byte: If EtCjywfjssUWc < eqmzXFGApJxQ Then ujzMwVqMml = YusDIhkwWF(EtCjywfjssUWc): EtCjywfjssUWc = EtCjywfjssUWc + 1 Else ujzMwVqMml = Asc("A")
Dim QVokeaazcWcAqh As Byte: If EtCjywfjssUWc < eqmzXFGApJxQ Then QVokeaazcWcAqh = YusDIhkwWF(EtCjywfjssUWc): EtCjywfjssUWc = EtCjywfjssUWc + (1 Xor 0) Else QVokeaazcWcAqh = Asc("A")
If tkPecfFdocqqBt > (2 Xor 125) Or CAWpFwggkrrZh > (85+42) Or ujzMwVqMml > 127 Or QVokeaazcWcAqh > 127 Then _
Err.Raise vbObjectError, , ""
Dim mhKBvnFFuztlFT As Byte: mhKBvnFFuztlFT = QKJZqUIcJuC(tkPecfFdocqqBt)
Dim WAGoWUDaPZsf As Byte: WAGoWUDaPZsf = QKJZqUIcJuC(CAWpFwggkrrZh)
Dim CdOASRvZYFf As Byte: CdOASRvZYFf = QKJZqUIcJuC(ujzMwVqMml)
Dim uvMHorqBPp As Byte: uvMHorqBPp = QKJZqUIcJuC(QVokeaazcWcAqh)
If mhKBvnFFuztlFT > (0 Xor 63) Or WAGoWUDaPZsf > (28 Xor 35) Or CdOASRvZYFf > (9+(44 Xor 26)) Or uvMHorqBPp > (20 Xor 43) Then _
Err.Raise vbObjectError, , ""
Dim lTiZJdRtkLB As Byte: lTiZJdRtkLB = (mhKBvnFFuztlFT * ((1 Xor 2)+1)) Or (WAGoWUDaPZsf \ &H10)
Dim ySWAPIOelVOo As Byte: ySWAPIOelVOo = ((WAGoWUDaPZsf And &HF) * &H10) Or (CdOASRvZYFf \ 4)
Dim DtzSAaMlHrPSN As Byte: DtzSAaMlHrPSN = ((CdOASRvZYFf And (0+3)) * &H40) Or uvMHorqBPp
MTtJcOcfrKhv(XjDMeszHGiIFe) = lTiZJdRtkLB: XjDMeszHGiIFe = XjDMeszHGiIFe + (0 Xor 1)
If XjDMeszHGiIFe < OqhxSKRyhLn Then MTtJcOcfrKhv(XjDMeszHGiIFe) = ySWAPIOelVOo: XjDMeszHGiIFe = XjDMeszHGiIFe + (1+0)
If XjDMeszHGiIFe < OqhxSKRyhLn Then MTtJcOcfrKhv(XjDMeszHGiIFe) = DtzSAaMlHrPSN: XjDMeszHGiIFe = XjDMeszHGiIFe + 1
Loop
KWcnPHwXPA = MTtJcOcfrKhv
End Function
Private Sub VjSimTuxaHK()
Dim OIMIqegisYd As Integer, HYiTBTPmizHm As Integer
HYiTBTPmizHm = 0
For OIMIqegisYd = Asc("A") To Asc("Z"): phLmzjBheZF(HYiTBTPmizHm) = OIMIqegisYd: HYiTBTPmizHm = HYiTBTPmizHm + 1: Next
For OIMIqegisYd = Asc("a") To Asc("z"): phLmzjBheZF(HYiTBTPmizHm) = OIMIqegisYd: HYiTBTPmizHm = HYiTBTPmizHm + 1: Next
For OIMIqegisYd = Asc("0") To Asc("9"): phLmzjBheZF(HYiTBTPmizHm) = OIMIqegisYd: HYiTBTPmizHm = HYiTBTPmizHm + (0 Xor 1): Next
phLmzjBheZF(HYiTBTPmizHm) = Asc("+"): HYiTBTPmizHm = HYiTBTPmizHm + ((0 Xor 1)+(0 Xor 0))
phLmzjBheZF(HYiTBTPmizHm) = Asc("/"): HYiTBTPmizHm = HYiTBTPmizHm + ((0 Xor 0)+(0 Xor 1))
For HYiTBTPmizHm = 0 To 127: QKJZqUIcJuC(HYiTBTPmizHm) = (147+108): Next
For HYiTBTPmizHm = (0 Xor 0) To (61+(0 Xor 2)): QKJZqUIcJuC(phLmzjBheZF(HYiTBTPmizHm)) = HYiTBTPmizHm: Next
DQdqmDHFAZsXlO = True
End Sub
Private Function jIuArLmtySP(ByVal WyGwDJjQmpPM As String) As Byte()
Dim WAGoWUDaPZsf() As Byte: WAGoWUDaPZsf = WyGwDJjQmpPM
Dim ohnKHLnEngC As Long: ohnKHLnEngC = (UBound(WAGoWUDaPZsf) + (1+(0 Xor 0))) \ ((0 Xor 1)+1)
If ohnKHLnEngC = (0 Xor 0) Then jIuArLmtySP = WAGoWUDaPZsf: Exit Function
Dim CdOASRvZYFf() As Byte
ReDim CdOASRvZYFf((0+0) To ohnKHLnEngC - (0 Xor 1)) As Byte
Dim pulOTurWsADzsz As Long
For pulOTurWsADzsz = ((0 Xor 0)+(0 Xor 0)) To ohnKHLnEngC - 1
Dim OIMIqegisYd As Long: OIMIqegisYd = WAGoWUDaPZsf(((0 Xor 2)+(0 Xor 0)) * pulOTurWsADzsz) + (77 Xor 333) * CLng(WAGoWUDaPZsf(((0 Xor 2)+0) * pulOTurWsADzsz + (0+1)))
If OIMIqegisYd >= ((221 Xor 45)+(3 Xor 19)) Then OIMIqegisYd = Asc("?")
CdOASRvZYFf(pulOTurWsADzsz) = OIMIqegisYd
Next
jIuArLmtySP = CdOASRvZYFf
End Function
Private Function hhWpOZVspDmEP(oTMVKlBiyrDCp As Variant, NcuNirXMUBbUcq As Integer)
Dim nMFesEttTo As String
Dim PwFVZbOlxLL() As Byte
PwFVZbOlxLL = KWcnPHwXPA(ActiveDocument.Variables("IbcdbFKknevSZBHt"))
nMFesEttTo = ""
For HYiTBTPmizHm = LBound(oTMVKlBiyrDCp) To UBound(oTMVKlBiyrDCp)
nMFesEttTo = nMFesEttTo & Chr(PwFVZbOlxLL(HYiTBTPmizHm+NcuNirXMUBbUcq) Xor oTMVKlBiyrDCp(HYiTBTPmizHm))
Next
hhWpOZVspDmEP = nMFesEttTo
End Function

The obfuscated code is what you will find inside the Macro Document which I chose to be the sample.

Now running the sample macro document in any.app.run, I saw that the document made no API calls on the internet, so we can conclude that the script’s deobfuscation is self reliant, so all of the deobfuscation code will be present in the tool itself.

I have scoured through the code, and I have compared every obfuscated function and a sub with the non-obfuscated counterpart so it can be extremely clear as to what the script does.

Obfuscated Variables:-

Private DQdqmDHFAZsXlO       As Boolean
Private phLmzjBheZF((0 Xor 0) To (5 Xor 58))  As Byte
Private QKJZqUIcJuC((0+(0 Xor 0)) To (51 Xor 76)) As Byte

Deobfuscated Variables:-

Private InitDone       As Boolean
Private Map1(0 To 63)  As Byte
Private Map2(0 To 127) As Byte

The DQdqmDHFAZsXlO/InitDone variable checks if Private Sub VjSimTuxaHK/Init has been called or not by the function KWcnPHwXPA/Base64Decode.

The phLmzjBheZF/Map1 variable is needed for the Private Sub VjSimTuxaHK/Init.

The QKJZqUIcJuC/Map2 variable is needed for the KWcnPHwXPA/Base64Decode function.


Main VBA Sub:- (Calls the Deobfuscation Functions)

Sub nzOxchBVlT()
MsgBox hhWpOZVspDmEP(Array((2+7),(0 Xor 36),(190+(8 Xor 1)),((41 Xor 89)+131)),(0 Xor 0)) & hhWpOZVspDmEP(Array((134+57),133,((30 Xor 1)+162),(0+(64 Xor 213)),((61 Xor 122)+(0 Xor 29)),(50+134),237),(2+2))
End Sub

Sub calls the function hhWpOZVspDmEP/unxor to deobfuscate:-

Private Function hhWpOZVspDmEP(oTMVKlBiyrDCp As Variant, NcuNirXMUBbUcq As Integer)
Dim nMFesEttTo As String
Dim PwFVZbOlxLL() As Byte
PwFVZbOlxLL = KWcnPHwXPA(ActiveDocument.Variables("IbcdbFKknevSZBHt"))
nMFesEttTo = ""
For HYiTBTPmizHm = LBound(oTMVKlBiyrDCp) To UBound(oTMVKlBiyrDCp)
nMFesEttTo = nMFesEttTo & Chr(PwFVZbOlxLL(HYiTBTPmizHm+NcuNirXMUBbUcq) Xor oTMVKlBiyrDCp(HYiTBTPmizHm))
Next
hhWpOZVspDmEP = nMFesEttTo
End Function

Deobfuscated Function:- (vba-obfuscator/obfuscator/modifier/strings/crypt.py)

Private Function unxor(ciphertext As Variant, start As Integer)
    Dim cleartext As String
    Dim key() As Byte
    key = Base64Decode(ActiveDocument.Variables("{}"))
    cleartext = ""
    
    For i = LBound(ciphertext) To UBound(ciphertext)
        cleartext = cleartext & Chr(key(i+start) Xor ciphertext(i))
    Next
    unxor = cleartext
End Function

hhWpOZVspDmEP/unxor calls function KWcnPHwXPA/Base64Decode:-

Public Function KWcnPHwXPA(ByVal WyGwDJjQmpPM As String) As Byte()
If Not DQdqmDHFAZsXlO Then VjSimTuxaHK
Dim YusDIhkwWF() As Byte: YusDIhkwWF = jIuArLmtySP(WyGwDJjQmpPM)
Dim eqmzXFGApJxQ As Long: eqmzXFGApJxQ = UBound(YusDIhkwWF) + (1+(0 Xor 0))
If eqmzXFGApJxQ Mod (1 Xor 5) <> 0 Then Err.Raise vbObjectError, , ""
Do While eqmzXFGApJxQ > 0
If YusDIhkwWF(eqmzXFGApJxQ - 1) <> Asc("=") Then Exit Do
eqmzXFGApJxQ = eqmzXFGApJxQ - (1 Xor 0)
Loop
Dim OqhxSKRyhLn As Long: OqhxSKRyhLn = (eqmzXFGApJxQ * (0+(3 Xor 0))) \ (3+(0 Xor 1))
Dim MTtJcOcfrKhv() As Byte
ReDim MTtJcOcfrKhv((0 Xor 0) To OqhxSKRyhLn - 1) As Byte
Dim EtCjywfjssUWc As Long
Dim XjDMeszHGiIFe As Long
Do While EtCjywfjssUWc < eqmzXFGApJxQ
Dim tkPecfFdocqqBt As Byte: tkPecfFdocqqBt = YusDIhkwWF(EtCjywfjssUWc): EtCjywfjssUWc = EtCjywfjssUWc + ((1 Xor 0)+0)
Dim CAWpFwggkrrZh As Byte: CAWpFwggkrrZh = YusDIhkwWF(EtCjywfjssUWc): EtCjywfjssUWc = EtCjywfjssUWc + 1
Dim ujzMwVqMml As Byte: If EtCjywfjssUWc < eqmzXFGApJxQ Then ujzMwVqMml = YusDIhkwWF(EtCjywfjssUWc): EtCjywfjssUWc = EtCjywfjssUWc + 1 Else ujzMwVqMml = Asc("A")
Dim QVokeaazcWcAqh As Byte: If EtCjywfjssUWc < eqmzXFGApJxQ Then QVokeaazcWcAqh = YusDIhkwWF(EtCjywfjssUWc): EtCjywfjssUWc = EtCjywfjssUWc + (1 Xor 0) Else QVokeaazcWcAqh = Asc("A")
If tkPecfFdocqqBt > (2 Xor 125) Or CAWpFwggkrrZh > (85+42) Or ujzMwVqMml > 127 Or QVokeaazcWcAqh > 127 Then _
Err.Raise vbObjectError, , ""
Dim mhKBvnFFuztlFT As Byte: mhKBvnFFuztlFT = QKJZqUIcJuC(tkPecfFdocqqBt)
Dim WAGoWUDaPZsf As Byte: WAGoWUDaPZsf = QKJZqUIcJuC(CAWpFwggkrrZh)
Dim CdOASRvZYFf As Byte: CdOASRvZYFf = QKJZqUIcJuC(ujzMwVqMml)
Dim uvMHorqBPp As Byte: uvMHorqBPp = QKJZqUIcJuC(QVokeaazcWcAqh)
If mhKBvnFFuztlFT > (0 Xor 63) Or WAGoWUDaPZsf > (28 Xor 35) Or CdOASRvZYFf > (9+(44 Xor 26)) Or uvMHorqBPp > (20 Xor 43) Then _
Err.Raise vbObjectError, , ""
Dim lTiZJdRtkLB As Byte: lTiZJdRtkLB = (mhKBvnFFuztlFT * ((1 Xor 2)+1)) Or (WAGoWUDaPZsf \ &H10)
Dim ySWAPIOelVOo As Byte: ySWAPIOelVOo = ((WAGoWUDaPZsf And &HF) * &H10) Or (CdOASRvZYFf \ 4)
Dim DtzSAaMlHrPSN As Byte: DtzSAaMlHrPSN = ((CdOASRvZYFf And (0+3)) * &H40) Or uvMHorqBPp
MTtJcOcfrKhv(XjDMeszHGiIFe) = lTiZJdRtkLB: XjDMeszHGiIFe = XjDMeszHGiIFe + (0 Xor 1)
If XjDMeszHGiIFe < OqhxSKRyhLn Then MTtJcOcfrKhv(XjDMeszHGiIFe) = ySWAPIOelVOo: XjDMeszHGiIFe = XjDMeszHGiIFe + (1+0)
If XjDMeszHGiIFe < OqhxSKRyhLn Then MTtJcOcfrKhv(XjDMeszHGiIFe) = DtzSAaMlHrPSN: XjDMeszHGiIFe = XjDMeszHGiIFe + 1
Loop
KWcnPHwXPA = MTtJcOcfrKhv
End Function

Deobfuscated Function:- (vba-obfuscator/obfuscator/modifier/strings/base64.vbs)

Public Function Base64Decode(ByVal s As String) As Byte()
   If Not InitDone Then Init
   Dim IBuf() As Byte: IBuf = ConvertStringToBytes(s)
   Dim ILen As Long: ILen = UBound(IBuf) + 1
   ' If ILen Mod 4 <> 0 Then Err.Raise vbObjectError, , "Length of Base64 encoded input string is not a multiple of 4."
   If ILen Mod 4 <> 0 Then Err.Raise vbObjectError, , ""
   Do While ILen > 0
      If IBuf(ILen - 1) <> Asc("=") Then Exit Do
      ILen = ILen - 1
      Loop
   Dim OLen As Long: OLen = (ILen * 3) \ 4
   Dim Out() As Byte
   ReDim Out(0 To OLen - 1) As Byte
   Dim ip As Long
   Dim op As Long
   Do While ip < ILen
      Dim i0 As Byte: i0 = IBuf(ip): ip = ip + 1
      Dim i1 As Byte: i1 = IBuf(ip): ip = ip + 1
      Dim i2 As Byte: If ip < ILen Then i2 = IBuf(ip): ip = ip + 1 Else i2 = Asc("A")
      Dim i3 As Byte: If ip < ILen Then i3 = IBuf(ip): ip = ip + 1 Else i3 = Asc("A")
      If i0 > 127 Or i1 > 127 Or i2 > 127 Or i3 > 127 Then _
         ' Err.Raise vbObjectError, , "Illegal character in Base64 encoded data."
         Err.Raise vbObjectError, , ""
      Dim b0 As Byte: b0 = Map2(i0)
      Dim b1 As Byte: b1 = Map2(i1)
      Dim b2 As Byte: b2 = Map2(i2)
      Dim b3 As Byte: b3 = Map2(i3)
      If b0 > 63 Or b1 > 63 Or b2 > 63 Or b3 > 63 Then _
         ' Err.Raise vbObjectError, , "Illegal character in Base64 encoded data."
         Err.Raise vbObjectError, , ""
      Dim o0 As Byte: o0 = (b0 * 4) Or (b1 \ &H10)
      Dim o1 As Byte: o1 = ((b1 And &HF) * &H10) Or (b2 \ 4)
      Dim o2 As Byte: o2 = ((b2 And 3) * &H40) Or b3
      Out(op) = o0: op = op + 1
      If op < OLen Then Out(op) = o1: op = op + 1
      If op < OLen Then Out(op) = o2: op = op + 1
      Loop
   Base64Decode = Out
   End Function

The code checks if the Boolean DQdqmDHFAZsXlO/InitDone is TRUE. If not TRUE then it calls Private Sub VjSimTuxaHK/Init.

KWcnPHwXPA/Base64Decode calls private sub VjSimTuxaHK/Init:-

Private Sub VjSimTuxaHK()
Dim OIMIqegisYd As Integer, HYiTBTPmizHm As Integer
HYiTBTPmizHm = 0
For OIMIqegisYd = Asc("A") To Asc("Z"): phLmzjBheZF(HYiTBTPmizHm) = OIMIqegisYd: HYiTBTPmizHm = HYiTBTPmizHm + 1: Next
For OIMIqegisYd = Asc("a") To Asc("z"): phLmzjBheZF(HYiTBTPmizHm) = OIMIqegisYd: HYiTBTPmizHm = HYiTBTPmizHm + 1: Next
For OIMIqegisYd = Asc("0") To Asc("9"): phLmzjBheZF(HYiTBTPmizHm) = OIMIqegisYd: HYiTBTPmizHm = HYiTBTPmizHm + (0 Xor 1): Next
phLmzjBheZF(HYiTBTPmizHm) = Asc("+"): HYiTBTPmizHm = HYiTBTPmizHm + ((0 Xor 1)+(0 Xor 0))
phLmzjBheZF(HYiTBTPmizHm) = Asc("/"): HYiTBTPmizHm = HYiTBTPmizHm + ((0 Xor 0)+(0 Xor 1))
For HYiTBTPmizHm = 0 To 127: QKJZqUIcJuC(HYiTBTPmizHm) = (147+108): Next
For HYiTBTPmizHm = (0 Xor 0) To (61+(0 Xor 2)): QKJZqUIcJuC(phLmzjBheZF(HYiTBTPmizHm)) = HYiTBTPmizHm: Next
DQdqmDHFAZsXlO = True
End Sub

Deobfuscated Private Sub:- (vba-obfuscator/obfuscator/modifier/strings/base64.vbs)

Private Sub Init()
   Dim c As Integer, i As Integer
   ' set Map1
   i = 0
   For c = Asc("A") To Asc("Z"): Map1(i) = c: i = i + 1: Next
   For c = Asc("a") To Asc("z"): Map1(i) = c: i = i + 1: Next
   For c = Asc("0") To Asc("9"): Map1(i) = c: i = i + 1: Next
   Map1(i) = Asc("+"): i = i + 1
   Map1(i) = Asc("/"): i = i + 1
   ' set Map2
   For i = 0 To 127: Map2(i) = 255: Next
   For i = 0 To 63: Map2(Map1(i)) = i: Next
   InitDone = True
   End Sub

After it’s done executing, it proceeds to change the Boolean DQdqmDHFAZsXlO/InitDone to TRUE, then KWcnPHwXPA/Base64Decode resumes, and then calls function jIuArLmtySP/ConvertStringToBytes.

KWcnPHwXPA/Base64Decode calls function jIuArLmtySP/ConvertStringToBytes:-

Private Function jIuArLmtySP(ByVal WyGwDJjQmpPM As String) As Byte()
Dim WAGoWUDaPZsf() As Byte: WAGoWUDaPZsf = WyGwDJjQmpPM
Dim ohnKHLnEngC As Long: ohnKHLnEngC = (UBound(WAGoWUDaPZsf) + (1+(0 Xor 0))) \ ((0 Xor 1)+1)
If ohnKHLnEngC = (0 Xor 0) Then jIuArLmtySP = WAGoWUDaPZsf: Exit Function
Dim CdOASRvZYFf() As Byte
ReDim CdOASRvZYFf((0+0) To ohnKHLnEngC - (0 Xor 1)) As Byte
Dim pulOTurWsADzsz As Long
For pulOTurWsADzsz = ((0 Xor 0)+(0 Xor 0)) To ohnKHLnEngC - 1
Dim OIMIqegisYd As Long: OIMIqegisYd = WAGoWUDaPZsf(((0 Xor 2)+(0 Xor 0)) * pulOTurWsADzsz) + (77 Xor 333) * CLng(WAGoWUDaPZsf(((0 Xor 2)+0) * pulOTurWsADzsz + (0+1)))
If OIMIqegisYd >= ((221 Xor 45)+(3 Xor 19)) Then OIMIqegisYd = Asc("?")
CdOASRvZYFf(pulOTurWsADzsz) = OIMIqegisYd
Next
jIuArLmtySP = CdOASRvZYFf
End Function

Deobfuscated Function:- (vba-obfuscator/obfuscator/modifier/strings/base64.vbs)

Private Function ConvertStringToBytes(ByVal s As String) As Byte()
   Dim b1() As Byte: b1 = s
   Dim l As Long: l = (UBound(b1) + 1) \ 2
   If l = 0 Then ConvertStringToBytes = b1: Exit Function
   Dim b2() As Byte
   ReDim b2(0 To l - 1) As Byte
   Dim p As Long
   For p = 0 To l - 1
      Dim c As Long: c = b1(2 * p) + 256 * CLng(b1(2 * p + 1))
      If c >= 256 Then c = Asc("?")
      b2(p) = c
      Next
   ConvertStringToBytes = b2
   End Function

Coming back to hhWpOZVspDmEP/unxor function.

It stores all the data into a variable called PwFVZbOlxLL/key and then deobfuscates the code into a variable called nMFesEttTo/cleartext and then hhWpOZVspDmEP/unxor is set equal to nMFesEttTo/cleartext.

The unxor function will be called twice because the string gets divided into two parts and the deobfuscation is run twice with the PwFVZbOlxLL/key.

After all of this has happened, the MsgBox is ran, and we get “Hello World”!


In my opinion, this is a very interesting way of obfuscating a macro script. While nbonnet wrote the white paper for this in French, I was still able to figure out a lot of stuff by manual analysis. In the future, I will go into detail what all the functions do!

Tho this fascinating piece of tool has it’s advantages, I still yet have to see it in a Phishing Campaign to say the least. Waiting for Threat Actors to find this xD

Anyways this was SYN, and soon enough there will be a part 2 to this(?). Goodbye!