SQL Injection Nedir? Hacker gibi düşün.. Bölüm 1

Diğer konulardan farklı olacak buradan sonra bölüm 1 bölüm 2 gibi konular gelecek takip ederseniz sıfırdan başlayan arkadaşlar için bir destek seviyesindedir, bu yazı, Efendim...

Diğer konulardan farklı olacak buradan sonra bölüm 1 bölüm 2 gibi konular gelecek takip ederseniz sıfırdan başlayan arkadaşlar için bir destek seviyesindedir, bu yazı, Efendim ben okumam direkt sonuca giderim derseniz mal olursunuz, okuyun ve mantığını çözün sonrası emin olun çok daha kolay olacak, Bir hacker bir siteye baktığında çoğu kişinin gördüğünü görmez.


Sen bir giriş formu görürsün.
O, arka tarafta çalışan sorguyu düşünür.


Sen bir arama kutusu görürsün.
O, o kutudan çıkan verinin hangi tabloya dokunduğunu merak eder.


Çünkü deneyimli biri şunu bilir:
Bir web uygulamasının ön yüzü sadece vitrindir. Asıl oyun arkada döner. Orada veritabanı vardır. Kullanıcılar vardır. Siparişler vardır. Kayıtlar vardır. Ve eğer geliştirici kullanıcıdan gelen veriyi sorguya yanlış bağladıysa, o zaman kullanıcı sadece veri göndermiyordur; bazen sorgunun akışına dokunuyordur. PortSwigger, SQL injection’ı uygulamanın veritabanına yaptığı sorgulara müdahale etmeye izin veren bir açık olarak tanımlar; bunun sonucu normalde görülemeyen verilerin açığa çıkması, hatta bazı durumlarda verinin değiştirilmesi veya silinmesi olabilir.


Hacker önce neye bakar?​


İlk bakışta şunu sorar:


“Bu uygulama benim verdiğim değeri gerçekten veri gibi mi kullanıyor, yoksa sorgunun içine mi karıştırıyor?”

Çünkü SQL injection’ın kalbi burada atar.


Mesela sistem, kullanıcı adı aramak için arkada şöyle bir sorgu çalıştırıyor olabilir:



SELECT * FROM users WHERE username = 'ali';



Bu sorgu normaldir.
Sorun, bu sorgunun nasıl üretildiğinde başlar.


Güvenli olmayan mantık nasıl görünür?​


Kötü yazılmış bir uygulama bazen şunu yapar:



Kullanıcıdan gelen değeri al
ve sorgunun içine doğrudan ekle



Bunun arka plandaki mantığı kabaca şöyledir:



SELECT * FROM users WHERE username = 'KULLANICI_GIRDISI';



Yani uygulama “kullanıcı ne yazdıysa onu bu SQL cümlesinin içine koyayım” diye düşünür.


Hacker’ın tam o anda gözleri parlar.
Çünkü o artık form görmüyordur.
Birleştirilmiş bir SQL cümlesi görüyordur.


Uygulama şöyle bir kod mantığıyla yazılmış olabilir:



$username = $_POST['username'];
$query = "SELECT * FROM users WHERE username = '" . $username . "'";



Buradaki problem çok nettir:
Kullanıcının girdiği veri, SQL komutunun içine karışmıştır. OWASP, SQL injection’ın temel nedenini güvenilmeyen verinin sorguya güvenli ayrıştırma olmadan dahil edilmesi olarak açıklar; buna karşı temel savunma da parameterized/prepared query kullanmaktır.


Hacker bunu nasıl okur?​


Normal kullanıcı burada şunu görür:


“Kullanıcı adı giriyorum.”

Hacker ise şunu görür:


“Benim girdiğim şey, WHERE username = '...' kısmının içine oturuyor.”

Bu çok kritik bir farktır.


Çünkü bir hacker saldırıya önce “ne yazayım?” diye başlamaz.
Önce şöyle düşünür:


  • Benim verim sorgunun neresine gidiyor?
  • Metin alanına mı?
  • Sayı alanına mı?
  • Filtre şartına mı?
  • Sıralama kısmına mı?
  • Arama bölümüne mi?

İyi öğretici tam burada devreye girer ve der ki:


“SQLi öğrenmek istiyorsan, payload ezberleme.
Önce verinin sorgudaki yerine bak.”



Bir arama kutusunu hacker nasıl görür?​


Dışarıdan bakınca kutu masum görünür:



Ama arkada şöyle bir sorgu olabilir:



SELECT id, name, price
FROM products
WHERE name LIKE '%telefon%';



Bu gayet normal görünüyor.
Fakat uygulama bunu güvenli kurmuyorsa, örneğin kullanıcıdan gelen metni doğrudan bu yapının içine yerleştiriyorsa, işte risk burada başlar.


Örneğin arama değeri önce alınır:



search = request.GET["q"]



Sonra güvensiz biçimde sorguya eklenirse:



query = "SELECT id, name, price FROM products WHERE name LIKE '%" + search + "%'"



