Копаемся в файлах JS в поисках багов
Этичный Хакер
Сегодня у нас история о багах стоимостью 2000 долларов, найденных в JS-файлах.
Некоторое время я работал над этой целью и обнаружил несколько уязвимостей, о которых было сообщено и за которые я получил награду. Назовем эту компанию target.com, а ресурс, который я тестировал, — connect.target.com . Родительская компания target.com приобрела объект api.previous.com и теперь он называется connect.target.com.
Давайте объясню проще:
Target.comявляется родительской компаниейapi.previous.com— объект, приобретенныйtarget.com.connect.target.com— это новое имяapi.previous.com(используется как CNAME)
При выполнении «dig connect.target.com», он показываетapi.previous.comв CNAME.
Первый баг
Я несколько раз искал connect.target.com в wayback архиве. Я прочитал все доступные файлы JS и получил URL-адреса, но ничего не показалось мне достаточно интересным. В этот момент искать было нечего, и через несколько дней я планировал сменить цель. Тогда мне пришла в голову мысль, почему бы не проверить запись CNAME в веб-архиве. Я быстро запустил waybackurl на api.previous.com, который является записью CNAME для connect.target.com.
Он извлек множество URL-адресов и JS-файлов и я начал их анализировать. Через несколько часов нашелся тяжелый JS-файл вида:
https://web.archive.org/web/20190721202446js_/https://api.previous.com/static/js/app.54f65e8a5f2e21fbf999.js.
Файл был слишком большим для анализа вручную, поэтому вместо этого я начал искать рабочий функционал внутри. Был обнаружен запрос:
PUT /api/v1/campaigns/action/cancel?campaign_id=768653 HTTP/2
Я быстро проверил его из обычной учетной записи. Это была конечная точка API, которая используется для отмены созданной вами компании.
Теперь, я попытался отменить создание компании другого пользователя, изменив campaign_id=768653, но она была должным образом защищена и проверена. Нельзя навредить другим клиентам. Но подождите минутку!! Я заметил что-то в HTTP ответе. Похоже, это метаданные учетной записи, которой принадлежит этот идентификатор компании. После некоторого изучения я обнаружил, что конечная точка верно проводила валидацию данных, и нельзя было отменить компании других клиентов, но эта конечная точка пропускала некоторые метаданные других учетных записей клиентов. Все, что нужно, это изменить campaign_id= в запросе, что приведет к утечке данных клиента, которому этот campaign_id принадлежит.
Утечки данных пользователей, которым принадлежат campaign_id , состоят из:
AccountId
AccountUid
SubAccountId
SubAccountUid
ProductCampaignId
CampaignStatusId
CampaignName
ScheduledAt
Эти метаданные не были настолько конфиденциальными и, вероятно, имели бы среднюю степень серьезности. Мне нужно было найти способ повысить серьезность этой уязвимость. Я вспомнил, что в этой программе поиска уязвимостей не принимают отчеты с IDOR, имеющим неугадываемые или неперебираемые идентификаторы. Поскольку идентификаторы учетных записей невозможно угадать, то их нельзя было использовать, и поэтому они были помечены как out of scope. Единственным способом использования IDOR была утечка UID и GUID где-то в ответе сервера.
Можем их получить? Да. Метаданные, просочившиеся в PUT /api/v1/campaigns/action/cancel?campaign_id=768653 HTTP/2, содержат AccountUid. Теперь, когда у меня есть AccountID, я могу проэксплуатировать IDOR. Все, что мне нужно, это найти функционал в котором используется GUID или AccountID. Я быстро нашел две функции, уязвимые для IDOR:
- Злоумышленник может изменить любые права пользователя с
userнаadmin. - Злоумышленник может обновить информацию профиля других клиентов.
Я добавил IDOR в отчет об уязвимости, чтобы показать влияние от утечки метаданных. Отчет получил высокую степень серьезности и мне заплатили 777 долларов.
Второй баг
Я начинаю копаться в JS-файле в поисках дополнительных функций и возможностей. В текущей версии connect.target.com было отредактировано множество конечных точек и функций. И в один прекрасный момент я наткнулся в JS-файле на:
/api/v1/api-keys/"+a.ApiKey,method:"PUT",body:a})
Эта конечная точка предназначена для обновления информации о вашем API ключе, то есть имени. Я отправил PUT запрос на /api/v1/api-keys/[api-keyID], и он обновил информацию о моем API ключе. Я попытался обновить чужой API, изменив идентификатор ключа /api/v1/api-keys/[Victim-apiKeyID], но тщетно. Запрос был правильно обработан, и получен ответ 404. Я меняю метод запроса на «GET», например GET /api/v1/api-keys/45432, чтобы увидеть, что он извлекает.
К моему удивлению, он отобразил API-ключ жертвы. Серьезно? — спросил я себя. Какое-то время я не мог в это поверить. Я попытался еще раз, указав API-key ID моей другой учетной записи, и он также отобразил ключи API этой учетной записи.
Злоумышленник может просто запустить Intruder на API-keyID, и он будет отображать все API-ключи клиентов с этим идентификатором. Я немедленно сообщил об уязвимости, и программа очень хорошо и ответственно справилась с этим, выпустив исправление в течение трех часов. Это был, наверное, самый простой баг, с которым я когда-либо сталкивался. Уязвимость была расценена как критическая и мне заплатили мою самую любимую цифру в 1337 долларов.
Выводы
Не игнорируйте файлы JS. Ищите различные функции и возможности. Поиграйтесь с этим и вы получите результат.
Каждый раз, когда вы взламываете старую цель, у вас будет ощущение, что это приложение, эта конечная точка, этот API или эта функция были протестированы многими другими хакерами, и стоит пропустить это. Но не слушайте здесь свой инстинкт. Будучи хакером, вы должны пробовать вещи, которые могут не сработать. Попробуйте, и иногда вы сможете обнаружить критическую уязвимость.