Опубликованы подробности атаки Clickjacking

Последние две недели в среде специалистов по веб-безопасности не утихали разговоры по поводу готовящейся публикации деталей новой атаки, позволяющей незаметно для пользователя “украсть” его клики. Первоначально предполагалось, что Robert Hansen, известный под ником “RSnake” и Jeremiah Grossman опубликуют доклад о найденной ими новой уязвимости, получившей название Clickjacking, на конференции OWASP в Нью-Йорке 24 сентября 2008 года, однако их выступление было отменено по просьбе компании Adobe, которая была крайне заинтересована в этой атаке, так как основной ее продукт, а именно Adobe Flash, был уязвим перед Clickjacking. Свою просьбу Adobe мотивировал желанием устранить уязвимость еще перед тем, как ее только начнут применять, тем самым обезопасив пользователей Flash. Разглашение подробностей произошло лишь недавно, после того, как на обозрение широкому кругу лиц был выставлен первый PoC от третьих лиц, которые самостоятельно провели собственное исследование, опираясь на ту небольшую информацию, которая все-таки просочилась в публичные блоги и сайты. Честно говоря, я ожидал большего и вся шумиха, которая была поднята по поводу Clickjacking, не сопоставима со значимостью угрозы самой атаки. Тем не менее, определенная степень опасности все же существует и исключать возможность проведения Clickjaсking разработчикам не стоит.

Clickjacking позволяет перехватывать клики мыши пользователя с целью нажатия на другие элементы, которые могут быть включены в контекст легитимного сайта, но без визуального отображения, что ведет к совершению пользователем непреднамеренных действий. Реализация атаки состоит в следующем: некий сайт A имеет в себе IFRAME, адресом которого является сайт B, к которому пользователь имеет доступ на основе авторизационных данных Cookie. Злонамеренный сайт A перекрывает страницу с сайта B таким образом, чтобы оставить видимым конкретный элемент, например кнопку “Удалить аккаунт”, “Добавить друга” и т.д. Сайт A может иметь такой интерфейс, который позволял бы рассматривать элемент с сайта B, как часть сайта A, побуждая пользователя нажать на него. Тем самым пользователь подвергается опасности соврешения абсолютно непредполагаемых им действий, который выгодны злоумышленнику. Добиться такого “перекрывания” интерфейса другого сайта можно с помощью метода CSS Overlay. Конечно все это выглядит мягко говоря не совсем практично, но возможности Clickjacking не ограничивается лишь подобным примером атаки. Например, Clickjacking ставит под сомнение эффективность метода защиты против CSRF с помощью токенов, о чем я писал в одном из предыдущих постов. Кроме того, возможна (точнее была возможна в связи с выходом патча) атака, при которой пользователь, нажимая на определенные области экрана, в дружелюбной игре, может поменять настройки Flash таким образом, что его компьютер превратился бы в настоящую станцию слежения с помощью веб-камеры или микрофона (разумеется, если таковые устройства подключены к компьютеру). Именно этот способ был раскрыт независимо от Гроссмана и Хансена, в следствие чего последний был вынужден снять завесу тайны с Clickjacking в своем блоге лишь недавно. Потенциальная уязвимость в Adobe Flash так и не стала реальностью, но мне удалось пощупать баг еще до выхода патча. Если вы не успели, то смотрите видео. Более подробно о всех тонкостях Clickjacking RSnake обещал рассказать в одноименном whitepaper’е, который готовится к выпуску на следующей неделе.

Меры по защите от Clickjacking могут быть предприняты как разработчиками веб-приложений, так и самими пользователями. Плагин для FireFox NoScript уже имеет защиту от Clickjacking, так что его пользователи могут быть уверены, что все их клики будут уходить только в одном направлении. Веб-разработчики также могут включить защиту в свои сайты, воспользовавшись достаточно простым способом, который носит название framebusting. Суть его заключается в том, что веб-приложение определяет не находиться ли оно во фрейме другого сайта, и если так, то просто выбирается из фрейма, и становится top’ом. Код приема:

var frameBusted = (top != self);
if (frameBusted) top.location.href = '/index.htm';

В заключение хочу отметить, что, несмотря на всю противоречивость атаки, она может быть использована для превращения кликов в деньги путем непреднамеренного нажатия пользователем на рекламе (привет сеошникам). Возможно скоро будут известны первые удачные атаки.


