
Outil de collecte d'inventaire AWS multi-threadé axé sur les ressources et métadonnées pertinentes pour la sécurité.
Un outil de collecte d'inventaire AWS orienté sécurité, multi-threadé, écrit en Ruby.
Cet outil a été créé pour faciliter la collecte efficace d'un grand nombre d'attributs et de métadonnées de ressources AWS. Il vise à collecter presque tout ce qui est pertinent pour la configuration de sécurité et la posture d'un environnement AWS.
Les outils existants (par exemple AWS Config) qui effectuent une forme de collecte de ressources manquent de couverture et de spécificité pour mesurer précisément la posture de sécurité (par exemple, données d'attributs de ressources détaillées, documents de politique entièrement analysés et relations de ressources imbriquées).
AWS Recon gère la collecte à partir de grands comptes en profitant des tentatives automatiques (que ce soit en raison de la fiabilité du réseau ou du limitation de l'API), de la pagination automatique des grandes réponses (> 100 ressources par appel API), et de requêtes multi-threadées parallèles pour accélérer la collecte.
** l'utilisation n'implique pas un aval
AWS Recon a besoin d'un rôle ou d'identifiants de compte AWS avec ReadOnlyAccess. Un accès AdministratorAccess complet est trop privilégié, mais fonctionnera aussi. La politique SecurityAudit n'est pas suffisante car elle omet l'accès à de nombreux services.
Utilisez Docker version 19.x ou supérieure pour exécuter l'image pré-construite sans avoir à installer quoi que ce soit.
Si vous avez déjà Ruby installé (2.6.x ou 2.7.x), vous pouvez installer la gem Ruby.
AWS Recon peut être exécuté localement via un conteneur Docker ou en installant la gem Ruby.
Pour exécuter via un conteneur Docker, passez les identifiants AWS nécessaires dans la commande docker run. Par exemple :
$ docker run -t --rm \
-e AWS_REGION \
-e AWS_ACCESS_KEY_ID \
-e AWS_SECRET_ACCESS_KEY \
-e AWS_SESSION_TOKEN \
-v $(pwd)/output.json:/recon/output.json \
darkbitio/aws_recon:latest \
aws_recon -v -s EC2 -r global,us-east-1,us-east-2
Pour exécuter localement, installez d'abord la gem :
$ gem install aws_recon
Fetching aws_recon-0.5.17.gem
Fetching aws-sdk-3.0.1.gem
Fetching parallel-1.20.1.gem
...
Successfully installed aws-sdk-3.0.1
Successfully installed parallel-1.20.1
Successfully installed aws_recon-0.5.17
Ou ajoutez-la à votre Gemfile en utilisant bundle :
$ bundle add aws_recon
Fetching gem metadata from https://rubygems.org/
Resolving dependencies...
...
Using aws-sdk 3.0.1
Using parallel-1.20.1
Using aws_recon 0.5.17
AWS Recon exploitera tous les identifiants AWS (voir prérequis) actuellement disponibles dans l'environnement où il s'exécute. Si vous collectez à partir de plusieurs comptes, vous pouvez utiliser un outil comme aws-vault pour gérer différents identifiants.
$ aws-vault exec profile -- aws_recon
Les variables d'environnement simples fonctionneront aussi bien.
$ AWS_PROFILE=<profil> aws_recon
Pour exécuter à partir d'un conteneur Docker en utilisant des identifiants gérés par aws-vault (sortie vers stdout) :
$ aws-vault exec <vault_profile> -- docker run -t --rm \
-e AWS_REGION \
-e AWS_ACCESS_KEY_ID \
-e AWS_SECRET_ACCESS_KEY \
-e AWS_SESSION_TOKEN \
darkbitio/aws_recon:latest \
aws_recon -j -s EC2 -r global,us-east-1,us-east-2
Pour exécuter à partir d'un conteneur Docker en utilisant des identifiants gérés par aws-vault et sortie vers un fichier, vous devez satisfaire quelques conditions. Tout d'abord, Docker doit avoir accès au montage bind du chemin que vous spécifiez (ou d'un chemin parent). Deuxièmement, vous devez créer un fichier vide pour enregistrer la sortie (par exemple output.json). En effet, seul ce fichier est monté dans le conteneur Docker au moment de l'exécution. Par exemple :
Créez un fichier vide.
$ touch output.json
Exécutez le conteneur aws_recon, en spécifiant le fichier de sortie.
$ aws-vault exec <vault_profile> -- docker run -t --rm \
-e AWS_REGION \
-e AWS_ACCESS_KEY_ID \
-e AWS_SECRET_ACCESS_KEY \
-e AWS_SESSION_TOKEN \
-v $(pwd)/output.json:/recon/output.json \
darkbitio/aws_recon:latest \
aws_recon -s EC2 -v -r global,us-east-1,us-east-2
Vous pouvez utiliser le flag -v ou --verbose au début pour voir l'état et l'activité pendant l'exécution de la collecte.
En mode verbeux, la sortie console affichera :
<thread>.<region>.<service>.<operation>
Le préfixe t indique sous quel thread une requête particulière est exécutée. Region, service et operation indiquent quelle opération de requête est actuellement en cours et où.
$ aws_recon -v
t0.global.EC2.describe_account_attributes
t2.global.S3.list_buckets
t3.global.Support.describe_trusted_advisor_checks
t2.global.S3.list_buckets.acl
t5.ap-southeast-1.WorkSpaces.describe_workspaces
t6.ap-northeast-1.Lightsail.get_instances
...
t2.us-west-2.WorkSpaces.describe_workspaces
t1.us-east-2.Lightsail.get_instances
t4.ap-southeast-1.Firehose.list_delivery_streams
t7.ap-southeast-1.Lightsail.get_instances
t0.ap-south-1.Lightsail.get_instances
t1.us-east-2.Lightsail.get_load_balancers
t7.ap-southeast-2.WorkSpaces.describe_workspaces
t2.eu-west-3.SageMaker.list_notebook_instances
t3.eu-west-2.SageMaker.list_notebook_instances
Finished in 46 seconds. Saving resources to output.json.
# collecter les ressources globales S3 et EC2, ainsi que us-east-1 et us-east-2
$ AWS_PROFILE=<profil> aws_recon -s S3,EC2 -r global,us-east-1,us-east-2
# collecter les ressources globales S3 et EC2, ainsi que us-east-1 et us-east-2
$ AWS_PROFILE=<profil> aws_recon --services S3,EC2 --regions global,us-east-1,us-east-2
# enregistrer la sortie dans un bucket S3
$ AWS_PROFILE=<profil> aws_recon \
--services S3,EC2 \
--regions global,us-east-1,us-east-2 \
--verbose \
--s3-bucket mon-bucket-recon
# enregistrer la sortie dans un bucket S3 avec une région d'accueil autre que us-east-1
$ AWS_PROFILE=<profil> aws_recon \
--services S3,EC2 \
--regions global,us-east-1,us-east-2 \
--verbose \
--s3-bucket mon-bucket-recon:us-west-2
Exemple de sortie au format OpenCSPM (NDJSON).
$ AWS_PROFILE=<profil> aws_recon -l \
-s S3,EC2 \
-r global,us-east-1,us-east-2 \
-f custom
ou
$ AWS_PROFILE=<profil> aws_recon -j \
-s S3,EC2 \
-r global,us-east-1,us-east-2 \
-f custom > output.json
Les exceptions API liées aux permissions sont ignorées silencieusement dans la plupart des cas. Ces erreurs sont généralement dues à l'un de ces cas :
En mode verbose, vous verrez des journaux d'exception dans la sortie :
t2.us-east-1.EC2.describe_subnets.0
t4.us-east-1.SSM.describe_instance_information.0
t6.us-east-1.SecurityHub.InvalidAccessException <-----
t2.us-east-1.EC2.describe_addresses.0
t4.us-east-1.SSM.describe_parameters.0
t1.us-east-1.GuardDuty.list_detectors.0
Utilisez l'option en ligne de commande -q pour relancer ces exceptions afin de faciliter le diagnostic des problèmes d'accès.
Traceback (most recent call last):
arn:aws:sts::1234567890:assumed-role/role/mon-rôle-audit n'est pas autorisé à effectuer :
codepipeline:GetPipeline sur la ressource : arn:aws:codepipeline:us-west-2:1234567890:pipeline
(Aws::CodePipeline::Errors::AccessDeniedException)
L'opération API exacte qui a déclenché l'exception est indiquée sur la dernière ligne de la trace de la pile. Si vous ne pouvez pas résoudre l'accès nécessaire, vous devez exclure ces services avec -x ou --not-services, ou ne pas utiliser l'option -q afin que la collecte puisse continuer.
AWS Recon utilise plusieurs threads pour tenter de surmonter certains des défis d'E/S liés à l'exécution de nombreux appels API vers des points d'accès partout dans le monde.
Pour les services globaux comme IAM, Shield et Support, les requêtes ne sont pas multi-threadées. Le module S3 est multi-threadé car chaque bucket nécessite plusieurs appels supplémentaires pour collecter des métadonnées complètes.
Pour les services régionaux, un thread (jusqu'à la limite de threads) est créé pour chaque service dans une région. Par défaut, jusqu'à 8 threads sont utilisés. Si votre compte a des ressources réparties sur plusieurs régions, vous pouvez constater une amélioration de la vitesse en augmentant le nombre de threads avec -t X, où X est le nombre de threads.
AWS Recon effectuera un minimum d'environ 2 000 appels API dans un compte nouveau/vide, juste pour interroger les services pris en charge dans toutes les 20 régions standard (non GovCloud, non Chine). Il est très probable de rencontrer une limitation de débit API (throttling) sur les grands comptes si vous activez plus de threads que la valeur par défaut (8).
Recon reculera automatiquement et respectera les limites de nouvelle tentative dans la réponse API. Si vous observez de longues pauses pendant la collecte, c'est probablement ce qui se passe. Relancez la collecte avec l'option -d ou --debug pour observer la trace filaire et voir si vous êtes limité. Envisagez d'utiliser moins de threads ou de demander des limites de débit plus élevées à AWS si vous êtes régulièrement limité.
La plupart des utilisateurs voudront limiter la collecte aux services et régions pertinents. L'exécution sans exclusions tentera de collecter toutes les ressources de toutes les régions activées pour le compte.
$ aws_recon -h
AWS Recon - Collecteur d'inventaire AWS (0.5.17)
Usage: aws_recon [options]
-r, --regions [REGIONS] Régions à analyser, séparées par des virgules (par défaut : toutes)
-n, --not-regions [REGIONS] Régions à ignorer, séparées par des virgules (par défaut : aucune)
-s, --services [SERVICES] Services à analyser, séparés par des virgules (par défaut : tous)
-x, --not-services [SERVICES] Services à ignorer, séparés par des virgules (par défaut : aucun)
-c, --config [CONFIG] Spécifier un fichier de configuration pour les services et régions (p. ex. config.yaml)
-b, --s3-bucket [BUCKET:REGION] Écrire le fichier de sortie dans un bucket S3 (par défaut : '')
-o, --output [OUTPUT] Spécifier le fichier de sortie (par défaut : output.json)
-f, --format [FORMAT] Spécifier le format de sortie (par défaut : aws)
-t, --threads [THREADS] Spécifier le nombre max de threads (par défaut : 8, max : 128)
-l, --json-lines Sortie au format NDJSON/JSONL (par défaut : faux)
-u, --user-data Collecter les données utilisateur des instances EC2 (par défaut : faux)
-z, --skip-slow Ignorer les opérations lentes (par défaut : faux)
-g, --skip-credential-report Ignorer la génération du rapport d'identifiants IAM (par défaut : faux)
-j, --stream-output Diffuser les lignes JSON vers stdout (par défaut : faux)
-v, --verbose Afficher la progression du client et l'opération en cours
-q, --quit-on-exception Arrêter la collecte si une erreur API est rencontrée (par défaut : faux)
-d, --debug Afficher les informations de débogage avec la trace filaire
-h, --help Afficher cette aide
La sortie est toujours une forme de JSON – soit des lignes JSON, soit du JSON simple. La sortie est écrite dans un fichier (par défaut) ou écrite vers stdout (avec -j).
Lors de l'écriture dans un bucket S3, la sortie JSON est automatiquement compressée avec gzip.
Si vous avez activé des régions activées manuellement :
et que vous utilisez STS pour assumer un rôle dans un compte, vous devrez activer les tokens STS v2 dans le compte à partir duquel vous assumez le rôle pour pouvoir exécuter AWS Recon dans ces régions.
Les tokens de version 1 ne sont valides que dans les régions AWS disponibles par défaut. Ces tokens ne fonctionnent pas dans les régions activées manuellement, comme l'Asie Pacifique (Hong Kong). Les tokens de version 2 sont valides dans toutes les régions. Cependant, les tokens de version 2 sont plus longs et peuvent affecter les systèmes où vous stockez temporairement des tokens.
Si vous utilisez une clé d'accès/clé secrète statique, vous pouvez collecter à partir de ces régions indépendamment de la version du token STS.
La "couverture" actuelle par service est listée ci-dessous. Les services sans couverture seront éventuellement ajoutés. Les PR sont les bienvenus. :)
AWS Recon vise à collecter toutes les ressources et métadonnées pertinentes pour déterminer la posture de sécurité de votre/vos compte(s) AWS. Cependant, il n'examine pas réellement les ressources pour la posture de sécurité – c'est le travail d'autres outils qui prennent la sortie d'AWS Recon comme entrée.
L'une des principales motivations d'AWS Recon était de construire un outil facile à maintenir et à étendre. Si vous pensez que la couverture pourrait être améliorée pour un service particulier, nous accueillerions volontiers les PR à cet effet. Toute personne ayant une familiarité modérée avec Ruby pourra imiter le modèle utilisé par les collecteurs existants pour interroger un service spécifique et ajouter les résultats à la collecte de ressources.
Clonez ce dépôt :
$ git clone [email protected]:darkbitio/aws-recon.git
$ cd aws-recon
Créez un gemset collant si vous utilisez RVM :
$ rvm use 2.7.2@aws_recon_dev --create --ruby-version
Exécutez bin/setup pour installer les dépendances. Ensuite, exécutez rake test pour lancer les tests. Vous pouvez également exécuter bin/console pour une invite interactive qui vous permettra d'expérimenter.
Pour installer cette gem sur votre machine locale, exécutez bundle exec rake install. Pour publier une nouvelle version, mettez à jour le numéro de version dans version.rb, puis exécutez bundle exec rake release, ce qui créera un tag git pour la version, poussera les commits et tags git, et poussera le fichier .gem vers rubygems.org.
AWS Recon a été inspiré par l'excellent travail des personnes et des équipes derrière ces outils :