マルウェアに感染したインスタンスを自動隔離する

# はじめに
本記事は、[AWS Jr.Champions Adventcalendar 2024](https://qiita.com/advent-calendar/2024/japan-aws-jr-champions) 9日目の記事です。

みなさん、GuardDutyのMalware Protection機能はご存知でしょうか。本機能は、EC2やS3のマルウェアファイルを検出することができる機能です。セキュリティ界隈（というかエンジニア界隈）では、人手不足がもっぱらの課題となっています。そこで、今回はGuardDutyを利用してマルウェアに感染したEC2インスタンスを検出し、自動隔離する方法をご紹介します。

# GuardDuty Malware Protection for EC2とは
GuardDuty Malware Protection for EC2は、マルウェアに感染したEC2インスタンスを検知することができる、GuardDutyのオプション機能です。本機能では、EC2インスタンスにアタッチされたEBSボリュームをスキャンすることで、マルウェアを検出します。検出結果はGuardDutyのコンソールから確認することが可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3075801/0824d620-8c61-7a64-add9-787967f9bd30.png)

## マルウェアスキャンの起動方法
マルウェアスキャンを起動する方法は二つあります。

|  | GuardDuty実行型マルウェアスキャン | オンデマンドマルウェアスキャン |
|:--|:--|:--|
| スキャンの起動方法  | [「GuardDuty 実行型マルウェアスキャンを起動する検出結果」](https://docs.aws.amazon.com/ja_jp/guardduty/latest/ug/gd-findings-initiate-malware-protection-scan.html)が生成されると自動で起動 | ユーザーが任意のタイミングでスキャンを実行 |
| 個別設定の必要有無  | 個別に機能の有効化が必要  | GuardDutyが有効化されていれば追加設定は不要  |
| 次回スキャンまでの待ち時間  | 最後のGuardDuty実行型マルウェアスキャンから24時間  | 前回のスキャンの開始時刻から 1 時間 |
| 無料トライアル  | 30日間の無料トライアルが利用可能  | 無料トライアル期間はなし |
| スキャンオプション  | [ユーザー定義タグ付きのスキャンオプション](https://docs.aws.amazon.com/ja_jp/guardduty/latest/ug/malware-protection-customizations.html#mp-scan-options)を利用して、タグベースのスキャン制御が可能  | スキャン時にリソースARNを指定するためユーザー定義タグ付きのスキャンオプションは利用不可|

## マルウェアスキャンの仕組み
マルウェアスキャンの仕組みは次の通りです。スキャンが完了すると、EBSボリュームのスナップショットとレプリカボリュームは削除されます。スナップショットの保持設定をオンにすることで、マルウェアが検出された場合に、作成されたスナップショットを保持することが可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3075801/787e374d-f77a-9ffe-c5de-d211e5bd2798.png)

※GuardDuty実行型マルウェアスキャンのイメージです

:::note
マルウェアスキャンに利用されるエンジンでは、主にファイルベースの検出を行います。検出に利用されるシグネチャは15分間隔で更新されます。ファイルレスマルウェアの検出には、GuardDuty Runtime Monitoringを有効にする必要があります。
:::

## 料金
GuardDuty Malware Protectionでは、スキャンされたデータ容量（GB）あたりの課金が発生します。詳細は、[公式ドキュメント](https://aws.amazon.com/jp/guardduty/pricing/)をご確認ください。スキャンが起動しないかぎり課金は発生しませんので、是非有効にしておきたい機能です。

:::note warn
スキャン時にEBSスナップショットが作成されますが、スナップショットには別途料金が発生します。スナップショットの料金は、無料トライアル期間中にも発生しますので、注意してください。
:::

# マルウェアに感染したインスタンスを自動隔離する
今回は、GuardDutyによってマルウェアが検出されたときに、インスタンスを隔離する処理を考えてみます。インスタンスのセキュリティグループを隔離用のグループ（インバウンド/アウトバウンドの通信を不許可）に変更することがポイントです。処理の流れは、次の通りです。

* GuardDutyがマルウェアを検出したときにEvent Bridgeをトリガー
* Event BridgeからStep Functionsを起動
* Step FunctionsでEC2のセキュリティグループを変更しSNSで通知

## 隔離用セキュリティグループの作成
該当のVPCで隔離用のセキュリティグループを作成しておきます。本セキュリティグループではインバウンド/アウトバウンドルールは設定しません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3075801/09044540-e616-211b-8f6c-934386a14580.png)

## SNSトピックの作成
セキュリティグループを変更した後にSNSで通知するため、事前にSNSトピックを作成しておきます。サブスクリプションとして、通知先のEメールアドレスを設定しておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3075801/1343b2ff-9cc9-02d7-4c25-2e0b9eae90d0.png)

## Step Functionsの設定
Step Functionsは次の通り設定します。

