カスタマーサクセス部の山﨑です。
GuardDutyは、AWS環境のセキュリティ監視を行う強力なサービスです。その中の一つであるGuardDuty Malware Protection for S3を活用することで、S3バケットにアップロードされたファイルに対して自動的にマルウェアのスキャンを実行し、潜在的な脅威を素早く検出することが可能になります。
本ブログでは、S3バケットにマルウェアを含むファイルがアップロードされた際に、この機能がどのように動作するかを実際に検証し、その結果を詳しく解説します。
おさらい
GuardDuty について
Amazon GuardDutyは、AWSの機械学習技術を活用し、継続的にデータを分析しながらセキュリティの監視を行うサービスです。GuardDutyは、脅威を検出するために、以下の6つのデータソースを分析します
- DNSクエリログ
- VPCフローログ
- CloudTrailイベントログ
- CloudTrail管理イベントログ
- CloudTrailのS3データイベントログ
- EKS監査ログ
これらのデータソースを使って、GuardDutyは機械学習技術を用い、セキュリティ上の脅威になりうるデータを検出します。そして、その脅威をリスクの度合いに応じて、HIGH(高)、MEDIUM(中)、LOW(低)という3つのレベルに分類して、検出結果として提供します。
検出結果はわかりやすく可視化され、詳細な情報とともに確認できるので、ユーザーはセキュリティ上の問題に迅速に対応することが可能です。これにより、GuardDutyはAWS環境のセキュリティを強化し、リスクに即座に対応できるようにします。
GuardDuty に関連する各種拡張機能
GuardDutyには下表の通り、様々な拡張機能が存在しています。本ブログは「Malware Protection for S3」に関する検証ブログとなります。
| 機能 | 説明 |
|---|---|
| S3 Protection | S3バケット内のデータに対する潜在的なセキュリティリスクを特定。CloudTrailのS3データイベントを分析し、オブジェクトレベルのAPI操作を監視 |
| EKS Protection | AWSアカウント内のAmazon EKSクラスターを保護。Kubernetes固有の脅威を自動的に検出し、セキュリティリスクを軽減 |
| Runtime Monitoring | EC2、ECS、EKSのランタイム動作を監視。ファイルアクセス、プロセス実行、ネットワーク接続などを可視化し、潜在的な脅威を検出 |
| Malware Protection for EC2 | EC2インスタンスのマルウェアスキャンを提供。エージェントレスで動作し、システムパフォーマンスに影響を与えずにマルウェアを検出 |
| Malware Protection for S3 | S3バケットに新しくアップロードされたファイルをスキャンしてマルウェアを検出。スキャン結果に基づいてオブジェクトにタグ付け可能 |
| RDS Protection | RDSインスタンスの疑わしいログイン動作や異常なログイン動作を検出。特にAurora MySQLとAurora PostgreSQLのログインアクティビティを監視 |
| Lambda Protection | Lambda関数の潜在的な脅威を検出。異常な動作を監視し、不正なアクセスや悪意のあるコード実行を特定。 |
Malware Protection for S3 とは?
Malware Protection for S3は、S3バケットにアップロードされたオブジェクトを自動的にスキャンし、マルウェアの存在を検出するセキュリティ機能です。この機能は、特に不特定多数のユーザーがファイルをアップロードする環境において、セキュリティを強化するために非常に効果的です。
Malware Protection for S3は、AWSが独自に開発したスキャンエンジンと、サードパーティベンダーのスキャンエンジンを併用して脅威を検出します。このスキャンはアップロードされたオブジェクトに対して行われ、ファイル形式を問わず、幅広い種類のマルウェアを検出可能です。
たとえば、暗号マイナーやランサムウェア、ウェブシェルなどの悪質なプログラムも見つけることができます。さらに、このスキャンエンジンは15分ごとにマルウェアのシグネチャリストを更新しているため、最新の脅威にも迅速に対応できます。
ユースケース
- ファイルアップロードのセキュリティ
- ユーザーやアプリケーションがS3にファイルをアップロードする際にリアルタイムでマルウェアをスキャンし、悪意のあるファイルを検出する。
- バックアップとアーカイブの保護
- 重要なデータのバックアップやアーカイブ時にスキャンを行い、過去のデータに潜むマルウェアを検出する
- データ共有の安全性確保
- 外部パートナーや顧客とデータを共有する際に、共有ファイルのマルウェアスキャンを行い、相手のシステムへの感染リスクを低減する
AWS利用料
S3のオブジェクトスキャンコストは、以下3つの指数に基づいて試算されます
- スキャンデータ容量:$0.1185 /GB
- 評価オブジェクト数:$0.282 /1,000個のオブジェクト
- オブジェクトへのタグ付け(タグ付け自体はオプション機能):$0.0065/1万タグ
1 か月間で、30,000 個のファイルアップロード、スキャンデータ総量が500 GB と仮定した場合の利用料は以下の通りです。
- スキャンデータ容量: 500GB × $0.1185/GB = $59.25
- 評価オブジェクト: 30,000個のオブジェクト ÷ 1,000 × $0.282 = $8.46
- タグ付け(オプション): 30,000タグ ÷ 10,000 × $0.0065 = $0.0195
- 合計 = $67.7295
諸注意
- Malware Protection for S3による検出結果はAWS Security Hubと統合されていないので、脅威の検出状況を確認する際は、GuardDutyコンソールを通じて行う
- スキャン可能な最大オブジェクトサイズは「5GB」
- Malware Protection for S3 を有効化できるS3バケットは最大で「25バケット」
その他、制限事項はAWS公式ドキュメントをご覧ください。
いざ検証
Malware Protection for S3 を設定する
まずは、GuardDuty のコンソール画面で「Enable(有効化)」をクリックします

