hubertwojcik/ssh-log-anomaly-detector

GitHub: hubertwojcik/ssh-log-anomaly-detector

一款结合启发式规则与 Isolation Forest 模型的 Python 工具,用于分析 Linux auth.log 并检测 SSH 暴力破解、异常登录时间、新 IP 和提权等可疑活动。

Stars: 0 | Forks: 0

# ssh-log-anomaly-detector 一个 Python 工具,它通过结合启发式规则和 Isolation Forest ML 模型,分析 Linux `auth.log` 文件并检测可疑的 SSH 活动。 检测四类异常:暴力破解攻击、非用户历史时间段的登录、来自新 IP 地址的登录,以及提权尝试。每项发现都包含严重程度、人类可读的描述以及原始日志证据。 ``` $ ssh-anomaly detect auth.log SSH Log Anomaly Detector File: auth.log | Events: 14,823 | Time range: 2024-06-01 → 2024-06-08 ┌──────────────────────┬────────────────┬───────────────┬──────────┬────────────────────────────────────────────────┐ │ Timestamp │ Source IP │ Type │ Severity │ Description │ ├──────────────────────┼────────────────┼───────────────┼──────────┼────────────────────────────────────────────────┤ │ 2024-06-03 03:12:44 │ 198.51.100.42 │ brute-force │ HIGH │ 538 failed attempts in 60s (threshold: 10) │ │ 2024-06-04 03:47:21 │ 203.0.113.17 │ unusual-time │ MEDIUM │ alice logged in at 03:47 — baseline: 08–18 │ │ 2024-06-05 11:23:05 │ 192.0.2.88 │ new-ip │ MEDIUM │ bob logged in from unseen IP (30-day baseline) │ │ 2024-06-06 14:55:33 │ — │ priv-esc │ HIGH │ 7 sudo failures then success for user charlie │ │ 2024-06-07 09:10:12 │ 198.51.100.99 │ ml-anomaly │ LOW │ Isolation Forest score: -0.41 (threshold -0.3) │ └──────────────────────┴────────────────┴───────────────┴──────────┴────────────────────────────────────────────────┘ Summary: 5 anomalies (HIGH: 2 MEDIUM: 2 LOW: 1) ``` ## 工作原理 ``` /var/log/auth.log │ ▼ ┌─────────┐ regex + pandas ┌──────────────────┐ │ Parser │ ──────────────────► │ Structured │ │ │ │ DataFrame │ └─────────┘ └────────┬─────────┘ │ ┌───────────────────┼───────────────────┐ ▼ ▼ ▼ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ Feature │ │ Heuristic │ │ ML │ │ Engineering │ │ Detectors │ │ Detector │ │ │ │ │ │ (Iso Forest) │ │ failure_rate │ │ brute-force │ │ │ │ inter_arrival│ │ unusual-time │ │ per-IP │ │ login_hour │ │ new-ip │ │ feature │ │ distinct_users │ priv-esc │ │ matrix │ └──────────────┘ └──────┬───────┘ └──────┬───────┘ │ │ └─────────┬─────────┘ ▼ ┌──────────────┐ │ Reporter │ │ table / json │ └──────────────┘ ``` **启发式规则** 快速、可解释,且在已知模式下零误报。**Isolation Forest** 能够捕获不匹配任何特定规则的异常——即在统计上偏离基线的异常特征组合。 ## 异常类型 | 类型 | 检测方法 | 捕获内容 | |---|---|---| | **暴力破解** | 启发式 —— 滑动窗口 | 同一 IP 在 T 秒内出现 N 次失败登录 | | **异常登录时间** | 启发式 —— 单用户基线 | 成功登录发生在用户的历史时间段之外 | | **新 IP** | 启发式 —— 单用户 IP 历史 | 成功登录来自基线期间从未见过的新 IP | | **提权** | 启发式 —— 事件序列 | Sudo 失败、root SSH 尝试、失败后紧接成功 | | **ML 异常** | Isolation Forest | 规则未涵盖的统计学异常 IP 行为 | 请参阅 [`docs/anomaly-types.md`](docs/anomaly-types.md) 以了解检测逻辑、调优指南以及每种类型的示例日志行。 ## 数据来源 两个互补的来源为该项目提供数据:用于确定性测试的合成数据,以及用于生成真实训练/评估数据的真实一次性蜜罐: | 来源 | 位置 | 用途 | |---|---|---| | **合成样本** | `data/samples/` | 带有已知位置已知异常的确定性测试夹具——用于解析器/检测器的单元测试。由 `data/generate_samples.py` 生成。 | | **真实蜜罐日志** | `data/real/` | 从暴露在 22 端口上的一次性云 VM 收集的真实 `auth.log` 流量——用于训练/评估 Isolation Forest,并针对真实攻击者行为验证启发式规则。 | **为什么要使用真实蜜罐?** 一个可公开访问的 SSH 端口会在几小时内被真实的僵尸网络扫描和暴力破解——这是目前最难令人信服地伪造的一类(攻击者 IP 的多样性、撞库的时间点、工具指纹)。编写脚本生成合成数据往往过于干净和规律,这使得模型可以通过学习生成器的特征来“作弊”,而不是学习真实的异常行为。 **哪些仍然需要编写脚本。** 没人会合法地登录到蜜罐,因此“正常”基线是刻意生成的:少数专用账户、仅密钥认证、通过 cron 在不同时间段驱动登录,以构建不同的单用户行为画像(参见 `infra/ansible/baseline_traffic.yml`)。提权示例也是合成的——一个隔离得当的蜜罐绝不应该真的被攻破。 **安全性。** 该蜜罐是一个一次性、隔离的实例:专用的安全组(仅开放 22 端口),不重复使用其他基础设施的密钥或凭证,没有敏感数据,真实访问仅限密钥认证。来自互联网的密码失败尝试会自然地填充到 `auth.log` 中,而无需冒任何账户被破解的风险。 ## 安装说明 ``` git clone https://github.com/hubertwojcik/ssh-log-anomaly-detector cd ssh-log-anomaly-detector pip install -e . ``` 要求 Python 3.11+。 ## 使用方法 **基础扫描:** ``` ssh-anomaly detect /var/log/auth.log ``` **输出 JSON 用于下游处理:** ``` ssh-anomaly detect auth.log --format json | jq '.[] | select(.severity == "HIGH")' ``` **仅输出 HIGH 严重级别,并写入文件:** ``` ssh-anomaly detect auth.log --quiet --output findings.txt ``` **调整阈值并仅运行启发式检测器:** ``` ssh-anomaly detect auth.log \ --detectors heuristic \ --threshold 5 \ --window 2m \ --baseline-days 14 ``` **完整选项:** ``` Usage: ssh-anomaly detect [OPTIONS] LOGFILE Options: --format [table|json|csv] Output format [default: table] --threshold INTEGER Brute-force failure threshold [default: 10] --window TEXT Aggregation time window [default: 1m] --baseline-days INTEGER Days of history for per-user baselines [default: 7] --detectors [all|heuristic|ml] Which detectors to run [default: all] --output FILE Write results to file instead of stdout --quiet Only report HIGH severity findings --help Show this message and exit. ``` ## 项目结构 ``` ssh-log-anomaly-detector/ ├── src/ │ └── ssh_anomaly/ │ ├── parser.py # auth.log → pd.DataFrame │ ├── features.py # per-event and per-IP feature engineering │ ├── detectors/ │ │ ├── heuristic.py # BruteForceDetector, UnusualTimeDetector, NewIPDetector, PrivEscDetector │ │ └── ml.py # IsolationForestDetector │ ├── reporter.py # rich table, JSON, CSV output │ └── cli.py # Click entrypoint │ ├── tests/ │ ├── test_parser.py │ ├── test_features.py │ └── test_detectors.py │ ├── infra/ │ ├── terraform/ # provisions the disposable honeypot VM (cheap cloud instance) │ └── ansible/ │ ├── honeypot.yml # sshd config, log rotation, syncs auth.log → data/real/ │ └── baseline_traffic.yml # cron-driven scripted logins simulating legitimate users │ ├── data/ │ ├── generate_samples.py # generates synthetic auth.log files with known anomalies │ ├── samples/ # synthetic, deterministic — unit test fixtures │ │ ├── normal.log # 7 days of clean traffic — no anomalies │ │ ├── bruteforce.log # 538 failed attempts from single IP │ │ ├── after_hours.log # 3am login for a 9–17 user │ │ ├── new_ip.log # login from unseen IP │ │ ├── privesc.log # sudo failures then success │ │ └── mixed.log # all of the above with realistic noise │ └── real/ # auth.log pulled from the honeypot — ML training/eval │ ├── docs/ │ ├── anomaly-types.md # detection logic and tuning guidance │ └── detector-comparison.md # heuristics vs ML: what each catches │ └── pyproject.toml ``` ## 技术栈 | 库 | 作用 | |---|---| | `pandas` | 日志解析,DataFrame 操作,滚动窗口聚合 | | `scikit-learn` | Isolation Forest,StandardScaler | | `click` | CLI 接口 | | `rich` | 带有严重程度颜色编码的终端表格输出 | | `pytest` | 测试套件 —— 基于合成日志文件的集成测试 | ## 运行测试 ``` pytest -v ``` 测试使用合成的 `data/samples/` 文件作为夹具 —— 无需对内部函数进行 mock。每个检测器都会进行端到端测试:解析器 → 特征 → 检测器 → 发现结果。 ## 设计说明 **为什么选择 Isolation Forest?** 它是无监督的,不需要带标签的攻击数据。考虑到真实的 `auth.log` 数据绝大多数是正常流量,这非常契合——异常在定义上就是特征空间中的稀有数据点。 **为什么优先使用启发式?** 启发式规则透明且可调。一条在“60 秒内失败 10 次”触发的暴力破解规则,在报告中一目了然。ML 层增加了对边缘情况的覆盖,而不是替代显式规则。 **作为关键特征的 `inter_arrival_std`:** 诸如 Hydra 之类的自动化工具会以近乎恒定的速率发送尝试。而手动进行暴力破解的人类会表现出极高的到达时间间隔方差。这一单一特征能够可靠地将工具生成的攻击与手动攻击区分开来。 **合成样本对比真实蜜罐数据:** 合成日志精确且非常适合单元测试——你能确切知道异常发生在哪里。但规律性对于 ML 来说恰恰是个问题:仅在脚本生成的“正常”和“攻击”流量上训练的模型,可能会学会识别生成器,而不是识别异常。取而代之的是,使用来自一次性蜜罐的真实攻击者流量(参见[数据来源](#data-sources))来训练和评估 Isolation Forest。 作为一个 Python 作品集项目开发 —— 涵盖了解析、特征工程、ML pipeline、CLI 设计,以及基于真实安全数据的端到端测试。
标签:Apex, CSV导出, Python, SSH, 安全, 安全规则引擎, 异常检测, 无后门, 机器学习, 系统提示词, 红队行动, 聊天机器人, 超时处理, 逆向工具