SQL injection
Bu bölümde, SQL enjeksiyonunun ne olduğunu açıklayacağız, bazı yaygın örnekleri açıklayacağız, çeşitli SQL enjeksiyon güvenlik açıklarının nasıl bulunacağını ve kullanılacağını açıklayacağız ve SQL enjeksiyonunun nasıl önleneceğini özetleyeceğiz.
Laboratuvarlar
SQL enjeksiyon güvenlik açıklarının arkasındaki temel kavramlara zaten aşinaysanız ve bunları gerçekçi, kasıtlı olarak savunmasız hedefler üzerinde kullanma alıştırması yapmak istiyorsanız, bu konudaki tüm laboratuvarlara aşağıdaki bağlantıdan erişebilirsiniz.
Tüm SQL enjeksiyon laboratuvarlarını görüntüleyinSQL injection (SQLi) nedir?
SQL enjeksiyonu, bir saldırganın bir uygulamanın veritabanına yaptığı sorgulara müdahale etmesine olanak tanıyan bir web güvenlik açığıdır. Genellikle bir saldırganın normalde alamadıkları verileri görüntülemesine izin verir. Bu, diğer kullanıcılara ait verileri veya uygulamanın kendisinin erişebildiği diğer verileri içerebilir. Çoğu durumda, bir saldırgan bu verileri değiştirebilir veya silebilir ve uygulamanın içeriğinde veya davranışında kalıcı değişikliklere neden olabilir.
Bazı durumlarda, saldırgan, temel alınan sunucunun veya diğer arka uç altyapısının güvenliğini aşmak için bir SQL enjeksiyon saldırısını yükseltebilir veya bir hizmet reddi saldırısı gerçekleştirebilir.
Başarılı bir SQL enjeksiyon saldırısının etkisi nedir?
Başarılı bir SQL enjeksiyon saldırısı, parolalar, kredi kartı ayrıntıları veya kişisel kullanıcı bilgileri gibi hassas verilere yetkisiz erişime neden olabilir. Son yıllardaki birçok yüksek profilli veri ihlali, itibarın zarar görmesine ve yasal para cezalarına yol açan SQL enjeksiyon saldırılarının sonucu olmuştur. Bazı durumlarda, bir saldırgan bir kuruluşun sistemlerine kalıcı bir arka kapı alabilir ve bu da uzun süre fark edilmeden gidebilecek uzun vadeli bir uzlaşmaya yol açabilir.
SQL enjeksiyon örnekleri
Farklı durumlarda ortaya çıkan çok çeşitli SQL enjeksiyon güvenlik açıkları, saldırılar ve teknikler vardır. Bazı yaygın SQL enjeksiyon örnekleri şunları içerir:
- Gizli verileri alma, ek sonuçlar döndürmek için bir SQL sorgusunu değiştirebileceğiniz yer.
- Uygulama mantığını alt üst etme, uygulamanın mantığına müdahale etmek için bir sorguyu değiştirebileceğiniz yer.
- UNION saldırıları, farklı veritabanı tablolarından veri alabileceğiniz yer.
- Veritabanını incelemek, veritabanının sürümü ve yapısı hakkında bilgi alabileceğiniz yer.
- Blind SQL injection, kontrol ettiğiniz bir sorgunun sonuçlarının uygulamanın yanıtlarında döndürülmediği yer.
Gizli verileri alma
Ürünleri farklı kategorilerde sergileyen bir alışveriş uygulaması düşünün. Kullanıcı Hediyeler kategorisine tıkladığında tarayıcısı şu URL'yi ister:
https://insecure-website.com/products?category=Gifts
Bu, uygulamanın ilgili ürünlerin ayrıntılarını veritabanından almak için bir SQL sorgusu yapmasına neden olur:
SELECT * FROM products WHERE category = 'Gifts' AND released = 1
Bu SQL sorgusu, veritabanından şunu döndürmesini ister:
- all details (*)
- ürünler tablosundan
- kategori nerede Hediyeler
- ve serbest bırakıldı 1.
kısıtlama released = 1
piyasaya sürülmeyen ürünleri gizlemek için kullanılıyor. Muhtemelen piyasaya sürülmemiş ürünler için released = 0
.
Uygulama, SQL enjeksiyon saldırılarına karşı herhangi bir savunma uygulamaz, bu nedenle bir saldırgan aşağıdaki gibi bir saldırı oluşturabilir:
https://insecure-website.com/products?category=Gifts'--
Bu, SQL sorgusu ile sonuçlanır:
SELECT * FROM products WHERE category = 'Gifts'--' AND released = 1
Buradaki en önemli şey, çift çizgi dizisinin --
SQL'de bir yorum göstergesidir ve sorgunun geri kalanının yorum olarak yorumlandığı anlamına gelir. Bu, sorgunun geri kalanını etkili bir şekilde kaldırır, dolayısıyla artık içermez AND released = 1
. Bu, piyasaya sürülmemiş ürünler de dahil olmak üzere tüm ürünlerin görüntülendiği anlamına gelir.
Daha da ileri giderek, bir saldırgan, uygulamanın bilmediği kategoriler de dahil olmak üzere herhangi bir kategorideki tüm ürünleri göstermesine neden olabilir:
https://insecure-website.com/products?category=Gifts'+OR+1=1--
Bu, SQL sorgusu ile sonuçlanır:
SELECT * FROM products WHERE category = 'Gifts' OR 1=1--' AND released = 1
Değiştirilen sorgu, kategorinin Hediyeler olduğu veya 1'in 1'e eşit olduğu tüm öğeleri döndürür. 1=1
her zaman doğrudur, sorgu tüm öğeleri döndürür.
Uygulama mantığını alt üst etme
Kullanıcıların bir kullanıcı adı ve şifre ile oturum açmasına izin veren bir uygulama düşünün. Bir kullanıcı kullanıcı adını gönderirse wiener
ve şifre bluecheese
, uygulama, aşağıdaki SQL sorgusunu gerçekleştirerek kimlik bilgilerini kontrol eder:
SELECT * FROM users WHERE username = 'wiener' AND password = 'bluecheese'
Sorgu bir kullanıcının ayrıntılarını döndürürse, oturum açma başarılıdır. Aksi takdirde reddedilir.
Burada, bir saldırgan sadece SQL yorum dizisini kullanarak herhangi bir kullanıcı olarak parola olmadan oturum açabilir. --
parola kontrolünü kaldırmak için WHERE
sorgu cümlesi. Örneğin, kullanıcı adını göndermek administrator'--
ve boş bir parola aşağıdaki sorguyla sonuçlanır:
SELECT * FROM users WHERE username = 'administrator'--' AND password = ''
Bu sorgu, kullanıcı adı olan kullanıcıyı döndürür.administrator
ve saldırganın o kullanıcı olarak başarıyla oturum açmasını sağlar.
Diğer veritabanı tablolarından veri alma
Bir SQL sorgusunun sonuçlarının uygulamanın yanıtları içinde döndürüldüğü durumlarda, bir saldırgan veritabanındaki diğer tablolardan veri almak için bir SQL enjeksiyon güvenlik açığından yararlanabilir. Bu, ek bir SELECT
sorgusu yürütmenize ve sonuçları orijinal sorguya eklemenize izin veren UNION
anahtar sözcüğü kullanılarak yapılır.
Örneğin, bir uygulama "Gifts" kullanıcı girişini içeren aşağıdaki sorguyu yürütürse:
SELECT name, description FROM products WHERE category = 'Gifts'
daha sonra bir saldırgan girişi gönderebilir:
' UNION SELECT username, password FROM users--
Bu, uygulamanın tüm kullanıcı adlarını ve şifreleri ürün adları ve açıklamalarıyla birlikte döndürmesine neden olacaktır.
Daha fazla oku
SQL enjeksiyon UNION saldırılarıVeritabanını incelemek
Bir SQL enjeksiyon güvenlik açığının ilk tespitini takiben, genellikle veritabanının kendisi hakkında bazı bilgiler edinmek yararlıdır. Bu bilgi genellikle daha fazla sömürünün önünü açabilir.
Veritabanı için sürüm ayrıntılarını sorgulayabilirsiniz. Bunun yapılma şekli veritabanı tipine bağlıdır, böylece hangi tekniğin işe yaradığı ile veritabanı tipini çıkarabilirsiniz. Örneğin, Oracle'da şunları yürütebilirsiniz:
SELECT * FROM v$version
Ayrıca hangi veritabanı tablolarının bulunduğunu ve hangi sütunları içerdiklerini de belirleyebilirsiniz. Örneğin, çoğu veritabanında tabloları listelemek için aşağıdaki sorguyu çalıştırabilirsiniz:
SELECT * FROM information_schema.tables
Blind SQL injection güvenlik açıkları [Kör SQL]
SQL enjeksiyonunun birçok örneği, kör güvenlik açıklarıdır. Bu, uygulamanın, SQL sorgusunun sonuçlarını veya yanıtlarında herhangi bir veritabanı hatasının ayrıntılarını döndürmediği anlamına gelir. Kör güvenlik açıkları, yetkisiz verilere erişmek için hala kullanılabilir, ancak ilgili teknikler genellikle daha karmaşık ve gerçekleştirilmesi zordur.
Güvenlik açığının doğasına ve ilgili veritabanına bağlı olarak, kör SQL enjeksiyon güvenlik açıklarından yararlanmak için aşağıdaki teknikler kullanılabilir:
- Tek bir koşulun doğruluğuna bağlı olarak uygulamanın yanıtında algılanabilir bir farkı tetiklemek için sorgunun mantığını değiştirebilirsiniz. Bu, bazı Boole mantığına yeni bir koşul enjekte etmeyi veya sıfıra bölme gibi bir hatayı koşullu olarak tetiklemeyi içerebilir.
- Sorgunun işlenmesinde koşullu olarak bir zaman gecikmesi tetikleyebilir ve uygulamanın yanıt vermesi için geçen süreye dayalı olarak koşulun doğruluğunu çıkarsamanıza olanak tanıyabilirsiniz.
- kullanarak bant dışı ağ etkileşimini tetikleyebilirsiniz. OAST teknikler. Bu teknik son derece güçlüdür ve diğer tekniklerin çalışmadığı durumlarda işe yarar. Genellikle, verileri, örneğin kontrol ettiğiniz bir etki alanı için bir DNS aramasına yerleştirerek, bant dışı kanal aracılığıyla doğrudan sızdırabilirsiniz.
Daha fazla oku
Blind SQL injectionSQL enjeksiyon güvenlik açıkları nasıl tespit edilir
SQL enjeksiyon güvenlik açıklarının çoğu, Burp Suite kullanılarak hızlı ve güvenilir bir şekilde bulunabilir. Web güvenlik açığı tarayıcısı.
SQL enjeksiyonu, uygulamadaki her giriş noktasına karşı sistematik bir test seti kullanılarak manuel olarak tespit edilebilir. Bu genellikle şunları içerir:
-
Tek tırnak karakteri gönderme
'
ve hataları veya diğer anormallikleri aramak. - Giriş noktasının temel (orijinal) değerini ve farklı bir değeri değerlendiren SQL'e özgü bazı sözdizimlerini göndermek ve sonuçta ortaya çıkan uygulama yanıtlarında sistematik farklılıklar aramak.
-
Gibi Boolean koşullarının gönderilmesi
OR 1=1
veOR 1=2, and
uygulamanın yanıtlarında farklılıklar aranıyor. - Bir SQL sorgusu içinde yürütüldüğünde zaman gecikmelerini tetiklemek için tasarlanmış yükleri göndermek ve yanıt vermek için geçen süredeki farklılıkları aramak.
- Bir SQL sorgusu içinde yürütüldüğünde bant dışı ağ etkileşimini tetiklemek için tasarlanmış OAST yüklerini gönderme ve sonuçta ortaya çıkan etkileşimleri izleme.
Sorgunun farklı bölümlerinde SQL enjeksiyonu
SQL enjeksiyon güvenlik açıklarının çoğu, WHERE
a'nın tümcesi SELECT
sorgu. Bu tür SQL enjeksiyonu genellikle deneyimli test uzmanları tarafından iyi anlaşılır.
Ancak SQL enjeksiyon güvenlik açıkları, ilke olarak, sorgu içindeki herhangi bir yerde ve farklı sorgu türleri içinde ortaya çıkabilir. SQL enjeksiyonunun ortaya çıktığı en yaygın diğer konumlar şunlardır:
-
İçinde
UPDATE
ifadeler, güncellenmiş değerler veyaWHERE
cümle. -
İçinde
INSERT
ifadeler, eklenen değerler içinde. -
İçinde
SELECT
tablo veya sütun adı içindeki ifadeler. -
İçinde
SELECT
açıklamaları, içindeORDER BY
cümle.
İkinci dereceden SQL enjeksiyonu
Birinci dereceden SQL enjeksiyonu, uygulamanın bir HTTP isteğinden kullanıcı girdisi aldığı ve bu isteğin işlenmesi sırasında girdiyi güvenli olmayan bir şekilde bir SQL sorgusuna dahil ettiği durumlarda ortaya çıkar.
İkinci dereceden SQL enjeksiyonunda (aynı zamanda depolanmış SQL enjeksiyonu olarak da bilinir), uygulama bir HTTP isteğinden kullanıcı girdisini alır ve gelecekte kullanmak üzere saklar. Bu genellikle girdiyi bir veritabanına yerleştirerek yapılır, ancak verilerin depolandığı noktada herhangi bir güvenlik açığı oluşmaz. Daha sonra, farklı bir HTTP isteğini işlerken, uygulama depolanan verileri alır ve güvenli olmayan bir şekilde bir SQL sorgusuna dahil eder.
İkinci dereceden SQL enjeksiyonu genellikle geliştiricilerin SQL enjeksiyon güvenlik açıklarından haberdar olduğu ve bu nedenle girdinin veritabanına ilk yerleşimini güvenli bir şekilde ele aldığı durumlarda ortaya çıkar. Veriler daha sonra işlendiğinde, daha önce veri tabanına güvenli bir şekilde yerleştirildiği için güvenli kabul edilir. Bu noktada veriler güvenli olmayan bir şekilde işlenir, çünkü geliştirici yanlış bir şekilde verilerin güvenilir olduğunu düşünür.
Veritabanına özgü faktörler
SQL dilinin bazı temel özellikleri, popüler veritabanı platformlarında aynı şekilde uygulanır ve SQL enjeksiyon güvenlik açıklarını algılamanın ve kullanmanın birçok yolu, farklı veritabanı türlerinde aynı şekilde çalışır.
Ancak, ortak veritabanları arasında da birçok fark vardır. Bunlar, SQL enjeksiyonunu tespit etmeye ve kullanmaya yönelik bazı tekniklerin farklı platformlarda farklı şekilde çalıştığı anlamına gelir. Örneğin:
- Dize birleştirme için sözdizimi.
- Yorumlar.
- Toplu (veya yığılmış) sorgular.
- Platforma özel API'ler.
- Hata mesajları.
Daha fazla oku
SQL enjeksiyon hile sayfasıSQL enjeksiyonu nasıl önlenir
SQL enjeksiyonunun çoğu örneği, sorgu içinde dize birleştirme yerine parametreli sorgular (hazırlanmış ifadeler olarak da bilinir) kullanılarak önlenebilir.
Kullanıcı girişi doğrudan sorguda birleştirildiğinden, aşağıdaki kod SQL enjeksiyonuna karşı savunmasızdır:
String query = "SELECT * FROM products WHERE category = '"+ input + "'";
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(query);
Bu kod, kullanıcı girdisinin sorgu yapısına müdahale etmesini önleyecek şekilde kolayca yeniden yazılabilir:
PreparedStatement statement = connection.prepareStatement("SELECT * FROM products WHERE category = ?");
statement.setString(1, input);
ResultSet resultSet = statement.executeQuery();
Parametreli sorgular, sorguda güvenilmeyen girdinin veri olarak göründüğü herhangi bir durum için kullanılabilir.WHERE
cümlesi ve değerleri bir INSERT
veya UPDATE
Beyan. Tablo veya sütun adları gibi sorgunun diğer bölümlerindeki güvenilmeyen girdileri veya ORDER BY
madde. Sorgunun bu bölümlerine güvenilmeyen verileri yerleştiren uygulama işlevselliğinin, izin verilen giriş değerlerini beyaz listeye alma veya gerekli davranışı sağlamak için farklı mantık kullanma gibi farklı bir yaklaşım benimsemesi gerekecektir.
Parametreli bir sorgunun SQL enjeksiyonunu önlemede etkili olması için, sorguda kullanılan dizenin her zaman sabit kodlanmış bir sabit olması ve hiçbir zaman herhangi bir kaynaktan herhangi bir değişken veri içermemesi gerekir. Bir veri öğesinin güvenilir olup olmadığına tek tek karar vermek için cazip olmayın ve güvenli kabul edilen durumlar için sorgu içinde dize birleştirmeyi kullanmaya devam edin. Verilerin olası kökeni hakkında hata yapmak veya diğer kodlardaki değişikliklerin hangi verilerin kusurlu olduğuna ilişkin varsayımları ihlal etmesi çok kolaydır.
Yorum yaptığın için teşekkürler