← 전체 글 IAM

세 가지 AWS 권한 상승 공격, CloudTrail 증거와 해결책

핵심 요약

  • AWS에서 권한 상승 공격은 주체가 가진 권한에서 한 번도 부여받지 않은 권한으로 넘어가게 하는 일련의 API 호출입니다. 호출 자체가 평범하기 때문에 눈에 잘 띄지 않습니다.
  • 실제 계정에서 반복해서 등장하는 체인은 세 가지입니다. iam:PassRole과 lambda:CreateFunction의 조합, iam:UpdateAssumeRolePolicy 후 sts:AssumeRole, 그리고 다른 사용자에 대한 iam:CreateAccessKey입니다.
  • 각 체인은 특정한 CloudTrail 이벤트를 남깁니다. 탐지란 그런 호출을 할 이유가 없는 주체에서 발생하는 해당 이벤트를 지켜보는 것이며, 요청 파라미터가 신호가 됩니다.
  • 각 체인에는 범위가 좁은 해결책이 있습니다. iam:PassedToService 조건, 권한 제거, 또는 특정 작업에 대한 Deny입니다. 대부분의 경우 정책 변경 하나로 충분합니다.
  • 탐지와 예방이 모두 필요합니다. CloudTrail은 호출이 일어난 뒤에 알려 줍니다. 경로를 미리 검증하면 애초에 어떤 주체가 그 호출을 할 수 있는지 알 수 있습니다.

AWS에서 권한 상승 공격은 주체가 보유한 권한에서 한 번도 부여받지 않은 권한으로 넘어가게 하는 일련의 API 호출입니다. 일반적인 의미의 익스플로잇은 없습니다. 호출은 관리자가 매일 사용하는 것과 같은 호출이며, 그래서 알아차리기 어렵고 열린 채로 남겨 두기 쉽습니다. AWS 권한 상승 맵은 이런 방식으로 사용될 수 있는 모든 권한을 나열합니다. 이 글에서는 가장 흔한 체인 세 가지를 골라 각각의 작동 방식, CloudTrail에 기록되는 내용, 그리고 체인을 차단하는 변경 사항을 보여 줍니다.

체인 1: Lambda에 역할 전달하기

CreateFunction iam:PassRole runs as role 01 Attacker principal 02 New Lambda 03 Passed role 04 Administrator
체인 1. iam:PassRole과 lambda:CreateFunction을 함께 보유한 주체는 함수를 만들고 그 함수에 특권 역할을 넘기며, 함수는 그 역할로 실행됩니다. 두 권한 모두 단독으로는 경계할 만한 것이 아닙니다.

권한. 특권 역할에 대한 iam:PassRole과 lambda:CreateFunction. 대개 lambda:InvokeFunction도 함께 필요하지만, 함수는 이벤트 소스를 통해 트리거될 수도 있습니다.

작동 방식. 공격자는 새 Lambda 함수를 만들고 특권 역할을 그 실행 역할로 전달합니다. 역할의 신뢰 정책이 lambda.amazonaws.com을 허용하므로 AWS는 이 전달을 수락합니다. 그런 다음 공격자가 함수를 호출하면, 그가 작성한 코드가 무엇이든 특권 역할의 권한으로 실행됩니다. 그 역할이 관리자라면 생성 한 번과 호출 한 번으로 계정은 공격자의 것이 됩니다. 같은 패턴이 EC2, ECS, Glue, CloudFormation, CodeBuild를 비롯해 전달된 역할을 받아들이는 모든 서비스에서 통합니다.

CloudTrail에 나타나는 것. lambda.amazonaws.com에서 발생한 CreateFunction 관리 이벤트로, requestParameters.role이 특권 역할의 ARN인 경우입니다. iam:PassRole 검사는 자체 이벤트를 생성하지 않으며, 전달 내용은 생성 호출의 파라미터에서 확인할 수 있습니다. 뒤이은 Invoke는 Lambda 데이터 이벤트이므로 트레일에서 Lambda 데이터 이벤트가 활성화된 경우에만 나타납니다. 이 설정은 기본적으로 꺼져 있으며, 바로 이런 이유로 켜 둘 가치가 있습니다. 둘 다 갖춰지면 신호는 두 이벤트의 짝입니다. 이전에 함수를 만든 적이 없는 주체가 고가치 역할을 연결한 함수를 만들고, 몇 분 안에 그것을 호출하는 것입니다. 데이터 이벤트가 없다면 신호는 생성 호출 자체와, 전달된 역할이 이후에 수행하는 API 활동입니다.

해결책. 전달 범위를 좁히세요. iam:PassRole 권한 부여에 iam:PassedToService 조건을 추가해 역할을 필요로 하는 서비스에만 전달할 수 있게 하고, 리소스 ARN의 와일드카드는 특정 역할로 바꾸세요. 주체가 역할을 전달할 필요가 전혀 없다면 권한을 제거하세요. 자세한 설명: Lambda에 역할 전달.

