정책 리스크를 파악하십시오. 정책에 대한 질문을 일상 언어로 하십시오. 데모 신청하기 →

Published:

AWS에서 공격자 킬 체인 차단하기: IAM 역할

by FireMon

지난 1년 동안 클라우드 네이티브 기법으로 클라우드 내부의 보안 사고를 처리하는 구체적인 조언에 대한 관심이 크게 늘어나는 것을 보았습니다. 조직이 프로덕션 워크로드를 클라우드로 옮기면, 보안 담당자들은 그 기본 원리가 개념적으로는 유사하더라도 실제로는 상당히 다르다는 점을 오래지 않아 깨닫게 됩니다. 그러한 핵심 개념 중 하나가 바로 킬 체인으로, 공격자의 진행 과정을 설명하기 위해 Lockheed Martin이 처음 만든 용어입니다. 어느 한 고리라도 끊으면 공격 자체가 무너지므로, 이는 심층 방어와 사고 대응의 능동적 요소를 결합하는 접근과 잘 들어맞습니다.

클라우드 배포 환경에서는 네 가지 주요 공격 유형이 있으며, 각각 킬 체인이 다릅니다.

  1. 클라우드 플랫폼 자체에 대한 공격. 클라우드 제공업체의 근본적인 침해(클라우드 고객이 통제할 수 없는 영역)를 논외로 하면, 이러한 공격은 대개 클라우드 서비스의 잘못된 구성에 집중됩니다. S3 버킷을 공개로 남겨두거나, API Gateway에 권한 검증기를 설정하지 않거나, AWS 자격 증명을 GitHub에 노출하는 경우가 이 범주에 해당합니다.
  2. 클라우드에 고객이 배포한 리소스와 애플리케이션에 대한 공격. 이러한 전통적인 공격은 데이터 센터를 대상으로 하는 공격과 다르지 않습니다. 대표적인 예로는 웹 애플리케이션의 SQL 인젝션, 인터넷에 잘못된 포트가 열려 있는 취약한 서버가 있습니다. 계정/구독/프로젝트와 VPC 또는 가상 네트워크를 사용해 피해 범위를 제한한다면, 이러한 공격은 데이터 센터에서보다는 다소 제한적인 경향이 있습니다.
  3. 클라우드 관리자와 개발자를 겨냥한 공격. 다음번 침투 테스트를 진행할 때는 공격자가 개발자와 관리자를 대상으로 피싱을 시도해 보도록 하십시오. 공격자 입장에서는 클라우드 애플리케이션 자체를 뚫는 것보다 개발자 시스템에 접근하는 편이 훨씬 쉬운 경우가 많기 때문에, 이는 클라우드로 침투하는 가장 효과적인 경로 중 하나입니다. 이 주제는 추후에 다루겠으며, 지금은 “MFA는 나의 친구”라는 말로 시작하겠습니다.
  4. 복합 공격. 오늘 집중해서 살펴볼 범주입니다. 이러한 공격에서 위협 행위자는 클라우드에 배포된 무언가에 침입한 뒤 이를 발판으로 클라우드 관리 플레인으로 이동합니다. (개발자를 겨냥한 공격도 복합 공격으로 보는 시각이 있지만, 저는 이를 별도로 구분하는 편입니다.)

원칙적으로 저는 어떤 수준에서든 성공한 공격은 복합 공격으로 권한이 상승하거나 확산될 수 있다고 항상 가정하며, 그 시점에서는 관리 플레인 보안과 사고 대응이 최선의 방어책이 됩니다.

오늘은 가장 흔한 복합 공격 과정 중 하나에 초점을 맞추고, 킬 체인을 끊는 데 도움이 되는 탐지적 통제와 예방적 통제를 함께 정리해 보겠습니다. 세부 내용에 들어가기에 앞서, 이 글을 복잡한 문제를 지나치게 단순화한 것으로 받아들이지 마십시오. 지금부터 다룰 내용을 대규모로 관리하는 일은 방법을 잘 알고 있더라도 매우 어렵습니다.

앞으로 몇 주에 걸쳐 이러한 문제를 위해 특별히 설계한 첫 번째 Ops를 얼리 액세스 고객에게 제공할 예정이며, 그 이후 비교적 빠른 시일 내에 정식 운영 환경에도 적용될 것입니다.

