목표 1) EC2 메타 데이터의 취약점을 이용해서 AWS 서비스들을 이용하기

 

현재 마스터 노드 1대, 워커 노드 2대가 배포되어있다.

우선 워커 노드 1대 (nodes-ap-northeast-2a)의 EC2 메타데이터 (IMDSv2) 보안을 제거한다.

#
kops edit ig nodes-ap-northeast-2a
---
# 아래 3줄 제거
spec:
  instanceMetadata:
    httpPutResponseHopLimit: 1
    httpTokens: required
---

# 업데이트 적용 : 노드1대 롤링업데이트
kops update cluster --yes && echo && sleep 3 && kops rolling-update cluster --yes

잠깐!

IMDS (Instance MetaData Service)란 무엇일까?

다음 두 가지 중 한 가지 방법으로 운영중인 인스턴스의 메타 데이터에 접근할 수 있다.

 

1. Instance Metadata Service Version 1 (IMDSv1) - a request/response method

2. Instance Metadata Service Version 2 (IMDSv2) - a session-oriented method

 

기본적으로 IMDSv1와 IMDSv2 둘 다 사용, 혹은 IMDSv2만 사용할 수 있다.

https://bosungtea9416.tistory.com/entry/AWS-EC2-Metadata-%EA%B4%80%EB%A0%A8%ED%95%98%EC%97%AC
https://bosungtea9416.tistory.com/entry/AWS-EC2-Metadata-%EA%B4%80%EB%A0%A8%ED%95%98%EC%97%AC

 

여기서 IMDSv2 보안 해제를 한 워커 노드의 메타 데이터만 조회가 되는 것을 볼 수 있다.

d359로 끝나는 인스턴스는 nodes-ap-northeast-2c 인스턴스 그룹에 속하고, 이 인스턴스는 IMDSv2 보안 해제를 하지 않았다.

그리고 이 인스턴스 위에 올라가있는 pod은 뒷자리가 8rxh4로 끝나고, PODNAME1로 alias를 만들어놨다.

뒷자리 8rxh4 pod이 PODNAME1이고, 뒷자리 s79h6이 PODNAME2이다.
보다시피 IMDSv2 보안 해제를 하지 않은 인스턴스 위에 올라간 PODNAME1은 메타 데이터 조회가 안된다.

취약점)

서버에 IAM Role이 할당되어 있는 상태라면, IMDS의 IAM 메타 데이터를 이용해서 Credential을 발급받을 수 있다.

https://bosungtea9416.tistory.com/entry/AWS-EC2-Metadata-%EA%B4%80%EB%A0%A8%ED%95%98%EC%97%AC

이제 이렇게 탈취한 Credentials를 가지고 AWS의 서비스들을 마음대로 사용할 수 있다.

AWS CLI를 사용할 수도 있고 Python Boto3를 사용할 수도 있다.

의문)

Credentials를 발급받기만 하고, aws configure같은걸 해서 등록을 한건 아닌 것 같은데, 왜 boto3를 쓸 수 있지?

답) 아래 이미지 7번에서 Credentials를 발급했기 때문에 가능하다.

https://tech.cloud.nongshim.co.kr/2021/03/12/boto3%EA%B0%80-aws%EC%9D%98-%EC%9E%90%EA%B2%A9%EC%A6%9D%EB%AA%85credentials%EC%9D%84-%ED%99%95%EC%9D%B8%ED%95%98%EB%8A%94-%EC%88%9C%EC%84%9C-from-python/

 

  • 탈취한 Credentials를 이용해 boto3로 AWS 서비스를 이용해보자.

그러기 위해서는 일단 탈취한 IAM Role이 무엇을 할 수 있는지부터 봐야한다.

 

# 파드1에서 boto3 사용
kubectl exec -it $PODNAME1 -- sh
------------
cat <<EOF> ec2.py
import boto3

ec2 = boto3.client('ec2', region_name = 'ap-northeast-2')
response = ec2.describe_instances()
print(response)
EOF

python ec2.py  # aws ec2 describe-vpcs
exit
------------

이를 방지하기 위해서는, 아예 처음부터 1)EC2 메타데이터 접속을 제한하든지 2)AWS IRSA를 사용해야 한다.

 

목표 2) AWS IRSA (IAM Roles for Service Accounts)를 자세히 살펴보자.

