CS-Abuhelal/log-anomaly-detector

GitHub: CS-Abuhelal/log-anomaly-detector

一款基于透明统计学方法的轻量级日志异常检测工具,用于离线分析 Windows 和 Linux 系统日志中的可疑安全行为。

Stars: 0 | Forks: 0

# 日志异常检测器 一个适合初学者的 Python 工具,用于扫描 Windows 安全事件日志 和 Linux `auth.log` 文件以查找可疑模式,它使用简单的 统计方法(仅使用 `pandas` 和 `numpy` - 没有繁重的机器学习库)而不是 黑盒模型。每个发现都会获得一个 **0-100 的风险评分**,以便您 可以快速分拣出最重要的问题。 ## 它能检测什么 | 检测项 | 查找目标 | |---|---| | **登录失败激增(暴力破解)** | 在一个较短的滑动时间窗口内,来自同一源 IP 的大量失败登录尝试 - 无论是猛攻单个账户还是“喷射”多个账户 | | **非正常时段登录** | 在网络中统计上极其罕见的时段内发生的成功登录,通过对通常有活动的时段使用 z-score 进行计算 | | **新建用户账户** | 呈现每一个新建账户,如果其是在非正常时段创建的,则会增加额外风险 | | **权限提升** | 被添加到特权组(Administrators、sudo、wheel、Domain Admins 等)的账户 | | **异常进程执行** | 已知攻击者工具/技术(Mimikatz、编码的 PowerShell、PsExec、反弹 shell 等)的监控列表,以及统计上罕见的单次执行进程 | ## 安装 要求 Python 3.8+。 ``` git clone https://github.com/CS-Abuhelal/log-anomaly-detector.git cd log-anomaly-detector pip install -r requirements.txt ``` 唯一的依赖项是 `pandas` 和 `numpy` - 这是刻意为之, 它*不是*一个机器学习工具。下面所有的检测逻辑都是纯粹的 计数、滑动时间窗口和 z-score,这使得它快速、 透明且易于推理(您始终可以解释*为什么* 某些内容会被标记)。 ## 快速开始 `sample_logs/` 中包含了十个示例日志文件,以便您可以立即 试用该工具: ``` python analyzer.py sample_logs/mixed_windows.csv sample_logs/mixed_linux.log ``` 您可以在一次运行中传入任意混合的 Windows CSV 导出文件和 Linux auth.log 文件 - 它们会被解析为一个统一的组合时间线并进行 共同分析。要将报告保存到文件: ``` python analyzer.py sample_logs/mixed_windows.csv sample_logs/mixed_linux.log --output report.txt ``` ### 示例输出 ``` ====================================================================== LOG ANOMALY DETECTOR - SUMMARY REPORT ====================================================================== Files analyzed : sample_logs/mixed_windows.csv, sample_logs/mixed_linux.log Events parsed : 65 Total findings : 6 Findings by severity: CRITICAL : 3 HIGH : 2 MEDIUM : 1 ====================================================================== --- CRITICAL ---------------------------------------------------------- [Risk 97/100 - CRITICAL] Suspicious Process Execution: 'mimikatz.exe' run by backup_svc2 matches a known attack pattern: Known credential-dumping tool. [Risk 90/100 - CRITICAL] Privilege Escalation: Account 'backup_svc2' was added to a highly privileged group (Group: Administrators). [Risk 90/100 - CRITICAL] Suspicious Process Execution: '/bin/nc' run by diego matches a known attack pattern: Netcat used to spawn a reverse shell. --- HIGH -------------------------------------------------------------- [Risk 74/100 - HIGH] Unusual Login Hour: diego logged in at 04:00, an hour when logins are statistically rare on this network (z-score -2.24). [Risk 70/100 - HIGH] New Account Created: New account 'backup_svc2' was created by svc_admin during an unusual hour. --- MEDIUM ------------------------------------------------------------ [Risk 63/100 - MEDIUM] Brute Force: 203.0.113.40 made 6 failed login attempts within 5 minutes (targeting 6 distinct account(s)). ``` ## 输入日志格式 ### Windows (`.csv`) 支持并会自动检测两种 Windows CSV 格式: **1. 事件查看器的 GUI 导出**(“Save All Events As...” / “Save Filtered Log File As...”) - 只需导出您的安全日志并让该工具 直接指向该文件即可,无需手动重新格式化。此格式 有一个众所周知的怪癖:它的标题只命名了 5 列 (`Keywords, Date and Time, Source, Event ID, Task Category`),但每 行实际上有 6 个字段 - 事件描述没有列名。 天真地读取它(例如在 Excel/pandas 中使用默认设置打开) 会悄悄地使每一列都向右错位一位。此工具会检测到该标题 并正确读取它,然后直接从 Windows 始终 写入描述中的结构化 `Field Name: value` 文本中提取所需的 账户/IP/进程详细信息。 **2. 一个简化的、有文档说明的 schema** - 如果您正在手动构建 CSV, 使用 `Get-WinEvent`,或用于测试,这会非常有用: ``` TimeCreated,EventID,Account,SourceIP,TargetAccount,ProcessName,CommandLine,Message ``` 两种格式都能理解的事件 ID: | Event ID | 含义 | 映射为 | |---|---|---| | 4624 | 账户成功登录 | `logon_success` | | 4625 | 账户登录失败 | `logon_failed` | | 4720 | 创建了用户账户 | `account_created` | | 4732 | 将成员添加到启用安全性的组中 | `privilege_change` | | 4688 | 创建了新进程 | `process_execution` | 其他所有内容都会被解析但会被忽略 - 只有这五种事件类型会提供给 检测器。 ### Linux(任何非 `.csv` 格式) 标准 syslog 风格的 `/var/log/auth.log` 行,例如: ``` Jun 18 03:14:12 host sshd[1234]: Failed password for invalid user admin from 203.0.113.5 port 51234 ssh2 Jun 18 03:14:15 host sshd[1234]: Accepted password for ahmed from 192.168.1.50 port 51240 ssh2 Jun 18 09:00:01 host useradd[2345]: new user: name=backdoor, UID=1001 Jun 18 09:00:05 host usermod[2345]: add 'backdoor' to group 'sudo' Jun 18 09:05:00 host sudo: ahmed : TTY=pts/0 ; PWD=/home/ahmed ; USER=root ; COMMAND=/usr/bin/whoami ``` 两种格式都会被规范化为一个内部表格(参见 `loganomaly/parsers.py`),因此无论数据来自何处,每个检测器 都以相同的方式工作。 ## 示例日志文件 | 文件 | 演示内容 | |---|---| | `windows_normal.csv` / `linux_auth_normal.log` | 干净的基线 - 仅包含工作时间内的登录。根据设计,产生 **零** 发现。 | | `windows_bruteforce.csv` / `linux_auth_bruteforce.log` | 来自一个 IP 的失败登录激增,速度快到足以越过暴力破解阈值 | | `windows_unusual_hours.csv` | 扎实的白天基线加上两次在统计上显得突出的非工作时间登录 | | `windows_new_account.csv` | 在凌晨 2:30 创建的新账户 | | `windows_privilege_escalation.csv` | 添加到 Administrators 组的账户 | | `windows_suspicious_process.csv` | 一个正常的、经常运行的进程(被忽略)旁边是一个编码的 PowerShell 命令和一个罕见的单次运行工具(均被标记) | | `mixed_windows.csv` + `mixed_linux.log` | 一次同时涉及所有五个检测类别的综合事件场景 - 即上面的示例 | 随时使用以下命令重新生成其中任何一个: ``` python sample_logs/generate_samples.py ``` 这些文件中的每个账户名、IP 地址和命令行都是 合成的 - 不涉及任何真实的主机、用户或凭据。 外部 IP 使用 `203.0.113.0/24` 范围,[RFC 5737](https://datatracker.ietf.org/doc/html/rfc5737) 专门为文档/示例保留了该范围,并且它在 真实的互联网上是不可路由的。 ## 真实世界测试 除了合成示例外,此工具还针对真实的 Windows 11 机器的安全事件日志运行过,该日志是使用事件查看器的“Save All Events As...”(GUI 导出格式 - 请参见上面的[输入日志格式](#input-log-formats) )导出的: ``` Events parsed : 1512 Total findings : 0 ``` 这里干净的结果不仅仅是“没有东西可以打印” - 每个 检测器实际上都对真实数据运行了检查,并且有 具体的依据来否定发现: - **异常登录时间**:成功的登录分布在 24 小时中的 21 个小时里(这台机器全天候运行计划任务和后台登录),因此 对于 z-score 检查来说,没有任何统计上罕见的小时可以标记 - 这 与典型的朝九晚五工作站的结果有着本质上的不同,检测器 正确地反映了这一点。 - **暴力破解**:整个日志中只出现了 2 次失败登录, 远未达到默认的“5 分钟内失败 5 次”阈值。 - **新建账户**:零次 `4720` 事件 - 在捕获期间没有创建 任何新账户。 - **权限提升**:零次 `4732` 事件 - 没有 组成员身份的更改。 - **可疑进程执行**:26 个进程创建事件,全部 是普通的 Windows 启动/系统进程(`smss.exe`、`csrss.exe`、 `lsass.exe`、`services.exe` 等),它们既不在攻击者 监控列表中,在统计上也不罕见。 这次运行还在 Event Viewer CSV 读取器中发现了一个真实的解析错误: 一个 `New Process Name` 字段为空的进程创建事件, 导致*下一行*的文本渗入其中,原因是正则表达式使用了 `\s*` (匹配换行符)而不是字段冒号后面的 `[ \t]*`。此问题已修复,并在 `tests/test_parsers.py` 中通过回归测试进行了锁定。 ## 调整检测阈值 ``` python analyzer.py mylog.csv \ --window-minutes 10 \ --count-threshold 8 \ --hour-z-threshold -2.0 ``` | 标志 | 默认值 | 含义 | |---|---|---| | `--window-minutes` | 5 | 用于暴力破解突发检测的滑动窗口大小 | | `--count-threshold` | 5 | 窗口内被视为突发的失败登录次数 | | `--hour-z-threshold` | -1.5 | 登录时间被视为统计上罕见的 z-score 阈值(负值越大 = 越严格) | | `--output` | *(无)* | 同时将报告保存到此文件 | ## 各个检测器的工作原理(供好奇者参考) - **暴力破解** (`detect_brute_force`):对于每个源 IP,按时间对其 失败登录进行排序,并使用 `numpy.searchsorted` 来为每次 尝试找出,该 IP 在前 N 分钟内发生了多少次 其他尝试。如果该计数超过阈值,则为 突发。如果攻击者尝试了 3 个或更多不同的账户 名(密码喷射,而不仅仅是猜测单个账户),则会增加奖励分数。 - **异常时间** (`detect_unusual_hours`):构建一个 24 格的直方图,显示 成功登录通常发生在哪个小时,但是 - 重要的是 - 仅在实际 有活动的小时上计算平均值/标准差(否则,十几个以上始终为空的夜间时段 会使数学计算严重倾斜,以至于任何登录看起来都像是 “激增”而不是异常值)。如果某个登录发生时间的小时 z-score 低于阈值,则该登录将被标记。 - **新建账户** (`detect_new_accounts`):标记每个账户 创建事件,如果它发生在统计 上罕见的小时(使用与上述相同的计算),则会增加风险。 - **权限提升** (`detect_privilege_escalation`):标记组 成员身份更改,当目标组名 与高价值模式(Administrators、sudo、wheel、Domain Admins 等)匹配时,得分会更高。 - **异常进程** (`detect_unusual_processes`):检查每个 执行的进程/命令是否与已知攻击者 技术(Mimikatz、编码的 PowerShell、PsExec、certutil/regsvr32/ bitsadmin LOLBins、通过 netcat 的反弹 shell 等)的监控列表匹配。任何不在 监控列表上的内容,如果在统计上很罕见,即在整个 日志中只出现一次或两次,仍然会被标记。 ## 运行测试 ``` python tests/test_detectors.py -v # 或者,如果你已经安装了 pytest: python -m pytest tests/ -v ``` ## 局限性 这是一个教育项目,而不是生产级的 SIEM 关联规则 集: - 所有分析都是**离线**的,针对静态日志文件 - 没有实时跟踪或 实时警报。 - 统计基线(小时罕见性、进程罕见性)需要 合理的数据量才能有意义;微小的日志文件无法提供 可靠的 z-score。 - Windows CSV schema 是为清晰起见而选择的简化、有文档说明的格式 - 真实世界的 `Get-WinEvent` 导出将需要映射其列以 与之匹配(或者扩展 `parsers.py` 以直接读取它们)。 - 进程监控列表是说明性的,并非详尽无遗 - 它不会 捕获每个攻击者工具,特别是自定义/重命名的二进制文件。 ## License MIT
标签:AMSI绕过, Python, 威胁检测, 安全, 异常检测, 无后门, 红队行动, 超时处理, 逆向工具