Résumé
Il est de la plus haute importance pour les entreprises de protéger leurs charges de travail informatiques, s’exécutant sur AWS ou d’autres clouds, contre un large éventail de logiciels malveillants (y compris les virus informatiques, les vers, les logiciels espions, les logiciels de botnet, les ransomwares, etc.
Le service AWS GuardDuty Malware Protection aide les clients à détecter ces fichiers malveillants dans un mécanisme sans agent. Une fois les résultats reçus, les clients doivent automatiser le processus de prise des mesures correctives nécessaires. Quand ECS/MaliciousFile
les types de résultats sont reçus pour les clusters Amazon ECS exécutés sur des instances Amazon EC2 ; il existe plusieurs façons de corriger en fonction du mode réseau des tâches ECS dans le cluster.
Lorsque des tâches sont exécutées avec un pont ou héberger, le processus de correction est relativement simple et nécessite d’attacher un groupe de sécurité sans règles entrantes et sortantes à l’instance EC2 sous-jacente. La correction devient plus complexe lorsque les tâches s’exécutent dans awsvpc mode réseau. Ce blog explique comment tirer parti d’AWS Lambda et d’AWS EventBridge pour isoler automatiquement un cluster ECS infecté s’exécutant sur des instances EC2 dans awsvpc mode réseau.
Conditions préalables
-
2 comptes AWS utilisant AWS Organization, 1 en tant que compte racine et un autre en tant que compte membre
-
GuardDuty doit être activé sur les deux comptes et le compte racine doit être attribué en tant que compte administrateur pour GuardDuty.
-
GuardDuty Malware Protection est activé sur les comptes
-
2 profils AWS pour l’utilisation de l’AWS CLI (cela doit être créé sur le m/c où les concepts décrits dans ce blog peuvent être implémentés), 1 pour le compte racine et un autre pour un compte membre, tous deux configurés avec l’utilisateur ayant un accès administrateur politique
-
NPM (version <=18) et Python sont installés
Limites
La protection contre les logiciels malveillants GuardDuty s’exécute une fois toutes les 24 heures. Il y a un temps d’attente de 24 heures pour que la correction automatique se déclenche. Ce n’est pas une solution en temps quasi réel.
Architecture cible
Le projet GuardDuty-Tester sera utilisé pour simuler un acteur malveillant dans le cluster ECS. La pile de formation de nuages fournie avec ce projet configurera l’infrastructure suivante dans le compte membre.
-
Amazon VPC avec 1 sous-réseau privé et 1 sous-réseau public.
-
Cluster ECS exécuté sur des instances EC2 avec le mode de mise en réseau par défaut dans le sous-réseau privé et un hôte bastion dans le sous-réseau public.
Les étapes suivantes doivent être effectuées pour exécuter le cluster ECS dans awsvpc
mode réseau.
Modifier le guardduty-tester.template
selon les instructions données ci-dessous.
-
Dans la section sur la définition de
taskdefinition:
deType: 'AWS::ECS::TaskDefinition'
ajoutez la configuration NetworkMode suivante.NetworkMode: 'awsvpc' ExecutionRoleArn: Fn::GetAtt: ECSExecutionRole.Arn TaskRoleArn: Fn::GetAtt: TaskInstanceIAMRole.Arn RequiresCompatibilities: - EC2
-
Dans la section sur la définition de
service:
deType: 'AWS::ECS::Service'
ajouter la configuration réseau suivanteNetworkConfiguration: AwsvpcConfiguration: SecurityGroups: - !Ref RedTeamSecurityGroup Subnets: - !Ref PrivateSubnet AssignPublicIp: DISABLED
-
Ajoutez l’extrait de code pour créer le rôle
ECSExecutionRole
ECSExecutionRole: Type: AWS::IAM::Role Properties: Path: / AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Action: "sts:AssumeRole" Principal: { "Service": "ecs-tasks.amazonaws.com"} ManagedPolicyArns: - 'arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly' - 'arn:aws:iam::aws:policy/CloudWatchLogsFullAccess'
-
Ajoutez l’extrait de code ci-dessous pour créer le rôle
TaskInstanceIAMRole
TaskInstanceIAMRole: Type: AWS::IAM::Role Properties: Path: / AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Action: "sts:AssumeRole" Principal: { "Service": "ecs-tasks.amazonaws.com"} ManagedPolicyArns: - 'arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly' - 'arn:aws:iam::aws:policy/CloudWatchLogsFullAccess' Policies: - PolicyName: ECSTaskRole PolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Action: - "cloudformation:List*" - "cloudformation:Describe*" - "cloudformation:Get*" Resource: "*" - Effect: "Allow" Action: - "cloudwatch:PutMetricData" Resource: "*" - Effect: "Allow" Action: - "ecs:DescribeTaskDefinition" - "ecs:DescribeTasks" Resource: "*" - Effect: "Allow" Action: - "ec2:DescribeSubnets" Resource: "*"
-
Ajoutez l’extrait de code ci-dessous pour créer le
ECSCrossAccountRole
qui sera pris en charge par la fonction Remediation Lambda pour modifier les groupes de sécurité lors de la correction.ECSCrossAccountRole: Type: AWS::IAM::Role Properties: Path: / AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Action: "sts:AssumeRole" Principal: { "AWS": "arn:aws:sts::<admin_account_no>:assumed-role/<remediation lambda role>/<remdiation lambda name>"} Policies: - PolicyName: ECSCrossAccountPolicy PolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Action: - "ecs:ListServices" - "ecs:UpdateService" Resource: "*" - Effect: "Allow" Action: - "ec2:CreateSecurityGroup" - "ec2:ModifyNetworkInterfaceAttribute" - "ec2:RevokeSecurityGroupEgress" - "ec2:RevokeSecurityGroupIngress" - "ec2:DescribeNetworkInterfaces" - "ec2:DescribeSecurityGroupRules" - "ec2:DeleteSecurityGroup" - "ec2:DescribeSecurityGroups" Resource: "*"
-
Rôle entre comptes à assumer à partir d’une fonction Lambda exécutée dans un compte administrateur.
Dans le cadre des actions de correction, les composants suivants doivent être créés dans le compte Admin :
-
Règle de pont d’événement pour capturer les résultats « ECS/MaliciousFile » et déclencher la fonction Lambda.
-
Fonction Lambda pour assumer le rôle entre comptes et isoler les instances infectées.
Contrairement à d’autres modes réseau d’exécution de tâches ECS (par exemple, hébergeroù le réseau hôte est utilisé, ou pontoù les dockers du réseau construit sont exploités), les tâches se voient attribuer leur propre interface réseau élastique (ENI) et une adresse IPv4 privée principale lors de l’exécution dans awsvpc mode réseau. Étant donné que ces ENI sont créées par AWS, il n’est pas autorisé de modifier le groupe de sécurité qui leur est associé. Par conséquent, l’approche EC2 de mise en quarantaine du cluster ECS et de ses tâches ne fonctionne pas pour cette configuration. Pour mettre ces tâches en quarantaine, il faut parcourir la liste d’un groupe de sécurité associé à chaque ENI et supprimer explicitement les règles entrantes et sortantes. La section ci-dessous décrit les étapes pour y parvenir.
-
Un acteur malveillant simulé se connecte au Bastion Host et simule le placement de fichiers malveillants dans le cluster ECS. Veuillez suivre les étapes 1, 2 et 3 fournies dans le fichier README.md du projet GuardDuty-Tester pour simuler cela.
-
Si les étapes préalables sont mises en œuvre avec succès, les étapes suivantes se produiront automatiquement.
-
La protection anti-malveillance GuardDuty analyse le compte du membre, découvre la présence d’un fichier malveillant et le signale sous la forme d’un
Execution:ECS/MaliciousFile
résultats. Les captures d’écran ci-dessous valideront la même chose : -
Le résultat est transmis à GuardDuty dans le compte Admin.
-
Les résultats de GuardDuty dans le compte administrateur déclenchent un événement CloudWatch.
- L’événement CloudWatch déclenche une règle pour appeler la correction Lambda.
-
-
Lambda effectue les étapes suivantes.
-
Assume un rôle dans le compte membre qui dispose de toutes les autorisations requises
-
sts_connection = boto3.client('sts') account_no = os.getenv('CHILD_ACCOUNT') acct_b = sts_connection.assume_role( RoleArn=f"arn:aws:iam::{account_no}:role/<role-name>", RoleSessionName="cross_acct_lambda" ) print('acct_b',acct_b) ACCESS_KEY = acct_b['Credentials']['AccessKeyId'] SECRET_KEY = acct_b['Credentials']['SecretAccessKey'] SESSION_TOKEN = acct_b['Credentials']['SessionToken']
-
-
Obtient la liste des services en cours d’exécution sur le cluster ECS.
-
cluster = event_dict.get('detail').get('resource').get('ecsClusterDetails').get('arn') #response.get('clusterArns')[0] print('cluster:',cluster) ecs = boto3.client('ecs', aws_access_key_id=ACCESS_KEY, aws_secret_access_key=SECRET_KEY, aws_session_token=SESSION_TOKEN) response = ecs.list_services( cluster=cluster, launchType="EC2", schedulingStrategy='REPLICA' ) service = response.get('serviceArns')[0] for service in response.get('serviceArns'): print('service:',service) for networkInterface in event_dict.get('detail').get('resource').get('instanceDetails').get('networkInterfaces'): vpc_id = networkInterface.get('vpcId') subnet = networkInterface.get('subnetId') eni_id = networkInterface.get('networkInterfaceId')
-
-
Crée un groupe de sécurité sans règle entrante et sortante.
…
-