SQL Injection
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
RootedCON є найважливішою подією в сфері кібербезпеки в Іспанії та однією з найважливіших в Європі. З метою просування технічних знань, цей конгрес є гарячою точкою зустрічі для професіоналів у сфері технологій та кібербезпеки в усіх дисциплінах.
SQL-ін'єкція — це вразливість безпеки, яка дозволяє зловмисникам втручатися в запити до бази даних програми. Ця вразливість може дозволити зловмисникам переглядати, змінювати або видаляти дані, до яких їм не слід мати доступ, включаючи інформацію інших користувачів або будь-які дані, до яких може отримати доступ програма. Такі дії можуть призвести до постійних змін у функціональності або змісті програми або навіть до компрометації сервера чи відмови в обслуговуванні.
Коли сайт виглядає вразливим до SQL-ін'єкції (SQLi) через незвичайні відповіді сервера на запити, пов'язані з SQLi, першим кроком є розуміння того, як впроваджувати дані в запит, не порушуючи його. Це вимагає визначення методу ефективного виходу з поточного контексту. Ось кілька корисних прикладів:
Тоді вам потрібно знати, як виправити запит, щоб не було помилок. Щоб виправити запит, ви можете ввести дані так, щоб попередній запит прийняв нові дані, або ви можете просто ввести свої дані та додати символ коментаря в кінці.
Зверніть увагу, що якщо ви можете бачити повідомлення про помилки або помітити відмінності, коли запит працює, а коли ні, цей етап буде легшим.
Надійний метод підтвердження вразливості до SQL-ін'єкцій полягає в виконанні логічної операції та спостереженні за очікуваними результатами. Наприклад, GET-параметр, такий як ?username=Peter
, що дає ідентичний контент при зміні на ?username=Peter' or '1'='1
, вказує на вразливість до SQL-ін'єкцій.
Аналогічно, застосування математичних операцій слугує ефективною технікою підтвердження. Наприклад, якщо доступ до ?id=1
та ?id=2-1
дає той самий результат, це вказує на SQL-ін'єкцію.
Приклади, що демонструють підтвердження логічної операції:
Цей список слів був створений, щоб спробувати підтвердити SQL-ін'єкції запропонованим способом:
В деяких випадках ви не помітите жодних змін на сторінці, яку ви тестуєте. Тому хороший спосіб виявити сліпі SQL-ін'єкції - це змусити БД виконувати дії, які матимуть вплив на час, необхідний для завантаження сторінки. Отже, ми будемо конкатенувати в SQL-запиті операцію, яка займе багато часу для виконання:
В деяких випадках функції затримки не будуть дозволені. Тоді, замість використання цих функцій, ви можете змусити запит виконувати складні операції, які займатимуть кілька секунд. Приклади цих технік будуть прокоментовані окремо для кожної технології (якщо такі є).
Найкращий спосіб ідентифікувати бекенд - це спробувати виконати функції різних бекендів. Ви можете використовувати sleep функції з попереднього розділу або ці (таблиця з payloadsallthethings:
Також, якщо у вас є доступ до виходу запиту, ви можете вивести версію бази даних.
У продовженні ми обговоримо різні методи експлуатації різних видів SQL Injection. Ми будемо використовувати MySQL як приклад.
Якщо ви можете бачити вихід запиту, це найкращий спосіб його експлуатувати. По-перше, нам потрібно дізнатися кількість стовпців, які початковий запит повертає. Це тому, що обидва запити повинні повертати однакову кількість стовпців. Для цієї мети зазвичай використовуються два методи:
Щоб визначити кількість стовпців у запиті, поступово коригуйте число, використане в ORDER BY або GROUP BY клаузах, поки не буде отримано хибну відповідь. Незважаючи на різні функціональні можливості GROUP BY та ORDER BY в SQL, обидва можуть бути використані однаково для визначення кількості стовпців запиту.
Виберіть все більше і більше значень null, поки запит не буде правильним:
Ви повинні використовувати null
значення, оскільки в деяких випадках типи стовпців з обох сторін запиту повинні бути однаковими, і null є дійсним у кожному випадку.
У наступних прикладах ми будемо отримувати назву всіх баз даних, назву таблиці бази даних, імена стовпців таблиці:
Існує різний спосіб виявлення цих даних у кожній різній базі даних, але методологія завжди однакова.
Коли вихід запиту видимий, але ін'єкція на основі об'єднання здається недосяжною, це свідчить про наявність прихованої ін'єкції на основі об'єднання. Цей сценарій часто призводить до ситуації сліпої ін'єкції. Щоб перетворити сліпу ін'єкцію на ін'єкцію на основі об'єднання, потрібно визначити запит виконання на бекенді.
Це можна зробити за допомогою технік сліпої ін'єкції разом з таблицями за замовчуванням, специфічними для вашої цільової системи управління базами даних (DBMS). Для розуміння цих таблиць за замовчуванням рекомендується звернутися до документації цільової DBMS.
Після того, як запит буде витягнуто, необхідно налаштувати ваш payload, щоб безпечно закрити оригінальний запит. Після цього до вашого payload додається запит об'єднання, що полегшує експлуатацію ново доступної ін'єкції на основі об'єднання.
Для більш детальної інформації зверніться до повної статті, доступної за посиланням Healing Blind Injections.
Якщо з якоїсь причини ви не можете бачити вихід запиту, але можете бачити повідомлення про помилки, ви можете використовувати ці повідомлення про помилки для екстракції даних з бази даних. Слідуючи подібному потоку, як у випадку експлуатації на основі об'єднання, ви можете змогти скинути базу даних.
У цьому випадку ви не можете бачити результати запиту або помилки, але ви можете відрізнити, коли запит повертає істинне або хибне значення, оскільки на сторінці є різний вміст. У цьому випадку ви можете зловживати цією поведінкою, щоб вивантажити базу даних символ за символом:
Це та сама ситуація, що й раніше, але замість того, щоб розрізняти істинну/хибну відповідь на запит, ви можете розрізняти наявність помилки в SQL запиті чи ні (можливо, через те, що HTTP сервер зривається). Тому в цьому випадку ви можете примусити SQL помилку щоразу, коли правильно вгадуєте символ:
У цьому випадку немає жодного способу відрізнити відповідь запиту на основі контексту сторінки. Але ви можете змусити сторінку завантажуватися довше, якщо вгаданий символ правильний. Ми вже бачили цю техніку раніше для підтвердження вразливості SQLi.
Ви можете використовувати stacked queries для виконання кількох запитів підряд. Зверніть увагу, що хоча наступні запити виконуються, результати не повертаються в додаток. Отже, ця техніка в основному корисна у зв'язку з сліпими вразливостями, де ви можете використовувати другий запит для виклику DNS-запиту, умовної помилки або затримки часу.
Oracle не підтримує stacked queries. MySQL, Microsoft та PostgreSQL їх підтримують: QUERY-1-HERE; QUERY-2-HERE
Якщо жоден інший метод експлуатації не спрацював, ви можете спробувати змусити базу даних ексфільтрувати інформацію на зовнішній хост, контрольований вами. Наприклад, через DNS-запити:
Перевірте SQLMap Cheatsheet для експлуатації вразливості SQLi за допомогою sqlmap.
Ми вже обговорили всі способи експлуатації вразливості SQL Injection. Знайдіть ще кілька трюків, залежних від технології бази даних, у цій книзі:
Або ви знайдете багато трюків щодо: MySQL, PostgreSQL, Oracle, MSSQL, SQLite та HQL у https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection
RootedCON є найактуальнішою подією в сфері кібербезпеки в Іспанії та однією з найважливіших в Європі. З місією просування технічних знань, цей конгрес є гарячою точкою зустрічі для професіоналів у сфері технологій та кібербезпеки в кожній дисципліні.
Список для спроби обійти функціональність входу:
Login bypass ListЦей запит демонструє вразливість, коли MD5 використовується з true для сирого виходу в перевірках автентифікації, що робить систему вразливою до SQL-ін'єкцій. Зловмисники можуть скористатися цим, створюючи введення, які, коли їх хешують, виробляють несподівані частини SQL-команд, що призводить до несанкціонованого доступу.
Рекомендований список:
Ви повинні використовувати як ім'я користувача кожен рядок списку, а як пароль завжди: Pass1234. &#xNAN;(Ці payloads також включені у великий список, згаданий на початку цього розділу)
Якщо ' екранується, ви можете використовувати %A8%27, і коли ' буде екрановано, буде створено: 0xA80x5c0x27 (╘')
Python скрипт:
To do so you should try to create a new object named as the "master object" (probably admin in case of users) modifying something:
Create user named: AdMIn (великі та малі літери)
Create a user named: admin=
SQL Truncation Attack (коли є якийсь обмеження по довжині в імені користувача або електронній пошті) --> Create user with name: admin [багато пробілів] a
If the database is vulnerable and the max number of chars for username is for example 30 and you want to impersonate the user admin, try to create a username called: "admin [30 пробілів] a" and any password.
The database will check if the introduced username exists inside the database. If not, it will cut the username to the max allowed number of characters (in this case to: "admin [25 пробілів]") and the it will automatically remove all the spaces at the end updating inside the database the user "admin" with the new password (some error could appear but it doesn't means that this hasn't worked).
More info: https://blog.lucideus.com/2018/03/sql-truncation-attack-2018-lucideus.html & https://resources.infosecinstitute.com/sql-truncation-attack/#gref
Note: This attack will no longer work as described above in latest MySQL installations. While comparisons still ignore trailing whitespace by default, attempting to insert a string that is longer than the length of a field will result in an error, and the insertion will fail. For more information about about this check: https://heinosass.gitbook.io/leet-sheet/web-app-hacking/exploitation/interesting-outdated-attacks/sql-truncation
Add as much ','',''
as you consider to exit the VALUES statement. If delay is executed, you have a SQLInjection.
Клаузула ON DUPLICATE KEY UPDATE
в MySQL використовується для визначення дій, які база даних повинна виконати, коли намагаються вставити рядок, що призведе до дублювання значення в унікальному індексі або первинному ключі. Наступний приклад демонструє, як цю функцію можна експлуатувати для зміни пароля облікового запису адміністратора:
Example Payload Injection:
Вантаж для ін'єкції може бути створений наступним чином, де намагаються вставити два рядки в таблицю users
. Перший рядок є приманкою, а другий рядок націлений на існуючу електронну пошту адміністратора з наміром оновити пароль:
Ось як це працює:
Запит намагається вставити два рядки: один для generic_user@example.com
і інший для admin_generic@example.com
.
Якщо рядок для admin_generic@example.com
вже існує, спрацьовує клаузула ON DUPLICATE KEY UPDATE
, яка інструктує MySQL оновити поле password
існуючого рядка на "bcrypt_hash_of_newpassword".
Відповідно, аутентифікацію можна спробувати виконати, використовуючи admin_generic@example.com
з паролем, що відповідає bcrypt хешу ("bcrypt_hash_of_newpassword" представляє bcrypt хеш нового пароля, який слід замінити на фактичний хеш бажаного пароля).
При спробі створити нового користувача потрібні ім'я користувача, пароль та електронна пошта:
За допомогою цієї техніки ви можете витягти інформацію, створивши лише 1 обліковий запис. Важливо зазначити, що вам не потрібно нічого коментувати.
Використовуючи hex2dec та substr:
Щоб отримати текст, ви можете використовувати:
Використовуючи hex та replace (і substr):
RootedCON є найактуальнішою подією в сфері кібербезпеки в Іспанії та однією з найважливіших в Європі. З метою популяризації технічних знань, цей конгрес є гарячою точкою зустрічі для професіоналів у сфері технологій та кібербезпеки в усіх дисциплінах.
Routed SQL injection - це ситуація, коли ін'єкційний запит не є тим, який дає вихід, але вихід ін'єкційного запиту йде до запиту, який дає вихід. (З документа)
Приклад:
No Space (%20) - обхід за допомогою альтернатив пробілів
No Whitespace - обхід за допомогою коментарів
No Whitespace - обхід за допомогою дужок
No Comma - обхід за допомогою OFFSET, FROM та JOIN
Чорний список за допомогою ключових слів - обхід за допомогою великих/малих літер
Чорний список за допомогою ключових слів без урахування регістру - обхід за допомогою еквівалентного оператора
Ви можете знайти більш детальне пояснення цього трюку в блозі gosecure. В основному, ви можете використовувати наукову нотацію несподіваними способами, щоб обійти WAF:
По-перше, зверніть увагу, що якщо оригінальний запит і таблиця, з якої ви хочете витягти прапор, мають однакову кількість стовпців, ви можете просто зробити: 0 UNION SELECT * FROM flag
Можливо отримати доступ до третього стовпця таблиці без використання його назви за допомогою запиту, подібного до наступного: SELECT F.3 FROM (SELECT 1, 2, 3 UNION SELECT * FROM demo)F;
, тому в sqlinjection це виглядатиме так:
Або використовуючи comma bypass:
Цей трюк був взятий з https://secgroup.github.io/2017/01/03/33c3ctf-writeup-shia/
RootedCON є найважливішою подією в сфері кібербезпеки в Іспанії та однією з найважливіших в Європі. З місією просування технічних знань, цей конгрес є гарячою точкою зустрічі для професіоналів у сфері технологій та кібербезпеки в кожній дисципліні.
Вчіться та практикуйте Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE) Вчіться та практикуйте Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)