轻量级 IOC 管理方案:Streamlit 驱动的恶意IP情报平台

轻量级 IOC 管理方案:Streamlit 驱动的恶意IP情报平台

一个基于 Streamlit + SQLite 的轻量级 IOC 管理工具,支持多格式情报导入、自动风险评分、可视化分析与去重管理。


一、背景:为什么需要自建 IOC 管理工具

在日常渗透测试和安全运维中,威胁情报的积累速度往往超出预期。一个中等规模的红蓝对抗项目,几周内就能沉淀出数百条恶意IP、域名和病毒家族信息。如果这些数据散落在 TXT 文件、Excel 表格和聊天记录里,真正需要查询时会陷入困境。

市面上的威胁情报平台(TIP)功能完善,但对个人或小团队而言,部署门槛高、成本不菲。更关键的是,安全人员经常需要对情报做二次标注------补充归属地、对照病毒家族、记录自己遇到该 IOC 的攻击场景------这些个性化需求在通用平台上很难满足。

因此,我动手构建了一个轻量级的恶意IP信息管理系统:全离线运行、SQLite 存储、支持多格式导入与自动解析、内置风险评分引擎。这篇文章从技术选型、架构设计、核心算法到实战用法,完整复盘整个项目的设计思路。


二、技术选型与架构概览

2.1 技术栈

组件 技术选型 理由
前端框架 Streamlit 纯 Python 即可构建交互式 Web UI,适合数据应用
数据库 SQLite 零配置、单文件部署、适合本地工具
可视化 Plotly 交互式图表,与 Streamlit 深度集成
数据处理 Pandas DataFrame 统一处理查询结果和导入数据
去重签名 SHA256 基于多字段拼接生成唯一签名

2.2 整体架构

#mermaid-svg-ZKksIlbTaY40og9n{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-ZKksIlbTaY40og9n .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-ZKksIlbTaY40og9n .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-ZKksIlbTaY40og9n .error-icon{fill:#552222;}#mermaid-svg-ZKksIlbTaY40og9n .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ZKksIlbTaY40og9n .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-ZKksIlbTaY40og9n .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ZKksIlbTaY40og9n .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ZKksIlbTaY40og9n .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-ZKksIlbTaY40og9n .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ZKksIlbTaY40og9n .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ZKksIlbTaY40og9n .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ZKksIlbTaY40og9n .marker.cross{stroke:#333333;}#mermaid-svg-ZKksIlbTaY40og9n svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ZKksIlbTaY40og9n p{margin:0;}#mermaid-svg-ZKksIlbTaY40og9n .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-ZKksIlbTaY40og9n .cluster-label text{fill:#333;}#mermaid-svg-ZKksIlbTaY40og9n .cluster-label span{color:#333;}#mermaid-svg-ZKksIlbTaY40og9n .cluster-label span p{background-color:transparent;}#mermaid-svg-ZKksIlbTaY40og9n .label text,#mermaid-svg-ZKksIlbTaY40og9n span{fill:#333;color:#333;}#mermaid-svg-ZKksIlbTaY40og9n .node rect,#mermaid-svg-ZKksIlbTaY40og9n .node circle,#mermaid-svg-ZKksIlbTaY40og9n .node ellipse,#mermaid-svg-ZKksIlbTaY40og9n .node polygon,#mermaid-svg-ZKksIlbTaY40og9n .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-ZKksIlbTaY40og9n .rough-node .label text,#mermaid-svg-ZKksIlbTaY40og9n .node .label text,#mermaid-svg-ZKksIlbTaY40og9n .image-shape .label,#mermaid-svg-ZKksIlbTaY40og9n .icon-shape .label{text-anchor:middle;}#mermaid-svg-ZKksIlbTaY40og9n .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-ZKksIlbTaY40og9n .rough-node .label,#mermaid-svg-ZKksIlbTaY40og9n .node .label,#mermaid-svg-ZKksIlbTaY40og9n .image-shape .label,#mermaid-svg-ZKksIlbTaY40og9n .icon-shape .label{text-align:center;}#mermaid-svg-ZKksIlbTaY40og9n .node.clickable{cursor:pointer;}#mermaid-svg-ZKksIlbTaY40og9n .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-ZKksIlbTaY40og9n .arrowheadPath{fill:#333333;}#mermaid-svg-ZKksIlbTaY40og9n .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-ZKksIlbTaY40og9n .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-ZKksIlbTaY40og9n .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ZKksIlbTaY40og9n .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-ZKksIlbTaY40og9n .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ZKksIlbTaY40og9n .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-ZKksIlbTaY40og9n .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-ZKksIlbTaY40og9n .cluster text{fill:#333;}#mermaid-svg-ZKksIlbTaY40og9n .cluster span{color:#333;}#mermaid-svg-ZKksIlbTaY40og9n div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-ZKksIlbTaY40og9n .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-ZKksIlbTaY40og9n rect.text{fill:none;stroke-width:0;}#mermaid-svg-ZKksIlbTaY40og9n .icon-shape,#mermaid-svg-ZKksIlbTaY40og9n .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ZKksIlbTaY40og9n .icon-shape p,#mermaid-svg-ZKksIlbTaY40og9n .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-ZKksIlbTaY40og9n .icon-shape .label rect,#mermaid-svg-ZKksIlbTaY40og9n .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ZKksIlbTaY40og9n .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-ZKksIlbTaY40og9n .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-ZKksIlbTaY40og9n :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 引擎层
Streamlit Web UI
仪表盘
情报列表
导入数据
手工录入/编辑
解析引擎