15 comments:

  1. Best, 16. October 2008, 10:23

    То есть по сути, сlickjacking – это не уязвимость, так как это всего лишь использование стандартного тега iframe, просто грамотно настроенного, и очень сильно зависит от пользователя, так как на кнопку (внутри фрейма) он может и не нажать, я правильно понимаю?

     
  2. Best, 16. October 2008, 10:34

    Вот еще одна реализация разрушения фреймов:

     if (self.parent.frames.length != 0) self.parent.location='http://www.Best-Of-The-Best.ru';
    
     
  3. Raz0r, 16. October 2008, 10:40

    То есть по сути, сlickjacking – это не уязвимость, так как это всего лишь использование стандартного тега iframe, просто грамотно настроенного

    нет, это уязвимость, просто она существует уже много лет, о которой между прочим время от времени говорили разные эксперты, но их не услышали и настоящее признание получила только сейчас благодаря деятельности (читай пиара) уважаемых RSnake и Grossman

    и очень сильно зависит от пользователя, так как на кнопку (внутри фрейма) он может и не нажать, я правильно понимаю?

    совершенно верно

     
  4. Best, 20. October 2008, 15:23

    Как выяснилось – методов выбраться из фрейма у сайта куча. Поэксперементировав, я нашёл небольшой недочёт в работе кода, срывающего фреймовую структуру на яндексе. Но эффект не достигается при работе из под IE6(7 не проверял). В Safari 3.1.2 и Firefox 3.0.3 данный дефект работает.

    Если вывести пустой iframe, а затем, используя Javascript подгрузить в него html код, который тоже iframe, но src у него указывает на яндекс, то Яндекс не выберется из фрейма.

    Я привел бы пример, но код срежется. Вот яваскрипт:

    //Это чтоб можно было к фрейму обращаться(с id EditFrame)
    if(navigator.userAgent.match(/msie/i)) EditField = frames['EditFrame'].document;
    else EditField = document.getElementById('EditFrame').contentDocument;
    
    //Открываем, пишем закрываем
    function sss()
    {
    EditField.open();
    EditField.write(content);
    EditField.close();
    }
    
    //content здесь - это фрейм, грузящий яндекс
    //ну и наконец сам фрейм(я напишу без стрелочек, а то вырежется)
    

    <iframe frameborder=0 name=EditFrame id=EditFrame width=100% height=100% style=margin: 0px>

    Теперь осталось повесить вызов sss() боди на онлоуд, и мы получаем Яндекс, уязвимый к Clickjacking.
    Все вопросы на почту. Если код срежется, притензии не ко мне.
    Разор, если заинтересует, поправь плз код, чтоб нормально было, я то убого выглядит:)

     
  5. Best, 20. October 2008, 15:39

    //Вот сам код, подобный и на рамблере, там дела абстоят так же.

    if((self.parent&&!(self.parent===self))&&(self.parent.frames.length!=0))
    {
       self.parent.location=document.location
    }
    
     
  6. Raz0r, 20. October 2008, 20:34

    @Best
    можешь отправить полный код мне на email? Кстати этот код, которым спасается Яндекс, не работает в Опере. А на рамблере вообще нет никакой защиты =)
    P.S. по поводу срезания кода пока не нашел решения. Ясно одно – во всем виноват kses (очень древний парсер html, которым до сих пор пользуется wp). Как его отключить пока непонятно…

     
  7. Best, 21. October 2008, 10:00

    Код выслал. На рамблере действительно код почему-то отсутствует, хотя буквально перед выходными он был, что очень странно.

     
  8. Best, 21. October 2008, 10:20

    @Raz0r
    При работе яндекса из под “такого” фрейма замечаются расхождения в отображении, например при поиске по изображениям в интернете, изображения вывозятся в одну колонку слева, хотя такой же запрос на обычном яндексе выводит изображения сеткой. (тестилось на Firefox 3.0.3 и Opera 9.23). Еще волнует тот факт, что код на яндексе в IE6 работает в пользу яндекса. Протести пожалуйста на IE7 и IE8, если есть возможность, хотя мне кажется, разницы не будет.

     
  9. Best, 21. October 2008, 10:42

    @Raz0r
    Твой метод срыва фрейма ( да и мой собственно тоже:) ) не уязвим к “фрейму во фрейме”. И тут в голову стали приходить мысли о том, что перед “вылезанием” из фрейма, не плохо было бы немного пособирать информации об атакующем, напрмер IP (первым IP скорее всего будет IP атакующего), а так же сайт, на котором размещен фрейм ( top.location ). То есть надо просто сделать AJAX-запрос к скрипту, передав ему top.location, а скрипт уже добавит в базу IP, сайт, дату и время. Такой вот модуль защиты. Я думаю, что подобные модули давно пора встраивать в популярные проекты (PHPBB, WP,…). Хотя возможно я отстал от жизни, и они там уже есть 🙂

     
  10. Raz0r, 21. October 2008, 19:43

    Еще волнует тот факт, что код на яндексе в IE6 работает в пользу яндекса.

    В IE7 яндекс также выбирается из ифрейма в ифрейме. А вот в Firefox 3.0.3 и Opera 9.60 действительно твой код нормально работает. Как я понимаю, ошибка подобной защиты заключается в том, что js-скрипт пытается определить self.parent, т.е. своего родителя, а не top – “абсолютного” родителя. Поэтому действительно ифрейм в ифрейме позволяет обойти такую защиту

    перед “вылезанием” из фрейма, не плохо было бы немного пособирать информации об атакующем

    также отличная идея, в популярных движках пока такого модуля не видел, да и вообще защиты от clickjacking. Можем вместе написать 😉

     
  11. Best, 22. October 2008, 11:14

    Давай напишем. Пиши на почту, скоординируем действия, и закодим.

     
  12. Raz0r, 3. November 2008, 23:49

    Я ошибался, решение по защите от Clickjacking уже реализовано в csrf-magic 1.0.1 (http://csrf.htmlpurifier.org/news/2008/1102-1.0.1-released.html)

     
  13. Raz0r, 10. November 2008, 22:58

    Нашел интересный пост с заголовком frame-buster-buster: оказывается код frame-buster’ов можно обойти в браузере Google Chrome
    http://maliciousmarkup.blogspot.com/2008/11/frame-buster-buster.html

     
  14. Гвест, 4. April 2009, 10:32

    if(self.parent.frames.length!=0) self.parent.location
    не могу это обойти. хочется чтобы стр во фрейме грузилась. а она редиректит.
    метот с чромом пробывал. не работает. csrf-magic 1.0.1 – какойто не понятный.\

    если найдете решение, отпишитесь плз

     
  15. Shred, 22. July 2009, 13:35

    Raz0r, Best удалось ли реализовать защиту от Clickjacking для цмсок? В частности интересует вп. Если да, может поделитесь наработаками?

     

Write a comment: