You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
apt-hunter/src/lib/EvtxHunt.py

76 lines
4.1 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import csv
import re
from netaddr import * # 导入netaddr库的所有内容用于处理网络地址
import xml.etree.ElementTree as ET # XML解析器
import pandas as pd # 数据分析库
from datetime import datetime, timezone # 日期时间处理
from evtx import PyEvtxParser # 解析Windows事件日志文件的库
from dateutil.parser import parse, isoparse # 解析日期时间字符串
from pytz import timezone # 处理时区
minlength = 1000 # 可能用于某个字符串长度的检查,但在这个文件中未使用
# 初始化一个字典列表,用于存储猎取的事件信息
Hunting_events = [{'Date and Time': [], 'timestamp': [], 'Channel': [], 'Computer': [], 'Event ID': [], 'Original Event Log': []}]
# 正则表达式用于从事件日志中提取特定信息
EventID_rex = re.compile('<EventID.*>(.*)<\/EventID>', re.IGNORECASE)
Channel_rex = re.compile('<Channel.*>(.*)<\/Channel>', re.IGNORECASE)
Computer_rex = re.compile('<Computer.*>(.*)<\/Computer>', re.IGNORECASE)
def Evtx_hunt(files, str_regexes, eid, input_timzone, output, timestart, timeend):
"""
解析并搜索Windows事件日志文件中的特定事件。
参数:
- files: 要解析的事件日志文件列表
- str_regexes: 用于匹配事件数据的正则表达式列表
- eid: 事件ID如果提供则只搜索此ID的事件
- input_timzone: 输入日志的时区
- output: 输出文件名
- timestart, timeend: 搜索时间范围
"""
for file in files:
file = str(file)
print("Analyzing " + file)
try:
parser = PyEvtxParser(file)
except:
print("Issue analyzing " + file + "\nplease check if its not corrupted")
continue
for record in parser.records():
try:
# 提取事件ID
EventID = EventID_rex.findall(record['data'])
# 如果提供了时间范围,则检查事件是否在该范围内
if timestart is not None and timeend is not None:
timestamp = datetime.timestamp(isoparse(parse(record["timestamp"]).astimezone(input_timzone).isoformat()))
if not (timestamp > timestart and timestamp < timeend):
continue # 事件不在时间范围内,跳过
# 如果有EventID并且匹配eid如果eid不为None
if len(EventID) > 0 and (eid is None or EventID[0] == eid):
Computer = Computer_rex.findall(record['data'])
Channel = Channel_rex.findall(record['data'])
channel = Channel[0] if len(Channel) > 0 else " "
# 遍历所有提供的正则表达式
for str_regex in str_regexes:
rex = re.compile(str_regex, re.IGNORECASE)
if rex.findall(record['data']):
# 如果匹配到正则表达式,记录事件信息
Hunting_events[0]['timestamp'].append(datetime.timestamp(isoparse(parse(record["timestamp"]).astimezone(input_timzone).isoformat())))
Hunting_events[0]['Date and Time'].append(parse(record["timestamp"]).astimezone(input_timzone).isoformat())
Hunting_events[0]['Channel'].append(channel)
Hunting_events[0]['Event ID'].append(EventID[0])
Hunting_events[0]['Computer'].append(Computer[0])
Hunting_events[0]['Original Event Log'].append(str(record['data']).replace("\r", " ").replace("\n", " "))
except Exception as e:
print("issue searching log : " + record['data'] + "\n Error : " + str(e)) # 修正了错误的打印函数调用
hunt_report(output)
def hunt_report(output):
"""
生成猎取事件的报告。
参数:
- output: 输出CSV文件的前缀
"""
global Hunting_events
Events = pd.DataFrame(Hunting_events[0])
print("Found " + str(len(Hunting_events[0]["timestamp"])) + " Events")
Events.to_csv(output + "_hunting.csv", index=False)