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

Published:

AWS ExternalID 및 교차 계정 AssumeRole 접근 방어를 위한 고급 기법

by FireMon

지난달 Praetorian Security의 Kesten Broughton은 Amazon이 권장하는 교차 계정 연결 기법을 사용하는 서드파티 클라우드 보안 제품에 관한 훌륭한 연구를 발표했습니다 - 다수의 주요 벤더에서 발견된 AWS IAM Assume Role 취약점. 첫 문단은 해당 연구를 잘 요약하고 있습니다:

교차 계정 신뢰(cross-account-trust)에 관한 이 시리즈의 첫 번째 블로그에서는 90개 벤더를 조사한 결과를 제시하며, 그중 37%가 혼동된 대리자(confused-deputy) 공격을 방어하기 위한 ExternalId를 올바르게 구현하지 않았음을 보여줍니다. 추가로 15%의 벤더는 UI에서는 AWS 계정 연동을 올바르게 구현했으나 백엔드에서 ExternalId 파라미터를 제대로 검증하지 않아 해당 사이트 역시 취약했습니다. 마지막으로 AWS 교차 계정 역할 수임 신뢰(cross-account-assume-role trust)로 인해 노출되는 새로운 공격 표면을 논의합니다. 결론적으로 벤더와 고객은 역할 신뢰가 자사의 멀티 테넌트 SaaS 솔루션에 가장 적합한 신뢰 메커니즘인지 비판적으로 검토해야 합니다.

이 연구를 읽고 제가 처음 보인 반응은 "왜 누군가 이런 잘못된 결정을 내리는가"였지만, 실제로 "클라우드 보안 전문가"라는 개념 자체가 비교적 새로운 것이며, AWS가 혼동된 대리자 문제를 비교적 잘 설명하고는 있으나 제품이 고객과 접점을 갖기 전까지는 좀처럼 떠올리기 어려운 실무적 구현 이슈까지는 다루지 않습니다. AssumeRole을 사용하는 교차 계정 연결에는 명확한 엔지니어링 해법이 있지만, 적절한 위협 모델링 없이는 Kesten의 연구에 기록된 실수를 저지르기가 매우 쉽습니다.

DisruptOps는 초기 위협 모델링을 바탕으로 현명한 결정을 일찍 내린 덕분에 안전을 유지할 수 있었습니다. 다만 이번 연구에서 몇 가지 유용한 시사점을 얻어 보안 강화를 추가로 진행하고 있습니다. 또한 고객 환경에 대한 직접적인 쓰기 권한 없이도 대규모 자동화를 가능하게 하면서 이 문제의 상당 부분을 제거하기 위한 비공개 프로젝트도 진행 중입니다.

다만 해당 게시물과 크게 의견이 다른 부분이 하나 있습니다. 저는 정적 자격 증명과 볼팅(vaulting)을 사용하라는 권고보다는 언제나 자동 순환 자격 증명을 택하겠습니다. 다른 클라우드 제공업체에는 여전히 정적 자격 증명을 사용해야 하지만, 저희는 환경 내 어디에도 정적 자격 증명을 두지 않는 방법을 항상 모색하고 있습니다.

문제점

오늘날 다양한 유형의 애플리케이션이 클라우드 API에 직접 연결해야 합니다. S3 버킷에 접근하는 단순한 작업일 수도 있고, 완전 자동화된 클라우드 탐지 및 대응 플랫폼처럼 복잡한 것일 수도 있습니다(물론 그저 임의의 예시일 뿐입니다). 이러한 요청에는 일종의 자격 증명이 필요하며, 이는 정적(사용자 이름과 비밀번호, 또는 IAM 액세스 키와 시크릿 키처럼)이거나 동적입니다. 동적 자격 증명에는 시간 제한이 있는 토큰이나 기타 임시 속성이 포함됩니다.

클라우드 관리 플레인에 직접 접근할 수 있게 하는 정적 애플리케이션 자격 증명은... 좋지 않습니다. 사용자에 대해서는 MFA로 해결할 수 있지만, 그다지 가상이 아닌 클라우드 탐지 및 대응 플랫폼과 같은 자동화된 애플리케이션에는 도움이 되지 않습니다. 얼마 전 Amazon Web Services는 IAM 역할이라는 개념으로 이 문제에 대응했습니다. AWS의 역할은 본질적으로 권한을 담는 컨테이너이며, 두 가지 정책을 갖습니다. 컨테이너가 무엇을 할 수 있는지, 그리고 누가(또는 무엇이) 그 역할을 수임할 수 있는지입니다. 역할은 세션 기반이므로, 권한이 있는 주체가 역할을 수임하면 세션 기간(1시간에서 24시간) 동안 사용할 수 있는 자격 증명 집합(액세스 키, 시크릿 키, 세션 토큰)을 갖게 됩니다.

