This artifact enables enumeration of process memory sections via the Virtual Address Descriptor (VAD). The VAD is used by the Windows memory manager to describe allocated process memory ranges.
Availible filters include process, mapping path, memory permissions or by content with yara.
NOTE:
name: Windows.System.VAD
author: "Matt Green - @mgreen27"
description: |
This artifact enables enumeration of process memory sections via the Virtual
Address Descriptor (VAD). The VAD is used by the Windows memory manager to
describe allocated process memory ranges.
Availible filters include process, mapping path, memory permissions
or by content with yara.
NOTE:
- ProtectionChoice is a choice to filter on section protection. Default is
all sections and ProtectionRegex can override selection.
- To filter on unmapped sections the MappingNameRegex: ^$ can be used.
parameters:
- name: ProcessRegex
description: A regex applied to process names.
default: .
type: regex
- name: PidRegex
default: .
type: regex
- name: ProtectionChoice
type: choices
description: Select memory permission you would like to return. Default All.
default: Any
choices:
- Any
- Execute, read and write
- Any executable
- name: ProtectionRegex
type: regex
description: Allows a manual regex selection of section Protection permissions. If configured take preference over Protection choice.
- name: MappingNameRegex
type: regex
- name: UploadSection
description: Upload suspicious section.
type: bool
- name: SuspiciousContent
description: A yara rule of suspicious section content
type: yara
- name: ContextBytes
description: Include this amount of bytes around yara hit as context.
default: 200
type: int
sources:
- query: |
-- firstly find processes in scope
LET processes = SELECT int(int=Pid) AS Pid,
Name, Exe, CommandLine, StartTime
FROM process_tracker_pslist()
WHERE Name =~ ProcessRegex
AND format(format="%d", args=Pid) =~ PidRegex
AND log(message="Scanning pid %v : %v", args=[Pid, Name])
-- next find sections in scope
LET sections = SELECT * FROM foreach(
row=processes,
query={
SELECT StartTime as ProcessCreateTime,Pid, Name, MappingName,
format(format='%x-%x', args=[Address, Address+Size]) AS AddressRange,
Address as _Address,
State,Type,ProtectionMsg,Protection,
Size as SectionSize,
pathspec(
DelegateAccessor="process",
DelegatePath=Pid,
Path=Address) AS _PathSpec
FROM vad(pid=Pid)
WHERE if(condition=MappingNameRegex,
then= MappingName=~MappingNameRegex,
else= True)
AND if(condition = ProtectionRegex,
then= Protection=~ProtectionRegex,
else= if(condition= ProtectionChoice='Any',
then= TRUE,
else= if(condition= ProtectionChoice='Execute, read and write',
then= Protection= 'xrw',
else= if(condition= ProtectionChoice='Any executable',
then= Protection=~'x'))))
})
-- if suspicious yara added, search for it
LET yara_sections = SELECT *
FROM foreach(row={
SELECT * FROM sections
WHERE NOT State =~ "RESERVE"
}, query={
SELECT
ProcessCreateTime, Pid, Name,MappingName,
AddressRange,State,Type,ProtectionMsg,
Protection,SectionSize,
dict(Rule=Rule,
Meta=Meta,
Tags=Tags,
Offset=String.Offset,
Name=String.Name) as YaraHit,
upload( accessor='scope',
file='String.Data',
name=format(format="%v-%v_%v.bin-%v-%v",
args=[
Name, Pid, AddressRange,
if(condition= String.Offset - ContextBytes < 0,
then= 0,
else= String.Offset - ContextBytes),
if(condition= String.Offset + ContextBytes > SectionSize,
then= SectionSize,
else= String.Offset + ContextBytes ) ])
) as HitContext,
_PathSpec, _Address
FROM yara(
accessor='offset',
files=_PathSpec,
rules=SuspiciousContent,
end=SectionSize, key='X',
number=1,
context=ContextBytes
)
})
-- finalise results
LET results = SELECT *,
process_tracker_callchain(id=Pid).Data as ProcessChain
FROM if(condition= SuspiciousContent,
then= yara_sections,
else= sections)
-- upload sections if selected
LET upload_results = SELECT *,
upload(accessor='sparse',
file=pathspec(
DelegateAccessor="process",
DelegatePath=Pid,
Path=[dict(Offset=_Address, Length=SectionSize),]),
name=pathspec(
Path=format(
format='%v-%v_%v.bin',
args= [ Name, Pid, AddressRange ]))) as SectionDump
FROM results
-- output rows
SELECT * FROM if(condition= UploadSection,
then= upload_results,
else= results)
column_types:
- name: HitContext
type: preview_upload