This artifact enables hunting for binary attributes.
The artifact takes a glob targetting input, then checks each file in scope for an MZ header. The artifact also queries Authenticode details and parses out PE attributes.
Both PE and Authenticode output can be queried for relevant strings using a regex filter and whitelist to hunt with. This enables unique capability to hunt for specific things such as PE imports, exports or other attributes.
Note: this artifacts filters are cumulative so a hash based hit will return no results if the file is filtered out by other filters. For most performant searches leverage path, size and and date filters. By default the artifact leverages the ‘auto’ data accessor but can also be changed as desired.
name: Windows.Detection.BinaryHunter
author: "Matt Green - @mgreen27"
description: |
This artifact enables hunting for binary attributes.
The artifact takes a glob targetting input, then checks each file in scope for an MZ header.
The artifact also queries Authenticode details and parses out PE attributes.
Both PE and Authenticode output can be queried for relevant strings using a regex filter and whitelist to hunt with.
This enables unique capability to hunt for specific things such as PE imports, exports or other attributes.
Note: this artifacts filters are cumulative so a hash based hit will return
no results if the file is filtered out by other filters.
For most performant searches leverage path, size and and date filters. By default
the artifact leverages the 'auto' data accessor but can also be changed as desired.
parameters:
- name: TargetGlob
description: Glob to target.
default: "C:/Users/**/*"
- name: Accessor
description: Velociraptor accessor to use. Changing to ntfs will increase scan time.
default: auto
- name: UnexpectedExtension
description: "Exclude binaries with expected extension: com|cpl|dll|drv|exe|mui|scr|sfx|sys|winmd"
type: bool
- name: ExcludeTrusted
description: Exclude binaries with Trusted Authenticode certificates.
type: bool
- name: AuthenticodeRegex
description: Regex to search through all authenrticode data.
default: .
type: regex
- name: AuthenticodeWhitelistRegex
description: Regex to whitelist in all Authenticode data.
default:
type: regex
- name: PEInformationRegex
description: Regex to filter for PE information. e.g VersionInformation, exports etc
default: .
type: regex
- name: PEInformationWhitelistRegex
description: Regex to whitelist for PE information. e.g VersionInformation, exports etc
default:
type: regex
- name: DateAfter
description: Search for binaries with timestamps after this date. YYYY-MM-DDTmm:hh:ssZ
type: timestamp
- name: DateBefore
description: Search for binaries with timestamps before this date. YYYY-MM-DDTmm:hh:ssZ
type: timestamp
- name: SizeMax
description: Return binaries only under this size in bytes.
type: int64
default: 4294967296
- name: SizeMin
description: Return binaries only over this size in bytes.
type: int64
default: 0
- name: MD5List
description: MD5 hash list to hunt for. New MD5 hash on each line
default:
- name: SHA1List
description: SHA1 hash list to hunt for. New SHA1 hash on each line
default:
- name: SHA256List
description: SHA256 hash list to hunt for. New SHA256 hash on each line
default:
- name: DISABLE_DANGEROUS_API_CALLS
type: bool
description: |
Enable this to disable potentially flakey APIs which may cause
crashes.
sources:
- query: |
-- setup hash lists if needed
LET MD5Array <= split(sep='\\s+',string=MD5List)
LET SHA1Array <= split(sep='\\s+',string=SHA1List)
LET SHA256Array <= split(sep='\\s+',string=SHA256List)
-- firstly find files in scope with performance
LET find_files = SELECT *,
read_file(filename=OSPath,accessor=Accessor,offset=0,length=2) as _Header
FROM if(condition=DateBefore AND DateAfter,
then={
SELECT OSPath, Name, Size,Mtime,Atime,Ctime,Btime
FROM glob(globs=TargetGlob,accessor=Accessor)
WHERE NOT IsDir AND NOT IsLink
AND Size > SizeMin AND Size < SizeMax
AND ( Mtime < DateBefore OR Ctime < DateBefore OR Btime < DateBefore )
AND ( Mtime > DateAfter OR Ctime > DateAfter OR Btime > DateAfter )
},
else={ SELECT * FROM if(condition=DateBefore,
then={
SELECT OSPath, Name, Size,Mtime,Atime,Ctime,Btime
FROM glob(globs=OSPath,accessor=Accessor)
WHERE NOT IsDir AND NOT IsLink
AND Size > SizeMin AND Size < SizeMax
AND ( Mtime < DateBefore OR Ctime < DateBefore OR Btime < DateBefore )
},
else={ SELECT * FROM if(condition=DateAfter,
then={
SELECT OSPath, Name, Size,Mtime,Atime,Ctime,Btime
FROM glob(globs=TargetGlob,accessor=Accessor)
WHERE NOT IsDir AND NOT IsLink
AND Size > SizeMin AND Size < SizeMax
AND ( Mtime > DateAfter OR Ctime > DateAfter OR Btime > DateAfter )
},
else={
SELECT OSPath, Name, Size,Mtime,Atime,Ctime,Btime
FROM glob(globs=TargetGlob,accessor=Accessor)
WHERE NOT IsDir AND NOT IsLink
AND Size > SizeMin AND Size < SizeMax
})})})
WHERE _Header = 'MZ'
AND if(condition= UnexpectedExtension,
then= NOT Name =~ '\.(com|cpl|dll|drv|exe|mui|scr|sfx|sys|winmd)$',
else= True)
-- parse PE attributes and run final filters
SELECT
dict(OSPath=OSPath,Name=Name,Size=Size,
Timestamps=dict(Mtime=Mtime,Atime=Atime,Ctime=Ctime,Btime=Btime)
) as File,
authenticode(filename=OSPath) as Authenticode,
parse_pe(file=OSPath) as PE,
hash(path=OSPath) as Hash
FROM find_files
WHERE
serialize(item=Authenticode) =~ AuthenticodeRegex
AND NOT if(condition=WhitelistRegex,
then= serialize(item=Authenticode) =~ AuthenticodeWhitelistRegex,
else= False)
AND serialize(item=PE) =~ PEInformationRegex
AND NOT if(condition=PEInformationWhitelistRegex,
then= serialize(item=PE) =~ PEInformationWhitelistRegex,
else= False)
AND if(condition= ExcludeTrusted,
then= NOT Authenticode.Trusted = "trusted",
else= True)
AND if(condition= MD5List OR SHA1List OR SHA256List,
then=(
if(condition= MD5List,
then= Hash.MD5 in MD5Array)
OR if(condition= SHA1List,
then= Hash.SHA1 in SHA1Array)
OR if(condition= SHA256List,
then= Hash.SHA256 in SHA256Array)
), else = True )