AWS의 역할은 외부 SAML 연결(사용자용), 내부 "신뢰된" 연결(다른 AWS 계정으로부터), 또는 AWS 서비스(EC2 인스턴스나 Lambda 함수 등)를 통해 수임할 수 있습니다. 따라서 인스턴스에서 코드를 실행하되 해당 인스턴스는 정적 자격 증명을 전혀 저장하지 않는 것과 같은 유용한 구성이 가능합니다. 이는 많은 골칫거리를 실제로 없애 줍니다.

직접 통제하지 않는 계정으로부터의 연결을 허용하는 것은 다소 다른 문제입니다. 특히 그 계정이 여러 고객을 대상으로 서비스하는 플랫폼이라면 더욱 그렇습니다. 그런 플랫폼은(네, 저희 같은 경우입니다) 수백 또는 수천 개의 다른 AWS 계정에 접근해야 합니다. 공격자가 플랫폼을 속여 엉뚱한 계정에서 무언가를 수행하게 만들 수 있다고 상상해 보십시오. 예를 들어 현재 사용자가 소유하지 않은 계정에 대해 구성 평가를 실행하는 경우입니다. 이것이 바로 혼동된 대리자 문제의 간략한 설명입니다. 대리자는 여러 계정으로부터 신뢰를 받고, 사용자는 대리자를 속여 현재 사용자가 결코 접근해서는 안 되는 계정에 대한 접근 권한을 얻습니다.

이에 대한 가장 현실적인 익스플로잇은 플랫폼이 사용자로 하여금 자신이 통제하지 않는 계정의 계정 ID를 입력해 프로필에 추가한 뒤, 플랫폼에 부여된 신뢰를 악용하도록 허용하는 경우입니다.

AWS는 이를 방어하기 위한 메커니즘으로 AWS ExternalID를 제공합니다. 이는 플랫폼 제공업체와 고객이 대역 외(out of band)로 교환하는 임의의 공유 비밀입니다. 이 ID는 고객 계정의 역할을 수임하려는 모든 요청에 전달되는 속성이며, 해당 계정의 역할 신뢰 정책에는 공유 비밀이 올바른지 확인하는 조건부 요구 사항이 포함됩니다. 이를 올바르게 구현하면, 공격자는 고객 계정의 공유 비밀을 설정하거나 알 수 없으므로 자신이 통제하지 않는 계정을 대리자에 임의로 추가할 수 없습니다.

다만...

어떤 방향인지 짐작하실 것입니다. Praetorian은 기본 AWS ExternalId를 사용하거나 고객이 계정 전체에 대해 고유하지 않은 ExternalId 값을 설정하도록 허용하는 다수의 제공업체를 확인했습니다. 또한 고객이 역할 신뢰 정책에서 External ID를 실제로 적용하고 있는지조차 검증하지 않는 제품도 발견했습니다. Praetorian은 교차 계정 역할에 대한 미흡한 보안으로 인해 혼동된 대리자 공격이 가능한, 실제로 악용 가능한 플랫폼들을 확인했습니다.

교차 계정 연결 강화