次にスキャン対象のS3バケットおよび、スキャンスコープを設定します。今回はS3バケット内の全てのオブジェクトをスキャンスコープとします。
Malware Protection for S3 ではスキャン結果に応じて、S3オブジェクトに対してタグを付与することができるので今回は有効にしています。
実際に付与されるタグの詳細はAWS公式ドキュメントをご覧ください。

最後にIAMロールを設定します。GuardDutyがS3オブジェクトをスキャンする際、S3側でSSE-KMSで暗号化しているとKMSキーへのアクセス許可も必要になるため、今回は事前に以下IAMポリシー(malware-protection-exec-policy)を割り当てたIAMロール(guardduty-malware-protection-execution-role)を指定します。
malware-protection-exec-policy(クリックして展開)
{ "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:アカウントID: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:アカウントID:rule/DO-NOT-DELETE-AmazonGuardDutyMalwareProtectionS3*" ] }, { "Sid": "AllowPostScanTag", "Effect": "Allow", "Action": [ "s3:PutObjectTagging", "s3:GetObjectTagging", "s3:PutObjectVersionTagging", "s3:GetObjectVersionTagging" ], "Resource": [ "arn:aws:s3:::バケット名/*" ] }, { "Sid": "AllowEnableS3EventBridgeEvents", "Effect": "Allow", "Action": [ "s3:PutBucketNotification", "s3:GetBucketNotification" ], "Resource": [ "arn:aws:s3:::バケット名" ] }, { "Sid": "AllowPutValidationObject", "Effect": "Allow", "Action": [ "s3:PutObject" ], "Resource": [ "arn:aws:s3:::バケット名/malware-protection-resource-validation-object" ] }, { "Effect": "Allow", "Action": [ "s3:ListBucket" ], "Resource": [ "arn:aws:s3:::バケット名" ] }, { "Sid": "AllowMalwareScan", "Effect": "Allow", "Action": [ "s3:GetObject", "s3:GetObjectVersion" ], "Resource": [ "arn:aws:s3:::バケット名/*" ] }, { "Sid": "AllowDecryptForMalwareScan", "Effect": "Allow", "Action": [ "kms:GenerateDataKey", "kms:Decrypt" ], "Resource": "arn:aws:kms:ap-northeast-1:アカウントID:key/KMSのキーID", "Condition": { "StringLike": { "kms:ViaService": "s3.*.amazonaws.com" } } } ] }

S3 にファイルをアップロードしてみる
コンソール画面からS3へ直接ファイルをアップロードしても検証上は問題ありませんが、今回は以前から触ってみようと思っていた「Transfer Family SFTP Connector」を利用して、SFTPサーバー(EC2インスタンス)からS3にオブジェクトをアップロードしてみます。

正常なファイルをアップロード
SFTPサーバー(EC2インスタンス)にログインして、SFTP Connector 経由でS3へ「send-to-s3.txt」をPUTしてみます。
[sftpuser@ip-10-0-13-153 receive-dir]$ aws transfer start-file-transfer --region ap-northeast-1 --connector-id SFTPコネクターID --retrieve-file-paths /home/sftpuser/receive-dir/send-to-s3.txt --local-directory-path /バケット名 { "TransferId": "04bc8863-01da-42cb-8f84-43915da3a1e9" } [sftpuser@ip-10-0-13-153 receive-dir]$ [sftpuser@ip-10-0-13-153 receive-dir]$ aws transfer list-file-transfer-results --connector-id SFTPコネクターID --transfer-id 04bc8863-01da-42cb-8f84-43915da3a1e9 { "FileTransferResults": [ { "FilePath": "/home/sftpuser/receive-dir/send-to-s3.txt", "StatusCode": "COMPLETED" } ] }
S3バケットを確認すると、「send-to-s3.txt」が無事にアップロードされていました!

