Windows.Vhdx.Sys.Users

List User accounts by inspecting registry keys. This method is a reliable indicator for users who have physically logged into the system and thereby created local profiles.

This will not include domain users or the output from NetUserEnum

  • you should collect the Windows.Sys.AllUsers artifact to get all possible users on the system.

This artifact should be rename to replace the official Windows.Sys.Users allowing to list the users for potential user profiles from virtual Velociraptor clients.

Read the dedicated blog post before using this artifact.


name: Windows.Vhdx.Sys.Users
description: |
  List User accounts by inspecting registry keys. This method is a
  reliable indicator for users who have physically logged into the
  system and thereby created local profiles.

  This will not include domain users or the output from `NetUserEnum`
  - you should collect the `Windows.Sys.AllUsers` artifact to get all
  possible users on the system.
  
  This artifact should be rename to replace the official 
  `Windows.Sys.Users` allowing to list the users for potential user 
  profiles from virtual Velociraptor clients.

  Read the dedicated blog post before using this artifact.
  
author: Yann Malherbe - @mirwitch

reference: 
  - https://labs.infoguard.ch/posts/automation_of_vhdx_investigations/

parameters:
  - name: remoteRegKey
    default: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\*
    description: "Location of the registry key holding the profile list."

  - name: labelName
    default: "remapped_profile"
    type: string
    description: "Client label that signals the use of VHDX-based enumeration."

imports:
  - Windows.Sys.AllUsers

sources:
  - precondition:
      SELECT OS From info() where OS = 'windows'

    query: |

        LET GetTimestamp(High, Low) = if(condition=High,
                then=timestamp(winfiletime=High * 4294967296 + Low))

        // lookupSID() may not be available on deaddisk analysis
        LET Standard = SELECT split(string=Key.OSPath.Basename, sep="-")[-1] as Uid,
           "" AS Gid,
           LookupSIDCache(SID=Key.OSPath.Basename || "") AS Name,
           Key.OSPath as Description,
           ProfileImagePath as Directory,
           Key.OSPath.Basename as UUID,
           Key.Mtime as Mtime,
           {
                SELECT Mtime
                FROM stat(filename=expand(path=ProfileImagePath))
            } AS HomedirMtime,
           dict(ProfileLoadTime=GetTimestamp(
                   High=LocalProfileLoadTimeHigh, Low=LocalProfileLoadTimeLow),
                ProfileUnloadTime=GetTimestamp(
                   High=LocalProfileUnloadTimeHigh, Low=LocalProfileUnloadTimeLow)
           ) AS Data
        FROM read_reg_key(globs=remoteRegKey, accessor="registry")
        
        // User list for VHDX profiles emulating the Standard one
        LET UserProfile = SELECT
              OSPath.Components[-2] AS Uid,
              OSPath.Dirname AS Directory,
              OSPath.Components[-2] AS UUID,
              OSPath.Components[-2] AS Name,
              "" AS Gid,
              Mtime,
              Mtime AS HomedirMtime,
              "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\" + OSPath.Components[-2] AS Description
            FROM glob(globs="C:/Users/*/NTUSER.DAT")
        
        // Get the labels of the agent 
        LET agent_config = SELECT labels FROM config

        // Take the appropriate user list method
        SELECT * FROM if(condition=agent_config.labels=~labelName, then=UserProfile, else=Standard)