AWS 복합 공격: IAM 역할 자격 증명 탈취

복합 공격에서 위협 행위자는 보다 전통적인 대상에 침입한 뒤 이를 발판으로 클라우드 관리 플레인으로 이동합니다. 이런 일이 발생하는 주요 경로는 세 가지입니다. 각 경우 공격자는 정적으로 저장된 자격 증명이나 일시적인 IAM 역할 자격 증명을 탈취하며, 이에 대해서는 잠시 후 설명하겠습니다.

  1. 인스턴스 또는 컨테이너의 직접 침해. 예를 들어 22번 포트를 열어 두어 공격자가 침입하거나 그 밖의 방법으로 셸 접근 권한을 획득하는 경우입니다.
  2. 서버 측 요청 위조(SSRF). 공격자가 (일반적으로) 웹 서버/서비스의 취약점을 악용해 셸 접근 권한 없이도 명령을 실행하는 경우입니다.
  3. Lambda 함수의 침해. Lambda에서는 셸을 획득할 수 없지만, 애플리케이션 결함이 있다면 여전히 코드 실행 취약점은 물론 임의 코드 실행에도 노출될 수 있습니다. 그 영향은 SSRF와 유사할 수 있습니다.

각 경우 공격자의 목표는 AWS 관리 플레인에 대한 자격 증명을 획득한 뒤 기존 권한을 활용하거나 권한을 상승시키는 것입니다. 권한 상승은 추후 게시물에서 다루기로 하고, 지금은 그 자격 증명이 무엇이며 남용을 어떻게 방지할 수 있는지에 초점을 맞추겠습니다.

대부분의 사람들은 정적 자격 증명을 알고 있습니다. AWS에서는 액세스 키와 시크릿 키가 이에 해당합니다. 이는 사용자 이름과 비밀번호와 비슷하지만 AWS API 호출에 사용됩니다. 현재 버전은 이러한 API 호출 시 HTTP 요청 서명을 위해 Signature 4로 알려진 암호화 절차를 사용합니다. 이를 사용자 이름과 비밀번호처럼 취급할 수 있으며, 또 그렇게 해야 합니다. 그리고 인스턴스나 Lambda와 같은 클라우드 리소스 내부에 절대 저장해서는 안 됩니다.

IAM 역할은 AWS를 처음 접할 때 더 까다롭습니다. 훌륭하면서도 무서운 존재입니다. AWS에서 IAM 역할은 사실상 세션에 사용할 권한을 담는 컨테이너입니다. IAM 역할이 훌륭한 이유는 그 자체가 자격 증명이 아니기 때문입니다. 역할을 수임(assume)하면 AWS가 시간 제한이 있는 세션용 자격 증명 세트를 제공합니다. 역할은 “AWS 내부 전용” 개념입니다. AWS 내의 리소스(인스턴스나 Lambda 함수 등)에 역할을 할당할 수 있으며, 그러면 해당 리소스는 정적으로 저장된 자격 증명 없이도 API 호출을 할 수 있습니다! 우리는 페더레이션 ID 연결, 인스턴스, Lambda 함수 및 AWS 내 다른 모든 서비스에 역할을 사용합니다. 액세스 키는 사실상 AWS 계정에 사용자를 생성할 때만 사용하며, 그 외에는 모두 역할을 사용합니다.

역할에는 네 가지 권한 유형이 연결되어 있습니다.

  1. 역할이 AWS 내에서 할 수 있는 작업. 이는 역할에 연결하는 권한 정책 그 자체입니다.
  2. 누가 또는 무엇이 역할을 사용할 수 있는지(신뢰 정책). 역할을 생성했다고 해서 아무나 또는 무엇이든 사용할 수 있는 것은 아니며, 이 정책은 예컨대 AWS 인스턴스나 특정 Lambda 함수로 접근을 제한합니다.
  3. 역할의 범위를 제한하는 권한 경계. 이는 다소 복잡하고 오늘 논의와는 관련이 없으므로 나중에 다루겠습니다.
  4. 세션을 위해 역할을 수임할 때, 해당 세션에 사용할 기존 권한의 일부만 지정할 수도 있습니다. 최소 권한 구현에 유용한 기능이지만, 역시 오늘 논의와는 크게 관련이 없습니다.

