{"id":"IL-0068","org":"Aqua Security","date":"2023-04-21","docs":[],"title":{"en":"Anonymous access to the Kubernetes API server used to plant a ClusterRoleBinding backdoor and a cryptominer DaemonSet","ko":"익명 요청을 허용한 쿠버네티스 API 서버로 공격자가 들어와 RBAC 로 백도어를 만들고, DaemonSet 으로 Monero 채굴기를 모든 노드에 띄웠다."},"domain":["kubernetes","security","aws"],"impact":{"scope":"an Aqua honeypot cluster; evidence of the same campaign on at least 60 other exposed clusters","users":"unknown","region":"unknown"},"review":{"written_by":"session","reviewed_at":null,"reviewed_by":null},"lessons":{"en":"Fixing an exposed API server is not enough once an attacker has been in: a ClusterRoleBinding to an attacker-created ServiceAccount keeps working after anonymous access is closed. Attackers name these objects and images after real Kubernetes components so they blend into the API audit logs and pass for legitimate deployments. Aqua recommends scanning clusters for vulnerabilities, exposed secrets and misconfigurations with a tool such as Trivy.","ko":"API 서버에 익명 접근을 허용하는 설정 실수 하나로 클러스터 전체를 내줄 수 있다. 공격자가 ClusterRoleBinding 으로 지속적인 접근 경로를 만들어 두면 잘못된 설정을 고친 뒤에도 계속 들어올 수 있다. 공격자는 system:controller: 로 시작하는 정상 구성 요소 같은 이름과 kube-controller-manager 를 닮은 이미지 이름으로 감사 로그와 사람의 눈을 피한다. Aqua 는 Trivy 같은 도구로 취약점, 노출된 Secret, 잘못된 설정을 찾으라고 권한다."},"related":[],"sources":[{"url":"https://www.aquasec.com/blog/leveraging-kubernetes-rbac-to-backdoor-clusters/","kind":"blog","license":"unknown","archived":null}],"summary":{"en":"The attacker came in through the API server, which let anonymous users make privileged requests. After listing secrets and looking around kube-system, the attacker checked whether the cluster was already infected, then tried to delete deployments that probably belonged to older or competing mining campaigns, to free CPU and avoid notice.\n\nFor persistence the attacker used RBAC (role-based access control): a new ClusterRole with near admin privileges, not tied to any namespace; a ServiceAccount kube-controller in kube-system; and a ClusterRoleBinding system:controller:kube-controller joining the two. With that binding the attacker keeps access even after anonymous access is turned off. One API request then created a DaemonSet that put the mining container on every node. The attacker also tried the AWS access keys found in the cluster to reach further into the cloud account.\n\nAqua named the attack RBAC Buster. The image had been pulled 14,399 times in the five months since it was uploaded, and Aqua found evidence of the same attacker on another 60 exposed clusters. Each of the image's three tags contained a binary kube-controller (MD5 2833c82055bf2d29c65cd9cf6684449a) that VirusTotal detects as a cryptominer, and the wallet in its configuration had already received 5 XMR.","ko":"Aqua Security 의 연구팀 Nautilus 는 공격자가 쿠버네티스 RBAC 를 악용해 백도어를 만든 첫 실제 사례를 찾았다. 잘못 설정된 쿠버네티스 클러스터를 조사하던 중 자사 허니팟에 들어온 공격을 기록하고 분석한 결과다. Aqua 는 이 공격에 RBAC Buster 라는 이름을 붙였다.\n\n공격자는 익명 요청을 받아들이는 API 서버로 들어와 Secret 과 kube-system 의 리소스를 조회하고, 이미 공격한 클러스터인지 확인하고, 다른 캠페인의 디플로이먼트를 지우려 했다. 그다음 관리자에 가까운 권한의 ClusterRole 과 kube-system 의 kube-controller ServiceAccount 를 만들고, 둘을 system:controller:kube-controller 라는 ClusterRoleBinding 으로 묶었다. 이렇게 해 두면 나중에 익명 접근을 막아도 공격자는 클러스터에 계속 들어올 수 있다. cluster-admin 을 새 사용자나 낯선 사용자에게 묶으면 알림이 울릴 수 있다. 하지만 이번 바인딩은 정상처럼 보이는 이름 덕분에 감사 로그에 묻혔다.\n\n공격자는 DaemonSet 으로 kuberntesio/kube-controller:1.0.1 이미지를 모든 노드에 띄워 Monero 를 채굴했다. 이 이미지는 다섯 달 전 Docker Hub 에 올라온 뒤 pull 횟수가 14,399번이었다. 이미지를 올린 계정 kuberntesio 는 정상 계정 kubernetesio 의 철자를 살짝 비튼 타이포스쿼팅이고, 이미지 이름도 컨트롤 플레인 구성 요소인 kube-controller-manager 를 흉내 냈다. 이 이미지의 세 태그에는 모두 kube-controller 바이너리와 설정 파일이 들어 있었다. 이 바이너리의 MD5 는 2833c82055bf2d29c65cd9cf6684449a 이고, VirusTotal 은 이를 암호화폐 채굴기로 탐지했다. 지갑 주소를 보면 공격자는 이미 5 XMR 을 캤다. 이 속도라면 워커 하나로 한 해에 5 XMR, 금액으로 200달러를 더 벌 수 있다. Aqua 는 같은 공격자가 활발히 공격한 흔적을 노출된 다른 쿠버네티스 클러스터 60개에서 더 찾았다."},"trigger":{"en":"An API server misconfigured to accept unauthenticated requests from anonymous users with privileges.","ko":"API 서버가 잘못 설정되어, 권한을 가진 익명 사용자의 인증 없는 요청을 받아들였다."},"severity":"unknown","symptoms":["unauthorized-access","resources-deleted"],"timeline":{"detected_after":null,"resolved_after":null},"date_kind":"published","detection":{"en":"Aqua recorded the attacker's API requests on its honeypot; planted AWS access keys raised a beacon when the attacker tried to use them.","ko":"Aqua 가 운영하는 쿠버네티스 허니팟에 들어온 공격을 기록하고 분석해 찾았다. 허니팟에 일부러 노출해 둔 AWS 액세스 키가 쓰이자 비컨 신호가 왔다."},"components":["kube-apiserver","rbac-service-account","registry"],"root_cause":"config-change","remediation":[],"action_items":[],"contributing":["monitoring-blind-spot"],"recurrence_of":null,"symptoms_text":{"en":"Aqua's research team Nautilus recorded the attack on one of its Kubernetes honeypots. What appeared in the cluster was a DaemonSet running the image kuberntesio/kube-controller:1.0.1 from Docker Hub on every node, using the nodes' CPU to mine Monero.\n\nThe names were chosen to look like part of Kubernetes: a ServiceAccount kube-controller in the kube-system namespace, a ClusterRole with near admin privileges, and a ClusterRoleBinding named system:controller:kube-controller. The image name kuberntesio/kube-controller is a typosquat of the legitimate kubernetesio account and imitates the control plane image kube-controller-manager. In audit logs and workload lists these look like normal components, unlike a new user bound to cluster-admin, which might raise an alarm.\n\nBefore that, the attacker listed secrets and the contents of kube-system, checked for an existing deployment named kube-controller, and tried to delete deployments in other namespaces, among them kube-secure-fhgxtsjh, kube-secure-fhgxt, api-proxy and worker-deployment. Later the same day, AWS access keys planted in the honeypot sent a beacon: the attacker had tried to use them against the cloud account.","ko":"Aqua 의 쿠버네티스 허니팟 클러스터에 공격이 들어왔다. 공격자는 Secret 목록을 조회하는 HTTP 요청 몇 개를 보내고, kube-system 네임스페이스의 리소스 목록을 조회하는 API 요청 두 개로 클러스터 정보를 모았다.\n\n공격자는 kube-controller 라는 디플로이먼트가 있는지 찾아 이미 공격한 클러스터인지 확인했다. 그리고 kube-secure-fhgxtsjh, kube-secure-fhgxt, api-proxy, worker-deployment 를 포함해 여러 네임스페이스의 기존 디플로이먼트를 지우려 했다. Aqua 는 공격자가 예전 캠페인이나 경쟁자의 캠페인을 꺼서 CPU 를 더 확보하고, 서버 자원이 바닥나 들킬 가능성을 줄이려 했다고 본다.\n\n다음으로 공격자는 관리자에 가까운 권한의 ClusterRole 을 만들고, kube-system 네임스페이스에 kube-controller 라는 ServiceAccount 를 만들고, 둘을 system:controller:kube-controller 라는 ClusterRoleBinding 으로 묶었다. 이 이름들은 정상 구성 요소처럼 보여서 API 감사 로그에 섞였고, 알림을 울리지 않았다.\n\n같은 날 클러스터 곳곳에 일부러 노출해 둔 AWS 액세스 키가 쓰였다는 비컨 신호가 왔다. 공격자는 이 키로 클라우드 계정에 더 접근하려 했다. 이어서 공격자는 API 요청 하나로 kuberntesio/kube-controller:1.0.1 이미지를 쓰는 DaemonSet 을 만들어 모든 노드에 컨테이너를 띄웠다."},"updated_at":"2026-11-08T19:10:31.893489Z","url":"https://benchlet.com/incidentlib/app/cases/IL-0068","org_slug":"aqua-security"}