Информационная безопасность
Тестирование веб-сервисов
24 марта

Распутывание клубка уязвимостей на сайтах

Из песочницы

После своей первой статьи, опубликованной на codeby, которая вошла в топ 3 публикаций недели, я был очень мотивирован написать следующую. Но 11 класс накладывает ограничения на свободное время подготовкой к егэ и олимпиадами. Поэтому вторую я пишу лишь спустя несколько месяцев вылетев со всех олимпиад.

В этом публикации будет рассказано об интересном случае, когда найденная на одном ресурсе уязвимость повлекла по цепочке нахождение их на нескольких других сайтах.

Beginning


Все началось с проверки сайта одного крупного производителя кованных изделий. Личного кабинета пользователя там не было, и зона поиска уязвимостей была не слишком обширной.

При тестировании формы отправки заказа, в ней был обнаружен ряд уязвимостей.
Во первых это достаточно стандартная stored XSS в данных покупателя, с которой и потянулся этот клубок. XSS стандартная, а отсутствие флага «httponly» на cookie, было явно не стандартным. Уже много раз мне приходили cookie с различных сайтов, но ни разу я не получал авторизационные, и уже стал сомневаться, что в природе остались сайты не использующие флаг «httponly», ведь его использование значительно снижает опасность XSS атак. Тем удивительнее было встретить такой случай на сайте большой компании. Но, как оказалось, сервис допустивший эту оплошность был гораздо крупнее, чем я предполагал. Но об этом после.

Подставил полученные куки и зашел в аккаунт crm системы сайта (не удержался, впервые так повезло). Права оказались не админскими, но их было достаточно для доступа к любой статистике по заказам, в т.ч. и данным покупателей.



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



Вернувшись к тестированию формы отправки заказа я нашел там еще iDOR уязвимость, позволяющую изменять цену заказа, посредством редактирование параметров «json_order[0][price]» и «json_order[0][total]» в POST запросе domain.ru/shop.php. Подмена ссылки на заказ в том же запросе в поле json_order[0][href] приводила к RFI.

На сообщение о новых находках ответа получено не было…

Continuation


У того сайта crm система оказалась не самописная, а предоставлялась по оплате одним известным сервисом. После их оплошности с cookie было логично предположить, что там найдутся и другие уязвимости.

Если отправленный мною через форму заказа скрипт отработал, значит валидации полей не было как на искомом сайте, так и в crm системе. x2. Поэтому получив пробный аккаунт я начал именно с поиска полей уязвимых к xss.

После долгих путешествий по обширной crm системе было выявлено более дюжины полей с недостаточной валидацией. Где-то можно было напрямую вставлять тег script, где-то приходилось использовать in-line скрипты по типу " onmouseover=alert() ". Причем в каких то местах встроить скрипт удавалось, а в каких то нет, интересно, какой логикой они руководствовались, в одни места добавляя фильтрацию, а в другие нет? С точки зрения логического предназначения полей я закономерности не увидел. В некоторых местах, куда почти не будут заходить все работало нормально, а, например, в ФИО контрагента добавить фильтрацию не потрудились.

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

На этом с xss было окончено, можно было переходить к более интересным вещам.

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

На удивление никакой защиты от CSRF не было. Можно было отправить любые запросы, проверки ни где не проводились.
— Изменить данные учетной записи? — Пожалуйста
— Поменять название и цену на товар? — Не вопрос

В куках, при этом, содержалось нечто, имеющее название «csrftoken».

Тогда я еще подумал, какой смысл помещать csrf токен в куки? Погуглив, я узнал, что есть довольно удобный способ защиты от csrf с токеном в куках и дублирование его в post запросе, при котором не требуется хранить токен на сервере. Подробнее тут.

Но в нашем случае сделали только половину работы, в куки токен поместили, а в запросах к серверу он отсутствовал. И даже больше, его полное удаление из кук ничего не меняло. Зачем он был добавлен?

В связке с обнаруженными csrf, наши xss, не доступные ранее извне, получают вторую жизнь. Нам ведь теперь не нужно попадать в аккаунт, для редактирования уязвимых полей.

Кроме этого через подмену mime-типа файла можно было загружать на сервер произвольные файлы. Но сервер был настроен правильно и php скрипты там не выполнялись.

Дальше еще интереснее. Все данные о товарах интернет магазин брал из crm. Т.е. название, описание, фото. Ссылка на изображение товара имела вид «yyyy.domain.ru/file/get/id=xxx». Для того чтобы интернет магазин мог брать изображения, на них должны стоять права на чтение для всех. 122.

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

— Вы сделали запрос на импорт данных о заказах в exel-файле? — Отлично, теперь его сможет скачать любой желающий.

Быть может там id имел вид типа «yt5bjFb54hb#HJ%$p» и не поддавался брутфорсу? Тоже нет. Все id файлов имели числовой формат и находились в диапазоне нескольких тысяч. Защиты от брута я тоже не заметил. Пробрутив все id от 1 до 10000 препятствий не встретил. Повторил еще несколько раз, никого такая активность не заинтересовала.

Ответили на мой отчет через 3 дня.

Касательно отсутствия флага httponly сказали, что он отсутствовал «Видимо уже давно, со времен обновления версии php». Включили в тот же день.

По xss сказали, что сами все знают, фильтр отключили в начале лета (в тот момент был уже август), это конечно не объясняет, почему где-то фильтрация была, а где-то нет, но, сделаем вид, что не заметили эту нестыковку. Также уверили, что фильтр будет запущен через пару дней. На деле оказалось, что через пару месяцев. Но, тут я их прекрасно понимаю: я тоже тогда планировал начать готовиться к экзаменам через пару дней…

Загрузка произвольных файлов на сервер их мало волновала, ведь на сервере они не выполняются, значит и беспокоиться нечего. Только во время написания статьи у меня возникла мысль, если сайт, который находится уже на отличном от crm хостинге, пытается взять изображение товара для витрины, а получает php скрипт, он его выполнит? Или из за того что он предназначен для тега img он будет обрабатываться только как изображение? Или это зависит он настроек сервера? Прошу ответить знающих людей.

Ответ на сообщение о csrf оказался совсем интересным. Ответили вопросом: «Что вы считаете токеном для защиты от csrf атак?» Действительно, о чем это я?



Про свободный доступ к любым файлам сказали, что не учли этот момент. Закрыли сразу.

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

'''
Довольствуемся малым, счастье не в больших деньгах
«Делай то что любишь» — ценится в наших кругах
''' © Коля Маню — Каждый день

Еnding


В техподдержке предыдущего сайт использовалась сторонняя система приема тикетов «UserEcho». Ее я не преминул проверить. В мечтах, конечно же, было добиться возможности читать любые приватные тикеты. Это мне, естественно, не удалось. Пришлось довольствоваться малым.



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



Если мы посылаем запрос на отписку от чужого тикета, нам, как и положено, сообщают, что у нас нет прав на это действие. Но при этом его заносят в наш список тикетов, как один из тех, на которые мы были подписаны ранее. Таким образом мы получаем возможность узнать его название и url формата «номер-назавание_тикета_в_транслите». Вреда это, конечно, никакого не несло. В очень редких случаях из названия можно будет узнать что-то важное и ценное. Но это было лучше чем остаться совсем ни с чем.

Через пару недель баг был исправлен.

Благодарю всех, кто дочитал до конца!

+14
4,8k 53
Комментарии 19