NetExec/cme/modules/enum_av.py

413 lines
12 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# All credit to @an0n_r0
# project : https://github.com/tothi/serviceDetector
from impacket.dcerpc.v5 import lsat, lsad
from impacket.dcerpc.v5.rpcrt import DCERPCException
from impacket.dcerpc.v5.dtypes import NULL, MAXIMUM_ALLOWED, RPC_UNICODE_STRING
from impacket.dcerpc.v5 import transport, epm
import json
import pathlib
class CMEModule:
'''
Uses LsarLookupNames and NamedPipes to gather information on all endpoint protection solutions installed on the the remote host(s)
Module by @mpgn_x64
'''
name = 'enum_av'
description = 'Gathers information on all endpoint protection solutions installed on the the remote host(s) via LsarLookupNames (no privilege needed)'
supported_protocols = ['smb']
opsec_safe = True
multiple_hosts = True
def options(self, context, module_options):
pass
def on_login(self, context, connection):
success = 0
results = {}
context.log.debug("Detecting installed services on {} using LsarLookupNames()...".format(connection.host))
try:
lsa = LsaLookupNames(connection.domain, connection.username, connection.password, connection.hostname if connection.kerberos else connection.host, connection.kerberos, connection.domain, connection.lmhash, connection.nthash)
dce, rpctransport = lsa.connect()
policyHandle = lsa.open_policy(dce)
for i, product in enumerate(conf['products']):
for service in product['services']:
try:
lsa.LsarLookupNames(dce, policyHandle, service['name'])
context.log.debug("Detected installed service on {}: {} {}".format(connection.host, product['name'], service['description']))
if product['name'] not in results:
results[product['name']] = {"services": []}
results[product['name']]['services'].append(service)
except Exception as e:
pass
success += 1
except Exception as e:
context.log.error(str(e))
context.log.debug("Detecting running processes on {} by enumerating pipes...".format(connection.host))
try:
for f in connection.conn.listPath('IPC$', '\\*'):
fl = f.get_longname()
for i, product in enumerate(conf['products']):
for pipe in product['pipes']:
if pathlib.PurePath(fl).match(pipe['name']):
context.log.debug("{} running claim found on {} by existing pipe {} (likely processes: {})".format(product['name'], connection.host, fl, pipe['processes']))
if product['name'] not in results:
results[product['name']] = {}
if "pipes" not in results[product['name']]:
results[product['name']]['pipes'] = []
results[product['name']]['pipes'].append(pipe)
success += 1
except Exception as e:
context.log.error(str(e))
self.dump_results(results, connection.hostname, success, context)
def dump_results(self, results, remoteName, success, context):
# out1 = "On host {} found".format(remoteName)
out1 = ""
for item in results:
out = out1
if 'services' in results[item]:
out += "{} INSTALLED".format(item)
if 'pipes' in results[item]:
out += " and it seems to be RUNNING".format()
# else:
# for product in conf['products']:
# if (item == product['name']) and (len(product['pipes']) == 0):
# out += " (NamedPipe for this service was not provided in config)"
elif 'pipes' in results[item]:
out += " {} RUNNING".format(item)
context.log.highlight(out)
if (len(results) < 1) and (success > 1):
out = out1 + " NOTHING!".format()
context.log.highlight(out)
class LsaLookupNames():
timeout = None
authn_level = None
protocol = None
transfer_syntax = None
machine_account = False
iface_uuid = lsat.MSRPC_UUID_LSAT
authn = True
def __init__(self, domain="", username="", password="", remoteName="", k=False, kdcHost="", lmhash="", nthash=""):
self.domain = domain
self.username = username
self.password = password
self.remoteName = remoteName
self.string_binding = r"ncacn_np:{}[\PIPE\lsarpc]".format(remoteName)
self.doKerberos = k
self.lmhash = lmhash
self.nthash = nthash
self.dcHost = kdcHost
def connect(self, string_binding=None, iface_uuid=None):
"""Obtains a RPC Transport and a DCE interface according to the bindings and
transfer syntax specified.
:return: tuple of DCE/RPC and RPC Transport objects
:rtype: (DCERPC_v5, DCERPCTransport)
"""
string_binding = string_binding or self.string_binding
if not string_binding:
raise NotImplemented("String binding must be defined")
rpc_transport = transport.DCERPCTransportFactory(string_binding)
# Set timeout if defined
if self.timeout:
rpc_transport.set_connect_timeout(self.timeout)
# Authenticate if specified
if self.authn and hasattr(rpc_transport, 'set_credentials'):
# This method exists only for selected protocol sequences.
rpc_transport.set_credentials(self.username, self.password, self.domain, self.lmhash, self.nthash)
if self.doKerberos:
rpc_transport.set_kerberos(self.doKerberos, kdcHost=self.dcHost)
# Gets the DCE RPC object
dce = rpc_transport.get_dce_rpc()
# Set the authentication level
if self.authn_level:
dce.set_auth_level(self.authn_level)
# Connect
dce.connect()
# Bind if specified
iface_uuid = iface_uuid or self.iface_uuid
if iface_uuid and self.transfer_syntax:
dce.bind(iface_uuid, transfer_syntax=self.transfer_syntax)
elif iface_uuid:
dce.bind(iface_uuid)
return dce, rpc_transport
def open_policy(self, dce):
request = lsad.LsarOpenPolicy2()
request['SystemName'] = NULL
request['ObjectAttributes']['RootDirectory'] = NULL
request['ObjectAttributes']['ObjectName'] = NULL
request['ObjectAttributes']['SecurityDescriptor'] = NULL
request['ObjectAttributes']['SecurityQualityOfService'] = NULL
request['DesiredAccess'] = MAXIMUM_ALLOWED | lsat.POLICY_LOOKUP_NAMES
resp = dce.request(request)
return resp['PolicyHandle']
def LsarLookupNames(self, dce, policyHandle, service):
request = lsat.LsarLookupNames()
request['PolicyHandle'] = policyHandle
request['Count'] = 1
name1 = RPC_UNICODE_STRING()
name1['Data'] = 'NT Service\{}'.format(service)
request['Names'].append(name1)
request['TranslatedSids']['Sids'] = NULL
request['LookupLevel'] = lsat.LSAP_LOOKUP_LEVEL.LsapLookupWksta
resp = dce.request(request)
return resp
conf = {
"products": [
{
"name": "Bitdefender",
"services": [
{
"name": "bdredline_agent",
"description": "Bitdefender Agent RedLine Service"
},
{
"name": "BDAuxSrv",
"description": "Bitdefender Auxiliary Service"
},
{
"name": "UPDATESRV",
"description": "Bitdefender Desktop Update Service"
},
{
"name": "VSSERV",
"description": "Bitdefender Virus Shield"
},
{
"name": "bdredline",
"description": "Bitdefender RedLine Service"
}
],
"pipes": [
{
"name": "local\\msgbus\\antitracker.low\\*",
"processes": [
"bdagent.exe"
]
},
{
"name": "local\\msgbus\\aspam.actions.low\\*",
"processes": [
"bdagent.exe"
]
},
{
"name": "local\\msgbus\\bd.process.broker.pipe",
"processes": [
"bdagent.exe",
"bdservicehost.exe",
"updatesrv.exe"
]
},
{
"name": "local\\msgbus\\bdagent*",
"processes": [
"bdagent.exe"
]
},
{
"name": "local\\msgbus\\bdauxsrv",
"processes": [
"bdagent.exe",
"bdntwrk.exe"
]
}
]
},
{
"name": "Windows Defender",
"services": [
{
"name": "WinDefend",
"description": "Windows Defender Antivirus Service"
},
{
"name": "Sense",
"description": "Windows Defender Advanced Threat Protection Service"
},
{
"name": "WdNisSvc",
"description": "Windows Defender Antivirus Network Inspection Service"
}
],
"pipes": []
},
{
"name": "ESET",
"services": [
{
"name": "ekm",
"description": "ESET"
},
{
"name": "epfw",
"description": "ESET"
},
{
"name": "epfwlwf",
"description": "ESET"
},
{
"name": "epfwwfp",
"description": "ESET"
},
{
"name": "EraAgentSvc",
"description": "ESET"
}
],
"pipes": [
{
"name": "nod_scriptmon_pipe",
"processes": [
""
]
}
]
},
{
"name": "CrowdStrike",
"services": [
{
"name": "CSFalconService",
"description": "CrowdStrike Falcon Sensor Service"
}
],
"pipes": [
{
"name": "CrowdStrike\\{*",
"processes": [
"CSFalconContainer.exe",
"CSFalconService.exe"
]
}
]
},
{
"name": "SentinelOne",
"services": [
{
"name": "SentinelAgent",
"description": "SentinelOne Endpoint Protection Agent"
},
{
"name": "SentinelStaticEngine",
"description": "Manage static engines for SentinelOne Endpoint Protection"
},
{
"name": "LogProcessorService",
"description": "Manage logs for SentinelOne Endpoint Protection"
}
],
"pipes": [
{
"name": "SentinelAgentWorkerCert.*",
"processes": [
""
]
},
{
"name": "DFIScanner.Etw.*",
"processes": [
"SentinelStaticEngine.exe"
]
},
{
"name": "DFIScanner.Inline.*",
"processes": [
"SentinelAgent.exe"
]
}
]
},
{
"name": "Carbon Black App Control",
"services": [
{
"name": "Parity",
"description": "Carbon Black App Control Agent"
}
],
"pipes": []
},
{
"name": "Cybereason",
"services": [
{
"name": "CybereasonActiveProbe",
"description": "Cybereason Active Probe"
},
{
"name": "CybereasonCRS",
"description": "Cybereason Anti-Ransomware"
},
{
"name": "CybereasonBlocki",
"description": "Cybereason Execution Prevention"
}
],
"pipes": [
{
"name": "CybereasonAPConsoleMinionHostIpc_*",
"processes": [
"minionhost.exe"
]
},
{
"name": "CybereasonAPServerProxyIpc_*",
"processes": [
"minionhost.exe"
]
}
]
},
{
"name": "Symantec Endpoint Protection",
"services": [
{
"name": "SepMasterService",
"description": "Symantec Endpoint Protection"
},
{
"name": "SepScanService",
"description": "Symantec Endpoint Protection Scan Services"
},
{
"name": "SNAC",
"description": "Symantec Network Access Control"
}
],
"pipes": []
}
]
}