이 과정은 단계별로 살펴보면 설명하기가 더 쉽습니다. S3 버킷이나 Dynamo 데이터베이스에 접근해야 하는 애플리케이션이 있다고 가정해 보겠습니다. 저는 인스턴스용 IAM 역할을 생성하고 EC2 서비스가 그 역할을 사용할 수 있도록 신뢰 정책을 설정합니다. 그런 다음 인스턴스를 실행하고 역할을 할당합니다. AWS는 인스턴스를 실행하면서 해당 인스턴스가 역할을 수임하도록 합니다. 역할을 수임하면 세션이 열리고 액세스 키, 시크릿 키, 세션 토큰이 할당됩니다. 이후 AWS는 이 자격 증명을 1-6시간마다 교체하며, 인스턴스는 권한 정책으로 허용된 API 호출을 할 수 있게 됩니다.

자격 증명이 인스턴스 안에 저장되어 있지는 않지만, 인스턴스는 여전히 그 자격 증명에 접근할 수 있습니다. 내부에서 실행되는 코드는 S3와 Dynamo에 접근하기 위한 실제 API 호출을 하려면 자격 증명을 알아야 하므로, 메타데이터 서비스라고 하는 것이 요청 시 이를 제공합니다. 메타데이터 서비스는 인스턴스와 컨테이너의 구성 정보를 모두 담고 있는 AWS의 특수한 기능입니다. 예를 들어 서버가 자신의 IP 주소를 알 수 있다는 점은 상당히 중요합니다.

바로 여기서 공격이 시작됩니다.

메타데이터 서비스는 요청한 정보를 반환하는, 접근 가능한 하나의 URL에 불과합니다. curl 169.254.169.254/latest/meta-data/ 는 모든 기본 정보를 제공하며, curl 169.254.169.254/latest/meta-data/iam-security-credentials/ 경로를 사용하면 액세스 키, 시크릿 키, 토큰을 얻을 수 있습니다. (Lambda 기반 공격의 경우 모습이 전혀 다르고 curl 대신 SDK 코드를 사용하지만, 동일한 원리가 적용됩니다.)

그러면 공격자는 이 자격 증명을 복사해, 침해한 서버에 코드를 올려 실행할 필요 없이 다른 곳의 도구에 삽입해 사용할 수 있습니다. 또한 URL 기반이기 때문에 완전한 임의 코드 실행이 필요하지 않아 메타데이터 서비스가 더 광범위한 SSRF 공격에 노출됩니다. 자격 증명은 언젠가 만료되지만, 공격 방식에 따라서는 현재 자격 증명이 작동하지 않는 것을 확인한 뒤 다시 돌아와 새로운 자격 증명을 가져갈 수도 있습니다.

요즘 영리한 공격자들은 자신이 통제하는 AWS 계정에서 그 자격 증명을 사용합니다. Amazon이 알려진 주소 범위 밖에서 탈취·사용된 자격 증명을 탐지하는 도구를 갖추고 있기 때문입니다.

IAM 역할 탈취 킬 체인 차단하기

킬 체인을 정리해 보겠습니다. 공격자는 다음 단계를 거쳐야 합니다.

  • 역할 자격 증명에 접근할 수 있게 해주는 인스턴스, 컨테이너 또는 Lambda의 취약점을 찾아 악용합니다. 이는 거의 대부분 고객 측의 실수에서 비롯됩니다. 패치를 적용하지 않았거나, 잘못된 포트를 열어두었거나, 취약한 코드를 배포한 경우 등입니다.
  • 현재 역할 자격 증명을 추출합니다.
  • 자신이 통제하는 환경에서 허용된 API 호출을 성공적으로 실행합니다.
  • 허용된 IAM 역할의 권한 정책 범위 내에서 악의적인 행위를 수행합니다. 아마도 악의적인 행위일 것입니다. 대부분의 공격자가 여러분을 대신해 코드를 패치해 주지는 않을 테니까요.

