
脅威検知ルールのエンドツーエンドテストのためのCLIおよびGoフレームワーク。攻撃手法を起動し、DatadogやElastic Securityなどのセキュリティプラットフォームでアラートを検証します。
Threatest は、脅威検知をエンドツーエンドでテストするための CLI および Go フレームワークです。
Threatest を使用すると、攻撃手法を detonate し、期待するアラートがお好みのセキュリティプラットフォームで生成されたことを確認できます。
アナウンスブログ記事を読む: https://securitylabs.datadoghq.com/articles/threatest-end-to-end-testing-threat-detection/
デトネーター は、攻撃手法をどこでどのように実行するかを記述します。
サポートされているデトネーター:
アラートマッチャー は、期待されるアラートがトリガーされたかどうかを確認できる、プラットフォーム固有の統合機能です。
サポートされているアラートマッチャー:
各デトネーションには UUID が割り当てられます。この UUID はデトネーションに反映され、マッチしたアラートがこのデトネーションに正確に対応することを保証するために使用されます。
その方法はデトネーターによって異なります。たとえば、Stratus Red Team と AWS デトネーターは UUID をユーザーエージェントに埋め込み、SSH デトネーターは UUID を含む親プロセスを使用します。
Threatest には CLI が付属しており、特定の スキーマ に従った YAML として記述されたテストシナリオを実行できます。このスキーマをエディターで設定すると、IDE 内での Lint と自動補完を利用できます(YAML 拡張機能 を使用した VSCode のドキュメント を参照)。
binary release をダウンロードするか、Homebrew を使用して CLI をインストールします:
brew tap datadog/threatest https://github.com/datadog/threatest
brew install datadog/threatest/threatest
使用例:
$ threatest lint scenarios.threatest.yaml
All 6 scenarios are syntaxically valid
# ローカルでのデトネーション
$ threatest run local-scenarios.threatest.yaml
# SSH 経由でのリモートデトネーション
$ threatest run scenarios.threatest.yaml --ssh-host test-box --ssh-username vagrant
# または、環境変数から SSH パラメータを指定
$ export THREATEST_SSH_HOST=test-box
$ export THREATEST_SSH_USERNAME=vagrant
$ threatest run scenarios.threatest.yaml
シナリオ定義ファイルのサンプル
scenarios:
# SSH 経由でのリモートデトネーション
# 注意: SSH 設定は --ssh-host、--ssh-username、--ssh-keyfile CLI 引数で指定します
- name: curl metadata service
detonate:
remoteDetonator:
commands: ["curl http://169.254.169.254 --connect-timeout 1"]
expectations:
- timeout: 1m
datadogSecuritySignal:
name: "Network utility accessed cloud metadata service"
severity: medium
scenarios:
# Stratus Red Team のデトネーション
# 注意: 実行する前に、関連するクラウドプロバイダーに認証されている必要があります
# 以下の例は、"stratus detonate aws.exfiltration.ec2-security-group-open-port-22-ingress" を手動で実行するのと同等です
- name: opening a security group to the Internet
detonate:
stratusRedTeamDetonator:
attackTechnique: aws.exfiltration.ec2-security-group-open-port-22-ingress
expectations:
- timeout: 15m
datadogSecuritySignal:
name: "Potential administrative port open to the world via AWS security group"
scenarios:
# AWS CLI でのデトネーション
# 注意: 実行する前に AWS に認証され、AWS CLI がインストールされている必要があります
- name: opening a security group to the Internet
detonate:
awsCliDetonator:
script: |
set -e
# Setup
vpc=$(aws ec2 create-vpc --cidr-block 10.0.0.0/16 --query Vpc.VpcId --output text)
sg=$(aws ec2 create-security-group --group-name sample-sg --description "Test security group" --vpc-id $vpc --query GroupId --output text)
# Open security group
aws ec2 authorize-security-group-ingress --group-id $sg --protocol tcp --port 22 --cidr 0.0.0.0/0
# Cleanup
aws ec2 delete-security-group --group-id $sg
aws ec2 delete-vpc --vpc-id $vpc
expectations:
- timeout: 15m
datadogSecuritySignal:
name: "Potential administrative port open to the world via AWS security group"
テスト結果を JSON ファイルに出力できます:
$ threatest run scenarios.threatest.yaml --output test-results.json
$ cat test-results.json
[
{
"description": "change user password",
"isSuccess": true,
"errorMessage": "",
"durationSeconds": 22.046627348,
"timeDetonated": "2022-11-15T22:26:14.182844+01:00"
},
{
"description": "adding an SSH key",
"isSuccess": true,
"errorMessage": "",
"durationSeconds": 23.604699625,
"timeDetonated": "2022-11-15T22:26:14.182832+01:00"
},
{
"description": "change user password",
"isSuccess": false,
"errorMessage": "At least one scenario failed:\n\nchange user password returned: change user password: 1 assertions did not pass\n =\u003e Did not find Datadog security signal 'bar'\n",
"durationSeconds": 3.505294235,
"timeDetonated": "2022-11-15T22:26:36.229349+01:00"
}
]
デフォルトでは、シナリオは最大 5 の並列度で実行されます。この設定は --parallelism 引数で増やすことができます。
リモート SSH デトネーターを使用する場合、各シナリオの実行ごとに新しい SSH 接続が確立されることに注意してください。
完全なプログラムでの使用例については、examples を参照してください。
threatest := Threatest()
threatest.Scenario("AWS console login").
WhenDetonating(StratusRedTeamTechnique("aws.initial-access.console-login-without-mfa")).
Expect(DatadogSecuritySignal("AWS Console login without MFA", WithSeverity("medium"))).
WithTimeout(15 * time.Minute)
assert.NoError(t, threatest.Run())
ssh, _ := NewSSHCommandExecutor("test-box", "", "")
threatest := Threatest()
threatest.Scenario("curl to metadata service").
WhenDetonating(NewCommandDetonator(ssh, "curl http://169.254.169.254 --connect-timeout 1")).
Expect(DatadogSecuritySignal("EC2 Instance Metadata Service Accessed via Network Utility"))
assert.NoError(t, threatest.Run())