체인 2: 역할의 신뢰 정책을 다시 쓴 뒤 수임하기

권한. 특권 역할에 대한 iam:UpdateAssumeRolePolicy, 그리고 sts:AssumeRole.

작동 방식. 역할의 신뢰 정책은 누가 그 역할을 수임할 수 있는지 결정합니다. 그 문서를 다시 쓸 수 있는 주체는 자신을 신뢰할 수 있는 주체로 추가한 뒤 sts:AssumeRole을 호출해 역할의 임시 자격 증명을 받습니다. 원래의 신뢰 관계는 덮어쓰이는 순간 의미가 없어지므로, 이 수법으로 주체는 업데이트 호출이 닿는 계정 내 모든 역할을 장악합니다. 다시 쓴 신뢰 정책은 누군가 알아챌 때까지 그대로 남기 때문에, 이것은 권한 상승이면서 동시에 지속성 확보 수단이기도 합니다.

CloudTrail에 나타나는 것. iam.amazonaws.com에서 발생한 UpdateAssumeRolePolicy 이벤트로 requestParameters.policyDocument에 새 정책 문서가 담겨 있고, 그 뒤로 방금 추가된 주체가 같은 역할에 대해 일으킨 sts.amazonaws.com의 AssumeRole 이벤트가 이어집니다. 건강한 계정에서 신뢰 정책은 거의 바뀌지 않으므로, 배포 파이프라인 밖에서 발생한 UpdateAssumeRolePolicy 이벤트는 무엇이든 살펴볼 가치가 있으며, 계정 내부의 주체를 추가하는 이벤트라면 강한 신호입니다.

해결책. IAM 관리 경로가 아닌 모든 주체에서 iam:UpdateAssumeRolePolicy를 제거하고, 계정의 특권 역할에 대해서는 이 작업에 명시적 Deny를 걸되 배포 역할만 예외로 두세요. 자세한 설명: 역할 신뢰 재작성 후 수임.

체인 3: 다른 사용자의 액세스 키 생성하기

권한. 호출자 이외의 사용자에 대한 iam:CreateAccessKey.

작동 방식. 공격자는 다른 사용자의 이름으로 iam:CreateAccessKey를 호출해 그 사용자의 새 장기 액세스 키를 받습니다. 사용자의 비밀번호나 기존 키는 전혀 필요하지 않습니다. 그때부터 공격자는 그 사용자로서 API를 호출할 수 있고, 새 키는 비밀번호 재설정과 사용자의 다른 키 교체 이후에도 살아남습니다. 세 가지 중 알아차리기 가장 어려운 체인인데, 단 한 번의 호출로 오래 유지되는 자격 증명이 생기고 신원을 빼앗긴 사용자는 아무것도 보지 못하기 때문입니다.

CloudTrail에 나타나는 것. iam.amazonaws.com에서 발생한 CreateAccessKey 이벤트로, requestParameters.userName이 userIdentity의 신원과 다른 경우입니다. 그 불일치가 신호입니다. 사용자가 자기 자신의 키를 만드는 것은 정상입니다. 한 주체가 다른 사용자의 키를 만드는 일은 온보딩 스크립트 외에는 드물고, 스크립트의 역할은 쉽게 허용 목록에 넣을 수 있습니다. 이후의 사용은 피해 사용자가 새로운 소스 IP와 사용자 에이전트에서 API를 호출하는 형태로 나타납니다.

해결책. 신원 관리 경로가 아닌 모든 주체에서 iam:CreateAccessKey를 제거하고, 사용자가 자신의 키를 직접 관리해야 하는 경우에는 권한 부여 범위를 ${aws:username}으로 좁혀 사용자가 자기 자신의 키만 만들 수 있게 하세요. 자세한 설명: 사용자용 액세스 키 발급.

AWS에서 권한 상승을 탐지하는 방법

위의 세 체인에는 일반화할 수 있는 공통 패턴이 있습니다. 권한 상승은 평범한 이벤트를 남기지만, 그 파라미터는 이례적이고, 그런 호출을 한 이력이 없는 주체에서 발생합니다. CloudTrail에서의 탐지는 네 가지에 달려 있습니다.

첫째, CloudTrail은 모든 계정과 모든 리전에서 켜져 있어야 하며, 트레일은 워크로드가 쓸 수 없는 중앙 계정으로 전달되어야 합니다. 트레일을 비활성화하거나 삭제할 수 있는 공격자는 증거를 지울 수 있으므로, StopLogging과 DeleteTrail은 권한 상승 이벤트와 같은 감시 목록에 올려야 합니다.

