threatgrid/ctia

GitHub: threatgrid/ctia

这是一个由思科开源的、务实且可运营化的威胁情报服务,旨在提供简单易用的 REST/GraphQL API 以存储、检索及共享可行动的威胁数据。

Stars: 73 | Forks: 26

[![构建状态](https://travis-ci.org/threatgrid/ctia.svg?branch=master)](https://travis-ci.org/threatgrid/ctia) # Cisco Threat Intel API 一个务实、可运营化的威胁情报服务和数据模型 完整文档请参阅 [文档](resources/ctia/public/doc/) 我们也认为 [用例](resources/ctia/public/doc/use_cases.md) 文档是一个很好的 起点。 一旦运行,API 的交互式 Swagger 文档即可通过以下地址访问: ``` http://localhost:3000/index.html ``` ## 目标 * 共享可操作的威胁情报 * 简单、务实的数据模型 * 易于集成和探索 * 极快的 Verdict(判定)查找 * 与其他服务的超文本集成 这不是一个完整的 STIX/TAXII 服务。其目的是帮助 分析师了解什么是重要的,并让检测和预防 工具知道要寻找什么。 除了 RESTful HTTP API 外,它还具有 GraphQL API 和许多事件处理程序。 数据模型在 [CTIM](https://github.com/threatgrid/ctim) 项目中定义, 尽管在运行后,使用内置的 [Swagger UI](http://localhost:3000/index.html) 很容易查看 API 及其处理的模型。 CTIA 使用 [Clojure](http://clojure.org) 实现 ## 使用 ### 数据存储和外部依赖 CTIA 使用 Leiningen 作为其“构建”工具,您可以按照此处的说明进行安装:http://leiningen.org/#install 默认情况下,CTIA 使用 Elasticsearch 5.x 作为其数据存储。假设您 在 127.0.0.1:9200 上运行它,您可以简单地启动 CTIA。 您可以跳转到 [开发](#Development) 部分查看有关 如何使用 Docker 运行 elasticsearch 和其他可选支持工具的说明。 CTIA 可能使用 Kafka、Redis 和 ES 来推送事件。 CTIA 支持 Java 21。 #### 清除 ES 存储 使用 uberjar 构建,您可以使用以下命令清除所有 ES 存储: `java -cp ctia.jar:resources:. clojure.main -m ctia.task.purge-es-stores` 使用 lein 请使用此命令: `lein run -m ctia.task.purge-es-stores` ### 在本地运行应用程序 从克隆的仓库运行: `lein run -m ctia.main` ### 打包并作为独立 jar 运行 这是在生产环境中运行此程序的正确方式。 ``` lein do clean, uberjar java -Xmx4g -Djava.awt.headless=true -Dlog.console.threshold=INFO -jar target/ctia.jar ``` 您可以根据需要调整 java 参数。 ## 开发 最简单的启动方式是使用 `docker`。 在 Mac OS X 上,您应该使用 [Docker for Mac](https://docs.docker.com/docker-for-mac/),它 包含运行 Docker 容器所需的所有依赖项。 **由于 Kafka 和 Zookeeper 现已成为开发集群的一部分,您需要 增加分配给 Docker 的内存。您可以通过 Docker 偏好设置进行此操作。这已在 6GB 分配下 测试通过。** 我们提供了一个默认的 `containers/dev/docker-compose.yml`,它将 在容器中启动您所需的依赖项。 您可以启动开发环境: ``` # 仅适用于 M1 mac,仅需构建一次 docker compose -f containers/dev/docker-compose.yml -f containers/dev/m1-docker-compose.yml build docker compose -f containers/dev/docker-compose.yml up ``` 使用 Docker for Mac,这会将开发机器上的以下端口绑定到容器中运行的服务: * Redis - 6379 * elasticsearch5 - 9205 和 9305 * elasticsearch7 - 9207 和 9307 * kibana - 5601 * zookeeper - 2181 * kafka - 9092 * riemann - 5555-5557 * riemann-dash - 4567 * aws - 4566 如果您需要重置整个开发环境, 只需终止 docker compose 进程并运行: ``` docker compose -f containers/dev/docker-compose.yml down docker compose -f containers/dev/docker-compose.yml up --force-recreate --remove-orphans ``` 特别是,这会重置 ElasticSearch 索引,因为它们无法 被多次创建。 ### 本地工作流 要在本地启动 CTIA,首先通过取消注释 `resources/ctia-default.properties` 中以 `ctia.store.es.default.auth` 开头的行来配置本地开发的 ES 认证。然后对于 ES5 使用 `./scripts/run`,对于 ES7 使用 `./scripts/run7`。 要运行测试,对于所有非集成测试使用 `./scripts/test`,对于仅 ES7 的非集成测试使用 `./scripts/test7`。 对于 REPL 工作流,运行 `lein repl`。使用 `(start)` 启动 CTIA, `(stop)` 停止它,使用 `(go)` 重启 ES5 --- 对于 ES7,请在每个名称后追加 `7`。 ### 测试和 CI 所有 PR 必须通过 `lein test` 且无失败才能被接受。 任何新的代码功能/更改都应附带测试。 PR 使用 GitHub Actions 构建和部署。 要跳过 PR 提交的 CI,请在提交消息中使用 [[skip ci]](https://github.blog/changelog/2021-02-08-github-actions-skip-pull-request-and-push-workflows-with-skip-ci/) 。由于分支保护规则,一旦您准备好 合并您的 PR,必须完成完整的构建。当您为压缩的 PR 选择 最终提交消息时,请注意 Travis 也支持在某些提交消息上跳过 CI——换句话说, 某些提交消息可能会跳过部署。 要在 PR 上运行更严格的 cron 作业(多 JVM/Clojure 矩阵),请以 `{:test-suite :cron}` 开始提交消息。 ### 测试平衡 持续集成测试运行使用 `dev-resources/ctia_test_timings.edn` 中的先前计时信息进行并行化。 对于 GitHub Actions Pull Requests,测试通过 访问先前构建的缓存自动平衡。 要在本地试验此功能,您需要本地仓库中的计时数据。 有两种生成它们的方法,在以下小节中描述: 1. 本地(慢) 2. 通过下载最近构建的 GitHub Actions artifact(快)。 #### 本地重新平衡测试(慢) 1. 运行 `./build/run-tests.sh` 获取最新的测试计时。 2. 运行 `./scripts/summarize-tests.clj` 收集计时 3. 运行 `cp target/test-results/all-test-timings.edn dev-resources/ctia_test_timings.edn` 以更新最新的计时。 4. 提交此更改并推送。 #### 通过 GitHub Actions 重新平衡测试(快) 您需要一个已完成的 GitHub Actions Pull Request 构建作为基础。 1. 访问您想用来重新平衡的 GitHub Actions Pull Request 构建 - 例如,https://github.com/threatgrid/ctia/actions/runs/342562872 2. 转到 `all-pr-checks` 作业(应该是最后一个作业)并下载 `all-test-timings` artifact 3. 解压下载的文件并找到解压后的 `all-test-timings.edn` 文件。 4. 将解压后的 `all-test-timings.edn` 文件复制到 `dev-resources/ctia_test_timings.edn` 5. 提交此更改并推送。 注意:不幸的是,即使是公共 artifacts 也需要 API 密钥才能通过 API 下载, 因此这并不容易自动化 ([查看更多](https://github.com/actions/upload-artifact/issues/51))。 ### 数据访问控制 文档访问控制在文档级别定义,规则默认使用 TLP 结合 max-record-visibility 属性(交通信号灯协议)定义: #### 所有人 最大记录可见性 ##### 绿色/白色 TLP | 身份 | 读取 | 写入 | |-----------|----------|----------| | 所有者 | ✔ | ✔ | | 组/组织 | ✔ | ✔ | | 其他人 | ✔ | | #### 琥珀色 TLP | 身份 | 读取 | 写入 | |-----------|----------|----------| | 所有者 | ✔ | ✔ | | 组/组织 | ✔ | ✔ | | 其他人 | | | #### 红色 TLP | 身份 | 读取 | 写入 | |-----------|----------|----------| | 所有者 | ✔ | ✔ | | 组/组织 | | | | 其他人 | | | #### 组 最大记录可见性 ##### 绿色/白色 TLP | 身份 | 读取 | 写入 | |-----------|----------|----------| | 所有者 | ✔ | ✔ | | 组/组织 | ✔ | ✔ | | 其他人 | | | #### 琥珀色 TLP | 身份 | 读取 | 写入 | |-----------|----------|----------| | 所有者 | ✔ | ✔ | | 组/组织 | ✔ | ✔ | | 其他人 | | | #### 红色 TLP | 身份 | 读取 | 写入 | |-----------|----------|----------| | 所有者 | ✔ | ✔ | | 组/组织 | | | | 其他人 | | | #### 自定义访问规则 可以使用 `authorized_users` 或 `authorized_groups` 文档字段向任何用户/组授予额外访问权限,当一个身份被标记在这些字段中时, 它将获得对文档的完整读/写访问权限。 请注意,`authorized_groups` 属性可能仅在最大记录可见性设置为 `everyone` 时有效 示例: 以下 actor 实体被标记为 `Red`,因此仅允许其所有者进行读写访问, 因为 "foo" 和 "bar" 被标记为 `authorized_users`,这些身份的所有者也拥有读写访问权限。 ``` {"id": "actor-5023697b-3857-4652-9b53-ccda297f9c3e", "type": "actor", "schema_version": "0.4.2", "actor_type": "Hacker", "confidence": "High", "source": "a source", "tlp": "red", "valid_time": {}, "authorized_users": ["foo" "bar"]} ``` 以下 actor 实体被标记为 `Amber`,因此仅允许其所有者或组进行读写访问, 因为 "foogroup" 和 "bargroup" 被标记为 `authorized_groups`,这些组中的身份也将获得完整的读写访问权限。 ``` {"id": "actor-5023697b-3857-4652-9b53-ccda297f9c3e", "type": "actor", "schema_version": "0.4.2", "actor_type": "Hacker", "confidence": "High", "source": "a source", "tlp": "red", "valid_time": {}, "authorized_groups": ["foogroup" "bargroup"]} ``` ## Bulk 和 Bundle CTIA 提供 Bulk 和 Bundle 路由以帮助处理多个实体。 请参阅 [Bulk 和 Bundle 文档](resources/ctia/public/doc/bulk-bundle.org) ### Bundle 导入 `/bundle` API 端点允许拥有正确权限的用户 POST 一个 CTIM [bundle object](https://github.com/threatgrid/ctim/blob/master/src/ctim/schemas/bundle.cljc)。 发布 bundle 的能力由 `import-bundle` 权限控制。 提交 bundle 时: 1. 搜索所有已使用前缀通过 `ctia.store.external-key-prefixes` 属性配置的外部 ID 导入的实体。 2. 如果它们通过瞬态 ID 标识,则会建立瞬态 ID 与存储 ID 之间的映射表。 3. 仅以与 `/bulk` API 端点相同的方式创建新实体,并进行瞬态 ID 解析。现有实体不会被修改。 如果多个实体引用同一个外部 ID,则选取检索到的第一个。 Bundle API 端点的响应: ``` {:results [{:id "http://example.com/ctia/entity-type/entity-type-991d8dfb-b54e-4435-ac58-2297b4d886c1" :tempid "transient:1f48f48c-4130-47f1-92dc-a6df8ab110b6" :action "create" :external_id "indicator-abuse-ch-077d653844d95d8cd8e4e51cb1f9215feae50426" :error "An error occurs"}] ``` | 字段 | 描述 | |----------------|----------------------------------------------------------| | `:id` | 真实 ID | | `:original_id` | 如果与真实 ID 不同则提供的 ID(例如:瞬态 ID) | | `:result` | `error`, `created` 或 `exists` | | `:external_id` | 用于标识实体的外部 ID | | `:error` | 错误消息 | ### Feeds CTIA 允许生成 Feed 作为公共 URL,旨在通过跳过身份验证的视图轻松交换数据。您可以使用此功能生成可被简单系统轻松使用的阻止列表。 第一种 `Feed` 是 `Indicator` 类型,您可以通过发布一个指定 `indicator_id` 和 `output` 类型的 `Feed` 文档来创建它。 CTIA 随后将返回已实现的 `Feed` 文档,包含两个新字段:`feed_view_url` 和 `feed_view_url_csv` - 这两个 URL 将无需认证即可公开访问,因此必须谨慎共享。 - 这两个 URL 都通过它们的关系返回与提供的 `indicator_id` 关联的 Judgements - 根据选择的 `output`,它将仅提取并返回 observable 或完整的 Judgements - CSV 视图输出根据 `output` 设置,要么输出完整的 `Judgement` CSV,要么仅输出 Observable 值。 ### Elasticsearch 存储管理 请参阅 [CTIA Elasticsearch Stores: managing big Indices](resources/ctia/public/doc/es_stores.md) 请参阅 [Migration procedure](resources/ctia/public/doc/migration.md) 请参阅 [CTIA Elasticsearch CRUD details](resources/ctia/public/doc/es_stores.pdf) ### 存储检查 有一个专门的任务用于检查已配置 CTIA 实例的所有存储。 此任务将遍历所有已配置的存储并批量验证每个文档。 使用以下命令启动任务: `java -cp ctia.jar:resources:. clojure.main -m ctia.task.check-es-stores ` 或使用 leiningen 从源码运行: `lein run -m ctia.task.check-es-stores ` #### 任务参数 | 参数 | 描述 | 示例 | |------------|----------------------------------------|---------| | batch-size | 一次验证多少文档 | 1000 | #### API ##### 列表分页 提供列表的 HTTP 路由默认使用 100 条记录的限制。 API 客户端可以将此参数更改为最多 10 0000 条记录。 当响应应用限制时,将返回分页标头: | 标头 | 描述 | 示例 | |------------|--------------------------------------------------------------------------------|------------------------------------------------| | X-TOTAL | 数据存储中的总数 | 5000 | | X-OFFSET | 当前的分页偏移量 | 200 | | X-NEXT | 用于获取下一页结果的现成参数 | limit=100&offset=100&search_after=foo | | X-PREVIOUS | 用于获取上一页结果的现成参数 | limit=100&offset=0 | | X-SORT | 与 `search_after` 一起使用的排序参数,最后一页结果的 ID | ["actor-77b01a42-6d2b-4081-8fd0-c887bf54140c"] | | | | | 要轻松滚动浏览列表的所有结果,只需迭代并将 `X-Next` 附加到您的基础查询 URL。 如果不存在 `X-Next` 标头,则您已到达最后一页。 ##### 偏移分页 用于简单情况,当结果窗口小于 10 000 (`offset` + `limit`) 时, 结合使用 `offset` 和 `limit` 参数对结果进行分页。 #### 无状态游标分页 用于结果窗口大于 `10 000` 的情况,允许轻松循环遍历查询响应的所有页面。 使用 `limit` 和 `offset` 以及用 `X-Sort` 响应标头的值填充的 `search_after` 来获取下一页。 #### 速率限制 可以通过使用 `ctia.http.rate-limit.enabled` 属性启用中间件来对请求进行速率限制。 它限制一个 CTIA 组在一小时内可以发出的 HTTP 请求数量。该组通过当前 Ring 请求的 :identity 属性进行标识。 在达到速率限制之前,响应中会返回标头 `X-Ratelimit-Group-Limit`: ``` HTTP/1.1 200 OK Content-Type: application/json;charset=utf-8 Date: Wed, 31 Oct 2018 14:05:30 GMT Server: Jetty(9.4.z-SNAPSHOT) Strict-Transport-Security: max-age=31536000; includeSubdomains Vary: Accept-Encoding, User-Agent X-Ctim-Version: 1.0.6 X-Ctia-Config: b9b3477528d9616ed85221f2827bf1da443e8f00 X-Ctia-Version: 70323eb3b72da558e7f056e418533402f65d335a X-Ratelimit-Group-Limit: 8000 ``` 如果超过速率限制: - 客户端收到带有 429 HTTP 状态、`retry-after` 标头和 JSON 消息 `{"error": "Too Many Requests"}` 的响应。retry-after 标头指示在发出新请求之前等待的秒数。 ``` HTTP/1.1 429 Too Many Requests Content-Length: 30 Content-Type: application/json Date: Wed, 31 Oct 2018 14:05:30 GMT Retry-After: 3557 Server: Jetty(9.4.z-SNAPSHOT) Strict-Transport-Security: max-age=31536000; includeSubdomains X-Ctim-Version: 1.0.6 X-Ctia-Config: b9b3477528d9616ed85221f2827bf1da443e8f00 X-Ctia-Version: 70323eb3b72da558e7f056e418533402f65d335a ``` - 记录一条 :info 级别的消息 ### 更新索引状态任务 有一个专门的任务用于在启动时更新 ES 索引状态。它执行 CTIA 启动前所需的 ES 映射和设置的幂等 更改。 理论上,此任务可以在 CTIA 启动时自动执行,但在 CTIA 跨多个实例负载均衡的情况下, 这会导致性能问题,因为所有实例 将同时更新 ES。因此将其分离出来。 必须通过以下方式成功完成此任务才能启动 CTIA: ``` java -cp ctia.jar:resources:. clojure.main -m ctia.task.update-index-state ``` 或使用 leiningen 从源码运行: ``` lein run -m ctia.task.update-index-state ``` # 常见问题 (FAQ) 问:在本地运行 CTIA 时,如何停止看到 `Unauthorized ES request`? 答:取消注释 `resources/ctia-default.properties` 中的以下行 ``` ctia.store.es.default.auth.type=basic-auth ctia.store.es.default.auth.params.user=elastic ctia.store.es.default.auth.params.pwd=ductile ``` ## 许可证 Copyright © 2015-2022 Cisco Systems Eclipse Public License v1.0 ## 数据模型 CTIA 的数据模型紧密基于 [STIX](http://stixproject.github.io/data-model/),并有一些 简化。详情请参阅 [Cisco Threat Intel Model](https://github.com/threatgrid/ctim/tree/master/doc/)。
标签:AMSI绕过, API, Cisco, Clojure, DNS解析, Docker, Elasticsearch, GraphQL, JS文件枚举, Kafka, Leiningen, Redis, RESTful, SonarQube插件, STIX, Swagger, Verdict Lookup, 威胁情报, 威胁检测, 安全防御评估, 开发者工具, 开源项目, 情报共享, 搜索引擎查询, 数据模型, 网络安全, 请求拦截, 隐私保护