
CLI et framework Go pour les tests de bout en bout des règles de détection des menaces. Déclenche des techniques d'attaque et vérifie les alertes dans des plateformes de sécurité comme Datadog et Elastic Security.
Threatest est un CLI et un framework Go pour tester la détection des menaces de bout en bout.
Threatest vous permet de détonner une technique d'attaque et de vérifier que l'alerte attendue a été générée dans votre plateforme de sécurité préférée.
Lisez l'article de blog annonçant l'outil : https://securitylabs.datadoghq.com/articles/threatest-end-to-end-testing-threat-detection/
Un détonateur décrit comment et où une technique d'attaque est exécutée.
Détonateurs supportés :
Un vérificateur d'alerte est une intégration spécifique à une plateforme qui peut vérifier si une alerte attendue a été déclenchée.
Vérificateurs d'alertes supportés :
Chaque détonation se voit attribuer un UUID. Cet UUID est reflété dans la détonation et utilisé pour garantir que l'alerte correspondante correspond exactement à cette détonation.
La manière dont cela est fait dépend du détonateur ; par exemple, Stratus Red Team et le détonateur AWS l'injectent dans le user-agent ; le détonateur SSH utilise un processus parent contenant l'UUID.
Threatest est livré avec un CLI que vous pouvez utiliser pour exécuter des scénarios de test décrits en YAML, suivant un schéma spécifique. Vous pouvez configurer ce schéma dans votre éditeur pour bénéficier de la vérification et de l'autocomplétion dans l'IDE (voir documentation pour VSCode en utilisant l'extension YAML).
Installez le CLI en téléchargeant une version binaire ou avec Homebrew :
brew tap datadog/threatest https://github.com/datadog/threatest
brew install datadog/threatest/threatest
Exemple d'utilisation :
$ threatest lint scenarios.threatest.yaml
Tous les 6 scénarios sont syntaxiquement valides
# Détonation locale
$ threatest run local-scenarios.threatest.yaml
# Détonation à distance via SSH
$ threatest run scenarios.threatest.yaml --ssh-host test-box --ssh-username vagrant
# Alternative : spécifier les paramètres SSH via des variables d'environnement
$ export THREATEST_SSH_HOST=test-box
$ export THREATEST_SSH_USERNAME=vagrant
$ threatest run scenarios.threatest.yaml
Exemples de fichiers de définition de scénarios
scenarios:
# Détonation à distance via SSH
# Note : La configuration SSH est fournie en utilisant les arguments CLI --ssh-host, --ssh-username et --ssh-keyfile
- name: curl vers le service de métadonnées
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:
# Détonation Stratus Red Team
# Note : Vous devez être authentifié auprès du fournisseur cloud concerné avant de l'exécuter
# L'exemple ci-dessous est équivalent à exécuter manuellement "stratus detonate aws.exfiltration.ec2-security-group-open-port-22-ingress"
- name: ouverture d'un groupe de sécurité vers 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:
# Détonation AWS CLI
# Note : Vous devez être authentifié auprès d'AWS avant de l'exécuter et avoir le AWS CLI installé
- name: ouverture d'un groupe de sécurité vers 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"
Vous pouvez exporter les résultats des tests dans un fichier 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"
}
]
Par défaut, les scénarios sont exécutés avec un parallélisme maximum de 5. Vous pouvez augmenter ce paramètre en utilisant l'argument --parallelism.
Notez qu'avec les détonateurs SSH à distance, chaque scénario en cours d'exécution établit une nouvelle connexion SSH.
Consultez examples pour un exemple d'utilisation programmatique complet.
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())