PowerShell Network Connections

Detects a Powershell process that opens network connections - check for suspicious target ports and target systems - adjust to your environment (e.g. extend filters with company's ip range')

Rule Content

- title: PowerShell Network Connections
  id: 1f21ec3f-810d-4b0e-8045-322202e22b4b
  status: experimental
  description: Detects a Powershell process that opens network connections - check
    for suspicious target ports and target systems - adjust to your environment (e.g.
    extend filters with company's ip range')
  author: Florian Roth
  references:
  - https://www.youtube.com/watch?v=DLtJTxMWZ2o
  tags:
  - attack.execution
  - attack.t1086
  logsource:
    product: windows
    service: sysmon
    category: null
  detection:
    selection:
      EventID: 3
      Image: '*\powershell.exe'
      Initiated: 'true'
    filter:
      DestinationIp:
      - 10.*
      - 192.168.*
      - 172.16.*
      - 172.17.*
      - 172.18.*
      - 172.19.*
      - 172.20.*
      - 172.21.*
      - 172.22.*
      - 172.23.*
      - 172.24.*
      - 172.25.*
      - 172.26.*
      - 172.27.*
      - 172.28.*
      - 172.29.*
      - 172.30.*
      - 172.31.*
      - 127.0.0.1
      DestinationIsIpv6: 'false'
      User: NT AUTHORITY\SYSTEM
    condition: selection and not filter
  falsepositives:
  - Administrative scripts
  level: low

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-endpoint-winevent-sysmon-*', doc_type='doc')

Run Elasticsearch Query


In [ ]:
s = searchContext.query('query_string', query='((event_id:"3" AND process_path.keyword:*\\powershell.exe AND network_initiated:"true") AND (NOT (dst_ip_addr.keyword:(10.* OR 192.168.* OR 172.16.* OR 172.17.* OR 172.18.* OR 172.19.* OR 172.20.* OR 172.21.* OR 172.22.* OR 172.23.* OR 172.24.* OR 172.25.* OR 172.26.* OR 172.27.* OR 172.28.* OR 172.29.* OR 172.30.* OR 172.31.* OR 127.0.0.1) AND DestinationIsIpv6:"false" AND user_account:"NT\ AUTHORITY\\SYSTEM")))')
response = s.execute()
if response.success():
    df = pd.DataFrame((d.to_dict() for d in s.scan()))

Show Results


In [ ]:
df.head()