AWS re:Inforce 2024にて、Amazon GuardDuty Malware Protection for Amazon S3 がリリースされましたので、早速検証してみました。
アップデート概要
GuardDuty Malware Protection の拡張機能で、選択した S3 バケットへの悪意のあるファイルのアップロードを検出
GuardDutyが有効になっていない場合、GuardDuty Malware Protection for Amazon S3機能のみの有効化もできる
スキャンしたオブジェクトにはGuardDutyMalwareScanStatusというタグが付与され、タグの値によって脅威と判定されたか分かる
タグの値は以下の通り
タグの詳細は以下のドキュメントにも記載があります docs.aws.amazon.com
- 料金はオブジェクトのサイズと数による従量課金
料金は以下の通り
- 1カ月のファイルサイズにおいて $0.79 / GB
- 1カ月のファイル数において $0.282 / 1k
Malware Protection for Amazon S3を有効化
GuardDutyの「S3のMalware Protection」から「S3のMalware Protectionを有効化」を押下します。
スキャン対象のS3バケットは「S3バケット内のすべてのオブジェクト」、タグ付けは「オブジェクトにタグを付ける」を選択します。
Malware Protection for Amazon S3機能のためのIAMロールを作成します。
「アクセス許可を表示」を押下します。
IAMロールに必要なポリシーが表示されるので、これらをコピーしておきます。
参考までにポリシーと信頼関係は以下のようになっています。
ポリシー
{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowManagedRuleToSendS3EventsToGuardDuty", "Effect": "Allow", "Action": [ "events:PutRule", "events:DeleteRule", "events:PutTargets", "events:RemoveTargets" ], "Resource": [ "arn:aws:events:ap-northeast-1:3<accountID>:rule/DO-NOT-DELETE-AmazonGuardDutyMalwareProtectionS3*" ], "Condition": { "StringLike": { "events:ManagedBy": "malware-protection-plan.guardduty.amazonaws.com" } } }, { "Sid": "AllowGuardDutyToMonitorEventBridgeManagedRule", "Effect": "Allow", "Action": [ "events:DescribeRule", "events:ListTargetsByRule" ], "Resource": [ "arn:aws:events:ap-northeast-1:<accountID>:rule/DO-NOT-DELETE-AmazonGuardDutyMalwareProtectionS3*" ] }, { "Sid": "AllowPostScanTag", "Effect": "Allow", "Action": [ "s3:PutObjectTagging", "s3:GetObjectTagging", "s3:PutObjectVersionTagging", "s3:GetObjectVersionTagging" ], "Resource": [ "arn:aws:s3:::test-s3mal-bucket/*" ] }, { "Sid": "AllowEnableS3EventBridgeEvents", "Effect": "Allow", "Action": [ "s3:PutBucketNotification", "s3:GetBucketNotification" ], "Resource": [ "arn:aws:s3:::test-s3mal-bucket" ] }, { "Sid": "AllowPutValidationObject", "Effect": "Allow", "Action": [ "s3:PutObject" ], "Resource": [ "arn:aws:s3:::test-s3mal-bucket/malware-protection-resource-validation-object" ] }, { "Effect": "Allow", "Action": [ "s3:ListBucket" ], "Resource": [ "arn:aws:s3:::test-s3mal-bucket" ] }, { "Sid": "AllowMalwareScan", "Effect": "Allow", "Action": [ "s3:GetObject", "s3:GetObjectVersion" ], "Resource": [ "arn:aws:s3:::test-s3mal-bucket/*" ] }, { "Sid": "AllowDecryptForMalwareScan", "Effect": "Allow", "Action": [ "kms:GenerateDataKey", "kms:Decrypt" ], "Resource": "arn:aws:kms:ap-northeast-1:<accountID>:key/<key_id>", "Condition": { "StringLike": { "kms:ViaService": "s3.*.amazonaws.com" } } } ] }
信頼関係
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "malware-protection-plan.guardduty.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
続いて、IAMロールを作成します。
エンティティタイプはカスタム信頼ポリシーとし、コピーした信頼関係をペーストします。
ポリシーはいったんロールを作成し後にインラインポリシーとして追加します。
ロール名を入力しロールを作成します。
インラインポリシーのアクセス許可で、コピーしたポリシーをペーストします。
ポリシー名を入力しポリシーを作成します。
S3のMalware Protectionを有効化の画面に戻り、作成したIAMロールを選択し、「有効にする」を押下します。
S3のMalware Protectionが有効化されました。
スキャン状況の監視ができるようです。
IAMポリシーではS3とEventBridgeへの権限がありました。
そこで、EventBridgeを確認してみると、「DO-NOT-DELETE-AmazonGuardDutyMalwareProtectionS3-<文字列>」というルールが作成されています。
イベントパターンとターゲットを見ると、S3バケットにオブジェクトが作成されたらguardduty-malware-protection-planが起動して、スキャンが行われる仕組みのようです。
マルウェアを検知させる
S3バケットにeicarファイルをアップロードします。
ちなみに、S3のMalware Protectionが有効化したときに「malware-protection-resource-validation-object」というテストファイルも自動作成されているようです。
モニタリングを見ていると、スキャンされており感染判定されていることを観測できます。
eicarファイルには「GuardDutyMalwareScanStatus : THREATS_FOUND」というタグが付いており、潜在的な脅威を検出したと判定されていることが分かります。
ちなみに、有効化時に作られた「malware-protection-resource-validation-object」というテストファイルのタグを見てみると、「GuardDutyMalwareScanStatus : NO_THREATS_FOUND」というタグが付いており、潜在的な脅威と判定されなかったことが分かります。
検出結果の確認
それでは検出結果を見ていきます。
GuardDutyの「検出結果」を見ると、重要度「高」で検出結果タイプが「Object:S3/MaliciousFile」が検出されています。
詳細を見ると、検出理由やオブジェクトの情報が表示されています。
マルウェアから保護する
スキャン後にオブジェクトにタグ付けが行われるので、タグベースのアクセス制御 (TBAC) をバケットポリシーに仕込むことで、アクセス元からマルウェアを隔離できます。
ポリシー例があるので、S3バケットポリシーに設定します。
タグが「GuardDutyMalwareScanStatus": "NO_THREATS_FOUND"」以外のオブジェクトへのアクセスを拒否するという内容です。
タグベースのアクセス制御 (TBAC) をバケットポリシー例
{ "Version": "2012-10-17", "Statement": [ { "Sid": "NoReadExceptForClean", "Effect": "Deny", "NotPrincipal": { "AWS": [ "arn:aws:iam::555555555555:root", "arn:aws:iam::555555555555:role/IAM-role-ARN", "arn:aws:iam::555555555555:assumed-role/role-ARN/GuardDutyMalwareProtection" ] }, "Action": [ "s3:GetObject", "s3:GetObjectVersion" ], "Resource": [ "arn:aws:s3:::DOC-EXAMPLE-BUCKET", "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*" ], "Condition": { "StringNotEquals": { "s3:ExistingObjectTag/GuardDutyMalwareScanStatus": "NO_THREATS_FOUND" } } }, { "Sid": "OnlyGuardDutyCanTag", "Effect": "Deny", "NotPrincipal": { "AWS": [ "arn:aws:iam::555555555555:root", "arn:aws:iam::555555555555:role/IAM-role-ARN", "arn:aws:iam::555555555555:assumed-role/role-ARN/GuardDutyMalwareProtection" ] }, "Action": "s3:PutObjectTagging", "Resource": [ "arn:aws:s3:::DOC-EXAMPLE-BUCKET", "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*" ] } ] }
試しに無害のファイルをS3バケットにアップロードします。
こちらは「GuardDutyMalwareScanStatus : NO_THREATS_FOUND」でした。
AWS CloudShellでローカルコピーしてみると、eicarファイルだけブロックされました。
$ aws s3 cp s3://test-s3mal-bucket/test.txt ./ download: s3://test-s3mal-bucket/test.txt to ./test.txt $ aws s3 cp s3://test-s3mal-bucket/eicar.com ./ fatal error: An error occurred (403) when calling the HeadObject operation: Forbidden
まとめ
Amazon GuardDuty Malware Protection for Amazon S3 を試してみました。
検出だけでなく、隔離の仕組みを簡単に実装できるのは嬉しい点です。
ユースケースとしては、不特定多数のユーザがS3バケットへファイルをアップロードできるようなアプリケーションで効果を発揮すると思います。
一方で、ログ保存など内部で使われていて、不特定多数のユーザからアップロードする余地のないS3バケットには、無理に設定する必要はなさそうです。
用途に応じて活用しましょう。
タグの付与やEventBridgeを自由にカスタマイズできるので、運用者に通知メールを送ったり、他のバケットへ隔離するといったこともできそうです。
要件に応じて柔軟に設計すると良いでしょう。
GuardDutyの活用範囲もどんどん増えているので、ぜひ活用してみてください。