txt_parser · dataframe_parser
评分引擎

compute_risk_score · risk_level
标签引擎

infer_tags
数据访问层

insert_or_update · query_records · delete
SQLite

threat_ioc.db

系统采用单文件部署 模式:app.py + threat_ioc.db 两个文件即可运行,不需要数据库安装、不需要 Web 服务器配置。


三、数据模型设计

3.1 核心表结构

sql 复制代码
CREATE TABLE ioc_records (
    id          INTEGER PRIMARY KEY AUTOINCREMENT,
    ip          TEXT    NOT NULL,
    domain      TEXT    DEFAULT '',
    location    TEXT    DEFAULT '',
    threat_type TEXT    DEFAULT '',
    family      TEXT    DEFAULT '',
    description TEXT    DEFAULT '',
    risk_score  INTEGER DEFAULT 0,
    risk_level  TEXT    DEFAULT '低危',
    tags        TEXT    DEFAULT '',
    status      TEXT    DEFAULT 'active',
    source_file TEXT    DEFAULT '',
    source_line INTEGER DEFAULT 0,
    first_seen  TEXT    DEFAULT '',
    last_seen   TEXT    DEFAULT '',
    created_at  TEXT    DEFAULT '',
    updated_at  TEXT    DEFAULT '',
    signature   TEXT    UNIQUE
);

3.2 关键设计决策

(1)signature 唯一约束的权衡

每条记录以 SHA256 对 {IP, 域名, 归属地, 威胁类型, 病毒家族, 攻击描述} 六字段拼接产生的签名作为唯一键。这避免了导入重复数据时的手动去重,但也意味着:如果同一个 IP 出现了新的攻击行为,更新描述后签名会变化,从而被识别为新记录而不是更新旧记录。

这实际上是一个有意的取舍------同一 IP 的不同攻击行为(如从僵尸网络转为后门)本质上就是两条不同的威胁情报,应当区分对待。

(2)标签字段的冗余存储

tags 以逗号分隔字符串存储,违反数据库范式。但在这个场景下,标签主要用于筛选和展示,不参与复杂的关联查询。反范式化后,前端直接以字符串形式读取和过滤,避免了额外的关联表开销。这对单用户工具而言是合理的工程权衡。

(3)来源追溯

source_filesource_line 两个字段记录了每条 IOC 的原始来源,当需要回溯某条情报的上下文时,可以直接定位到原始文件的对应位置。这在批量导入数百条数据后尤为有用。


四、核心引擎实现

4.1 多格式解析引擎

系统需要同时支持三种输入格式:结构化文本(TXT)、CSV、Excel(XLSX)

TXT 格式解析采用正则 + 状态机模式:

复制代码
IP地址: 192.168.1.100
关联域名: malicious.example.com
归属地: 中国/广东/深圳
威胁类型: 后门
病毒家族: AsyncRAT
攻击描述: 该样本通过钓鱼邮件传播,安装后建立与C2的加密通道,
执行键盘记录和屏幕监控。

解析器逐个匹配 字段名: 值 模式,遇到新的 IP地址: 即视为新记录的开始;非字段行的文本自动追加到当前字段的值中,实现多行攻击描述的自动合并。状态机维护当前的"活跃字段",解决了攻击描述跨行续写的实际问题。

CSV/XLSX 格式 采用更灵活的列名匹配:通过 find_col() 函数按候选词列表(如 ["IP地址", "ip", "IP"])模糊匹配列名,对列顺序不敏感。这意味着不同来源的情报文件即使列名略有差异,也能正确导入。

