Malicious Base64 encoded PowerShell Keywords in command lines

Detects base64 encoded strings used in hidden malicious PowerShell command lines

Rule Content

- title: Malicious Base64 encoded PowerShell Keywords in command lines
  id: f26c6093-6f14-4b12-800f-0fcb46f5ffd0
  status: experimental
  description: Detects base64 encoded strings used in hidden malicious PowerShell
    command lines
  references:
  - http://www.leeholmes.com/blog/2017/09/21/searching-for-content-in-base-64-strings/
  tags:
  - attack.execution
  - attack.t1086
  author: John Lambert (rule)
  logsource:
    category: process_creation
    product: windows
    service: null
  detection:
    encoded:
      Image: '*\powershell.exe'
      CommandLine: '* hidden *'
    selection:
      CommandLine:
      - '*AGkAdABzAGEAZABtAGkAbgAgAC8AdAByAGEAbgBzAGYAZQByA*'
      - '*aXRzYWRtaW4gL3RyYW5zZmVy*'
      - '*IAaQB0AHMAYQBkAG0AaQBuACAALwB0AHIAYQBuAHMAZgBlAHIA*'
      - '*JpdHNhZG1pbiAvdHJhbnNmZX*'
      - '*YgBpAHQAcwBhAGQAbQBpAG4AIAAvAHQAcgBhAG4AcwBmAGUAcg*'
      - '*Yml0c2FkbWluIC90cmFuc2Zlc*'
      - '*AGMAaAB1AG4AawBfAHMAaQB6AGUA*'
      - '*JABjAGgAdQBuAGsAXwBzAGkAegBlA*'
      - '*JGNodW5rX3Npem*'
      - '*QAYwBoAHUAbgBrAF8AcwBpAHoAZQ*'
      - '*RjaHVua19zaXpl*'
      - '*Y2h1bmtfc2l6Z*'
      - '*AE8ALgBDAG8AbQBwAHIAZQBzAHMAaQBvAG4A*'
      - '*kATwAuAEMAbwBtAHAAcgBlAHMAcwBpAG8Abg*'
      - '*lPLkNvbXByZXNzaW9u*'
      - '*SQBPAC4AQwBvAG0AcAByAGUAcwBzAGkAbwBuA*'
      - '*SU8uQ29tcHJlc3Npb2*'
      - '*Ty5Db21wcmVzc2lvb*'
      - '*AE8ALgBNAGUAbQBvAHIAeQBTAHQAcgBlAGEAbQ*'
      - '*kATwAuAE0AZQBtAG8AcgB5AFMAdAByAGUAYQBtA*'
      - '*lPLk1lbW9yeVN0cmVhb*'
      - '*SQBPAC4ATQBlAG0AbwByAHkAUwB0AHIAZQBhAG0A*'
      - '*SU8uTWVtb3J5U3RyZWFt*'
      - '*Ty5NZW1vcnlTdHJlYW*'
      - '*4ARwBlAHQAQwBoAHUAbgBrA*'
      - '*5HZXRDaHVua*'
      - '*AEcAZQB0AEMAaAB1AG4Aaw*'
      - '*LgBHAGUAdABDAGgAdQBuAGsA*'
      - '*LkdldENodW5r*'
      - '*R2V0Q2h1bm*'
      - '*AEgAUgBFAEEARABfAEkATgBGAE8ANgA0A*'
      - '*QASABSAEUAQQBEAF8ASQBOAEYATwA2ADQA*'
      - '*RIUkVBRF9JTkZPNj*'
      - '*SFJFQURfSU5GTzY0*'
      - '*VABIAFIARQBBAEQAXwBJAE4ARgBPADYANA*'
      - '*VEhSRUFEX0lORk82N*'
      - '*AHIAZQBhAHQAZQBSAGUAbQBvAHQAZQBUAGgAcgBlAGEAZA*'
      - '*cmVhdGVSZW1vdGVUaHJlYW*'
      - '*MAcgBlAGEAdABlAFIAZQBtAG8AdABlAFQAaAByAGUAYQBkA*'
      - '*NyZWF0ZVJlbW90ZVRocmVhZ*'
      - '*Q3JlYXRlUmVtb3RlVGhyZWFk*'
      - '*QwByAGUAYQB0AGUAUgBlAG0AbwB0AGUAVABoAHIAZQBhAGQA*'
      - '*0AZQBtAG0AbwB2AGUA*'
      - '*1lbW1vdm*'
      - '*AGUAbQBtAG8AdgBlA*'
      - '*bQBlAG0AbQBvAHYAZQ*'
      - '*bWVtbW92Z*'
      - '*ZW1tb3Zl*'
    condition: encoded and selection
  falsepositives:
  - Penetration tests
  level: high