이는 모두 DisruptOps의 위협 모델링 과정에서 다룬 내용이므로 저희는 양호한 상태이지만, 개선을 위한 아이디어도 한두 가지 얻었습니다. Praetorian이 식별한 각 문제를 살펴보고 보안 강화를 위한 최선의 방안을 검토해 보겠습니다:

  • AWS ExternalID가 기본 설정을 사용함: 저희는 무작위 ExternalID를 사용합니다.
  • AWS ExternalID가 여러 고객 계정에 공유됨:저희는 고객 단위가 아니라 계정 단위로 무작위 ExternalID를 사용합니다.
  • AWS ExternalID가 열거 가능하거나 추측 가능함: 저희는 완전히 무작위이며 긴 AWS ExternalID를 사용합니다. API 속도 제한 덕분에 PRNG 선택에 대해서는 걱정하지 않습니다(암호학에 관심 있는 분들을 위해).
  • 고객이 자체 ExternalID를 설정할 수 있어 중복되거나 취약한 ExternalID를 사용할 수 있음: 저희는 고객이 자체 ExternalID를 설정하는 것을 지원하지 않습니다. 다만 이러한 요청은 분명히 있었습니다. 다른 제공업체들이 곤란을 겪은 지점이 바로 여기라고 생각합니다. 고객은 제품 프로비저닝을 직접 자동화하기 위해 이 기능을 원하지만, 이를 안전하게 수행하려면 ExternalID가 길이와 무작위성 요건을 충족하는지 검증해야 합니다. 적절한 검증이 이루어진다면 안전하게 구현할 수 있을 것입니다.
  • 플랫폼이 동일한 AWS 계정을 여러 번 프로비저닝하도록 허용함: 저희는 이를 허용하지 않습니다.
  • IAM 역할이 제공업체 계정의 단일 주체가 아니라 해당 계정의 모든 역할에 대해 허용됨: 이 글에서 다루지는 않았지만, 고객 계정의 "워커" 역할에 대한 접근을 계정 내 모든 역할에 부여할 수도 있고, 단일 리소스나 역할에만 부여할 수도 있습니다. 저희는 교차 계정 접근에 사용하는 특정 역할로 접근을 제한합니다.
  • IAM 역할 이름이 모든 고객 계정에서 동일함: 여기서의 위험은 본질적으로 사용자 이름(역할 이름)이 추측 가능하다는 점입니다. 다른 매우 근본적인 실수가 없는 한 저는 이를 위험으로 보지 않습니다. 한 가지 예로, 공격자가 역할 이름을 알고 있고 고객 계정에 접근할 수 있게 되면 역할 신뢰 정책에 자신을 추가한 뒤 그 권한을 사용할 수 있습니다(저는 사고 대응 교육 과정에서 이와 유사한 내용을 가르칩니다). 이는 잠재적 위험이지만 저희는 상당히 낮게 평가합니다. 공격자가 그 정도 수준의 접근 권한을 가지고 있다면 해당 계정의 어떤 역할이든 장악할 수 있을 것이기 때문입니다.
  • 제공업체가 ExternalID가 접근 조건으로 설정되었는지 검증하지 않음: 저희는 이 설정이 올바르게 적용되도록 보장하는 프로비저닝용 CloudFormation 템플릿을 고객에게 제공합니다. 특히 고객 요구 사항을 충족하기 위해 CloudFormation 이외의 프로비저닝 옵션을 계속 추가함에 따라, 해당 설정이 유지되는지 검증하는 기능도 추가할 예정입니다.

Kesten은 연결 보안을 위해 정적 자격 증명 모델과 제공업체 측의 우수한 볼팅 사용을 선호하는 것으로 보입니다. 개인적으로 저는 이에 동의하지 않으며, 기본적인 예방 조치를 따른다면 AWS 모델이 처음부터 더 안전하다고 생각합니다.

저희는 현재 Praetorian의 권고 사항 외에 두 가지 추가 예방 조치를 취하고 있습니다:

  • CloudFormation에서 ExternalID를 마스킹합니다: 저희는 CloudFormation 템플릿에서 ExternalID를 파라미터로 설정하면서 NoEcho 옵션을 지정합니다. 이렇게 하면 콘솔, 명령줄 도구, API에서 해당 값이 마스킹됩니다. 이는 IAM 권한은 없으나 CloudFormation 실행 권한을 가진 사람에게 값이 노출될 위험을 줄여 줍니다.
  • CloudFormation 템플릿에 대한 접근을 대상 계정으로만 제한합니다: 이는 프로비저닝 과정에서 누군가 끼어들어 ExternalID를 탈취할 위험을 줄여 줍니다.

ExternalID가 노출되더라도 문제가 되어서는 안 됩니다. 플랫폼은 대상 계정이 한 번만 등록되도록, 그리고 무작위 ExternalID로만 등록되도록 보장해야 합니다. 공격자가 역할 이름과 ExternalID를 알고 있더라도 플랫폼에 그 정보를 입력할 수 있는 곳이 없고, AWS 자체가 교차 계정 연결이 신뢰된 계정에서 시작되도록 강제하기 때문에 아무것도 할 수 없습니다. 이는 스푸핑할 수 있는 것이 아닙니다.

저희가 이 문제를 어떻게 처리하는지 보시고 각자의 도구에 적용할 아이디어를 얻으시길 바랍니다. 저는 계정 등록 및 무작위 ExternalID 요건을 AWS Organizations를 사용하는 경우에도 권장합니다. 자체 조직으로만 접근을 제한하는 조건을 추가하더라도 보안 수준이 낮은 계정에서 보안 수준이 높은 계정으로의 공격에 여전히 노출될 수 있기 때문입니다.

그리고 새로운 비공개 프로젝트 소식도 기대해 주십시오. 몇 달 안에 공개할 수 있을 것으로 보이며, 이런 종류의 문제에 있어 진정한 판도를 바꾸는 기술입니다.

AWS ExternalID 방어를 위한 고급 기법 | FireMon