다음 기법들은 이 체인의 서로 다른 고리를 끊을 수 있으며, 탐지적 통제와 예방적 통제가 함께 포함되어 있습니다. 부담스러워 보이더라도 걱정하지 마십시오. 제가 함께 일해 본 조직 중 이를 포괄적으로, 특히 대규모로 구현한 곳은 극히, 정말 극히 드뭅니다.

공격 체인의 여러 고리를 끊는 데 도움이 되는 6가지 기법

  1. 취약점 관리
  2. 리소스 제한을 포함한 최소 권한 IAM 권한 정책
  3. 권한 정책에 IP, VPC 또는 기타 요청 출처 조건부 제한 적용
  4. 정책이 적용된 서비스 엔드포인트와 리소스 정책 함께 사용
  5. HTTP User Agent 필터를 적용한 메타데이터 프록시 추가 (메타데이터 서비스 보호)
  6. 중복 역할 사용 방지

취약점 관리

  • 복잡도: 보통
  • 효과: 낮음
  • 확장성: 어려움
  • 유형: 탐지적 및 예방적

당연하게도, 출발점은 공격자가 측면 이동과 자격 증명 탈취에 활용할 수 있는 초기 취약점과 잘못된 구성을 모두 제거하는 것입니다. 이 항목에는 새롭거나 클라우드에 특화된 요소가 없기 때문에 복잡도는 보통으로만 평가했습니다. 다만 효과 또한 낮음으로 평가했는데, 지난 수십 년간 포괄적인 취약점 관리가 수많은 침해 사고를 막아내지는 못했기 때문입니다. 개념은 단순하지만 대규모 환경에서는 엄청나게 복잡합니다.

리소스 제한을 포함한 최소 권한 IAM 권한 정책

  • 복잡도: 보통
  • 효과: 높음
  • 확장성: 보통에서 어려움
  • 유형: 예방적

AWS의 IAM 정책은 기본적으로 거부이며, 명시적 허용 및 거부 구문을 포함합니다. 예를 들어 S3 버킷 읽기만 허용하는 정책을 작성할 수 있습니다. 또한 리소스 제한도 포함되어 있어, 허용 구문이 해당 역할에 읽기 API 호출 권한을 부여하더라도 리소스 제한을 통해 특정 버킷이나 객체만 읽도록 제한할 수 있습니다. 방어는 항상, 언제나 여기에서 시작해야 합니다. 제가 평가를 수행할 때마다 거의 모든 프로젝트에서 지나치게 많은 권한(API 호출)을 허용하면서 리소스 제한은 너무 적은 IAM 정책을 발견합니다. 해당 서비스가 Dynamo 데이터베이스에 접근해야 할 수는 있지만, 모든 테이블에 접근할 필요가 있을까요? 이 통제는 소규모에서는 구현하기가 그리 어렵지 않지만, 조직이 커지고 이러한 정책 결정을 내리는 사람이 많아질수록 대규모에서 일관성을 유지하기가 어려워집니다. 또한 누군가 새로운 권한이 담긴 정책을 해당 역할에 추가하는 경우에 대비해 명시적 거부 구문을 추가하는 것도 중요합니다. 권한은 누적되지만, 거부 구문은 모든 허용 구문을 무효화합니다.

권한 정책에 IP, VPC 또는 기타 요청 출처 조건부 제한 적용

  • 복잡도: 높음
  • 효과: 보통에서 높음
  • 확장성: 어려움
  • 유형: 예방적

IAM 정책은 IP 주소나 소스 VPC 등 다양한 옵션을 지원하는 조건부 구문을 지원합니다. 특정 역할이 애플리케이션 스택 내 특정 리소스에서만 API를 호출해야 한다는 것을 알고 있다면, 권한 부여를 해당 IP 주소나 서브넷으로 정확히 고정할 수 있습니다. 공격자가 자격 증명을 탈취해 다른 곳에서 실행하려 하면 API 호출은 실패합니다. 이는 정밀 유도 대형 해머와 같습니다. 개념은 쉽지만 실행은 어려운데, 다른 복잡한 요소들이 제대로 된 구현을 방해할 수 있기 때문입니다. 예를 들어 AWS 서비스에 대한 API 호출은 인터넷으로 직접 나가거나, NAT 게이트웨이를 거치거나, 서비스 엔드포인트(잠시 후 설명합니다)를 통해 내부적으로 라우팅됩니다. 탐지되는 IP 주소는 인터넷으로 나가는 API 호출 경로에 따라 달라집니다. 이 모든 것은 관리, 탐지(그리고 자동화)가 가능하지만, 먼저 관련 자료를 읽고 다양한 경우의 수를 확실히 이해하는 것이 좋습니다.

