收集 MISP IOC 日志
支持的语言:
Google SecOps
SIEM
本文档介绍了如何使用 Bindplane 将 MISP(恶意软件信息共享平台)IOC 日志注入到 Google Security Operations。解析器会处理 CSV 和 JSON 格式的数据。它会提取 IP 地址、网域、哈希和网址等 IOC 属性,并将这些属性与严重程度、可信度和说明等威胁详细信息一起映射到统一数据模型 (UDM)。解析器可处理输入数据中的单个和多个 IOC 条目,并将其标准化为一致的 UDM 输出。
准备工作
请确保满足以下前提条件:
- Google SecOps 实例。
- 具有
systemd
的 Linux 主机。 - 如果通过代理运行,请确保防火墙端口已根据 Bindplane 代理要求打开。
- 对 MISP 服务器的特权访问权限。
获取 Google SecOps 注入身份验证文件
- 登录 Google SecOps 控制台。
- 依次前往 SIEM 设置 > 收集代理。
- 下载注入身份验证文件。
- 将文件安全地保存在将要安装 Bindplane 的系统上。
获取 Google SecOps 客户 ID
- 登录 Google SecOps 控制台。
- 依次前往 SIEM 设置*> 配置文件。
- 复制并保存组织详细信息部分中的客户 ID。
获取 MISP API 凭据
- 以管理员身份登录 MISP 网页界面。
- 依次前往管理 > 列出授权密钥。
- 点击添加身份验证密钥。
- 提供以下配置详细信息:
- 用户:选择与密钥关联的用户账号。
- 可选:允许使用的 IP 地址:为密钥指定允许使用的 IP 地址。
- 到期时间:留空表示永不过期,也可以根据需要进行设置。
- 点击提交。
- 复制 API 密钥并将其保存在安全的位置。
- 点击我已记下密钥。
配置 MISP 数据导出
在 MISP 服务器上安装 PyMISP:
pip3 install pymisp
创建导出目录:
sudo mkdir -p /opt/misp/scripts sudo mkdir -p /opt/misp/ioc_export
创建凭据文件
/opt/misp/scripts/keys.py
:misp_url = 'https://<MISP_SERVER_URL>' misp_key = '<MISP_API_KEY>' misp_verifycert = True misp_client_cert = ''
- 将
<MISP_SERVER_URL>
替换为您的 MISP 服务器网址。 - 将
<MISP_API_KEY>
替换为前提条件中的 API 密钥。
- 将
创建导出脚本
/opt/misp/scripts/misp_export.py
:#!/usr/bin/env python3 # -*- coding: utf-8 -*- import argparse from pymisp import ExpandedPyMISP from keys import misp_url, misp_key, misp_verifycert if __name__ == '__main__': parser = argparse.ArgumentParser(description='Export MISP IOCs to CSV format.') parser.add_argument("--controller", default='attributes', help="Controller to use for search (events, objects, attributes)") parser.add_argument("--event_id", help="Event ID to fetch. Without it, fetches recent data.") parser.add_argument("--attributes", nargs='*', help="Requested attributes for CSV export") parser.add_argument("--misp_types", nargs='+', help="MISP types to fetch (ip-src, hostname, domain, etc.)") parser.add_argument("--context", action='store_true', help="Add event level context (tags, metadata)") parser.add_argument("--outfile", required=True, help="Output file to write the CSV data") parser.add_argument("--last", required=True, help="Time period: days (d), hours (h), minutes (m) - e.g., 1d, 12h, 30m") args = parser.parse_args() api = ExpandedPyMISP(misp_url, misp_key, misp_verifycert, debug=False) response = api.search( controller=args.controller, return_format='csv', type_attribute=args.misp_types, publish_timestamp=args.last, include_context=args.context, requested_attributes=args.attributes or None ) with open(args.outfile, 'w') as response_file: response_file.write(response)
- 让该脚本可执行:
sudo chmod +x /opt/misp/scripts/misp_export.py
安排 MISP 数据导出
- 使用 crontab 创建定期导出:
sudo crontab -e
添加以下 cron 条目:
# Export different IOC types daily with context 0 0 * * * python3 /opt/misp/scripts/misp_export.py --outfile /opt/misp/ioc_export/domains.csv --misp_types domain --last 1d --context --attributes uuid event_id category type value comment to_ids date attribute_tag event_info 0 1 * * * python3 /opt/misp/scripts/misp_export.py --outfile /opt/misp/ioc_export/ip-src.csv --misp_types ip-src --last 1d --context --attributes uuid event_id category type value comment to_ids date attribute_tag event_info 0 2 * * * python3 /opt/misp/scripts/misp_export.py --outfile /opt/misp/ioc_export/ip-dst.csv --misp_types ip-dst --last 1d --context --attributes uuid event_id category type value comment to_ids date attribute_tag event_info 0 3 * * * python3 /opt/misp/scripts/misp_export.py --outfile /opt/misp/ioc_export/urls.csv --misp_types url --last 1d --context --attributes uuid event_id category type value comment to_ids date attribute_tag event_info 0 4 * * * python3 /opt/misp/scripts/misp_export.py --outfile /opt/misp/ioc_export/sha256.csv --misp_types sha256 --last 1d --context --attributes uuid event_id category type value comment to_ids date attribute_tag event_info 0 5 * * * python3 /opt/misp/scripts/misp_export.py --outfile /opt/misp/ioc_export/filenames.csv --misp_types filename --last 1d --context --attributes uuid event_id category type value comment to_ids date attribute_tag event_info 0 6 * * * python3 /opt/misp/scripts/misp_export.py --outfile /opt/misp/ioc_export/registries.csv --misp_types regkey --last 1d --context --attributes uuid event_id category type value comment to_ids date attribute_tag event_info 0 7 * * * python3 /opt/misp/scripts/misp_export.py --outfile /opt/misp/ioc_export/mutexes.csv --misp_types mutex --last 1d --context --attributes uuid event_id category type value comment to_ids date attribute_tag event_info
(可选)安排从 MISP 拉取 Feed 的时间:
23 0 * * * curl --insecure --header "Authorization: <MISP_API_KEY>" --header "Accept: application/json" --header "Content-Type: application/json" https://<MISP_SERVER_URL>/feeds/fetchFromAllFeeds
安装 Bindplane 代理
按照以下说明在 Linux 操作系统上安装 Bindplane 代理。
Linux 安装
- 打开具有 root 或 sudo 权限的终端。
运行以下命令:
sudo sh -c "$(curl -fsSlL https://github.com/observiq/bindplane-otel-collector/releases/latest/download/install_unix.sh)" install_unix.sh
其他安装资源
- 如需了解其他安装选项,请参阅安装指南。
配置 Bindplane 代理以注入 MISP 日志并将其发送到 Google SecOps
访问配置文件:
- 找到
config.yaml
文件。通常,它位于 Linux 上的/etc/bindplane-agent/
目录中。 - 使用文本编辑器(例如
nano
、vi
)打开该文件。
- 找到
按如下方式修改
config.yaml
文件:receivers: filelog: file_path: /opt/misp/ioc_export/*.log exporters: chronicle/chronicle_w_labels: compression: gzip # Adjust the path to the credentials file you downloaded in Step 1 creds_file_path: '/path/to/ingestion-authentication-file.json' # Replace with your actual customer ID from Step 2 customer_id: <customer_id> endpoint: malachiteingestion-pa.googleapis.com # Add optional ingestion labels for better organization ingestion_labels: log_type: 'MISP_IOC' raw_log_field: body service: pipelines: logs/source0__chronicle_w_labels-0: receivers: - filelog exporters: - chronicle/chronicle_w_labels
- 将
<CUSTOMER_ID>
替换为前提条件中的实际客户 ID。 - 将
/path/to/ingestion-authentication-file.json
更新为身份验证文件的保存路径。
- 将
重启 Bindplane 代理以应用更改
如需在 Linux 中重启 Bindplane 代理,请运行以下命令:
sudo systemctl restart observiq-otel-collector
UDM 映射表
日志字段 | UDM 映射 | 逻辑 |
---|---|---|
Attribute.category | entity.metadata.threat.category_details | 直接从 Attribute 对象中的 category 字段进行映射。 |
Attribute.comment | entity.metadata.threat.summary | 直接从 Attribute 对象中的 comment 字段进行映射。 |
Attribute.deleted | entity.metadata.threat.detection_fields.value | 直接从 Attribute 对象中的 deleted 字段进行映射。该键设置为 Attribute deleted 。 |
Attribute.event_id | entity.metadata.threat.detection_fields.value | 直接从 Attribute 对象中的 event_id 字段进行映射。该键设置为 Attribute event_id 。 |
Attribute.first_seen | entity.metadata.threat.detection_fields.value | 直接从 Attribute 对象中的 first_seen 字段进行映射。该键设置为 Attribute first_seen 。 |
Attribute.id | entity.metadata.threat.detection_fields.value | 直接从 Attribute 对象中的 id 字段进行映射。该键会设置为 Attribute id 或 Attribute id $$ ,具体取决于原始日志的格式。 |
Attribute.timestamp | entity.metadata.threat.detection_fields.value | 直接从 Attribute 对象中的 timestamp 字段进行映射。该键设置为 Attribute timestamp 。 |
Attribute.to_ids | entity.metadata.threat.detection_fields.value | 直接从 Attribute 对象中的 to_ids 字段进行映射。该键设置为 Attribute to_ids 。 |
Attribute.type | entity.metadata.threat.category_details | 直接从 Attribute 对象中的 type 字段进行映射。 |
Attribute.type | log_type | 用于确定 IOC 的类型并将其映射到相应的 UDM 字段。 |
Attribute.uuid | entity.metadata.product_entity_id | 直接从 Attribute 对象中的 uuid 字段进行映射。 |
Attribute.value | entity.entity.file.full_path | 如果 Attribute.type 为 filename ,则映射。 |
Attribute.value | entity.entity.file.md5 | 如果 Attribute.type 为 md5 ,则映射。 |
Attribute.value | entity.entity.file.sha1 | 如果 Attribute.type 为 sha1 ,则映射。 |
Attribute.value | entity.entity.file.sha256 | 如果 Attribute.type 为 sha256 ,则映射。 |
Attribute.value | entity.entity.hostname | 如果 Attribute.type 为 domain ,则映射。 |
Attribute.value | entity.entity.ip | 如果 Attribute.type 为 ip-dst 、ip-dst|port 或 ip-src ,则进行映射。该值是使用 Grok 模式提取的。 |
Attribute.value | entity.entity.resource.name | 如果 Attribute.type 为 mutex ,则映射。 |
Attribute.value | entity.entity.registry.registry_key | 如果 Attribute.type 为 regkey ,则映射。 |
Attribute.value | entity.entity.url | 如果 Attribute.type 为 uri 或 URL ,则进行映射。 |
第 1 列 | entity.metadata.product_entity_id | 直接从 CSV 数据的第一列进行映射。 |
column14 | event_info | 用于向 threat_sr.description 字段附加其他信息。 |
column16 | event_source_org | 直接映射自 CSV 数据中的第 16 列。 |
column18 | threat_level | 直接映射自 CSV 数据中的第 18 列。 |
column21 | 说明 | 直接映射自 CSV 数据中的第 21 列。 |
第 3 列 | misp_category | 直接映射自 CSV 数据中的第三列。 |
column4 | 类型 | 直接映射自 CSV 数据中的第四列。 |
column5 | 值 | 直接映射自 CSV 数据中的第五列。 |
column6 | 评论 | 直接映射自 CSV 数据中的第 6 列。 |
column8 | ts1 | 直接映射自 CSV 数据中的第 8 列。 |
说明 | ioc.description | 该值通过将 description 字段与 event_info 字段(以 - additional info: 分隔)组合生成。 |
说明 | entity.metadata.threat.description | 直接从 description 字段进行映射。 |
event_creator_email | entity.entity.labels.value | 直接从 event_creator_email 字段进行映射。该键设置为 event_creator_email 。 |
event_source_org | ioc.feed_name | 直接从 event_source_org 字段进行映射。 |
event_source_org | entity.metadata.threat.threat_feed_name | 直接从 event_source_org 字段进行映射。 |
Feed.publish | entity.metadata.threat.detection_fields.value | 直接从 Feed 对象中的 publish 字段进行映射。该键设置为 Feed publish 。 |
first_seen | ioc.active_timerange.start | 直接从 first_seen 字段进行映射。该值会被解析为日期。 |
first_seen | entity.metadata.interval.start_time | 直接从 first_seen 字段进行映射。该值会被解析为日期。 |
信息 | entity.metadata.description | 直接从 info 字段进行映射。 |
last_seen | ioc.active_timerange.end | 直接从 last_seen 字段进行映射。该值会被解析为日期。 |
log.category | ioc.categorization | 直接从 log 对象中的 category 字段进行映射。 |
log.category | entity.metadata.threat.category_details | 直接从 log 对象中的 category 字段进行映射。 |
log.comment | entity.entity.file.full_path | 如果 log.type 为 filename 且 comment 字段不为 Artifacts dropped ,则进行映射。 |
log.comment | entity.metadata.threat.detection_fields.value | 直接从 log 对象中的 comment 字段进行映射。该键设置为 Attribute comment 。 |
log.comment | entity.metadata.threat.summary | 直接从 log 对象中的 comment 字段进行映射。 |
log.deleted | entity.metadata.threat.detection_fields.value | 直接从 log 对象中的 deleted 字段进行映射。该键设置为 Attribute deleted 。 |
log.event_id | entity.metadata.threat.detection_fields.value | 直接从 log 对象中的 event_id 字段进行映射。该键设置为 Attribute event_id 。 |
log.first_seen | entity.metadata.threat.detection_fields.value | 直接从 log 对象中的 first_seen 字段进行映射。该键设置为 Attribute first_seen 。 |
log.id | entity.metadata.threat.detection_fields.value | 直接从 log 对象中的 id 字段进行映射。该键设置为 Attribute id 。 |
log.timestamp | entity.metadata.threat.detection_fields.value | 直接从 log 对象中的 timestamp 字段进行映射。该键设置为 Attribute timestamp 。 |
log.to_ids | entity.metadata.threat.detection_fields.value | 直接从 log 对象中的 to_ids 字段进行映射。该键设置为 Attribute to_ids 。 |
log.type | ioc.categorization | 直接从 log 对象中的 type 字段进行映射。 |
log.type | log_type | 用于确定 IOC 的类型并将其映射到相应的 UDM 字段。 |
log.uuid | entity.metadata.product_entity_id | 直接从 log 对象中的 uuid 字段进行映射。 |
log.value | entity.entity.file.full_path | 如果 log.type 为 filename ,则映射。 |
log.value | entity.entity.file.md5 | 如果 log.type 为 md5 ,则映射。 |
log.value | entity.entity.file.sha1 | 如果 log.type 为 sha1 ,则映射。 |
log.value | entity.entity.file.sha256 | 如果 log.type 为 sha256 ,则映射。 |
log.value | entity.entity.hostname | 如果 log.type 为 domain ,则映射。 |
log.value | entity.entity.ip | 如果 log.type 为 ip-dst 、ip-dst|port 或 ip-src ,则进行映射。该值是使用 Grok 模式提取的。 |
log.value | entity.entity.resource.name | 如果 log.type 为 mutex ,则映射。 |
log.value | entity.entity.registry.registry_key | 如果 log.type 为 regkey ,则映射。 |
log.value | entity.entity.url | 如果 log.type 为 uri 或 url ,则进行映射。 |
log.value | ioc.domain_and_ports.domain | 如果 log.type 为 domain ,则映射。 |
log.value | entity.entity.user.email_addresses | 如果 log.type 为 threat-actor ,则映射。 |
misp_category | entity.metadata.threat.category_details | 直接从 misp_category 字段进行映射。 |
Org.name | entity.metadata.threat.detection_fields.value | 直接从 Org 对象中的 name 字段进行映射。该键设置为 Org name 。 |
published | entity.metadata.threat.detection_fields.value | 直接从 published 字段进行映射。该键设置为 published 。 |
Tag.colour | entity.metadata.threat.detection_fields.value | 直接从 Tag 对象中的 colour 字段进行映射。该键设置为 tag colour 。 |
Tag.exportable | entity.metadata.threat.detection_fields.value | 直接从 Tag 对象中的 exportable 字段进行映射。该键设置为 tag exportable 。 |
Tag.hide_tag | entity.metadata.threat.detection_fields.value | 直接从 Tag 对象中的 hide_tag 字段进行映射。该键设置为 tag hide_tag 。 |
Tag.id | entity.metadata.threat.detection_fields.value | 直接从 Tag 对象中的 id 字段进行映射。该键设置为 tag id 。 |
Tag.is_custom_galaxy | entity.metadata.threat.detection_fields.value | 直接从 Tag 对象中的 is_custom_galaxy 字段进行映射。该键设置为 tag is_custom_galaxy 。 |
Tag.is_galaxy | entity.metadata.threat.detection_fields.value | 直接从 Tag 对象中的 is_galaxy 字段进行映射。该键设置为 tag is_galaxy 。 |
Tag.isinherited | entity.metadata.threat.detection_fields.value | 直接从 Tag 对象中的 isinherited 字段进行映射。该键设置为 tag isinherited 。 |
Tag.name | entity.metadata.threat.detection_fields.value | 直接从 Tag 对象中的 name 字段进行映射。该键设置为 tag name 。 |
Tag.numerical_value | entity.metadata.threat.detection_fields.value | 直接从 Tag 对象中的 numerical_value 字段进行映射。该键设置为 tag numerical_value 。 |
Tag.user_id | entity.metadata.threat.detection_fields.value | 直接从 Tag 对象中的 user_id 字段进行映射。该键设置为 tag user_id 。 |
threat_level | ioc.raw_severity | 直接从 threat_level 字段进行映射。 |
threat_level | entity.metadata.threat.severity_details | 直接从 threat_level 字段进行映射。 |
threat_level_id | entity.entity.labels.value | 直接从 threat_level_id 字段进行映射。该键设置为 threat_level_id 。 |
ts1 | ioc.active_timerange.start | 直接从 ts1 字段进行映射。该值会被解析为日期。 |
ts1 | entity.metadata.interval.start_time | 直接从 ts1 字段进行映射。该值会被解析为日期。 |
entity.entity.file.full_path | 如果 type 为 filename ,则映射。 |
|
entity.entity.file.md5 | 如果 type 为 md5 ,则映射。 |
|
entity.entity.file.sha1 | 如果 type 为 sha1 ,则映射。 |
|
entity.entity.file.sha256 | 如果 type 为 sha256 ,则映射。 |
|
entity.entity.hostname | 如果 type 为 domain ,则映射。 |
|
entity.entity.ip | 如果 type 为 ip-dst 、ip-dst|port 或 ip-src ,则进行映射。该值是使用 Grok 模式提取的。 |
|
entity.entity.port | 如果 port 字段不为空,则进行映射。该值会转换为整数。 |
|
entity.entity.resource.name | 如果 type 为 mutex ,则映射。 |
|
entity.entity.resource.resource_subtype | 如果 type 为 regkey ,则映射。该值设置为 regkey 。 |
|
entity.entity.resource.resource_type | 如果 type 为 mutex 或 regkey ,则进行映射。该值分别设置为 MUTEX 或 STORAGE_OBJECT 。 |
|
entity.entity.registry.registry_key | 如果 type 为 regkey ,则映射。 |
|
entity.entity.url | 如果 type 为 uri 或 url ,则进行映射。 |
|
entity.metadata.collected_timestamp | 该值会设为原始日志条目的时间戳。 | |
entity.metadata.description | 如果原始日志采用 CSV 格式,则该值会设置为 type 字段。否则,该值会设置为 info 字段。 |
|
entity.metadata.entity_type | 该值根据 type 或 log_type 字段确定。可以是 DOMAIN_NAME 、FILE 、IP_ADDRESS 、MUTEX 、RESOURCE 或 URL 。 |
|
entity.metadata.interval.end_time | 该值设置为默认值 253402300799 秒。 | |
entity.metadata.interval.start_time | 如果 first_seen 字段不为空,则将该值设置为 first_seen 字段。否则,该值会设置为默认值 1 秒或原始日志条目的时间戳。 |
|
entity.metadata.product_name | 该值设置为 MISP 。 |
|
entity.metadata.threat.confidence | 如果 confidence 字段为空或为 f ,则该值设置为 UNKNOWN_CONFIDENCE 。否则,系统会根据 confidence 字段的值将其设置为 HIGH_CONFIDENCE 、MEDIUM_CONFIDENCE 或 LOW_CONFIDENCE 。 |
|
entity.metadata.threat.confidence_details | 直接从 confidence 字段进行映射。 |
|
entity.metadata.threat.detection_fields | 该值是从原始日志的各个字段中提取的键值对列表。 | |
entity.metadata.vendor_name | 该值设置为 MISP 。 |
|
ioc.active_timerange.end | 如果 last_seen 字段不为空,则将该值设置为 last_seen 字段。 |
|
ioc.active_timerange.start | 如果 ts1 或 first_seen 字段不为空,则将值设置为这两个字段。否则,系统会将其设置为默认值 1 秒。 |
|
ioc.categorization | 如果原始日志采用 CSV 格式,则该值设置为 misp_category IOCs 。否则,该值会设置为 Attribute 或 log 对象中的 category 字段。 |
|
ioc.confidence_score | 直接从 confidence 字段进行映射。 |
|
ioc.description | 该值通过将 description 字段与 event_info 字段(以 - additional info: 分隔)组合生成。 |
|
ioc.domain_and_ports.domain | 如果 type 或 log_type 为 domain ,则进行映射。 |
|
ioc.feed_name | 如果 event_source_org 字段为空,则该值设置为 MISP 。否则,该值会设置为 event_source_org 字段。 |
|
ioc.ip_and_ports.ip_address | 如果 ip 字段不为空,则进行映射。该值会转换为 IP 地址。 |
|
ioc.ip_and_ports.ports | 如果 port 字段不为空,则进行映射。该值会转换为无符号整数。 |
|
ioc.raw_severity | 直接从 threat_level 字段进行映射。 |
|
时间戳 | 该值会设为原始日志条目的时间戳。 |
需要更多帮助?从社区成员和 Google SecOps 专业人士那里获得解答。