malikk-abdullah/Log-Analyzer
GitHub: malikk-abdullah/Log-Analyzer
一款基于C++的数字取证日志分析器,通过规则引擎解析系统日志并自动检测威胁,支持多案件与多用户管理。
Stars: 0 | Forks: 0
# 数字取证日志分析器
一款用于多案件数字取证调查的 C++ 控制台应用程序 —— 作为**空军大学网络空间安全系 BSCYS-F-25-B** 的面向对象编程课程项目而开发。
该系统接收原始系统日志文件,通过基于规则的威胁检测引擎对其进行处理,并生成结构化的调查报告,所有这些都包含在一个多用户、基于角色的身份验证系统中。
## 作者
- Abdullah Sajid —
## 功能
- **多用户身份验证**,支持基于角色的访问控制(`admin` / `user`)
- 账号注册、登录、5 次尝试失败后自动锁定,以及管理员解锁
- **多案件工作区** —— 最多支持 10 个同时进行的取证案件
- **双日志解析器层级** —— 用于结构化演示日志的 `SampleLogParser`,以及用于 `/var/log/auth.log` 风格 syslog 输入的 `RealLinuxLogParser`
- **8 规则威胁检测引擎**,触发 `CRITICAL` 和 `WARNING` 警报
- 屏幕显示和基于文件的调查报告生成
- 内置示例日志生成器,用于演示和测试
- 用于用户管理(升级、降级、删除、解锁)的管理员控制面板
## 演示的 OOP 概念
| 概念 | 位置 |
|---|---|
| 类与对象 | `Analyst`、`ForensicCase`、`LogParser` 层级 |
| 封装 | `Analyst` 和 `ForensicCase` 中的私有成员/辅助函数,仅通过 public getter 和方法访问 |
| 继承 | `SampleLogParser` 和 `RealLinuxLogParser` 继承自抽象类 `LogParser` |
| 多态 | 通过 `LogParser*` 基类指针调用 `parseAndLoad()` 实现运行时分发 |
| 构造函数 / 析构函数 | `Analyst` 和 `ForensicCase` 中的完整规范形式(默认、带参、拷贝、析构函数),用于管理堆内存 |
| 静态成员 | `Analyst::totalAnalysts`、`ForensicCase::caseCounter` |
| 动态内存管理 | 手动管理、针对事件/警报的倍增容量动态数组(使用 `std::vector` 替代固定大小的容器) |
| Const 正确性 | Getter 和报告打印标记为 `const`;`caseID` 被声明为 `const`,仅通过成员初始化列表设置 |
| Union | `EventSource` 存储 IP 地址或主机名,并配有一个 `bool` 判别标志以确保安全访问 |
## 核心类与数据结构
| 类型 | 作用 |
|---|---|
| `Analyst` | 对调查员/管理员进行建模 —— 姓名、徽章 ID、角色、`isAdmin()` |
| `ForensicCase` | 对单个调查进行建模 —— 拥有事件、警报、运行分析、生成报告 |
| `LogParser` (抽象) | 通过纯虚函数 `parseAndLoad()` 定义解析器接口 |
| `SampleLogParser` | 解析 `[timestamp] EVENT key=value` 格式的示例日志 |
| `RealLinuxLogParser` | 解析 Linux `auth.log` syslog 风格的行 |
| `RawEvent` (结构体) | 单个解析后的日志条目(时间戳、事件类型、用户名、详情、严重程度、小时) |
| `Alert` (结构体) | 触发的威胁警报(类型、描述、严重等级、时间戳) |
| `EventSource` (union) | 案件来源的 IP 地址或主机名 |
| `UserAccount` (结构体) | 用户名、密码哈希(此版本中为纯文本)、角色、锁定标志 |
## 威胁检测规则
分析引擎会扫描所有已加载的事件并应用 8 条独立的规则,同时进行去重,以确保不会对同一警报触发两次:
| # | 警报类型 | 等级 | 触发条件 |
|---|---|---|---|
| 1 | `BRUTE_FORCE` | CRITICAL | 同一用户发生 3 次及以上 `LOGIN_FAILED` 事件 |
| 2 | `SUCCESSFUL_BRUTE_FORCE` | CRITICAL | `LOGIN_SUCCESS` 之前,同一用户发生过 3 次及以上 `LOGIN_FAILED` |
| 3 | `SENSITIVE_FILE_ACCESS` | CRITICAL | 针对 `/etc/passwd`、`/etc/shadow`、SAM 或 `id_rsa` 的 `FILE_ACCESS` |
| 4 | `REPEATED_FILE_ACCESS` | WARNING | 同一文件被访问 3 次及以上 |
| 5 | `SUSPICIOUS_COMMAND` | WARNING | 包含 `whoami`、`mimikatz`、`powershell`、`curl` 或 `net_user` 的 `CMD_EXEC` |
| 6 | `PRIVILEGE_ESCALATION` | CRITICAL | 任何 `PRIV_ESCALATION` 事件 |
| 7 | `SUSPICIOUS_LOGIN_TIME` | WARNING | 在 00:00–04:59 之间的登录/提权活动 |
| 8 | `PORT_SCAN` | WARNING | 5 次及以上的 `PORT_SCAN` 事件 |
**结论** 根据生成的警报组合计算得出:
| 条件 | 结论 |
|---|---|
| 2 个及以上 CRITICAL 警报 | HIGH RISK |
| 1 个 CRITICAL,或 3 个及以上 WARNING 警报 | MEDIUM RISK |
| 1 个及以上 WARNING 警报 | LOW RISK |
| 无警报 | CLEAN |
## 基于角色的访问
| 功能 | 管理员 | 用户 |
|---|---|---|
| 创建新案件 | ✅ | ❌ |
| 加载日志文件 | ✅ | ✅ |
| 运行分析 | ✅ | ✅ |
| 打印 / 保存报告 | ✅ | ✅ |
| 生成示例日志 | ✅ | ❌ |
| 用户管理面板 | ✅ | ❌ |
| 切换 / 查看 / 删除 / 取消选择案件 | ✅ | ✅ |
登录最多允许 5 次密码尝试,之后将自动锁定。代码中硬编码的 4 个核心管理员账号永远不会被锁定、删除或降级。
## 文件 I/O
| 文件 | 用途 | 格式 |
|---|---|---|
| `users.txt` | 跨会话持久化非管理员账号 | CSV: `username,password,role,locked(0/1)` |
| `.log` | 用于分析的输入日志文件 | 示例格式或 Linux `auth.log` syslog 格式 |
| `.txt` | 输出调查报告 | 格式化的纯文本报告 |
解析器会根据文件名自动选择:如果包含 `"Linux"`,则使用 `RealLinuxLogParser`;否则使用 `SampleLogParser`。
## 构建
该项目是一个单一的 `.cpp` 翻译单元,除了 C++ 标准库之外没有其他外部依赖。
```
g++ -std=c++17 -o forensics_analyzer main.cpp
./forensics_analyzer
```
(在 Windows 系统上使用 MSVC 时,只需将 `.cpp` 文件作为控制台应用程序构建即可 —— `_CRT_SECURE_NO_WARNINGS` 已在文件顶部定义。)
## 运行
1. 首次启动时,选择 **1. Login** 或 **2. Register**。
2. 系统默认存在硬编码的管理员账号(参见源码中的 `ADMIN_NAMES` / `ADMIN_PLAIN_PASSWORDS`)——这些仅供演示/评分使用。
3. 以管理员身份登录后,创建一个新案件,然后使用 **Generate Sample Log** 生成演示日志文件,或加载真实的 `auth.log` 风格的文件。
4. 对活动案件运行分析,以触发警报并计算结论。
5. 将报告打印到屏幕上或保存到 `.txt` 文件中。
## 示例报告输出
```
=======================================================================
DIGITAL FORENSICS CASE REPORT
=======================================================================
Case ID : 2
Title : Sample Linux Log File
Source : 192.111.222.333
Investigator : abdullah (Badge #1234)
-----------------------------------------------------------------------
Events Parsed : 20
Alerts Raised : 16
-----------------------------------------------------------------------
[1] BRUTE_FORCE [CRITICAL]
Threshold breached: Total 3 auth failures detected for user: root
Time: May 31 17:36:55
...
-----------------------------------------------------------------------
VERDICT : HIGH RISK
=======================================================================
```
## 设计决策
- 使用具有倍增容量策略的动态数组代替 `std::vector`,以满足 OOP 课程对手动内存管理的要求。
- `EventSource` 被实现为一个 `union`(与一个 `bool sourceIsIP` 标志配对),在语言层面为“IP 或主机名”进行建模,即使两个成员的大小相同。
- `LogParser` 层级使用了纯虚函数 `parseAndLoad()`,强制每个派生解析器实现该接口 —— 添加新的日志格式只需要一个新的派生类,而无需更改客户端代码。
- `ForensicCase::caseCounter` 是一个静态类成员,无需外部簿记即可保证案件 ID 的唯一顺序。
- 核心管理员凭据在编译时硬编码,因此即使 `users.txt` 丢失或损坏,系统也始终至少拥有一个有效的管理员账号。
## 已知限制
- **密码以纯文本形式存储和比较。** `hashPassword()` 目前只是一个直接透传;生产构建版本应使用加密哈希(例如 SHA-256 或 bcrypt)。
- 最大案件容量被硬编码为 10;这可以设为动态调整。
- `RealLinuxLogParser` 仅处理 `auth.log` 模式的一个子集 —— 完整的 syslog 覆盖需要更全面的解析器。
- `users.txt` 以未加密形式存储,并且可以作为纯文本读取。
- 暴力破解规则会全局统计失败次数,而不是在特定时间窗口内统计,这在长时间运行的日志中可能会产生误报。
## 可能的扩展
- 通过网络 socket 进行实时日志摄取
- 加密密码哈希
- 用于持久化案件存储的数据库后端
- 图形用户界面
标签:AMSI绕过, C++, OOP, 威胁检测, 数字取证, 数据擦除, 自动化脚本, 速率限制