몇 가지 예시는 Netflix의 이 게시물 앞부분을 참고하십시오.

Lambda 함수를 VPC에서 실행하지 않는 한, 침해된 함수를 보호하는 데 이 방법을 사용할 수는 없습니다.

정책이 적용된 서비스 엔드포인트와 리소스 정책 함께 사용

  • 복잡도: 보통
  • 효과: 보통에서 높음
  • 확장성: 보통
  • 유형: 예방적

AWS에서 서비스 엔드포인트는 네트워크상의 분기점과 같아서, 원래 인터넷을 거쳐 AWS 서비스로 향하는 트래픽을 내부로 다시 라우팅합니다. 원래는 인터넷에 도달할 수단이 전혀 없는 완전한 프라이빗 서브넷에서도 특정 AWS 서비스에 접근할 수 있도록 하기 위해 만들어졌습니다. 엔드포인트는 IAM 정책과 매우 유사한 방식으로 접근과 작업을 제한하는 데 사용할 수 있는 정책을 지원합니다. 이 경우 엔드포인트 정책에 제한을 추가해 해당 엔드포인트 뒤에 있는 특정 리소스(S3가 가장 일반적인 예입니다)에 대한 접근 허용합니다. 어떤 버킷이 허용되는지 지정하면, 해당 서브넷의 다른 어떤 리소스도 그 서비스에 접근할 수 없습니다. 이를 IAM 정책의 최후 방어선으로 생각하십시오. 제한적인 정책이 적용된 서비스 엔드포인트를 사용하면, 누군가 실수로(또는 고의로) 역할에 필요 이상으로 넓은 접근 권한을 부여하더라도 서비스 엔드포인트 정책에서 허용하지 않은 대상에는 접근할 수 없습니다. 즉, 이제 리소스 접근을 허용해야 하는 세 개의 정책 계층이 생기는 것입니다:

  • 역할의 리소스 접근을 허용하는 IAM 권한 정책.
  • 사용된 역할의 권한과 관계없이, 요청이 엔드포인트를 통해 들어올 때 리소스 접근을 허용하는 서비스 엔드포인트 정책.
  • 승인된 IP 주소에서의 접근만 허용하도록 제한할 수 있는 버킷 또는 리소스 정책(리소스 종류에 따라 다릅니다).

Lambda 함수를 VPC에서 실행하지 않는 한, 이 역시 침해된 함수를 보호하는 데 사용할 수는 없습니다.

HTTP User Agent 필터를 적용한 메타데이터 프록시 추가(메타데이터 서비스 보호)

  • 복잡도: 높음
  • 효과: 보통
  • 확장성: 어려움
  • 유형: 예방적

지금까지의 모든 통제는 공격자가 역할 자격 증명을 탈취할 수 있다는 전제를 두고 있습니다. 그런데 공격자가 인가된 인스턴스나 컨테이너를 침해하더라도 자격 증명을 획득할 가능성 자체를 줄일 방법이 있다면 어떨까요? (이 기법은 Lambda 함수에는 적용되지 않습니다.) 새롭게 떠오르는 방법은 애초에 메타데이터 서비스에 대한 접근을 제한하는 것입니다. IPTables로 이를 시도한 사례들이 있었지만, 이는 인스턴스에서 실행 중인 코드에 필요한 기능까지 망가뜨릴 수 있습니다. 2018년 11월 AWS와 Netflix는 협력하여 AWS SDK에서 이루어지는 API 호출의 HTTP 헤더에 사용자 데이터를 추가하기 시작했습니다. 이는 SSRF에 대한 방어책입니다. 대부분의 SSRF 공격은 애플리케이션을 속여 공격자를 대신해 HTTP 요청을 보내게 하는 방식에 의존하는데, 이러한 요청은 보통 curl 같은 명령줄 도구나 다른 프로세스에서 발생하므로 AWS SDK가 넣어주는 사용자 데이터 헤더가 없기 때문입니다. 이를 구현하려면 해당 요청에 대한 프록시를 삽입해야 합니다. 인스턴스와 컨테이너를 위한 오픈소스 옵션들이 있으며, 트래픽을 가상 어플라이언스나 squid 프록시로 라우팅할 필요 없이 인스턴스에서 직접 실행되는 프록시도 있습니다.