둘째, 이벤트 이름만이 아니라 파라미터를 살펴보세요. CreateFunction 자체는 일상적이지만, 파라미터에 관리자 역할이 들어 있는 CreateFunction은 경보를 울릴 만합니다. 대상 사용자가 호출자와 다른 CreateAccessKey도 마찬가지입니다.

셋째, 주체별로 기준선을 잡으세요. 매시간 함수를 만드는 CI 역할과 1년 동안 IAM을 한 번도 호출하지 않은 개발자는 서로 다른 출처이며, 같은 이벤트라도 각각에서 나오면 의미가 다릅니다.

넷째, 이벤트를 짝지으세요. 권한 상승은 순서가 있는 과정입니다. 생성 후 호출, 신뢰 업데이트 후 수임, 키 생성 후 새로운 곳에서 사용하는 식입니다. 첫 번째 이벤트와 두 번째 이벤트를 짧은 시간 창 안에서 연결하는 규칙은 어느 한 이벤트만 보는 것보다 오탐이 훨씬 적습니다. Lambda, S3, DynamoDB 활동은 데이터 이벤트이므로, 짝지으려면 먼저 트레일에서 활성화해야 합니다.

탐지는 두 번째 방어선입니다

CloudTrail은 호출이 일어난 뒤에 알려 줍니다. 첫 번째 방어선은 어떤 호출이든 일어나기 전에 어떤 주체가 그 호출을 할 수 있는지 아는 것입니다. 즉 맵의 모든 체인을 가져와 계정의 실제 권한 부여, 곧 자격 증명 정책, 경계, SCP, 신뢰 정책, 조건에 비추어 판정하는 것입니다. 어떤 주체에 대해 허용으로 판정되는 체인은 입증된 경로이며, 해결책은 위의 변경 사항을 누군가 시도하기 전에 적용하는 것입니다. Pathbreak는 모든 계정에 걸쳐 읽기 전용으로 이 판정을 수행하고, 입증된 경로를 도달 대상 기준으로 순위를 매기며, 각 해결책이 배포된 후 이를 확인합니다. 무료 도구인 pathbreak-audit는 출발점으로서 단일 계정에서 어떤 주체가 이러한 권한을 보유하는지 나열합니다.

자주 묻는 질문

AWS에서 권한 상승 공격이란 무엇인가요?

AWS에서 권한 상승 공격은 주체가 부여받지 않은 권한을 얻게 되는 일련의 API 호출입니다. 예를 들어 자신이 생성할 수 있는 서비스에 특권 역할을 전달하거나, 역할의 신뢰 정책을 다시 써서 수임하거나, 더 높은 권한을 가진 사용자의 액세스 키를 생성하는 방식입니다. Pathbreak는 AWS 계정의 어떤 보안 주체가 이러한 호출을 할 수 있는지 검증합니다.

CloudTrail에서 권한 상승을 어떻게 탐지하나요?

각 체인이 만들어 내는 특정 이벤트를 지켜보세요. 예를 들어 파라미터에 특권 역할이 들어 있는 CreateFunction, AssumeRole이 뒤따르는 UpdateAssumeRolePolicy, 대상 사용자가 호출자와 다른 CreateAccessKey 등입니다. 주체별로 기준선을 잡고, 첫 번째 이벤트와 두 번째 이벤트를 짝지으며, 트레일은 워크로드가 수정할 수 없는 계정에 보관하세요. Pathbreak는 호출이 일어나기 전에 어떤 보안 주체가 그 호출을 할 수 있는지 보여 줌으로써 CloudTrail 탐지를 보완합니다.

iam:PassRole은 그 자체로 위험한가요?

그 자체로는 위험하지 않습니다. lambda:CreateFunction이나 ec2:RunInstances처럼 역할을 받아들이는 컴퓨팅 리소스를 만들거나 업데이트하는 권한과 결합되고, 대상 역할이 해당 서비스를 신뢰할 때 권한 상승 경로가 됩니다. iam:PassedToService와 특정 역할 ARN으로 전달 범위를 좁히면 그 경로가 사라집니다. Pathbreak는 경로를 검증할 때 각 역할 전달의 신뢰 정책과 조건을 확인합니다.

어떤 해결책이 가장 많은 권한 상승 경로를 제거하나요?

대부분의 계정에서는 특권 역할에 대한 iam:PassRole의 범위를 좁히거나 제거하는 것이 가장 큰 몫을 제거합니다. 수십 개의 서비스가 전달된 역할을 받아들이기 때문입니다. Pathbreak 랩 계정에서는 한 역할에 대한 단일 Deny가 4,087개 경로 중 3,893개를 제거했습니다. 올바른 첫 번째 변경은 입증된 경로가 어떤 주체를 거쳐 가는지에 따라 달라집니다.

관련 글

CloudTrail이 알려 주기 전에, 지금 여러분의 계정에서 어떤 주체가 이러한 호출을 할 수 있는지 확인하세요.

데모 신청 데모 보기