Skip to content

Commit

Permalink
Merge pull request #291 from cccs-kevin/update/sysmon-aux
Browse files Browse the repository at this point in the history
Updating the sysmon module
  • Loading branch information
doomedraven authored Jul 11, 2022
2 parents 0eb6cc7 + 6a01230 commit 6776fe1
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 19 deletions.
57 changes: 38 additions & 19 deletions analyzer/windows/modules/auxiliary/sysmon.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import logging
import os
import platform
import subprocess
import threading
import time

from lib.common.abstracts import Auxiliary
from lib.common.exceptions import CuckooPackageError
from lib.common.results import upload_to_host
from lib.core.config import Config

Expand All @@ -15,11 +16,8 @@


class Sysmon(threading.Thread, Auxiliary):
def __init__(self, options=None, analyzer=None):
if options is None:
options = {}
threading.Thread.__init__(self)
Auxiliary.__init__(self, options, analyzer)
def __init__(self, options, config):
Auxiliary.__init__(self, options, config)
self.config = Config(cfg="analysis.conf")
self.enabled = self.config.sysmon
self.do_run = self.enabled
Expand All @@ -36,36 +34,57 @@ def clear_log(self):
log.error("Error clearing Sysmon events - %s", e)

def collect_logs(self):
sysmon_xml_path = "C:\\sysmon.xml"
try:
subprocess.call(
(
"C:\\Windows\\System32\\wevtutil.exe",
"query-events",
"microsoft-windows-sysmon/operational",
"/rd:true",
"/e:root",
"/e:Events",
"/format:xml",
"/uni:true",
),
startupinfo=self.startupinfo,
stdout=open("C:\\sysmon.xml", "w"),
stdout=open(sysmon_xml_path, "w"),
)
except Exception as e:
log.error("Could not create sysmon log file - %s", e)

# Give it some time to create the file
# time.sleep(5)

if os.path.exists("C:\\sysmon.xml"):
upload_to_host("C:\\sysmon.xml", f"sysmon/{time.time()}.sysmon.xml", False)
if os.path.exists(sysmon_xml_path):
upload_to_host(sysmon_xml_path, "sysmon/sysmon.xml")
else:
log.error("Sysmon log file not found in guest machine")

def run(self) -> bool:
if self.enabled:
self.clear_log()
return True
return False
def start(self):
if not self.enabled:
return False

self.clear_log()

# First figure out what architecture the system in running (x64 or x86)
bin_path = os.path.join(os.getcwd(), "bin")

if "Windows" in platform.uname():
if "AMD64" in platform.uname():
sysmon = os.path.join(bin_path, "SMaster64.exe")
else:
sysmon = os.path.join(bin_path, "SMaster32.exe")
#TODO: Platform is Linux, add support for https://github.com/Sysinternals/SysmonForLinux
else:
self.enabled = False
return False

config_file = os.path.join(bin_path, "sysmonconfig-export.xml")
if not os.path.exists(sysmon) or not os.path.exists(config_file):
raise CuckooPackageError(
"In order to use the Sysmon functionality, it "
"is required to have the sysmon(64|32).exe file and "
"sysmonconfig.xml file in the bin path."
)

# Start Sysmon in the background
subprocess.call([sysmon, "-accepteula", "-n", "-i", config_file], startupinfo=self.startupinfo)

def stop(self) -> bool:
if self.enabled:
Expand Down
59 changes: 59 additions & 0 deletions modules/processing/sysmon.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import logging
import os
import re
import xmltodict

from lib.cuckoo.common.abstracts import Processing
from lib.cuckoo.common.exceptions import CuckooProcessingError

log = logging.getLogger(__name__)

__author__ = "@FernandoDoming"
__version__ = "1.0.0"


def parseXmlToJson(xml):
return {child.tag: parseXmlToJson(child) if list(child) else child.text or "" for child in list(xml)}


class Sysmon(Processing):
def remove_noise(self, data):
filtered_proc_creations_re = (
r"C:\\Windows\\System32\\wevtutil\.exe\s+clear-log\s+microsoft-windows-(sysmon|powershell)\/operational",
r"bin\\is32bit.exe",
r"bin\\inject-(?:x86|x64).exe",
r"C:\\Windows\\System32\\wevtutil.exe\s+query-events microsoft-windows-powershell\/operational\s+\/rd:true\s+\/e:root\s+\/format:xml\s+\/uni:true",
r"C:\\Windows\\System32\\wevtutil.exe\s+query-events\s+microsoft-windows-sysmon\/operational\s+\/format:xml",
)

filtered = []
for event in data:
is_filtered = False
if event["System"]["EventID"] == "1":
for p in filtered_proc_creations_re:
cmdline = event["EventData"]["Data"][9].get("#text")
if cmdline and re.search(p, cmdline):
log.info("Supressed %s because it is noisy", cmdline)
is_filtered = True

if not is_filtered:
filtered.append(event)

return filtered

def run(self):
self.key = "sysmon"
sysmon_path = f"{self.analysis_path}/sysmon/sysmon.xml"

if not os.path.exists(sysmon_path) or os.path.getsize(sysmon_path) < 100:
return

data = None
try:
xml = open(sysmon_path, "rb").read()
xml = xml.decode("latin1").encode("utf8")
data = xmltodict.parse(xml)["Events"]["Event"]
except Exception as e:
raise CuckooProcessingError("Failed parsing sysmon.xml: %s" % e.message)

return self.remove_noise(data)

0 comments on commit 6776fe1

Please sign in to comment.