EC2에 IAM Role을 할당해서 EC2 위에서 동작하는 애플리케이션이 AWS SDK를 사용할 수 있도록 하듯이,

AWS IRSA는 K8S의 Service Account 기능을 활용해서 K8S 클러스터 위에서 동작하는 Pod에 AWS IAM Role을 주기위한 방법이다.

 

오른쪽 그림이 AWS IRSA을 사용한 방법

참고) Service Account란?

https://kimjingo.tistory.com/156

잠깐, 그런데 Service Account는 AWS의 자원이 아닌데, 어떻게 이게 가능할까?

바로 OpenID Connect (OIDC)를 통해서 가능하다.

 

그럼 OIDC는 뭘까?

https://hudi.blog/open-id/

 

OIDC는 AWS, Google과 같은 IdP(Identity Provider)에 로그인할 수 있도록 도와주는 표준 인증 프로토콜이고,

OAuth 2.0을 확장하여 인증 방식을 표준화한다.

https://velog.io/@jakeseo_me/Oauth-2.0%EA%B3%BC-OpenID-Connect-%ED%94%84%EB%A1%9C%ED%86%A0%EC%BD%9C-%EC%A0%95%EB%A6%AC

OAuth 2.0은 어떤 데이터에 접근할 권한은 부여를(Authorization)을 해주는데, 그래서 그 권한을 갖고 있는 사람이 누구인지는 확인을 해주지 않는다. (Authentication) 그래서 OIDC는 Authentication을 해주는 레이어를 OAuth 2.0에 추가해서, 인증된 사용자에게 권한을 부여하고자 하는 것이다.

 

잠깐, OAuth 2.0이란?

사용자가 서드파티 애플리케이션에게 아이디와 비밀번호를 주지 않으면서도 사용자의 데이터에 접근할 수 있도록 권한을 부여하기 위한 프로토콜이다.

 

https://velog.io/@jakeseo_me/Oauth-2.0%EA%B3%BC-OpenID-Connect-%ED%94%84%EB%A1%9C%ED%86%A0%EC%BD%9C-%EC%A0%95%EB%A6%AC

 

Oauth 2.0과 OpenID Connect 프로토콜 정리

https://medium.com/better-programming/the-complete-guide-to-oauth-2-0-and-openid-connect-protocols-35ebc1cbc11a 이 글을 번역한 내용입니다.인증과 권한 관리를 위해 가장 널

velog.io

(정리가 매우 잘 된 블로그)

 

kops edit cluster
kops update cluster --yes

https://kops.sigs.k8s.io/cluster_spec/#service-account-issuer-discovery-and-aws-iam-roles-for-service-accounts-irsa

kops edit cluster를 통해 AWS Permissions(IAM Policy)를 임의의 Service Account에서 사용할 수 있도록 프로비저닝했다.

kops를 update한 후에, IAM-Identity Providers에 다음과 같은 OpenID Connect가 추가되었다.

 

 

그리고 S3 bucket에는 다음과 같은 파일들이 다운로드 되었다.

openid/ 폴더에 들어가면 v1/jwks 라는 파일이 존재한다.

 

잠깐, 위에서는 JWT라고 했는데 저장된 파일은 jwks라고 한다.

차이가 무엇일까?

 

https://minhan2.tistory.com/69

JWT와 JWK)

JWT : JSON Web Token의 약자로, 일반적으로 HTTP API 서버를 만들 때에 인증 방법으로 사용.

서버는 사용자가 로그인할 때 고유한 Token을 생성하고, 이를 사용자에게 알려주어 사용자가 다른 API를 사용할 때에 헤더에 이 Token을 넣으면, 자신이라는 것을 증명한다.

 

https://kaonsoft.tistory.com/6

 

그럼 JWT는 어디에 있을까?

https://tech.devsisters.com/posts/pod-iam-role/

Service Account를 생성하면, Secret이 생기고, 그 안에 JWT token이 들어간다.

 

 

본론으로 돌아오면,

k exec -it sa-irsa -- /bin/bash

EC2에 대한 접근은 가능하지만, 그 외에 접근은 모두 불가능하다.

 

 

아래 그림은 Pod 위에서 동작하는 App이 AWS S3 Bucket List를 가져올 때의 workflow다. (AWS 블로그 발췌)

 

https://aws.amazon.com/ko/blogs/containers/diving-into-iam-roles-for-service-accounts/

 

https://kim-dragon.tistory.com/279

  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기