4.2 风险评估算法

风险评估是系统的核心差异化功能:不依赖外部API,完全基于本地规则

算法从四个维度加权评分:

维度 评分逻辑 最高分值
威胁类型 僵尸网络 +30,窃密 +35,后门 +25,挖矿 +20 35
病毒家族 命中已知高危家族列表(Mirai、AsyncRAT、DCRat 等) +15
行为特征 DDoS、IoT漏洞利用、键盘记录、密码窃取等关键词匹配 +15
动态DNS 域名包含 duckdns/no-ip/ddns 等 +5

最终分数封顶 100。风险等级的映射:

  • 80~100:严重
  • 60~79:高危
  • 30~59:中危
  • 0~29:低危

这里值得注意的细节:风险评分在导入时计算并固化存储,不在查询时动态计算。这保证了对同一 IOC 在不同时间段的评估一致性。如果威胁情报环境变化导致评分规则调整,可以通过手工编辑页面逐一更新评分。

4.3 智能标签推断

标签系统同时处理三类来源:

  1. 用户显式指定的标签 :从 CSV 的 tags 列直接读取
  2. 威胁类型与家族:自动转为标签(如"后门"→标签"后门")
  3. 描述文本推理:关键字匹配自动打标

第三类的推理规则覆盖六种常见威胁场景:

python 复制代码
# DDoS / 僵尸网络
if any(x in desc for x in ["ddos", "分布式拒绝服务", "僵尸网络", "botnet"]):
    tags.add("DDoS")

# IoT 设备
if any(x in desc for x in ["telnet", "ssh", "iot", "路由器", "摄像头"]):
    tags.add("IoT")

# 远程访问木马
if any(x in desc for x in ["键盘记录", "屏幕监控", "远程控制", "shell"]):
    tags.add("RAT")

# 窃密木马
if any(x in desc for x in ["窃密", "密码窃取", "cookie", "凭证"]):
    tags.add("Stealer")

# 加载器
if any(x in desc for x in ["加载器", "loader", "下载并执行"]):
    tags.add("Loader")

# 挖矿
if any(x in desc for x in ["挖矿", "xmr", "xmrig", "monero"]):
    tags.add("Miner")

# 动态DNS
if any(x in domain for x in ["duckdns", "no-ip", "ddns"]):
    tags.add("DynamicDNS")

标签自动补齐大幅减少了手工标注的工作量,且同类 IOC 的标签风格统一,后续筛选时不会遗漏。


五、功能模块详解

5.1 仪表盘

打开系统后首先看到的是仪表盘:四个核心指标卡片(总记录数、高危/严重数量、后门类数量、僵尸网络类数量)加四张统计图表。

图表方面:

  • 威胁类型分布:柱状图展示各威胁类型的 IOC 数量,一眼看出哪类威胁最活跃
  • Top 病毒家族:饼图展示排名前 10 的活跃家族
  • 风险等级分布:按严重/高危/中危/低危分色展示
  • 记录状态分布:active / blacklist / whitelist 等状态分布

所有图表均使用 Plotly 的 plotly_dark 模板,与深色主题 UI 风格统一。图表可交互------悬停显示数值、点击图例筛选、拖拽缩放,这些都是 Plotly 自带的能力,不需要额外代码。

5.2 情报列表

这是日常使用频率最高的页面。支持六维联合筛选:

  • 关键词搜索:同时命中 IP、域名、归属地、威胁类型、家族、描述、标签
  • 威胁类型筛选:下拉框自动从数据库去重取值
  • 病毒家族筛选:同上
  • 状态筛选:active / blacklist / whitelist / review / inactive
  • 风险等级筛选:低危 / 中危 / 高危 / 严重
  • 归属地关键词:按国家/地区模糊筛选

查询结果以 DataFrame 表格展示,支持导出当前结果为 CSV。点击某条记录可展开详情面板:左侧显示基础信息(IP、域名、归属地等),右侧显示来源追溯和时间戳。最底部有完整的 JSON 视图,方便复制到其他工具。

批量删除功能通过多选框勾选记录 ID 完成,比逐条删除的效率高得多。

5.3 数据导入

提供两种导入路径:

粘贴文本导入:直接将 TXT 内容粘贴到大文本框,点击"解析并导入"。适合从聊天记录、报告截取的少量 IOC。

文件上传导入 :支持 txt / csv / xlsx / xls 四种格式。上传后先预览解析结果,确认无误再写入数据库。导入采用 INSERT OR UPDATE 逻辑------新签名直接插入,已存在的签名更新 last_seen 时间戳。系统会明确告知"新增 X 条,更新 Y 条",避免静默覆盖。