```state.json
{
  "Comment": "State machine to handle GuardDuty EC2 malware findings",
  "StartAt": "UpdateSecurityGroup",
  "States": {
    "UpdateSecurityGroup": {
      "Type": "Task",
      "Resource": "arn:aws:states:::aws-sdk:ec2:modifyInstanceAttribute",
      "Parameters": {
        "InstanceId.$": "$.detail.resource.instanceDetails.instanceId",
        "Groups": [
          "<securityGroupId>"
        ]
      },
      "Next": "SendSNSNotification",
      "ResultPath": "$.updateResult"
    },
    "SendSNSNotification": {
      "Type": "Task",
      "Resource": "arn:aws:states:::sns:publish",
      "Parameters": {
        "TopicArn": "<SNS ARN>",
        "Message": {
          "finding_id.$": "$.detail.id",
          "finding_type.$": "$.detail.type",
          "instance_id.$": "$.detail.resource.instanceDetails.instanceId",
          "instance_name.$": "$.detail.resource.instanceDetails.tags[0].value",
          "severity.$": "$.detail.severity",
          "description.$": "$.detail.description",
          "action": "The instance has been quarantined",
          "status": "SUCCESS"
        }
      },
      "End": true
    }
  }
}
```
※「securityGroupId」、「SNS ARN」は各自の環境に合わせて設定してください

本ステートマシンでは、セキュリティグループの変更とSNSトピックをパブリッシュするため、下記の権限を付与しました。
```permission.json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ec2:ModifyInstanceAttribute"
            ],
            "Resource": [
                "arn:aws:ec2:*:<accountID>:instance/*",
                "arn:aws:ec2:*:<accountID>:security-group/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "sns:Publish"
            ],
            "Resource": "<SNS ARN>"
        }
    ]
}
```
※「accountID」、「SNS ARN」は各自の環境に合わせて設定してください

## Event Bridge ルールの作成
マルウェアを検知したときにトリガーされるEvent Bridgeのルールを作成します。[Malware Protection for EC2 の検出結果のタイプ](https://docs.aws.amazon.com/ja_jp/guardduty/latest/ug/findings-malware-protection.html)は複数ありますが、今回はExecution:EC2/MaliciousFileのイベントをトリガーの対象とします。イベントパターンは、次のように設定します。

```evenpattern.json
{
  "source": ["aws.guardduty"],
  "detail-type": ["GuardDuty Finding"],
  "detail": {
    "type": ["Execution:EC2/MaliciousFile"]
  }
}
```

ターゲットとして、上記で作成したStep Functionsステートマシンを設定し、自動で作成される実行ロールを選択してルールを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3075801/73d45b54-e3ae-a95a-e808-5752354c094f.png)

## 動作確認
実際に動作確認をしていきましょう。動作確認を行う前に、下記の前提が満たされていることを確認してください。

* GuardDuty実行型マルウェアスキャンが有効になっている
* テスト用のEC2インスタンスに隔離用以外のセキュリティグループが設定されている
* テスト用のEC2インスタンスが動作するVPCでVPCフローログが設定されている

今回は、テスト用のEC2インスタンスにEICARテストファイルをダウンロードしておきます。EICARテストファイルは、ウイルス対策ソフトのテストを実施するために作成された、疑似的なウイルスファイルです。テスト用の無害なファイルのため、安心して利用することができます。本ファイルは、[EICARの公式サイト](https://www.eicar.org/download-anti-malware-testfile/)からダウンロードすることができます。

マルウェアスキャンを起動するための検出結果を生成するため、[Tor Browser](https://www.torproject.org/)を利用します。Tor Browserは匿名ネットワークを経由してインターネットへアクセスする為のオープンソースのウェブブラウザです。Tor Browserでインターネットにアクセスすることで、[UnauthorizedAccess:EC2/TorClient](https://docs.aws.amazon.com/ja_jp/guardduty/latest/ug/guardduty_finding-types-ec2.html#unauthorizedaccess-ec2-torclient)が検出されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3075801/eb3463b3-0191-d047-f3e3-69d0dc6c4bd4.png)

:::note warn
実際の環境でUnauthorizedAccess:EC2/TorClientが検出された場合、EC2インスタンスが侵害されている可能性があります。そのため、すぐに調査することを推奨します。
:::

上記の検出結果が生成されると、すぐにマルウェアスキャンが開始されます。マルウェアスキャンの実施状況は、コンソール画面から確認が可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3075801/3bb3b1aa-b36b-b989-037e-4f51d48ef903.png)

マルウェアスキャンが完了すると、スキャン結果がInfectedとなりGuardDutyの検出結果が生成されます。EICARはテストファイルなので、(not a virus)と書いてありますね！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3075801/4402512a-b383-9dd0-9a99-479bb6c7deac.png)

少しすると、下記のようなメールが届きます。文章が改行されていないので少しわかりづらいですが、インスタンスID、インスタンス名、GuardDutyの検出結果名など有用な情報が記載されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3075801/e240b25f-39e0-2920-f227-f099eaf54783.png)


実際にマネジメントコンソールを確認すると、セキュリティグループが隔離用グループに変更されていることがわかります。

# さいごに
セキュリティの重要性はますます高まっています。そんな中、人がいないというのも切実な悩みでしょう。できるだけ自動化できるところは、自動化していきたいですね。

[AWS Jr.Champions Adventcalendar 2024](https://qiita.com/advent-calendar/2024/japan-aws-jr-champions)は続いていきますので、明日以降の投稿にも是非ご注目ください！！