yuj1osm's tech blog

クラウドやセキュリティなど

Amazon GuardDuty Malware Protection for Amazon S3 がリリースされました

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

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) をバケットポリシーに仕込むことで、アクセス元からマルウェアを隔離できます。

docs.aws.amazon.com

ポリシー例があるので、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の活用範囲もどんどん増えているので、ぜひ活用してみてください。