5.4 手工录入与编辑

除了批量导入,系统也支持逐条手工录入。编辑页面同时承载"新增"和"修改"两个功能。修改模式下,所有字段预填当前值,保存时重新计算签名并检查冲突。删除操作支持单条删除(从编辑页面)和批量删除(从列表页面)。


六、生产环境使用建议

6.1 部署

bash 复制代码
pip install streamlit pandas plotly openpyxl
streamlit run app.py

启动后浏览器访问 http://localhost:8501。如需远程访问,加 --server.address 0.0.0.0 参数,但务必配合防火墙或 VPN 使用------这个系统没有内置的认证机制。

6.2 数据备份

threat_ioc.db 是一个独立的 SQLite 文件,直接复制该文件即可完成备份。建议配合 cron 做定期备份:

bash 复制代码
# 每天凌晨备份
0 2 * * * cp /path/to/threat_ioc.db /backup/threat_ioc_$(date +\%Y\%m\%d).db

6.3 情报流转工作流建议

  1. 采集阶段:从蜜罐日志、外部威胁情报源、同行分享获取原始 IOC 数据
  2. 导入阶段:通过本系统的导入模块批量入库,自动完成解析、评分、去重
  3. 标注阶段:对自动评分较高或缺失关键字段的记录,通过手工编辑补充
  4. 分析阶段:利用仪表盘和筛选功能分析威胁趋势、识别高频家族
  5. 输出阶段:导出 CSV 后投入防火墙规则、IDS 签名、SIEM 告警等下游系统

七、扩展方向

当前版本是一个"能用的基础版",以下是我认为值得扩展的方向:

  1. API 接口:用 FastAPI 封装查询和导入端点,方便与 SOAR 平台对接
  2. 外部情报源集成:对接 AbuseIPDB、VirusTotal 等 API,自动补全归属地和风险评分
  3. PDF 报告生成:按周/月导出威胁态势报告,适合向上汇报
  4. 黑白名单自动同步:通过 SSH/API 将黑名单 IP 批量写入防火墙规则
  5. 告警推送:当出现严重级别的新 IOC 时,通过企业微信/钉钉推送通知
  6. 多用户权限:为团队场景增加登录认证和操作审计

这些功能的核心逻辑都已经预留了扩展接口:状态字段区分了黑白名单、标签字段支持任意维度的分类、source_file 字段可追溯数据来源。在现有架构上叠加这些能力不会涉及大的重构。


八、总结

这个恶意IP管理系统本质上解决的是一个很朴素的问题:让安全人员能高效地管理自己积累的威胁情报。1078 行 Python 代码,基于 Streamlit 和 SQLite 两个成熟组件,实现了从数据导入、智能解析、风险评估到可视化分析、检索导出的完整闭环。

它不替代企业级 TIP 平台,而是填补了 TIP 所不覆盖的场景------个人渗透测试中的情报积累、小团队的红蓝对抗资产管理、以及安全研究人员对自有情报库的精细化管理。

完整的源代码和部署文档详见项目仓库。如果在使用过程中遇到问题或有改进建议,欢迎交流。


本文所有技术细节基于 恶意IP管理系统 v1.0 版本,最后更新于 2026 年 8 月。

相关推荐
数字新视界1 小时前
用电安全管理系统解决方案
物联网·安全·电力监控系统·用电安全·大榕树
2601_965798472 小时前
Is Hygia Good for Maid & Janitorial Sites? Technical Audit
服务器·网络·数据库
蚰蜒螟2 小时前
从内核源码看Linux启动:chroot、execve与MS_MOVE的协奏曲
linux·服务器·网络
数据知道4 小时前
容器安全入门:Docker 逃逸原理与 5 个经典 CVE
安全·网络安全·docker·容器
Dawn-bit5 小时前
Linux磁盘分区与Swap和磁盘故障查询
linux·运维·服务器·网络·云计算
JonLee20205 小时前
适配 Yii 3.0,php-casbin/yii-permission 3.0 正式发布
安全·php·rbac·yii·权限·casbin
llilian_166 小时前
便携式相位测量模块应用方案的核心优势
网络·功能测试·单片机
MartinYeung57 小时前
[论文学习]PACT:溯源感知能力合约——面向智能体安全的参数级溯源
人工智能·学习·安全
QH139292318807 小时前
# R&S ZNB43 ZNA43 ZNA67矢量网络分析仪
开发语言·网络·php