GuardDutyでECS on Fargateでランタイムセキュリティの脅威を検出してみた

目的・やりたいこと

Amazon GuardDuty の新機能、Amazon ECS および AWS Fargate でランタイムセキュリティの脅威を検出
コンテナのリスク対策にはこれまでEKS Runtime Monitoringなどがあったが、Fargateにはなかった。
今回のアップデートによって、ECS on Fargateでもコンテナのリスクへの対応が可能に

AWSサービス ECS on Fargate ECS on EC2 EKS on Fargate EKS on EC2
GuardDuty Runtime Monitoring ⭕️(今回の対象) △(プレビュー) ×
GuardDuty Malware Protection × ×

そこでECS on Fargateを対象とし、ランタイムセキュリティの脅威を検出する検証をしてみた。
ただ検知させるだけならいくらでも参考ブログはありますが、そこに至る過程でかなり苦労したので、他では省略されているその苦労をありのままに記載することで、初心者がECS on Fargateでランタイムセキュリティの脅威を検出できるようになることへの一助になればと思います。

対象者

ECS on Fargateでランタイムセキュリティの脅威を検出してみたい初心者

対象となる技術

  • GuardDuty(ランタイムモニタリング)
  • ECS on Fargate

条件(導入にあたっての前提事項)

  • 今回使用したタスクロール「ecsTaskExecutionRoke」にはあらかじめ必要な権限やポリシーが付与されているものとします。

参考URL

概要図

作業の流れ

事前作業

1.まずはこちらのハンズオンに従ってECS on Fargateを構築

dockerコンテナの確認

cloudpack-federation-admin:~/environment $ docker ps
CONTAINER ID   IMAGE         COMMAND                  CREATED             STATUS             PORTS                                   NAMES
8ea9c3a5c1cb   hello-world   "/bin/sh -c /root/ru…"   About an hour ago   Up About an hour   0.0.0.0:8080->80/tcp, :::8080->80/tcp   h4b-local-run

cloudpack-federation-admin:~/environment $ docker exec -it h4b-local-run /bin/bash              
root@8ea9c3a5c1cb:/# 

2.次にこちらの手順に従い、GuardDuty ECS Runtime Monitoringを有効化

ところが、[ランタイムカバレッジ]タブで[ECSクラスターのランタイムカバレッジ]欄を見ると、カバレッジステータスが「Unhealthy」に

「1個の問題を表示」をクリックしても、タスクに問題がありそうというくらいしかわからない

そもそもタスクのヘルスステータスが「不明」なのが問題


ヘルスステータスの詳細を見ると、「タスク内の重要なコンテナのヘルスチェックがまだ評価されているか、コンテナのヘルスチェックが定義されていません。」とのこと

と思ったが、タイムラグがあるだけで時間が経つとちゃんと認識してくれた。

これでひとまず準備は完了

検証手順

1.コンテナにログイン

cloudpack-federation-admin:~/environment $ docker exec -it h4b-local-run /bin/bash
Error response from daemon: Container 8ea9c3a5c1cbab2f094954a88aaca8ca5e4924db4c9bfb6a84f0b537ea7a6fd0 is not running
cloudpack-federation-admin:~/environment $ docker ps -a
CONTAINER ID   IMAGE         COMMAND                  CREATED        STATUS                     PORTS     NAMES
8ea9c3a5c1cb   hello-world   "/bin/sh -c /root/ru…"   23 hours ago   Exited (137) 9 hours ago             h4b-local-run
cloudpack-federation-admin:~/environment $ docker start 8ea9c3a5c1cb
8ea9c3a5c1cb
cloudpack-federation-admin:~/environment $ docker exec -it h4b-local-run /bin/bash
root@8ea9c3a5c1cb:/# 

コンテナが停止していたので再実行しました。

2.GuradDutyが検知してくれそうなコマンドを実行
ここでGuardDutyが検知してくれて、かつ安全無害なコマンドを実行しないといけません。検証環境といえども
候補は二つあります。

  • nslookup guarddutyc2activityb.com

