Amazon EKS環境の特権コンテナ起動を検出するGuardDutyイベントを発生させてみた
コンサル部のとばち(@toda_kk)です。
先日、GuardDutyがAmazon EKSに対応し、EKSクラスターにおける脅威を検出できるようになりました。
検出できる脅威のタイプ(Finding Types)のうちPrivilegeEscalation:Kubernetes/PrivilegedContainerがあります。これは、EKSクラスターにおいて特権コンテナ(Privileged Container)が起動されたことを検出するイベントです。
実際にどんなイベントが検出されるのか確認したかったので、本記事では特権コンテナの起動手順について記載します。
特権コンテナとは?
特権コンテナ(Privileged Container)とは、実行されているホストコンピューター上においてroot相当の権限を持つコンテナのことです。
具体的には、通常のコンテナプロセスはホスト上のLinux Capabilitiesが制限された状態で実行されますが、特権コンテナでは全てのLinux Capabilitiesが有効になった状態で実行されます。
rootユーザーでのコンテナ実行とは異なりますので、ご注意ください。
なお、2022年4月現在、Fargateでは特権コンテナの実行をサポートしていません。EKSで特権コンテナを実行したい場合は、EKS on EC2環境のみとなります。
Privileged containers aren't supported on Fargate.
PrivilegeEscalation:Kubernetes/PrivilegedContainerの発生条件
AWS公式ドキュメントには、下記のように記載されています。
This finding informs you that a privileged container was launched on your Kubernetes cluster using an image has never before been used to launch privileged containers in your cluster. A privileged container has root level access to the host. Adversaries can launch privileged containers as a privilege escalation tactic to gain access to and then compromise the host.
EKSクラスターにおいて、これまで特権コンテナの起動に使用されたことのないイメージを使用して特権コンテナが起動されたときに、発生するようです。
EKSにおける特権コンテナの起動
前提として、EKSクラスターはすでに作成済みとします。eksctl
によるクラスター作成については、下記の記事をご参照ください。
今回はtest-eks
という名前でEKSクラスターを作成しておきます。
その上で、EKSクラスターで特権コンテナを実行するためには、下記のマニフェストファイルを作成してkubectl apply
します。
apiVersion: v1 kind: Namespace metadata: name: test-app --- apiVersion: apps/v1 kind: Deployment metadata: labels: name: test-app-deployment name: test-app-deployment namespace: test-app spec: replicas: 1 selector: matchLabels: app: test-app template: metadata: labels: app: test-app spec: containers: - image: nginx:latest name: test-app-container securityContext: privileged: true
Namespacetest-app
およびDeploymenttest-app-deployment
を作成するマニフェストとなっています。Deploymentでは、nginx:latest
をイメージとして使用してPodを実行します。
特権コンテナとして実行するためには、spec.template.spec.containers
のなかでsecurityContext.privileged
をtrue
で指定する必要があります。
- Privileged mode for containers | Pods | Kubernetes
- Configure a Security Context for a Pod or Container | Kubernetes
- SecurityContext v1 core | Kubernetes API Reference Docs
kubectl apply
コマンドを実行することで、マニフェストを適用します。
$ kubectl apply -f privileged-container.yml namespace/test-app created deployment.apps/test-app-deployment created
NamespaceやDeploymentなしで単にPodだけ起動したい場合は、上記のマニフェストファイルは使わずに下記のようにkubectl run
コマンドで--privileged
フラグを指定することで特権コンテナを実行できます。
$ kubectl run test-nginx --image=nginx:latest --privileged pod/test-nginx created
GuardDutyイベントの確認
上記のマニフェストファイルをapplyすると、EKSクラスターの監査ログ(Audit)からGuardDutyが特権コンテナの実行を検知し、下記のようなJSON形式のイベントが作成されます。
下記は2022年4月現在のものになります。フォーマットなど今後変更になる可能性もあるのでご注意ください。
[ { "AccountId": "123456789012", "Arn": "arn:aws:guardduty:ap-northeast-1:123456789012:detector/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/finding/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "CreatedAt": "2022-04-11T09:32:32.008Z", "Description": "A privileged container with root level access was launched on EKS Cluster test-eks. If this behavior is not expected, it may indicate that your credentials are compromised.", "Id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "Partition": "aws", "Region": "ap-northeast-1", "Resource": { "AccessKeyDetails": { "AccessKeyId": "ASIAXXXXXXXXXXXXXXXX", "PrincipalId": "", "UserName": "user-name", "UserType": "Unknown" }, "EksClusterDetails": { "Name": "test-eks", "Arn": "arn:aws:eks:ap-northeast-1:123456789012:cluster/test-eks", "VpcId": "vpc-xxxxxxxxxxxxxxxxx", "Status": "ACTIVE", "Tags": [ { "Key": "aws:cloudformation:stack-name", "Value": "eksctl-test-eks-cluster" }, { "Key": "alpha.eksctl.io/cluster-name", "Value": "test-eks" }, { "Key": "aws:cloudformation:stack-id", "Value": "arn:aws:cloudformation:ap-northeast-1:123456789012:stack/eksctl-test-eks-cluster/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" }, { "Key": "eksctl.cluster.k8s.io/v1alpha1/cluster-name", "Value": "test-eks" }, { "Key": "aws:cloudformation:logical-id", "Value": "ControlPlane" }, { "Key": "alpha.eksctl.io/eksctl-version", "Value": "0.90.0" } ], "CreatedAt": "2022-04-11T07:04:46.350Z" }, "KubernetesDetails": { "KubernetesUserDetails": { "Username": "kubernetes-admin", "Uid": "aws-iam-authenticator:123456789012:XXXXXXXXXXXXXXXXXXXXX", "Groups": [ "system:masters", "system:authenticated" ] }, "KubernetesWorkloadDetails": { "Name": "test-app-deployment", "Type": "deployments", "Uid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "Namespace": "test-app", "HostNetwork": false, "Containers": [ { "ContainerRuntime": null, "Id": null, "Name": "test-app-container", "Image": "nginx:latest", "ImagePrefix": "", "SecurityContext": { "Privileged": true } } ] } }, "ResourceType": "EKSCluster" }, "SchemaVersion": "2.0", "Service": { "Action": { "ActionType": "KUBERNETES_API_CALL", "KubernetesApiCallAction": { "RequestUri": "/apis/apps/v1/namespaces/test-app/deployments", "Verb": "create", "UserAgent": "kubectl/v1.22.4 (darwin/amd64) kubernetes/xxxxxxx", "RemoteIpDetails": { "City": { "CityName": "Chiyoda-ku" }, "Country": { "CountryName": "Japan" }, "GeoLocation": { "Lat": xx.xxxx, "Lon": xxx.xxxx }, "IpAddressV4": "xxx.xxx.xxx.xxx", "Organization": { "Asn": "1234", "AsnOrg": "XXXXXXXXXX", "Isp": "XXXXXXXXXX", "Org": "XXXXXXXXXX" } }, "StatusCode": 201 } }, "Archived": false, "Count": 1, "DetectorId": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "EventFirstSeen": "2022-04-11T09:32:03.976Z", "EventLastSeen": "2022-04-11T09:32:04.017Z", "ResourceRole": "TARGET", "ServiceName": "guardduty", "AdditionalInfo": { "Value": "{}", "Type": "default" } }, "Severity": 5, "Title": "Privileged container with root level access launched on the EKS Cluster.", "Type": "PrivilegeEscalation:Kubernetes/PrivilegedContainer", "UpdatedAt": "2022-04-11T09:32:32.008Z" } ]
同じイメージでは一度しか通知されないので注意
上述の通り、脅威のタイプがPrivilegeEscalation:Kubernetes/PrivilegedContainerのイベントの発生条件は、「これまで特権コンテナの起動に使用されたことのないイメージを使用して特権コンテナが起動されたとき」です。
そのため、一度このイベントを発生させたEKSクラスターにおいて同じイメージを使用して特権コンテナを実行したとしても、GuardDutyは特権コンテナの実行を通知してくれません。
また、今回はnginx:latest
で指定していましたが、別のタグを指定したとしても同様に通知されません。
発生済みのGuardDutyイベントを一度アーカイブした上で、同じイメージを使用して特権コンテナを実行しても、通知はされません。
別のEKSクラスターで同じイメージを使用して特権コンテナを実行した場合は、新たにGuardDutyイベントが発生してくれます。
つまり、あくまでも1つのEKSクラスターにおいて1つのイメージで特権コンテナが実行されたときに通知される、という点にご注意ください。
以上、コンサル部のとばち(@toda_kk)でした。