Как я проник на сервер PayPal через баг в загрузке файлов и получил доступ к удаленному выполнению кода

в 8:53, , рубрики: Блог компании Fondy, информационная безопасность, код, отладка, поиск багов, Программирование, удалённый доступ

Пентестер (тестировщик на проникновение) рассказывает, как ему удалось найти баг в загрузке файлов и проникнуть на сервер платежной системы PayPal.

image

Привет всем!

Надеюсь, у вас все хорошо. Уверен, что заголовок вас немало удивил, и вы ринулись сюда чтобы глянуть, реально ли я cмог получить удаленный доступ не куда-нибудь, а на сервер PayPal.

На самом деле это был довольно простенький взлом, направленный на проверку уязвимости (так называемый POC). Единственный момент, с которым мне повезло — поиск и успешное определение уязвимого домена.

image

Начнем с небольшой предыстории. Как вы могли ранее видеть в моем предыдущем посте, я недавно сдал экзамен на сертификацию OSCP. Вот на это у меня действительно ушло немало дней и ночей упорной работы — почти 4 месяца сосредоточенных занятий и никакого поиска багов, то есть, по сути, никакого зарабатывания карманных денег.

Нормальные люди: выходные полные выпивки, тусовок, веселья, похмелья и прочего. Вопросы вроде: «Ты смотрел нового «Человека-паука»? Игру престолов?»

Люди вроде меня:

image

Итак, в один из выходных, просматривая кое-какие блоги и ролики на YouTube, я наткнулся на материал по PayPal, подумал зайти на их страницу программы поощрения поиска багов с помощью Burp и обнаружил следующее:

image

На скриншоте показан обычный ответ от http://paypal.com/bugbounty/. Присмотревшись, можно увидеть любопытный список доменов PayPal, в заголовке ответа Content Security Policy. Меня заинтересовал https://*.paypalcorp.com. Этот типовой подход, который я использую в отлавливании багов. Я ищу как можно больше рабочих поддоменов конечной цели, поскольку именно их, как правило, оставляют без должного внимания, и, такие как я, в итоге, что-нибудь там находят.

Вы можете воспользоваться Subbrute, Knockpy, enumall или другими похожими утилитами. Обычно я так и делаю, но в этот выходной лень взяла верх и я просканил их в VirusTotal. Итоговый список можно посмотреть здесь.

Я скопировал список поддоменов на локальную машину, запустил dig -f paypal +noall +answer чтобы получить удобную картину того, куда на самом деле указывают все субдомены.

image

Один из них, brandpermission.paypalcorp.com, указывал на https://www.paypal-brandcentral.com/ — сайт для регистрации запросов в службу онлайн-поддержки вендоров, поставщиков и партнеров PayPal, посредством которого они запрашивают разрешение на использование бренда. В системе доступна функция загрузки черновых вариантов логотипов и графики во время оформления запроса.

Реакция любого охотника за багами, увидевшего форму загрузки файлов:

image

Пахнет уловом

Поэтому для начала я создал «тикет», загрузив простое изображение с названием finished.jpg. На сервер оно попало под именем finished_thumb.jpg по пути /content/helpdesk/368/867/. Я быстро проверил, загрузился ли файл, который мы отправляли через форму с именем finished.jpg и да, к счастью (этот факт еще сыграет свою роль позже) он там присутствовал.

Далее я немного изучил схему работы приложения: как оно загружает файлы, куда они попадают, какие шаблоны имен для файлов и папок в нем приняты. Стало ясно, что каталог 368 был назван так по номеру созданного мной тикета, а 867 — идентификатор папки, в которой хранятся все связанные с ним файлы, то есть различные графические материалы, прилагаемые к тикету.

Я быстро повторил те же действия, создал еще одно обращение, из которого стало видно, что идентификаторы тикета и папки генерируются серийно. Создал еще один тикет, но в этот раз загрузил файл с расширением .php, содержащий простой однострочный скрипт для командной строки:

image

Скрипт вернул 302 код (то есть, по сути, 200 ОК). Это означало, что приложение не делало никаких проверок типов файлов, контента и прочего. Есть! Мое лицо в этот момент:

image

Да ладно...

Увидев 302 код, я ринулся открывать новый тикет чтобы скопировать ссылку как это было в случае загрузки файла изображения. Но при отправке .php увидеть путь загружаемого файла было нельзя. Единственное что можно было узнать — номер тикета. Что делать дальше?

image

Ну а теперь...

Получив номер тикета (366 в данном случае), мы узнаем имя директории, куда были загружены наши «графические примеры». Не хватает только идентификатора папки, куда попадает файл (поскольку мы не можем видеть php-файл при просмотре исходного кода страницы как это возможно с изображениями).

Но мы знаем имя файла — success.php (поскольку проверили до этого, что example.jpg оказался в той же папке, что и example_thumb.jpg).

Итак, мы знаем, что success.php также существует, а помещенный в success_thumb.php код отработал. Мы также знаем идентификатор папки (867), полученный при загрузке ранее простого изображения. Номер тикета для загрузки проверочного php — 366.

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

image

Нельзя просто взять и забрутфорсить

Поэтому я по-быстрому запустил в Intruder’е следующий перебор с идентификаторами 500–1000:
https://www.paypal-brandcentral.com/content/_helpdesk/366/$(bruteforced 500-1000)$/success.php. В итоге 200 код был получен на идентификаторе 865.

image
Моя реакция:

image

Круто! Теперь, когда мы узнали «айдишник» каталога с файлом давайте попробуем выполнить код: https://www.paypal-brandcentral.com/content/_helpdesk/366/865/success.php?cmd=uname-a;whoami

image

Немного магии cat /etc/passwd чтобы самому убедиться, что возможность удаленного исполнения кода действительно есть:

image

На сервере также была страница авторизации для сотрудников PayPal.

Надеюсь, вам понравился этот материал! Буду очень признателен обратной связи в комментах ;)

Хронология обработки обращения:
~ 8 июля, 2017 18:03 — Сообщил о баге в PayPal
~ 11 июля, 2017 18:03 — Баг исправлен
~ 25 июля, 2017 3:30 — Получил награду

Но подождите-ка! На этом история не заканчивается. Вот еще немного материала для затравки. О нем я поведаю в своем блоге на следующих выходных:

image

Я сообщил о той же самой уязвимости в разных точках приложения. Одно из сообщений было довольно очевидным, поэтому их объединили в одно обращение, а второе пометили, как дублирующее.

image

От переводчика:
На момент публикации перевода, сайт www.paypal-brandcentral.com стал недоступен, отдавая ошибку HTTP 500. Вероятно публикация оригинальной статьи послужила источником обнаружению более серъезных уязвимостей другими исследователями.

Как я проник на сервер PayPal через баг в загрузке файлов и получил доступ к удаленному выполнению кода - 17

Автор: Fondy

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js