Querying Elasticsearch

Import Libraries


In [ ]:
from elasticsearch import Elasticsearch
from elasticsearch_dsl import Search
import pandas as pd

Initialize Elasticsearch client


In [ ]:
es = Elasticsearch(['http://helk-elasticsearch:9200'])
searchContext = Search(using=es, index='logs-*', doc_type='doc')

Run Elasticsearch Query


In [ ]:
s = searchContext.query('query_string', query='(process_path.keyword:*\\powershell.exe AND process_command_line.keyword:*\ hidden\ * AND process_command_line.keyword:(*AGkAdABzAGEAZABtAGkAbgAgAC8AdAByAGEAbgBzAGYAZQByA* OR *aXRzYWRtaW4gL3RyYW5zZmVy* OR *IAaQB0AHMAYQBkAG0AaQBuACAALwB0AHIAYQBuAHMAZgBlAHIA* OR *JpdHNhZG1pbiAvdHJhbnNmZX* OR *YgBpAHQAcwBhAGQAbQBpAG4AIAAvAHQAcgBhAG4AcwBmAGUAcg* OR *Yml0c2FkbWluIC90cmFuc2Zlc* OR *AGMAaAB1AG4AawBfAHMAaQB6AGUA* OR *JABjAGgAdQBuAGsAXwBzAGkAegBlA* OR *JGNodW5rX3Npem* OR *QAYwBoAHUAbgBrAF8AcwBpAHoAZQ* OR *RjaHVua19zaXpl* OR *Y2h1bmtfc2l6Z* OR *AE8ALgBDAG8AbQBwAHIAZQBzAHMAaQBvAG4A* OR *kATwAuAEMAbwBtAHAAcgBlAHMAcwBpAG8Abg* OR *lPLkNvbXByZXNzaW9u* OR *SQBPAC4AQwBvAG0AcAByAGUAcwBzAGkAbwBuA* OR *SU8uQ29tcHJlc3Npb2* OR *Ty5Db21wcmVzc2lvb* OR *AE8ALgBNAGUAbQBvAHIAeQBTAHQAcgBlAGEAbQ* OR *kATwAuAE0AZQBtAG8AcgB5AFMAdAByAGUAYQBtA* OR *lPLk1lbW9yeVN0cmVhb* OR *SQBPAC4ATQBlAG0AbwByAHkAUwB0AHIAZQBhAG0A* OR *SU8uTWVtb3J5U3RyZWFt* OR *Ty5NZW1vcnlTdHJlYW* OR *4ARwBlAHQAQwBoAHUAbgBrA* OR *5HZXRDaHVua* OR *AEcAZQB0AEMAaAB1AG4Aaw* OR *LgBHAGUAdABDAGgAdQBuAGsA* OR *LkdldENodW5r* OR *R2V0Q2h1bm* OR *AEgAUgBFAEEARABfAEkATgBGAE8ANgA0A* OR *QASABSAEUAQQBEAF8ASQBOAEYATwA2ADQA* OR *RIUkVBRF9JTkZPNj* OR *SFJFQURfSU5GTzY0* OR *VABIAFIARQBBAEQAXwBJAE4ARgBPADYANA* OR *VEhSRUFEX0lORk82N* OR *AHIAZQBhAHQAZQBSAGUAbQBvAHQAZQBUAGgAcgBlAGEAZA* OR *cmVhdGVSZW1vdGVUaHJlYW* OR *MAcgBlAGEAdABlAFIAZQBtAG8AdABlAFQAaAByAGUAYQBkA* OR *NyZWF0ZVJlbW90ZVRocmVhZ* OR *Q3JlYXRlUmVtb3RlVGhyZWFk* OR *QwByAGUAYQB0AGUAUgBlAG0AbwB0AGUAVABoAHIAZQBhAGQA* OR *0AZQBtAG0AbwB2AGUA* OR *1lbW1vdm* OR *AGUAbQBtAG8AdgBlA* OR *bQBlAG0AbQBvAHYAZQ* OR *bWVtbW92Z* OR *ZW1tb3Zl*))')
response = s.execute()
if response.success():
    df = pd.DataFrame((d.to_dict() for d in s.scan()))

Show Results


In [ ]:
df.head()