公式に記載されているあらかじめ用意されているテスト用のドメイン

GuardDuty がこの検出タイプ(バックドア:EC2/C&CActivity.B!DNS)をどのように生成するかをテストするには、インスタンス ( Linuxの場合dig、Windows の場合をnslookupを使用) からテストドメインguarddutyc2activityb.comに対してDNSリクエストを作成できます。

  • nslookup pool.supportxmr.com

こちらのブログに記載のあるCryptoCurrency:EC2/BitcoinTool.B!DNSを検知してくれるドメイン

このドメインはモネロのマイニングプールの1つです。一応これ自体は正規なものなのでアクセスしても大丈夫だと思います。

これら二つともコンテナ上で実行してみる。nslookupするだけなので害はない。

cloudpack-federation-admin:~/environment $ docker exec -it h4b-local-run /bin/bash
root@8ea9c3a5c1cb:/# nslookup guarddutyc2activityb.com
Server:         10.0.0.2
Address:        10.0.0.2#53

Non-authoritative answer:
*** Can't find guarddutyc2activityb.com: No answer

root@8ea9c3a5c1cb:/# nslookup pool.supportxmr.com
Server:         10.0.0.2
Address:        10.0.0.2#53

Non-authoritative answer:
pool.supportxmr.com     canonical name = pool-hk.supportxmr.com.
Name:   pool-hk.supportxmr.com
Address: 139.99.124.170
Name:   pool-hk.supportxmr.com
Address: 139.99.125.38
Name:   pool-hk.supportxmr.com
Address: 139.99.123.196

前者は見つからなくて正解、後者はちゃんと回答がある。

3.GuardDutyの検出結果を確認


ご覧のように一応検知はしてくれているが、検出結果タイプに「EC2」、リソースも「Instance」になっている。これではECS on EC2によるEC2セキュリティの検知であって、今回の対象であるECS on Fargateによるランタイムセキュリティの検知ではない。

どうも調べてみると、今回の意図した結果を得るには、コンテナにシェルログイン(起動したECSタスクにECS Execでログイン)してコマンドを実行する必要があるらしい。

4.ECS Execの設定
そこで、公式ドキュメントUsing Amazon ECS Exec for debuggingに従い、ECS Execを実装します。
ところが、「Turning on ECS Exec for your tasks and services」に記載のコマンドを実行してもエラーが

cloudpack-federation-admin:~/environment $ aws ecs create-service \
>     --cluster h4b-ecs-cluster \
>     --task-definition arn:aws:ecs:ap-northeast-1:************:task-definition/h4b-ecs-task-definition:16 \
>     --enable-execute-command \
>     --service-name h4b-ecs-service2 \
>     --desired-count 1

An error occurred (InvalidParameterException) when calling the CreateService operation: The service couldn't be created because a valid taskRoleArn is not being used. Specify a valid task role in your task definition and try again.

これはECS integration sets TaskRoleArn: null, doesn't work with ECS Exec #2120のCodaBoolさんのコメント通りにやることでうまくいきました。単にタスク定義で「タスクロール」を設定すればよかったらしい。


タスクロールはデフォルトでは「なし」になっているので、ここでは下のタスク実行ロールと同じロールを付与。

再度チャレンジ

