Windows.Detection.Yara.Process

This artifact enables running Yara over processes in memory.

There are 2 kinds of Yara rules that can be deployed:

  1. Url link to a yara rule.
  2. or a Standard Yara rule attached as a parameter.

Only one method of Yara will be applied and search order is as above. The default is Cobalt Strike opcodes.

Regex parameters can be applied for process name and pid for targeting. The artifact also has an option to upload any process with Yara hits.

Note: by default the Yara scan will stop after one hit. Multi-string rules will also only show one string in returned rows. If upload is selected NumberOfHits is redundant and not advised as hits are grouped by path to ensure files only downloaded once.


name: Windows.Detection.Yara.Process
author: Matt Green - @mgreen27
description: |
  This artifact enables running Yara over processes in memory.

  There are 2 kinds of Yara rules that can be deployed:

  1. Url link to a yara rule.
  3. or a Standard Yara rule attached as a parameter.

  Only one method of Yara will be applied and search order is as above. The
  default is Cobalt Strike opcodes.

  Regex parameters can be applied for process name and pid for targeting. The
  artifact also has an option to upload any process with Yara hits.

  Note: by default the Yara scan will stop after one hit. Multi-string rules will also only
  show one string in returned rows.
  If upload is selected NumberOfHits is redundant and not advised as hits are
  grouped by path to ensure files only downloaded once.


type: CLIENT
parameters:
  - name: ProcessRegex
    default: .
    type: regex
  - name: PidRegex
    default: .
    type: regex
  - name: UploadHits
    type: bool
  - name: YaraUrl
    description: If configured will attempt to download Yara rules from Url
    type: upload
  - name: YaraRule
    type: yara
    description: Final Yara option and the default if no other options provided.
    default: |
      rule win_cobalt_strike_auto {
         meta:
           author = "Felix Bilstein - yara-signator at cocacoding dot com"
           date = "2019-11-26"
           version = "1"
           description = "autogenerated rule brought to you by yara-signator"
           tool = "yara-signator 0.2a"
           malpedia_reference = "https://malpedia.caad.fkie.fraunhofer.de/details/win.cobalt_strike"
           malpedia_license = "CC BY-SA 4.0"
           malpedia_sharing = "TLP:WHITE"

         strings:
           $sequence_0 = { 3bc7 750d ff15???????? 3d33270000 }
           $sequence_1 = { e9???????? eb0a b801000000 e9???????? }
           $sequence_2 = { 8bd0 e8???????? 85c0 7e0e }
           $sequence_3 = { ffb5f8f9ffff ff15???????? 8b4dfc 33cd e8???????? c9 c3 }
           $sequence_4 = { e8???????? e9???????? 833d?????????? 7505 e8???????? }
           $sequence_5 = { 250000ff00 33d0 8b4db0 c1e908 }
           $sequence_6 = { ff75f4 ff7610 ff761c ff75fc }
           $sequence_7 = { 8903 6a06 eb39 33ff 85c0 762b 03f1 }
           $sequence_8 = { 894dd4 8b458c d1f8 894580 8b45f8 c1e818 0fb6c8 }
           $sequence_9 = { 890a 8b4508 0fb64804 81e1ff000000 c1e118 8b5508 0fb64205 }
           $sequence_10 = { 33d2 e8???????? 48b873797374656d3332 4c8bc7 488903 49ffc0 }
           $sequence_11 = { 488bd1 498d4bd8 498943e0 498943e8 }
           $sequence_12 = { b904000000 486bc90e 488b542430 4c8b442430 418b0c08 8b0402 }
           $sequence_13 = { ba80000000 e8???????? 488d4c2438 e8???????? 488d4c2420 8bd0 e8???????? }
           $sequence_14 = { 488b4c2430 8b0401 89442428 b804000000 486bc004 }
           $sequence_15 = { 4883c708 4883c304 49ffc3 48ffcd 0f854fffffff 488d4c2420 }

        condition:
            7 of them
      }
  - name: NumberOfHits
    description: THis artifact will stop by default at one hit. This setting allows additional hits
    default: 1
    type: int
  - name: ContextBytes
    description: Include this amount of bytes around hit as context.
    default: 0
    type: int64
  - name: ExePathWhitelist
    description: Regex of ProcessPaths to exclude
    type: regex


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

    query: |
      -- check which Yara to use
      LET yara_rules <= YaraUrl || YaraRule
      
      -- find velociraptor process
      LET me = SELECT Pid FROM pslist(pid=getpid())

      -- find all processes and add filters
      LET processes = SELECT Name as ProcessName, Exe as ExePath, CommandLine, Pid, WorkingSetSize
        FROM pslist()
        WHERE
            Name =~ ProcessRegex
            AND format(format="%d", args=Pid) =~ PidRegex
            AND NOT Pid in me.Pid
            AND NOT if(condition=ExePathWhitelist,
                    then= Exe=~ExePathWhitelist)

      -- scan processes in scope with our rule, limit 1 hit
      LET hits = SELECT * FROM foreach(
        row=processes,
        query={
            SELECT
                ProcessName,
                ExePath,
                CommandLine,
                Pid,
                Rule,
                Tags,
                Meta,
                String.Name as YaraString,
                String.Offset as HitOffset,
                upload( accessor='scope',
                    file='String.Data',
                    name=format(format="%v-%v_%v",
                    args=[
                        split(string=ProcessName, sep='\\.')[0], Pid,
                        String.Offset ]
                    )) as HitContext
                
            FROM proc_yara(
                            pid=int(int=Pid),
                            rules=yara_rules,
                            context=ContextBytes,
                            number=NumberOfHits
                        )
          })

      -- upload hits using proc_dump plugin
      LET upload_hits = SELECT * FROM foreach(
        row=hits,
        query={
            SELECT 
                ProcessName,
                ExePath,
                CommandLine,
                Pid,
                Rule,
                Tags,
                Meta,
                YaraString,
                HitOffset,
                HitContext,
                upload(
                  file=OSPath,
                  name=format(format='%v-%v.dmp',
                    args= [ split(string=ProcessName, sep='\\.')[0], Pid ])
                ) as ProcessDump
            FROM proc_dump(pid=Pid)
          })
          
      -- return rows
      SELECT * FROM if(condition=UploadHits,
        then=upload_hits,
        else=hits)

column_types:
  - name: HitContext
    type: preview_upload