На пентесте AWS-инфраструктуры финтех-компании в прошлом году мы нашли IAM-пользователя с единственным «лишним» разрешением -
iam:CreatePolicyVersion. Пользователь создавался для CI/CD-пайплайна, по документации считался readonly. Три команды aws-cli, пять минут - у этого пользователя AdministratorAccess на весь аккаунт. Админы были уверены, что всё закрыто. Таких кейсов за последние два года набралось достаточно, чтобы разложить повышение привилегий AWS IAM в рабочий формат: какие разрешения искать, что запускать, что увидит CloudTrail и где SCP не спасёт.Требования к окружению
- ОС: Linux, macOS или WSL2. Команды ниже - под bash
- aws-cli v2 - проверить
aws --version, настроить профиль:aws configure --profile target - Pacu - фреймворк для AWS exploitation (github.com/RhinoSecurityLabs/pacu, активно поддерживается). Установка:
pip install pacu - PMapper (Principal Mapper) - построение графов привилегий IAM. Установка:
pip install principalmapper - Сеть: доступ к AWS API (443/tcp на
*.amazonaws.com). В изолированных сетях - через HTTP-прокси - Стартовые права: валидные AWS Access Key ID + Secret Access Key с любыми IAM-разрешениями
.env, CI/CD secrets или публичные репозитории. На внешнем пентесте сначала нужен initial access: скомпрометированные ключи из утечек, bucket misconfiguration или эксплуатация веб-приложения с доступом к EC2 instance metadata (T1552.005, Credential Access).Разведка: от whoami до графа привилегий
Прежде чем пытаться повысить привилегии - нужно понять, кто ты и что можешь. В терминах MITRE ATT&CK это Cloud Account Discovery (T1087.004) и Cloud Service Discovery (T1526).Первая команда - всегда
aws sts get-caller-identity --profile target. Она возвращает ARN текущей сущности: user, role или federated session. Тип сущности определяет доступные векторы. Если ARN содержит :assumed-role/ - это STS-сессия с временными токенами, и часть техник (например, iam:CreateAccessKey) будет неприменима напрямую к исходной роли.Дальше - перечисление разрешений. Вручную:
aws iam list-attached-user-policies --user-name <USER>, затем aws iam get-policy-version --policy-arn <ARN> --version-id <VID> для чтения JSON каждой managed-политики. Для inline-политик: aws iam list-user-policies --user-name <USER>, затем aws iam get-user-policy --user-name <USER> --policy-name <POLICY>. Для групп - aws iam list-groups-for-user (T1069.003, Cloud Groups), затем аналогичные вызовы для group policies.На практике проще запустить модуль Pacu
iam__enum_permissions - он соберёт все прикреплённые и inline-политики автоматически. Результат - полный набор разрешений текущей сущности. Руками перебирать JSON по десяткам политик - занятие на час, Pacu делает это за секунды.Что искать: любые IAM-действия из семейства
iam:[I]Policy[/I], iam:Create[I], iam:Update[/I], iam:Delete[I], iam:Attach[/I], iam:Put*, [URL='https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_passrole.html']iam:PassRole[/URL], iam:AddUserToGroup. Хотя бы одно из них - и путь к IAM privilege escalation открыт.Визуализация графа: PMapper строит граф привилегий и показывает пути от текущей сущности до admin-уровня. Запуск:
pmapper graph create, затем pmapper query 'who can do iam:[I] with [/I]'. Экономит часы ручного ковыряния в JSON-политиках и сразу показывает, какие цепочки эскалации доступны. Без PMapper на аккаунте с 50+ ролями можно просидеть полдня и всё равно пропустить неочевидный путь.Три поколения IAM Privilege Escalation
По данным исследования Software Secured совместно с Sonrai Security, privilege escalation в облаке прошло три эволюционные стадии. Это не академическая классификация - она определяет, какие техники искать в конкретном аккаунте и что из защитных мер реально их остановит.
📚 Часть контента скрыта. Этот материал доступен участникам сообщества с рангом One Level или выше
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме
Ограничение всех техник первого поколения: каждая оставляет явный след в CloudTrail. GuardDuty генерирует alert для большинства IAM-модификаций по умолчанию. Быстро, грубо, шумно.
Удаление ограничений: Permission Boundary и Deny-политики
Применимость: среда с настроенными Permission Boundaries - зрелые AWS-аккаунты enterprise-уровня. Неприменимо к аккаунтам без boundaries.Этот вектор IAM misconfiguration часто упускают - он не добавляет разрешений, а снимает ограничения. Разница принципиальная: мониторинг обычно заточен на «кто что добавил», а не «кто что удалил». Согласно данным hackingthe.cloud:
iam:DeleteRolePermissionsBoundary / iam:DeleteUserPermissionsBoundary - удаление Permission Boundary. Если effective permissions ограничены boundary, после удаления identity-based policy начинает действовать в полном объёме. Реальный кейс: роль EC2-инстанса имела AdministratorAccess, но boundary сужал её до S3 и DynamoDB. У CI/CD-пользователя обнаружилось iam:DeleteRolePermissionsBoundary - IAM permission boundary bypass одной командой, и роль EC2 стала полноценным админом. Boundary выглядел как надёжная защита - до тех пор, пока кто-то не получил право его снять.iam:DeleteRolePolicy / iam:DeleteUserPolicy - удаление inline-политик с explicit deny (эти API работают только с inline policies). Если у роли широкий Allow и узкий inline Deny, удаление Deny расширяет эффективные разрешения.iam:DetachRolePolicy / iam:DetachUserPolicy - удаление managed-политик с deny-statements (эти API работают только с managed policies - другой механизм, другой API-вызов). Менее очевидный вектор, потому что защитники обычно мониторят добавление политик, а не их удаление.Service-Based Escalation: PassRole как ключевой примитив
Применимость: внутренний пентест, любой AWS-аккаунт с вычислительными сервисами (EC2, Lambda, Glue, CloudFormation). Особенно эффективен в средах с избыточно привилегированными сервисными ролями - а это подавляющее большинство production-аккаунтов.Если первое поколение техник - «изменить свои разрешения», то второе - «создать ресурс с чужими разрешениями и выполнить код от его имени». Ключевой примитив -
iam:PassRole: разрешение передать IAM-роль другому AWS-сервису. По данным Software Secured, это общий enabler для большинства service-centric escalation paths.PassRole + EC2: атакующий создаёт EC2-инстанс, передавая привилегированную роль через instance profile. После подключения - запрос кредов через metadata API (T1552.005):
Bash:
# Создание EC2 с привилегированной ролью
aws ec2 run-instances --image-id ami-0abcdef1234567890 \ # placeholder - заменить на актуальный AMI для вашего региона
--instance-type t2.micro \
--iam-instance-profile Name=AdminProfile \
--key-name my-key --profile target
# После SSH на инстанс - получение кредов роли
# IMDSv2 (по умолчанию с 2022 для новых инстансов):
TOKEN=$(curl -X PUT 'http://169.254.169.254/latest/api/token' -H 'X-aws-ec2-metadata-token-ttl-seconds: 21600')
curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/security-credentials/AdminRole
iam:PassRole для целевой роли + ec2:RunInstances + существующий instance profile с привилегированной ролью. На практике instance profiles создаются «с запасом» при настройке Terraform-модулей - и это основной вектор AWS роли повышение привилегий. Никто не возвращается сузить права, когда «и так работает».PassRole + Lambda:
iam:PassRole + lambda:CreateFunction + lambda:InvokeFunction - создание Lambda-функции с привилегированной ролью, код которой выполняет нужные API-вызовы. Не требует SSH-доступа, быстрее и тише EC2. Мой предпочтительный вектор, когда есть выбор.PassRole + CloudFormation:
iam:PassRole + cloudformation:CreateStack - стек наследует переданную роль и создаёт произвольные ресурсы с её правами. Через CloudFormation можно создать любой ресурс AWS - по сути это «iam:*» с дополнительным шагом.PassRole + Bedrock AgentCore (новый вектор): по данным hackingthe.cloud, комбинация
iam:PassRole + bedrock-agentcore:CreateCodeInterpreter + bedrock-agentcore:InvokeCodeInterpreter позволяет создать code interpreter с привилегированной ролью и выполнить произвольный код. Это escalation через IAM роли AWS третьего поколения - через AI-сервисы. Каждый новый AWS-сервис с compute-возможностями автоматически становится новой поверхностью для PassRole exploitation. AWS добавляет сервисы быстрее, чем команды безопасности успевают их покрывать.PassRole + Glue:
iam:PassRole + glue:CreateDevEndpoint - создание dev endpoint с привилегированной ролью и SSH-подключение. Альтернативно: glue:UpdateDevEndpoint без PassRole - подмена SSH-ключа на существующем endpoint для получения кредов связанной роли.Lateral Movement через дефолтные роли AWS
Отдельный класс cloud security misconfiguration - дефолтные IAM-роли, которые AWS-сервисы создают при первичной настройке. По данным исследования Aqua Security (опубликовано в мае 2025), сервисы SageMaker, Glue, EMR и Lightsail создавали роли с политикойAmazonS3FullAccess по умолчанию.Сценарий lateral movement AWS: атакующий компрометирует сервисную роль SageMaker (
AmazonSageMaker-ExecutionRole-<Date&Time>). Роль имеет полный доступ к S3. Через S3 атакующий модифицирует CloudFormation-шаблоны, EMR-скрипты или артефакты других сервисов - и двигается laterally через аккаунт, не эскалируя IAM-привилегии напрямую. Красота подхода - ни одного IAM API-вызова, чистый data plane. По данным Aqua, AWS уже изменил политики дефолтных ролей, но ранее созданные роли в существующих аккаунтах остаются уязвимыми.Ограничение: вектор работает только если дефолтные роли не были пересозданы и администратор не сузил политики вручную после обновления AWS. На свежих аккаунтах (2025+) этого уже нет.
Когда что применять: decision tree
| Имеющиеся разрешения | Техника | Шумность CloudTrail | Контекст |
|---|---|---|---|
iam:CreatePolicyVersion на свою managed policy | CreatePolicyVersion с admin JSON | Высокая | Внутренний пентест, быстрая эскалация |
iam:AttachUserPolicy с Resource * | Attach AdministratorAccess | Высокая | Внутренний пентест, быстрая эскалация |
iam:PassRole + lambda:CreateFunction + lambda:InvokeFunction | Lambda с привилегированной ролью | Средняя | Внутренний пентест, предпочтителен для stealth |
iam:PassRole + ec2:RunInstances | EC2 с привилегированным instance profile | Средняя | Внутренний пентест, нужен SSH-доступ |
iam:DeleteRolePermissionsBoundary | Удаление boundary у роли с широким Allow | Высокая | Enterprise-среда с boundaries |
iam:UpdateAssumeRolePolicy | Модификация trust policy для AssumeRole | Высокая | AWS STS AssumeRole к привилегированной роли |
Доступ к роли с AmazonS3FullAccess | Lateral через S3 к CloudFormation/EMR | Низкая | Аккаунт с дефолтными ролями сервисов |
iam:CreateAccessKey на другого пользователя | Генерация ключей привилегированного пользователя | Высокая | Когда нет IAM-мутационных прав на себя |
Приоритет выбора: сначала PassRole-вектора (средняя шумность), затем lateral через S3 (низкая шумность), в последнюю очередь - прямая модификация IAM-политик (высокая шумность, но гарантированный результат). На реальном пентесте обычно начинаю с Lambda - создание функций не вызывает подозрений в аккаунтах с активной разработкой.
Что засветится в CloudTrail: OPSEC при повышении привилегий
Каждый IAM API-вызов фиксируется в CloudTrail как management event. Отключить это невозможно. Но можно учитывать, что именно увидит SOC - и чего не увидит.Высокорисковые события (GuardDuty алертует по умолчанию):
CreatePolicyVersionсSetAsDefault: true- прямой индикатор escalationAttachUserPolicy/AttachRolePolicyсPolicyArnсодержащимAdministratorAccessCreateAccessKeyдля пользователя, отличного от вызывающегоDeleteRolePermissionsBoundary- редкое легитимное действие, почти всегда подозрительно
RunInstancesс IAM instance profile - легитимная операция, но в сочетании с PassRole к admin-роли подозрительнаCreateFunction+Invoke- паттерн «создать Lambda и сразу вызвать» нетипичен для production-процессов, хотя в dev-аккаунтах такое бывает
PutObject/GetObjectв S3 при lateral movement через дефолтные роли - требует data-level CloudTrail (S3 data events), который стоит дополнительных денег и требует явной активации. Большинство аккаунтов его не включают - слишком дорого при высоком объёме S3-операций
CreatePolicyVersion:
JSON:
{
"eventName": "CreatePolicyVersion",
"userIdentity": {
"arn": "arn:aws:iam::123456789012:user/ci-deploy"
},
"requestParameters": {
"policyArn": "arn:aws:iam::123456789012:policy/CIDeploy",
"setAsDefault": true
}
}
Защитные меры и их слепые зоны
Service Control Policies (SCP) - мощный механизм ограничения на уровне AWS Organization. SCP может запретить конкретные IAM-действия для всех аккаунтов. Проблема: по данным Software Secured, многие IAM-действия (iam:CreatePolicyVersion, iam:PutRolePolicy, iam:CreateAccessKey) не поддерживают resource-level ARN. Можно только полностью запретить или разрешить действие, без гранулярности по конкретным политикам или пользователям. Блокировка lambda:UpdateFunctionCode через SCP работает штатно, а iam:PutGroupPolicy - нет, потому что IAM API не предоставляет условных ключей для фильтрации. Грубый инструмент для тонкой работы.Permission Boundaries - ограничивают максимальный набор разрешений для IAM-сущности. Эффективны, но: требуют ручной настройки при создании каждой роли, и если у атакующего есть
iam:DeleteRolePermissionsBoundary - boundary удаляется одной командой. Защита ровно до тех пор, пока кто-то не может её снять.IAM Access Analyzer - обнаруживает ресурсы, доступные извне аккаунта, и выявляет неиспользуемые разрешения. Полезен для аудита, но не блокирует escalation в реальном времени. Инструмент для профилактики, не для лечения.
GuardDuty - детектирует аномалии в IAM-использовании: вызовы из нетипичных регионов, создание access keys. Покрывает прямые IAM-модификации, но service-based escalation (PassRole + Lambda) может проскочить, если паттерн совпадает с легитимным. Детект lateral movement через S3 требует отдельно включённых S3 data events - облачная безопасность AWS IAM на этом уровне зависит от бюджета на мониторинг.
За два года тестирования AWS-инфраструктур вижу устойчивый паттерн: компании, вложившиеся в SCP и Permission Boundaries, считают тему закрытой. На практике PassRole остаётся ахиллесовой пятой подавляющего большинства аккаунтов - потому что сервисные роли создаются через Terraform-модули и CDK-конструкты с defaults, которые никто не пересматривает. Aqua Security показала, что даже AWS-created дефолтные роли были избыточны - в managed-сервисах самого вендора.
Эволюция от прямой IAM-модификации к service-based escalation и дальше к AI-orchestration (Bedrock AgentCore) ускоряется: каждый новый AWS-сервис с compute-возможностями - новый PassRole-вектор. Через год-полтора основные находки на AWS-пентестах будут не в IAM-политиках, а в trust relationships между сервисами, которые не попадают в стандартные аудиты. SOC-командам стоит уже сейчас выстраивать детект не вокруг отдельных IAM-событий, а вокруг цепочек:
PassRole → CreateFunction → Invoke с привилегированной ролью - именно такие паттерны отражают реальную механику misconfiguration IAM политик в production.Проверьте свой аккаунт через
pmapper query 'who can do iam:[I] with [/I]'. Если граф показывает путь от CI/CD-пользователя до admin - у вас та же проблема, что и у той финтех-компании из начала статьи. На курсе WAPT эту цепочку - от разведки IAM до полной эскалации через PassRole - проходят в лабораторном окружении с реальными AWS-аккаунтами.