공격자가 호스트 인스턴스를 침해하고 셸을 실행하는 경우에는 Roxy를 비활성화하거나 승인된 프로세스를 가로챌 수 있으므로 이 기법은 효과가 없습니다.

자세한 내용은 Netflix의 이 게시물에서 확인하실 수 있습니다.

중복 역할 사용 방지

  • 복잡도: 높음
  • 효과: 높음
  • 확장성: 높음
  • 유형: 탐지적

이 역시 Netflix 팀에서 나온 기법입니다. 이들은 AWS 내부에서조차 IAM 역할이 인가되지 않은 위치에서 사용되는 시점을 탐지하는 훌륭한 기법의 사용 방법을 공개했습니다. 링크된 게시물을 꼭 읽어보시기를 권합니다. 요약하자면, CloudTrail 로그와 몇 가지 다른 도구를 결합하여 어떤 인스턴스가 어떤 IP 주소에서 어떤 역할을 사용하고 있는지에 대한 테이블을 유지합니다. 그런 다음 다른 API 호출을 모니터링하여, 승인된 위치에서 사용 중인 역할이 동시에 새로운 IP 주소에서 재사용되는 시점을 찾아냅니다. 이 방법을 사용하면 조직 전체에서 사용 중인 모든 IP 주소를 알 필요가 없습니다. 사용 중인 항목의 테이블을 동적으로 구축하고, 해당 역할이 동시에 다른 곳에서 사용되는 것을 탐지하기 때문입니다. CloudTrail을 중앙화하면 로직도 중앙에서 실행할 수 있으므로 확장성이 매우 뛰어나며, 어차피 CloudTrail 중앙화는 일반적인 모범 사례입니다.

요약

이번에도 상당히 방대한 글이었으며, 모든 배포 환경에서 이 모든 옵션을 구현할 수 있으리라고는 기대하지 않습니다. 정리를 위해 IAM 역할 악용 킬 체인을 단계별로 살펴보겠습니다:

  • 역할 자격 증명에 접근할 수 있게 해주는 인스턴스, 컨테이너 또는 Lambda의 취약점을 찾아 악용합니다. 이는 거의 대부분 고객 측의 실수에서 비롯됩니다. 패치를 적용하지 않았거나, 잘못된 포트를 열어두었거나, 취약한 코드를 배포한 경우 등입니다.
    • 취약점 관리(애플리케이션을 위한 SASST, DAST 같은 도구 포함)와 클라우드 구성 평가(DisruptOps 같은 도구 또는 Prowler, CloudMapper 같은 오픈소스 도구 활용)가 첫 번째 방어선입니다.
  • 현재 역할 자격 증명을 추출합니다.
    • 메타데이터 서비스 보호 및 취약점 관리
  • 자신이 통제하는 환경에서 허용된 API 호출을 성공적으로 실행합니다.
    • 중복 역할 사용 탐지, 권한 정책에 IP, VPC 또는 기타 요청 출처 조건부 제한 적용, 정책이 적용된 서비스 엔드포인트와 리소스 정책 함께 사용
  • 허용된 IAM 역할의 권한 정책 범위 내에서 악의적인 행위를 수행합니다. 아마도 악의적인 행위일 것입니다. 대부분의 공격자가 여러분을 대신해 코드를 패치해 주지는 않을 테니까요.
    • 리소스 제한을 포함한 최소 권한 IAM 권한 정책

이 글이 이러한 유형의 공격이 성공할 가능성을 줄이는 방법을 더 잘 이해하는 데 도움이 되기를 바랍니다.

AWS IAM에서 공격자 킬 체인 차단하기 | FireMon