この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
コンサル部のとばち(@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
します。
privileged-container.yml
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月現在のものになります。フォーマットなど今後変更になる可能性もあるのでご注意ください。
PrivilegeEscalation:Kubernetes/PrivilegedContainer
[
{
"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)でした。