オブジェクトの中身を見ると、タグもきちんと付与されています!
今回は無害なファイルだったため、「NO_THREATS_FOUND」というタグ値が付与されていました。

異常なファイル(eicar)をアップロード
今回はテスト用の擬似ウイルスファイルとして、eicarファイルを利用します。
SFTPサーバー(EC2インスタンス)にログインして、SFTP Connector 経由でS3へ「eicar.com」をPUTしてみます。
[sftpuser@ip-10-0-13-153 receive-dir]$ aws transfer start-file-transfer --region ap-northeast-1 --connector-id SFTPコネクターID --retrieve-file-paths /home/sftpuser/receive-dir/eicar.com --local-directory-path /バケット名 { "TransferId": "924217b3-7c25-4a7a-aaaf-4743cc4824e4" } [sftpuser@ip-10-0-13-153 receive-dir]$ aws transfer list-file-transfer-results --connector-id SFTPコネクターID --transfer-id 924217b3-7c25-4a7a-aaaf-4743cc4824e4 { "FileTransferResults": [ { "FilePath": "/home/sftpuser/receive-dir/eicar.com", "StatusCode": "COMPLETED" } ] }
S3バケットを確認すると、「eicar.com」が無事にアップロードされていました!

オブジェクトの中身を見ると、タグもきちんと付与されています!
今回は擬似ウイルスファイルだったので、「THREATS_FOUND」というタグ値が付与されていました。

GuardDuty のFindingsでも検出結果が確認できました。

異常なファイル(eicar)へのアクセスを禁止する
先ほどの検証でeicarファイルはマルウェアファイルとして、Malware Protection for S3 が検知していました。
ユーザーをマルウェアファイルにアクセスさせたくないので、S3バケットポリシーでアクセスを禁止します。 以下はAWS公式ドキュメントに記載されているバケットポリシー例を転載したものです。
{ "Version": "2012-10-17", "Statement": [ { "Sid": "NoReadExceptForClean", "Effect": "Deny", "NotPrincipal": { "AWS": [ "arn:aws:iam::555555555555:root", "arn:aws:iam::555555555555:role/IAM-role-name", "arn:aws:iam::555555555555:assumed-role/IAM-role-name/GuardDutyMalwareProtection" ] }, "Action": [ "s3:GetObject", "s3:GetObjectVersion" ], "Resource": [ "arn:aws:s3:::amzn-s3-demo-bucket", "arn:aws:s3:::amzn-s3-demo-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-name", "arn:aws:iam::555555555555:assumed-role/IAM-role-name/GuardDutyMalwareProtection" ] }, "Action": "s3:PutObjectTagging", "Resource": [ "arn:aws:s3:::amzn-s3-demo-bucket", "arn:aws:s3:::amzn-s3-demo-bucket/*" ] } ] }
S3バケットポリシーを定義した上で、同ファイルにアクセスするとエラーになります。

<Error> <Code>AccessDenied</Code> <Message>User: arn:aws:iam::111111111111:user/sample-user is not authorized to perform: s3:GetObject on resource: "arn:aws:s3:::バケット名/eicar.com" with an explicit deny in a resource-based policy</Message> <RequestId>KMXC42CYMKAKM59K</RequestId> <HostId>RS7ojSvVbvSMaooK9ENaEPQPUzDXsKJ8Yhxf1L97Nov2VZbssHkZcmWN1h7CKzBjmEJr0ZpK5Zg=</HostId> </Error>
まとめ
今回の検証で、無害なファイルはもちろん、擬似ウイルスファイルも適切に検出し、S3オブジェクトにタグ付けが行われました。さらに、検出されたマルウェアファイルへのアクセスをバケットポリシーで制限することで、マルウェアの拡散を防ぐことも確認できました。
GuardDuty Malware Protection for S3は、特に複数のユーザーがS3へファイルをアップロードする環境において、S3バケットのセキュリティを大幅に向上させる強力なツールだと思いますので、是非利用をご検討ください。
山﨑 翔平 (Shohei Yamasaki) 記事一覧はコチラ
カスタマーサクセス部所属。2019年12月にインフラ未経験で入社し、AWSエンジニアとしてのキャリアを始める。2023 Japan AWS Ambassadors/2023-2024 Japan AWS Top Engineers