Windows.Detection.HyperV

Scope suspicious Hyper-V worker process and activity on Windows workstations.

  • Checks for Hyper-V worker process, vmwp.exe, for handles to disk images.
  • Returns Microsoft-Windows-Hyper-V-VMMS-Admin events with a VmName or VmID referenced.
  • Returns Microsoft-Windows-VHDMP-Operational events with a VhdFileName matching a disk image.

By default, this artifact targets Windows workstations only, Hyper-V is an unusual service on Windows workstations.

Windows.Search.WSLFileFinder may be used for some detection triage but VHDX can be a complex format so collection for offline analysis may be needed.


name: Windows.Detection.HyperV
author: Matt Green - @mgreen27
description: |
   Scope suspicious Hyper-V worker process and activity on Windows workstations. 
   
   - Checks for Hyper-V worker process, vmwp.exe, for handles to disk images.
   - Returns  Microsoft-Windows-Hyper-V-VMMS-Admin events with a VmName or VmID 
   referenced.
   - Returns  Microsoft-Windows-VHDMP-Operational events with a VhdFileName 
   matching a disk image.
   
   By default, this artifact targets Windows workstations only, Hyper-V is an 
   unusual service on Windows workstations.
   
   Windows.Search.WSLFileFinder may be used for some detection triage but VHDX 
   can be a complex format so collection for offline analysis may be needed.
   
reference:
    - https://www.bitdefender.com/en-us/blog/businessinsights/curly-comrades-evasion-persistence-hidden-hyper-v-virtual-machines
type: CLIENT

parameters:
   - name: ProcessRegex
     default: vmwp\.exe
     type: regex
   - name: FileRegex
     default: \.(a?vhdx?)$
     description: "Default for Hyper-V image files: .vhdx .avhdx, .vhd"
     type: regex
   - name: DefaultLocationRegex
     default: (\\Program Files\\WSL|\\AppData\\Local)\\.+\.(a?vhdx?)$
     description: "Default location for WSL vhdx"
     type: regex
   - name: RunOnAll
     type: bool
     description: If Selected will run accross all Windows machines. By Default we filter out Windows Servers.
     
sources:
  - query: |
      LET precondition <= SELECT OS, Platform 
        FROM info() 
        WHERE OS = 'windows' 
            AND NOT if(condition= RunOnAll,
                            then= False,
                            else= Platform =~ 'Server' )

      LET process <= SELECT * FROM Artifact.Windows.System.Pslist(ProcessRegex=ProcessRegex)
      LET find_process(pid) = SELECT Pid,Name,CommandLine, Exe,Username 
        FROM process 
        WHERE Pid = pid
      
      LET results = SELECT ProcPid,ProcName,Exe,
        find_process(pid=ProcPid)[0].CommandLine as CommandLine,
        Name as HandleName,
        split(sep='''}\\''',string=Name)[1] as __OSPath,
        Type,
        find_process(pid=ProcPid)[0].Username as Username
      FROM Artifact.Windows.System.Handles(processRegex=ProcessRegex)
      WHERE Name =~ FileRegex
      
      SELECT *,
        {   SELECT OSPath, Size, Mtime,Atime,Ctime, Btime,
                magic(path=OSPath) as FileMagic
            FROM stat(filename=__OSPath)
        } as FileInfo,
        if(condition= __OSPath=~DefaultLocationRegex,
                then= True,
                else= False ) as DefaultLocation
      FROM if(condition= precondition,
                            then= results )

  - name: Microsoft-Windows-Hyper-V-VMMS-Admin
    query: |
      LET vmms = SELECT EventTime,
                 Provider,
                 EventID,
                 UserSID,
                 Username,
                 UserData.VmlEventLog.VmName AS VmName,
                 UserData.VmlEventLog.VmId AS VmId,
                 Message,
                 OSPath
          FROM Artifact.Windows.EventLogs.EvtxHunter(
            EvtxGlob="C:\\Windows\\System32\\winevt\\Logs\\Microsoft-Windows-Hyper-V-VMMS-Admin.evtx",
            IdRegex=".")
          WHERE UserData.VmlEventLog.VmId OR UserData.VmlEventLog.VmName
      SELECT * FROM if(condition= precondition,
                            then= vmms )
      
  - name: Microsoft-Windows-VHDMP-Operational
    query: |
      LET vhdmp = SELECT EventTime, Provider,EventID,UserSID,Username,
                if(condition=EventData.VhdFileName,
                    then= EventData.VhdFileName,
                    else= EventData.Data.Value ) as VhdFileName,
                Message,OSPath
          FROM Artifact.Windows.EventLogs.EvtxHunter(preconditions=TRUE,
            EvtxGlob="C:\\Windows\\System32\\winevt\\Logs\\Microsoft-Windows-VHDMP-Operational.evtx",
            IdRegex=".")
          WHERE EventData.VhdFileName OR EventData.Data.Name = "VhdFileName"
            AND VhdFileName =~ FileRegex
      SELECT * FROM if(condition= precondition,
                            then= vhdmp )