Ис­сле­дуя веб‑при­ложе­ние в рам­ках зак­рытого баг‑баун­ти BI.ZONE, я обна­ружил ошиб­ку в генера­ции UUID. Она давала неп­ривиле­гиро­ван­ному поль­зовате­лю дос­туп к фай­лам дру­гих людей. В статье я покажу, что такие нес­тандар­тные уяз­вимос­ти откры­вают­ся для тех, кто готов уйти в иссле­дова­ние с головой.
 

Proof of Concept

 

Ищем таргет и определяем вектор

Для пен­тесте­ра пра­виль­ный век­тор — глав­ный ресурс: без рабоче­го сце­нария не поможет даже най­ден­ная мно­гос­тупен­чатая уяз­вимость. На прак­тике мно­гие цепоч­ки ока­зыва­ются нере­али­зуемы­ми из‑за недос­татка информа­ции и общей слож­ности, поэто­му иссле­дова­тели час­то отка­зыва­ются от «тяжелых» кей­сов. Я же ста­раюсь брать­ся за слож­ные уяз­вимос­ти, и на этот раз имен­но такой ана­лиз поз­волил получить вос­про­изво­димые и цен­ные наход­ки.

Итак, при иссле­дова­нии сер­виса я заметил, что пос­ле заг­рузки фай­ла в хра­нили­ще нам выда­ется инте­рес­ный UUID, одна­ко его фор­мат меня сму­тил.

На пер­вый взгляд это не UUID: по стан­дарту он дол­жен пред­став­лять собой 128-бит­ную мет­ку, нап­ример, такую:

f81d4fae-7dec-11d0-a765-00a0c91e6bf6

Ве­роят­но, это UUID в какой‑то нес­тандар­тной фор­ме, нап­ример, с мета­информа­цией. Думаю, раз­работ­чик дол­жен знать о том, как стро­ятся иден­тфи­ика­торы фай­лов, поэто­му я решил прог­нать базовые энтро­пий­ные тес­ты.

 

Находим неслучайную последовательность

Я стал собирать иден­тифика­торы, что­бы сос­тавить выбор­ку для ана­лиза.

Структура первого полученного UUID
Струк­тура пер­вого получен­ного UUID

За­тем я сде­лал ряд зап­росов с раз­ной дель­той по вре­мени и нашел законо­мер­ность в пос­тро­ении UUID.

Второй UUID для того же файла с тем же содержимым
Вто­рой UUID для того же фай­ла с тем же содер­жимым
Третий UUID для файла с тем же именем, но пустым содержимым
Тре­тий UUID для фай­ла с тем же име­нем, но пус­тым содер­жимым

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

Я прог­нал серию зап­росов через Intruder в Burp Suite и быс­тро заметил кол­лизию в UUID: при срав­нитель­но неболь­шом сме­щении зап­росов хеши сов­падали. Кол­лизия — это приз­нак недос­татка энтро­пии в генера­ции иден­тифика­тора: даже если дефицит про­явля­ется толь­ко на корот­ком вре­мен­ном интерва­ле; этот факт дал мне реаль­ную точ­ку опо­ры для даль­нейше­го вос­ста­нов­ления логики фор­мирова­ния име­ни.

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

Я вос­поль­зовал­ся Burp Sequencer для ана­лиза боль­шого количес­тва токенов и самое инте­рес­ное, что я нашел — оче­вид­ное отсутс­твие энтро­пии для пов­торя­ющих­ся фраг­ментов и наличие боль­шого количес­тва ано­малий, свя­зан­ных с появ­лени­ем сим­волов.

О чем дол­жен сде­лать вывод ана­литик? Что сер­вер не пре­дос­тавля­ет никаких уни­каль­ных дан­ных, которые не были бы извес­тны нам на кли­енте. При генера­ции иден­тифика­тора фай­ла он исполь­зует вре­мен­ную мет­ку в качес­тве клю­чево­го парамет­ра, по которо­му раз­лича­ет иден­тичные фай­лы.

Для даль­нейше­го ана­лиза нам нуж­но как‑то заг­лянуть «внутрь» это­го UUID. Давай попыта­емся выяс­нить алго­ритм его генера­ции.

 

Восстанавливаем алгоритм генерации

Я пред­положил, что иден­тифика­тор не зависит от содер­жимого фай­ла и сге­нери­ровал нес­коль­ко UUID для фай­лов, которые отли­чались толь­ко дли­ной. К моему удив­лению, я получил еще более ясную струк­туру!

Здесь нас преж­де все­го инте­ресу­ет оди­нако­вая подс­тро­ка, которая фор­миру­ется в зависи­мос­ти от чис­ла, которое оста­ется при пол­ном делении на 5. Оставша­яся часть спра­ва тоже пов­торя­ется и обе эти час­ти раз­ные для фай­лов с раз­ными име­нами.

Пер­вое, что при­ходит в голову, ког­да обна­ружи­вают­ся такие законо­мер­ности, — алго­рит­мы кодиро­вания или сжа­тия. Так как изоб­ретать велоси­пед любят далеко не все, я пред­положил, что ответ сто­ит искать в том самом делении на 5 и пошел гуг­лить раз­ные вари­анты кодиро­вания.

Продолжение доступно только участникам

Материалы из последних выпусков становятся доступны по отдельности только через два месяца после публикации. Чтобы продолжить чтение, необходимо стать участником сообщества «Xakep.ru».

Присоединяйся к сообществу «Xakep.ru»!

Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее

  • Подпишись на наc в Telegram!

    Только важные новости и лучшие статьи

    Подписаться

  • Подписаться
    Уведомить о
    4 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии