Create remapping configuration YAML file(s) to virtually mount
VHDX profiles into virtual Velociraptor clients.
This artifact is part of the Vhdx Suite. This suite requires to have
the Velociraptor server artifact Windows.Sys.Users override on the
server to work properly.
Read the dedicated blog post before using this artifact.
name: Windows.Vhdx.RemapConfigBuilder
description: |
Create remapping configuration YAML file(s) to virtually mount
VHDX profiles into virtual Velociraptor clients.
This artifact is part of the Vhdx Suite. This suite requires to have
the Velociraptor server artifact `Windows.Sys.Users` override on the
server to work properly.
Read the dedicated blog post before using this artifact.
author: Yann Malherbe - @mirwitch
reference:
- https://labs.infoguard.ch/posts/automation_of_vhdx_investigations/
type: CLIENT
implied_permissions:
- FILESYSTEM_WRITE
parameters:
- name: vhdxFolderPath
type: string
default: "F:\\vhdx\\"
description: "Directory containing VHDX profile files."
- name: usernameExtractor
type: regex
default: "profile_(?<Username>.*).vhdx"
description: "Regex used to extract usernames from filenames."
- name: user
type: regex
default: Administrator
description: "Optional filter to restrict which profiles to process."
- name: virtualHostname
type: string
default: "VHDX"
description: "Hostname to assign to the virtual clients."
- name: vhdxOffset
type: hidden
default: 1048576
description: "NTFS start offset inside VHDX."
- name: batchSize
type: int
default: 30
description: "Number of profiles per virtual client."
sources:
- precondition:
SELECT OS From info() where OS = 'windows'
query: |
// Static remapping header
LET RemappingHeader ='''
remappings:
- type: permissions
permissions:
- COLLECT_CLIENT
- FILESYSTEM_READ
- FILESYSTEM_WRITE
- READ_RESULTS
- MACHINE_STATE
- SERVER_ADMIN
- type: impersonation
os: windows
hostname: "<VIRTUAL_HOSTNAME>"
env:
- key: SystemRoot
value: C:\Windows
- key: WinDir
value: C:\Windows
disabled_functions:
- amsi
- lookupSID
- token
disabled_plugins:
- users
- certificates
- handles
- pslist
- interfaces
- modules
- netstat
- partitions
- proc_dump
- proc_yara
- vad
- winobj
- wmi
- type: shadow
from:
accessor: data
"on":
accessor: data
- type: shadow
from:
accessor: raw_reg
"on":
accessor: raw_reg
- type: shadow
from:
accessor: zip
"on":
accessor: zip
'''
// Remapping required per user
LET RemappingUser = '''
- type: mount
description: 'NTFS - <USERNAME>'
from:
accessor: raw_ntfs
prefix: |
{
"DelegateAccessor": "offset",
"Delegate": {
"DelegateAccessor": "vhdx",
"DelegatePath": "<VHDX_PATH>",
"Path":"/<VHDX_OFFSET>"
},
"Path": "<PROFILE_PATH>"
}
"on":
accessor: ntfs
prefix: '\\.\C:\Users\<USERNAME>'
path_type: ntfs
- type: mount
description: 'File - <USERNAME>'
from:
accessor: raw_ntfs
prefix: |
{
"DelegateAccessor": "offset",
"Delegate": {
"DelegateAccessor": "vhdx",
"DelegatePath": "<VHDX_PATH>",
"Path":"/<VHDX_OFFSET>"
},
"Path": "<PROFILE_PATH>"
}
"on":
accessor: file
prefix: 'C:\Users\<USERNAME>'
path_type: windows
- type: mount
description: 'Auto - <USERNAME>'
from:
accessor: raw_ntfs
prefix: |
{
"DelegateAccessor": "offset",
"Delegate": {
"DelegateAccessor": "vhdx",
"DelegatePath": "<VHDX_PATH>",
"Path":"/<VHDX_OFFSET>"
},
"Path": "<PROFILE_PATH>"
}
"on":
accessor: auto
prefix: 'C:\Users\<USERNAME>'
path_type: windows
- type: mount
description: 'Registry - <USERNAME> NTUSER.DAT'
from:
accessor: raw_reg
prefix: |-
{
"Path": "/",
"DelegateAccessor": "raw_ntfs",
"Delegate": {
"DelegateAccessor":"offset",
"Delegate": {
"DelegateAccessor": "vhdx",
"DelegatePath": "<VHDX_PATH>",
"Path": "/<VHDX_OFFSET>"
},
"Path":"<PROFILE_PATH>/NTUSER.DAT"
}
}
path_type: registry
"on":
accessor: registry
prefix: HKEY_USERS\<USERNAME>
path_type: registry
- type: mount
description: 'Registry - <USERNAME> UsrClass'
from:
accessor: raw_reg
prefix: |-
{
"Path": "/",
"DelegateAccessor": "raw_ntfs",
"Delegate": {
"DelegateAccessor":"offset",
"Delegate": {
"DelegateAccessor": "vhdx",
"DelegatePath": "<VHDX_PATH>",
"Path": "/<VHDX_OFFSET>"
},
"Path":"<PROFILE_PATH>/AppData/Local/Microsoft/Windows/UsrClass.dat"
}
}
path_type: registry
"on":
accessor: registry
prefix: HKEY_USERS\<USERNAME>_Classes
path_type: registry
'''
// Get the list of user profiles of interest
LET userProfilesList = SELECT *,
parse_string_with_regex(
string=Name,
regex=usernameExtractor
) AS userProfile
FROM glob(globs=vhdxFolderPath+"/*.vhdx")
WHERE userProfile.Username AND userProfile.Username =~ user
// Split the user list into batches
LET userBatch = SELECT rows AS user_batch
FROM batch(query={
SELECT *
FROM userProfilesList
}, batch_size=batchSize)
// Create the header of the remapping file
LET HeaderRemapping = regex_replace(re="<VIRTUAL_HOSTNAME>",
replace=virtualHostname + "_" + firstBatchUser,
source=RemappingHeader)
// Create the user sections of the remapping file
LET UserRemapping = SELECT
regex_replace(re="<USERNAME>",
replace=userProfile.Username, source=
regex_replace(re="<PROFILE_PATH>",
replace="/Profile", source=
regex_replace(re="<VHDX_OFFSET>",
replace=vhdxOffset, source=
regex_replace(re="<VHDX_PATH>",
replace=regex_replace(
re="\\\\", replace="/", source=OSPath),
source=RemappingUser)
))) AS Content
FROM scope()
// Iterate on the users part of the bulk
LET BulkUserRemapping = SELECT * FROM foreach(
row=user_batch,
query=UserRemapping
)
// Write the remapping content in a temp file
LET tmpFile = tempfile(
data=HeaderRemapping + BulkUserRemapping.Content,
remove_last=TRUE
)
// Retrieve the directory from the running Velociraptor executable
LET veloInfo = SELECT Exe FROM info()
// Get the first user of the batch
LET firstBatchUser = user_batch[0].userProfile.Username
// Get the remapping filename
LET remappingFilename = firstBatchUser + ".yaml"
// Copy the file to the remapping YAML file
LET copyFile = SELECT copy(
filename=tmpFile,
dest=pathspec(parse=veloInfo[0].Exe).Dirname + "Vhdx" + "Remapping" + remappingFilename,
create_directories=TRUE) AS CreatedConfig
FROM scope()
// Create dedicated YAML file for each batch of users
SELECT * FROM foreach(row=userBatch, query=copyFile)