hacker hemen şunu anlar:


“Benim girdiğim veri, LIKE '%...%' bloğunun ortasına giriyor.”

Yani o noktada mesele arama yapmak değildir.
Mesele, uygulamanın güven sınırını yanlış yerde çizmiş olmasıdır.


Bir giriş ekranı nasıl riskli hale gelir?​


Giriş ekranı için tipik mantık şudur:



SELECT * FROM users
WHERE username = 'kullanici'
AND password = 'sifre';



Bu cümleyi okuyan sıradan biri der ki:


“Tamam, kullanıcı adı ve şifre kontrol ediliyor.”

Bir hacker ise der ki:


“Bu değerler sorguya hangi yöntemle bağlandı?”

Çünkü eğer geliştirici şunu yaptıysa:



const query =
"SELECT * FROM users WHERE username = '" +
username +
"' AND password = '" +
password +
"'";



o zaman kullanıcı adı ve şifre sadece veri değildir; sorgu cümlesine bağlanmış ham içeriktir.


Ve hacker şunu düşünür:


“Eğer uygulama veri ile SQL komutunu ayırmıyorsa, sorun burada.”

Bu yüzden SQL injection bazen çok şatafatlı değil, aksine çok sessiz bir hatadır.
Bir string birleştirmesi kadar küçük başlar.
Ama etkisi hesap ele geçirmeden veri sızıntısına kadar büyüyebilir. PortSwigger ve OWASP, veritabanlarının hassas bilgiler tuttuğunu ve başarılı SQL injection’ın veri görüntüleme, değiştirme veya silmeye kadar gidebildiğini açıkça söylüyor.


Hacker’ın “vay be” dediği an nedir?​


O an şudur:


Uygulama aslında kullanıcıdan sadece bilgi almak istiyordur.
Ama kod öyle yazılmıştır ki, kullanıcı verisi sorgunun anlamını etkileyebilecek kadar içeri alınmıştır.


Yani sistem aslında şunu söylemektedir:


“Ben sana güveniyorum.
Yazdığın şeyi sorgunun içine koyacağım.”

İşte SQL injection’ın bütün trajedisi burada.


Kod tarafında küçük bir kolaycılık yapılır:



String sql = "SELECT * FROM orders WHERE id = " + orderId;



Burada geliştirici için bu satır masum olabilir.
Ama hacker için bu satır bir alarmdır.


Çünkü o artık şunu bilir:


  • orderId sayı mı?
  • Tip kontrolü var mı?
  • Sorgu sabit mi?
  • Parametre mi kullanılmış?
  • Hata yakalanıyor mu?
  • Girdi doğrulanıyor mu?

Demek ki SQLi sadece “sorgu var” konusu değildir.
Asıl mesele şudur:


“Kullanıcıdan gelen şey, SQL komutundan ayrı tutulmuş mu?”

OWASP’ın önerdiği parameterized query yaklaşımı tam olarak bunun için var: sorgunun yapısı sabit kalır, kullanıcı girdisi ayrı parametre olarak bağlanır; böylece girilen değer sorgunun niyetini değiştiremez.


Güvenli yaklaşım nasıl görünür?​


Aynı kullanıcı araması güvenli şekilde şöyle kurulabilir:


PHP örneği​



$stmt = $pdo->prepare("SELECT * FROM users WHERE username = :username");
$stmt->execute(["username" => $username]);



Python örneği​



cursor.execute(
"SELECT * FROM users WHERE username = %s",
(username,)
)



Java örneği​



PreparedStatement ps = conn.prepareStatement(
"SELECT * FROM users WHERE username = ?"
);
ps.setString(1, username);



Burada çok önemli bir fark var:


  • İlk örneklerde veri, sorgu metninin içine yapıştırılıyordu.
  • Burada veri, sorgudan ayrı geçiriliyor.

OWASP buna açıkça en güçlü savunmalardan biri olarak işaret ediyor.


Hacker neden bunu hemen fark eder?​


Çünkü o ekrana değil, akışa bakar.


Bir arama kutusunda şunu düşünür:



SELECT * FROM products WHERE category = 'elektronik';



Bir sıralama menüsünde şunu düşünür:



SELECT id, name, price FROM products ORDER BY price;



Bir filtre ekranında şunu düşünür:



SELECT * FROM invoices WHERE customer_id = 42;



Sonra kendine şu soruları sorar:


  • Bu değer sabit mi?
  • Kullanıcıdan mı geliyor?
  • Doğrulanıyor mu?
  • Tipi gerçekten sınırlandırılmış mı?
  • Parametreli mi, yoksa string birleştirme mi?
Bu yazı: https://spyhackerz.org/ için yazılmıştır kaynaksız lütfen paylaşmayın.
 
💬 SpyHackerz Telegram — Anlık tartışmalar ve duyurular için katıl
132,229Konular
3,277,534Mesajlar
317,248Kullanıcılar
spdySon Üye
Üst Alt