Generic.Detection.HashHunter

This artifact enables searching for hashes.

The artifact takes a glob targetting input, then generates a hash for each file in scope to compare to several types of hash lists provided by the user.

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: Generic.Detection.HashHunter
author: "Matt Green - @mgreen27"
description: |
    This artifact enables searching for hashes.
    
    The artifact takes a glob targetting input, then generates a hash for each 
    file in scope to compare to several types of hash lists provided by the user.
    
    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: 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:

sources:
  - query: |
      -- setup hash lists
      LET MD5List <= if(condition= MD5List,
                        then= split(sep='\\s+',string=MD5List), else=Null)
      LET SHA1List <= if(condition= SHA1List,
                        then= split(sep='\\s+',string=SHA1List), else=Null)
      LET SHA256List <= if(condition= SHA256List,
                        then= split(sep='\\s+',string=SHA256List), else=Null)
      
      -- set hash selector for optimised hash calculation
      LET HashSelector <= SELECT * FROM chain(
          a={ SELECT "MD5" AS Hash FROM scope() WHERE MD5List },
          b={ SELECT "SHA1" AS Hash FROM scope() WHERE SHA1List },
          c={ SELECT "SHA256" AS Hash FROM scope() WHERE SHA256List })
      
      -- firstly find files in scope with performance
      LET find_files = SELECT * FROM if(condition=DateBefore AND DateAfter,
            then={
                SELECT OSPath, Name, Size,Mtime,Atime,Ctime,Btime
                FROM glob(globs=TargetGlob,accessor=Accessor,nosymlink='True')
                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
                })})})
      
      
      -- lookup hash and run finl filters
      SELECT OSPath,Name,Size,
            dict(Mtime=Mtime,Atime=Atime,Ctime=Ctime,Btime=Btime) as Timestamps,
            hash(path=OSPath,hashselect=HashSelector.Hash) as Hash
        FROM if(condition= HashSelector.Hash, then= find_files)
        WHERE 
            ( Hash.MD5 in MD5List OR Hash.SHA1 in SHA1List OR Hash.SHA256 in SHA256List )