cloudpack-federation-admin:~/environment $ aws ecs update-service \
>     --cluster h4b-ecs-cluster \
>     --task-definition arn:aws:ecs:ap-northeast-1:************:task-definition/h4b-ecs-task-definition:17 \
>     --enable-execute-command \
>     --service h4b-ecs-service \
>     --desired-count 1 \
>     --force-new-deployment
{
    "service": {
        "serviceArn": "arn:aws:ecs:ap-northeast-1:************:service/h4b-ecs-cluster/h4b-ecs-service",
        "serviceName": "h4b-ecs-service",
        "clusterArn": "arn:aws:ecs:ap-northeast-1:************:cluster/h4b-ecs-cluster",
        "loadBalancers": [
〜略〜

5.念願のExecログイン!

cloudpack-federation-admin:~/environment $ aws ecs list-tasks --cluster h4b-ecs-cluster
{
    "taskArns": [
        "arn:aws:ecs:ap-northeast-1:************:task/h4b-ecs-cluster/0a5f2c7ef29947c3ab2c01cb8f477237"
    ]
}
cloudpack-federation-admin:~/environment $ aws ecs execute-command --cluster h4b-ecs-cluster \
>     --task 0a5f2c7ef29947c3ab2c01cb8f477237 \
>     --container apache-helloworld \
>     --interactive \
>     --command "/bin/sh"

The Session Manager plugin was installed successfully. Use the AWS CLI to start a session.


Starting session with SessionId: ecs-execute-command-0b66d5e4f32d71eda
# 

6.再度検知コマンドを実行

# nslookup pool.supportxmr.com
Server:         10.0.0.2
Address:        10.0.0.2#53

Non-authoritative answer:
pool.supportxmr.com     canonical name = pool-hk.supportxmr.com.
Name:   pool-hk.supportxmr.com
Address: 139.99.124.170
Name:   pool-hk.supportxmr.com
Address: 139.99.123.196
Name:   pool-hk.supportxmr.com
Address: 139.99.125.38

# nslookup guarddutyc2activityb.com
Server:         10.0.0.2
Address:        10.0.0.2#53

Non-authoritative answer:
*** Can't find guarddutyc2activityb.com: No answer

7.再度GuardDutyの検出結果を確認


検出結果に「Runtime」、リソースに「ECScluster」が入っていて意図通りの検知結果が得られました!

さらに詳細を見ると、EC2タイプには見られなかった「Containers」「ランタイムの詳細」という項目があります。

Eicarを検知できるか検証

Eicarの実行も検知できました!

# wget https://files.trendmicro.com/products/eicar-file/eicar.com
--2023-12-12 04:16:02--  https://files.trendmicro.com/products/eicar-file/eicar.com
Resolving files.trendmicro.com (files.trendmicro.com)... 23.37.117.19, 2600:140b:400:29a::1e79, 2600:140b:400:2b8::1e79
Connecting to files.trendmicro.com (files.trendmicro.com)|23.37.117.19|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 68 [application/octet-stream]
Saving to: ‘eicar.com’

eicar.com                                           100%[================================================================================================================>]      68  --.-KB/s    in 0s      

2023-12-12 04:16:02 (7.58 MB/s) - ‘eicar.com’ saved [68/68]

# ls
bin  boot  dev  eicar.com  etc  home  lib  lib64  managed-agents  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
# more eicar.com
(Eicarのコードなので念のためマスクしておきます)
# chmod +x eicar.com
# ./eicar.com
./eicar.com: 1: ./eicar.com: Syntax error: word unexpected (expecting ")")

Execution:Runtime/NewBinaryExecuted
コンテナで新しく作成、または最近変更されたバイナリファイルが実行されました。
デフォルトの重要度: Medium

機能: Runtime Monitoring

この検出結果から、コンテナ内で新たに作成、または変更されたバイナリファイルが実行されたことがわかります。実行時にコンテナを不変に保つことがベストプラクティスであり、バイナリファイル、スクリプト、またはライブラリはコンテナの存続期間中に作成または変更しないでください。新しく作成されたバイナリがコンテナ環境で実行されたことは非常に疑わしい状況です。この動作は、悪意のある攻撃者がワークロードにアクセスし、潜在的な侵害の一環としてマルウェアやその他のソフトウェアをダウンロードして実行したことを示しています。

所要時間

2時間

まとめ

今回のアップデートによって、GuardDutyでもECS on Fargateコンテナのランタイムセキュリティが検知できるようになりました。残るEKS on Fargateに対しても対応できるようになれば、コンテナ対策という意味では完璧ですね!更なるアップデートに期待です。
参考までに、GuradDuty、Prisma Cloud、Sysdigでのランタイム保護機能をECSで比較したものを載せておきます。