AWS re:Inforce 2024にて、Amazon GuardDuty Malware Protection for Amazon S3 がリリースされましたので、早速検証してみました。
aws.amazon.com
aws.amazon.com
アップデート概要
GuardDuty Malware Protection の拡張機能で、選択した S3 バケットへの悪意のあるファイルのアップロードを検出
GuardDutyが有効になっていない場合、GuardDuty Malware Protection for Amazon S3機能のみの有効化もできる
スキャンしたオブジェクトにはGuardDutyMalwareScanStatusというタグが付与され、タグの値によって脅威と判定されたか分かる
タグの値は以下の通り
- NO_THREATS_FOUND : 潜在的な脅威を検出しなかった
- THREATS_FOUND : 潜在的な脅威を検出した
- UNSUPPORTED : 当該オブジェクトのスキャンをサポートしていない
- ACCESS_DENIED : オブジェクトにアクセスできない
- FAILED : マルウェアスキャンを実行できない
タグの詳細は以下のドキュメントにも記載があります
docs.aws.amazon.com
- 料金はオブジェクトのサイズと数による従量課金
料金は以下の通り
- 1カ月のファイルサイズにおいて $0.79 / GB
- 1カ月のファイル数において $0.282 / 1k
aws.amazon.com
GuardDutyの「S3のMalware Protection」から「S3のMalware Protectionを有効化」を押下します。
![](https://cdn-ak.f.st-hatena.com/images/fotolife/y/yuj1osm/20240613/20240613112150.png)
スキャン対象のS3バケットは「S3バケット内のすべてのオブジェクト」、タグ付けは「オブジェクトにタグを付ける」を選択します。
Malware Protection for Amazon S3機能のためのIAMロールを作成します。
「アクセス許可を表示」を押下します。
![](https://cdn-ak.f.st-hatena.com/images/fotolife/y/yuj1osm/20240613/20240613113042.png)
IAMロールに必要なポリシーが表示されるので、これらをコピーしておきます。
![](https://cdn-ak.f.st-hatena.com/images/fotolife/y/yuj1osm/20240613/20240613113144.png)
参考までにポリシーと信頼関係は以下のようになっています。
ポリシー
{
"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ロールを作成します。
エンティティタイプはカスタム信頼ポリシーとし、コピーした信頼関係をペーストします。
![](https://cdn-ak.f.st-hatena.com/images/fotolife/y/yuj1osm/20240613/20240613113819.png)
ポリシーはいったんロールを作成し後にインラインポリシーとして追加します。
ロール名を入力しロールを作成します。
![](https://cdn-ak.f.st-hatena.com/images/fotolife/y/yuj1osm/20240613/20240613113908.png)
インラインポリシーのアクセス許可で、コピーしたポリシーをペーストします。
![](https://cdn-ak.f.st-hatena.com/images/fotolife/y/yuj1osm/20240613/20240613114120.png)
ポリシー名を入力しポリシーを作成します。
![](https://cdn-ak.f.st-hatena.com/images/fotolife/y/yuj1osm/20240613/20240613114303.png)
S3のMalware Protectionを有効化の画面に戻り、作成したIAMロールを選択し、「有効にする」を押下します。
![](https://cdn-ak.f.st-hatena.com/images/fotolife/y/yuj1osm/20240613/20240613114357.png)
S3のMalware Protectionが有効化されました。
![](https://cdn-ak.f.st-hatena.com/images/fotolife/y/yuj1osm/20240613/20240613114534.png)
スキャン状況の監視ができるようです。
![](https://cdn-ak.f.st-hatena.com/images/fotolife/y/yuj1osm/20240613/20240613114649.png)
IAMポリシーではS3とEventBridgeへの権限がありました。
そこで、EventBridgeを確認してみると、「DO-NOT-DELETE-AmazonGuardDutyMalwareProtectionS3-<文字列>」というルールが作成されています。
イベントパターンとターゲットを見ると、S3バケットにオブジェクトが作成されたらguardduty-malware-protection-planが起動して、スキャンが行われる仕組みのようです。
![](https://cdn-ak.f.st-hatena.com/images/fotolife/y/yuj1osm/20240613/20240613172147.png)
![](https://cdn-ak.f.st-hatena.com/images/fotolife/y/yuj1osm/20240613/20240613172208.png)
S3バケットにeicarファイルをアップロードします。
ちなみに、S3のMalware Protectionが有効化したときに「malware-protection-resource-validation-object」というテストファイルも自動作成されているようです。
![](https://cdn-ak.f.st-hatena.com/images/fotolife/y/yuj1osm/20240613/20240613114809.png)
モニタリングを見ていると、スキャンされており感染判定されていることを観測できます。
![](https://cdn-ak.f.st-hatena.com/images/fotolife/y/yuj1osm/20240613/20240613115128.png)
eicarファイルには「GuardDutyMalwareScanStatus : THREATS_FOUND」というタグが付いており、潜在的な脅威を検出したと判定されていることが分かります。
![](https://cdn-ak.f.st-hatena.com/images/fotolife/y/yuj1osm/20240613/20240613115202.png)
ちなみに、有効化時に作られた「malware-protection-resource-validation-object」というテストファイルのタグを見てみると、「GuardDutyMalwareScanStatus : NO_THREATS_FOUND」というタグが付いており、潜在的な脅威と判定されなかったことが分かります。
![](https://cdn-ak.f.st-hatena.com/images/fotolife/y/yuj1osm/20240613/20240613135840.png)
検出結果の確認
それでは検出結果を見ていきます。
GuardDutyの「検出結果」を見ると、重要度「高」で検出結果タイプが「Object:S3/MaliciousFile」が検出されています。
![](https://cdn-ak.f.st-hatena.com/images/fotolife/y/yuj1osm/20240613/20240613171242.png)
詳細を見ると、検出理由やオブジェクトの情報が表示されています。
![](https://cdn-ak.f.st-hatena.com/images/fotolife/y/yuj1osm/20240613/20240613171451.png)
スキャン後にオブジェクトにタグ付けが行われるので、タグベースのアクセス制御 (TBAC) をバケットポリシーに仕込むことで、アクセス元からマルウェアを隔離できます。
docs.aws.amazon.com
ポリシー例があるので、S3バケットポリシーに設定します。
![](https://cdn-ak.f.st-hatena.com/images/fotolife/y/yuj1osm/20240613/20240613173237.png)
タグが「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バケットにアップロードします。
![](https://cdn-ak.f.st-hatena.com/images/fotolife/y/yuj1osm/20240613/20240613173626.png)
![](https://cdn-ak.f.st-hatena.com/images/fotolife/y/yuj1osm/20240613/20240613173639.png)
こちらは「GuardDutyMalwareScanStatus : NO_THREATS_FOUND」でした。
![](https://cdn-ak.f.st-hatena.com/images/fotolife/y/yuj1osm/20240613/20240613173653.png)
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の活用範囲もどんどん増えているので、ぜひ活用してみてください。