riccithesecond/fried-plantains
GitHub: riccithesecond/fried-plantains
一款基于 DuckDB 和 Parquet 构建的轻量级自托管 SIEM 平台,专为家庭实验室设计,支持 KQL/SPL/SQL 查询及无缝迁移至企业级 Microsoft Sentinel 的检测规则。
Stars: 1 | Forks: 0
# fried-plantains
一个基于 DuckDB 和 Apache Parquet 构建的自托管 SIEM 与威胁狩猎平台。旨在模拟 Microsoft Sentinel / Defender for Endpoint (KQL)、Splunk Enterprise Security (SPL) 以及直接 SQL 分析——可在 Intel NUC 的家庭实验室规模下运行。
此处编写的针对 MDE 原生表的检测规则,无需修改即可直接移植到真实的 MDE 和 Microsoft Sentinel 环境中。
## 功能特性
- 接收并标准化来自 Windows Event logs、AWS CloudTrail、Cloudflare、Zscaler、Proofpoint TAP、Abnormal Security、syslog 以及 MDE 原始导出的安全日志
- 将数据存储为 Hive 分区的 Parquet 文件,支持使用 KQL、SPL 或 SQL 进行查询
- 按计划运行检测规则,并生成带有严重级别和 MITRE ATT&CK 标签的告警
- 提供用于查询、告警分诊、检测规则管理和日志接收的浏览器 UI
## 技术栈
| 层级 | 技术 |
|---|---|
| Backend | FastAPI (Python) |
| 查询引擎 | DuckDB |
| 存储 | Apache Parquet (Hive 风格分区) |
| 检测规则 | YAML |
| 认证 | JWT (短期过期 + refresh tokens) |
| Frontend | React 18 + Vite + TypeScript |
| UI 组件 | shadcn/ui + Tailwind CSS |
| 查询编辑器 | Monaco Editor |
| 数据表格 | AG Grid Community |
| 图表 | Recharts |
| 测试 | pytest (backend), Vitest (frontend) |
## 入门指南
**Backend**
```
pip install -r backend/requirements.txt
cp .env.example .env # fill in secrets
uvicorn backend.main:app --reload
```
**Frontend**
```
cd frontend
npm install
npm run dev
```
默认情况下,API 运行在 `http://localhost:8000`,UI 运行在 `http://localhost:5173`。
## 仓库结构
```
fried-plantains/
├── backend/
│ ├── api/ # FastAPI route handlers (auth, ingest, query, detections, alerts)
│ ├── engine/ # KQL → SQL, SPL → SQL transpilers, query router, detection runner
│ ├── ingest/ # Validator, normalizer, atomic Parquet writer
│ ├── parsers/ # Per-source normalization (Windows Events, CloudTrail, Cloudflare,
│ │ # Zscaler, Proofpoint, Abnormal, syslog, MDE)
│ ├── models/ # Pydantic models
│ ├── schema/ # Canonical MDE table definitions (source of truth)
│ └── tests/
├── detections/
│ └── rules/ # YAML detection rules (FP-XXXX series)
├── frontend/
│ └── src/
│ ├── views/ # Dashboard, Workbench, Detections, Alerts, Ingest, Settings
│ └── components/ # QueryEditor (Monaco), LogTable (AG Grid), AlertBadge, SeverityPill
├── scripts/
│ └── generate_logs.py # Synthetic log generator with embedded malicious scenarios
└── storage/ # Parquet files (gitignored) — partitioned by table/year/month/day
```
## 表支持
已实现 19 个表,包含精确的列名、类型和 ActionType 枚举。
### MDE 原生表
针对这些表的查询无需修改即可移植到真实的 Microsoft Sentinel 和 MDE Advanced Hunting 环境 (`mde_portable: true`)。
| 表 | 来源 |
|---|---|
| `DeviceProcessEvents` | 进程创建与注入 |
| `DeviceNetworkEvents` | 网络连接 |
| `DeviceFileEvents` | 文件创建、修改、删除、重命名 |
| `DeviceRegistryEvents` | 注册表键值更改 |
| `DeviceLogonEvents` | 交互式、网络和远程登录 |
| `DeviceEvents` | 防病毒、PowerShell、浏览器遥测 |
| `DeviceAlertEvents` | MDE 生成的告警事件 |
| `IdentityLogonEvents` | Azure AD / 本地 AD 身份验证 |
| `CloudAppEvents` | Microsoft 365 及云应用活动 |
### 云和代理表
不可移植 (`mde_portable: false`) — 模式反映了供应商的原生数据模型。
| 表 | 来源 |
|---|---|
| `AWSCloudTrailEvents` | AWS CloudTrail API 调用事件 |
| `CloudflareHttpEvents` | Cloudflare 边缘 HTTP/S 请求 |
| `CloudflareFirewallEvents` | Cloudflare 防火墙规则匹配 |
| `CloudflareDnsEvents` | Cloudflare Gateway DNS 查询 |
| `ZscalerWebEvents` | Zscaler Internet Access 代理事务 |
| `ZscalerDnsEvents` | Zscaler DNS Security 查询事件 |
### 电子邮件安全表
不可移植 (`mde_portable: false`)。`NetworkMessageId` 是所有电子邮件表的关联键——在接收时会去除尖括号,以符合 MDO 的约定。
| 表 | 来源 |
|---|---|
| `ProofpointMessageEvents` | Proofpoint TAP SIEM API — 邮件过滤判定、评分、认证结果 |
| `ProofpointClickEvents` | Proofpoint TAP URL Defense — 每次点击的阻止/允许事件 |
| `AbnormalThreatEvents` | Abnormal Security — AI 检测到的 BEC、钓鱼、冒充威胁 |
| `AbnormalCaseEvents` | Abnormal Security — 案例生命周期事件(打开、更新、关闭) |
## 检测规则
规则以带有自增 ID (`FP-XXXX`) 的 YAML 文件形式存放在 `detections/rules/` 中。每条规则指定了查询语言、严重级别、MITRE ATT&CK 技术标签和误报说明。规则在执行前会经过 schema 验证——绝不使用 eval。
### 当前规则
| ID | 名称 | 严重性 | 表 | MITRE |
|---|---|---|---|---|
| FP-0001 | 可疑的 PowerShell 编码命令 | high | DeviceProcessEvents | T1059.001 |
| FP-0002 | LSASS 内存访问(凭据转储) | critical | DeviceProcessEvents | T1003.001 |
| FP-0003 | 通过注册表运行键实现持久化 | high | DeviceRegistryEvents | T1547.001 |
| FP-0004 | 暴力破解 → 凭据验证成功 | high | DeviceLogonEvents | T1110, T1078 |
| FP-0005 | LOLBin 执行 | medium | DeviceProcessEvents | T1218 |
| FP-0006 | 通过 PsExec 进行横向移动 | high | DeviceNetworkEvents, DeviceLogonEvents | T1021, T1570 |
| FP-0007 | 非工作时间的大量文件访问(内部威胁) | high | DeviceFileEvents, DeviceLogonEvents | T1078, T1048 |
| FP-0008 | AWS root 账户 API 调用 | critical | AWSCloudTrailEvents | T1078.004 |
| FP-0009 | AWS IAM 权限提升 | high | AWSCloudTrailEvents | T1078.004, T1548 |
| FP-0010 | CloudTrail 日志被禁用 | critical | AWSCloudTrailEvents | T1562.008 |
| FP-0011 | Cloudflare WAF 阻断激增 | high | CloudflareFirewallEvents | T1190 |
| FP-0012 | Cloudflare 机器人评分异常 | medium | CloudflareHttpEvents | T1595 |
| FP-0013 | Zscaler 恶意软件下载被阻止 | high | ZscalerWebEvents | T1105 |
| FP-0014 | Zscaler DLP 违规 — 潜在数据泄露 | high | ZscalerWebEvents | T1048 |
| FP-0015 | Zscaler DNS sinkhole — 活跃 C2 尝试 | critical | ZscalerDnsEvents | T1071.004 |
| FP-0016 | Proofpoint 钓鱼邮件被阻止,VeryMalicious 发件人 | high | ProofpointMessageEvents | T1566.001 |
| FP-0017 | Proofpoint 冒充邮件已送达(BEC 先兆) | high | ProofpointMessageEvents | T1566.001, T1534 |
| FP-0018 | Proofpoint 恶意附件被沙箱阻止 | critical | ProofpointMessageEvents | T1566.001, T1059 |
| FP-0019 | Proofpoint 用户点击了恶意 URL | critical | ProofpointClickEvents | T1566.002, T1204.001 |
| FP-0020 | Abnormal BEC / 冒充威胁被检测到 | high | AbnormalThreatEvents | T1566.001, T1534 |
| FP-0021 | 跨层:Proofpoint + Abnormal 标记同一封邮件 | critical | ProofpointMessageEvents, AbnormalThreatEvents | T1566.001, T1566.002 |
| FP-0022 | Abnormal 高严重性案例被打开 | high | AbnormalCaseEvents | T1566, T1078 |
FP-0021 是基于 `NetworkMessageId` 的 `let` + `join kind=inner` 操作——两个独立的 AI 引擎分别标记了同一封邮件。
示例规则结构:
```
id: FP-0016
name: Proofpoint — high-confidence phishing blocked, VeryMalicious sender
severity: high
language: kql
mde_portable: false
query: |
ProofpointMessageEvents
| where Timestamp > ago(1h)
| where ActionType in ("PhishFiltered", "Quarantined")
| where SenderReputation == "VeryMalicious"
| project Timestamp, SenderFromAddress, SenderFromDomain, SenderIP,
SenderReputation, RecipientEmailAddress, Subject,
PhishScore, ImpostorScore, DispositionAction, NetworkMessageId
| order by PhishScore desc
tags:
- T1566.001
- phishing
mde_portable: false
```
## 存储布局
```
storage/
└── DeviceProcessEvents/
└── 2025/
└── 01/
└── 15/
└── data.parquet
```
每个 MDE 表名都是一个独立的分区树。DuckDB 视图在启动时注册,因此 KQL 表引用会直接映射到磁盘上的 Parquet 文件。这些文件同样可以在 ClickHouse、Snowflake 或 Databricks 中查询,而无需更改检测逻辑。
## 支持的日志源
| 解析器 | 接收格式 | `source=` 值 |
|---|---|---|
| Windows Event Log | JSON (Security, System, Application) | `windows_event` |
| AWS CloudTrail | JSON Records wrapper, 单个事件, JSON lines | `cloudtrail` |
| Cloudflare | JSON lines (HTTP, Firewall, DNS Logpush datasets) | `cloudflare` |
| Zscaler | NSS key=value, JSON | `zscaler_web`, `zscaler_dns` |
| Proofpoint TAP | TAP SIEM API JSON, syslog/CEF | `proofpoint_tap`, `proofpoint_syslog` |
| Abnormal Security | `/threats` API, `/cases` API, webhook | `abnormal_threats`, `abnormal_cases` |
| Syslog | RFC 5424 | `syslog` |
| MDE export | MDE raw JSON export format | `defender` |
标签:AV绕过, AWS CloudTrail, Cloudflare, DuckDB, EDR, FastAPI, Hive分区, Homelab, JWT认证, KQL, MDE, Microsoft Sentinel, MITRE ATT&CK, Monaco Editor, Parquet, Proofpoint, Python, React, shadcn/ui, SPL, SQL, Syscalls, Tailwind CSS, TypeScript, Vite, Windows事件日志, YAML规则, Zscaler, 全栈项目, 列式存储, 后端开发, 告警分诊, 安全合规, 安全插件, 安全运营, 微软Defender, 扫描框架, 数据查询引擎, 无后门, 日志规范化, 日志采集, 检测规则, 系统审计, 网络代理, 网络安全, 网络日志, 网络资产发现, 脆弱性评估, 自托管, 逆向工具, 隐私保护, 黑客技术