Bu uygulamanın kaynak kodunda “eregi” metodu kullanılmaktadır. PHP‘deki POSIX düzenli ifade işlevlerinden olan “eregi” metodu, düzenli ifadeyi büyük/küçük harf duyarsız olarak karşılaştırır. Metodun ilk parametresi, ikinci parametresinde geçiyorsa doğru (True), geçmiyorsa yanlış (False) sonuç döndürür. Örnek:
1 2 3 4 5 6 |
<?php $ifade = 'ABCDE'; if (eregi('d', $ifade)) { echo "'$ifade' dizgesi bir 'd' veya 'd' içeriyor!"; } ?> |
Ayrıntılı bilgi için PHP klavuzu incelenebilir.
http://php.net/manual/tr/function.eregi.php
Mevcut uygulamada etkin bir kontrol (eski parolayı sormak gibi) olmadan parola değiştirilebilmektedir. Gerçekleştirilen tek kontrol HTTP başlıklarındaki sunucuya ait 2 değerden birincisinin (SERVER_NAME) ikincisi (HTTP_REFERER) içerisinde bulunup bulunmadığıdır.
if ( eregi ( $_SERVER[‘SERVER_NAME’], $_SERVER[‘HTTP_REFERER’] ) ){
Not: Bazı DVWA sürümlerinde “$_SERVER[‘SERVER_NAME’]” yerine “127.0.0.1” yazılı olabilir. Uygulamanın düzgün çalışması için “if” ile başlayan bu kontrolün yukarıdaki gibi değiştirilmesi gereklidir.
vi /var/www/dvwa/vulnerabilities/csrf/source
Parola değişikliği için belirlenen parola (“deneme123” gibi) yazıldığında, elde edilen URL ve ekran görüntüsü aşağıdaki gibidir.
http://10.10.2.156/dvwa/vulnerabilities/csrf/?password_new=deneme123&password_conf=deneme123&Change=Change#
Burp ile yakalanan talep içeriğinde de görüldüğü gibi, parola URL içerisinde (GET metodu ile) taşınmakta ve yeni parola bu şekilde belirlenmiş olmaktadır.
Oturumu açık bir kullanıcı parolasını değiştirmek istediğinde URL içerisindeki parola bilgisini güncellemesi yeterli olacaktır. Yani, kullanıcı parolasını “Aa123456” yapmak isterse kullanıcının aşağıdaki linke tıklaması yeterli olamayacaktır. Çünkü HTTP_REFERER alanı sunucuya gitmemektedir ve “if” blokları içerisindeki karşılaştırma işlemi başarısız sonuç dönmektedir.
http://10.10.2.156/dvwa/vulnerabilities/csrf/?password_new=Aa123456&password_conf=Aa123456&Change=Change#
Uygulamanın kaynak koduna aşağıdaki 2 satır eklendiğinde SERVER_NAME ve HTTP_REFERER alanlarının aldığı değerler ekrana basılabilir.
$html .= “<pre> Sunucu Host Adı (SERVER_NAME):” . $_SERVER[‘SERVER_NAME’] . “</pre>”;
$html .= “<pre> Talep Kaynağı (HTTP_REFERER):” . $_SERVER[‘HTTP_REFERER’] . “</pre>”;
SERVER_NAME ve HTTP_REFERER alanlarının kontrol edilmesi CSRF saldırısını engellemek için kullanılmıştır. Saldırgan, kurbana aşağıdaki URL’i göndererek tıklamasını sağladığında, kurbanın oturumu açık olsa bile kurbanın parolası, saldırganın belirlediği şekilde (Parola12345) ayarlanmayacaktır. Çünkü HTTP_REFERER alanı boş olarak iletilecektir.
http://10.10.2.156/dvwa/vulnerabilities/csrf/?password_new=Parola12345&password_conf=Parola12345&Change=Change#
Benzer olarak yukarıdaki bağlantı, resim dosyasının kaynağına ekleme gibi bir yöntemle saldırgana ait bir web sayfasından çağrılsa bile parola değişmeyecektir. Örneğin; 10.10.2.128 IP adresi saldırganın yönetiminde olan bir web sitesi olduğu durumda, saldırganın kurbana gönderdiği link aşağıdaki gibi olsun.
http://10.10.2.128/oltalama.html
Bu linke tıklandığında sayfa içerisindeki gizli (boyutları 0x0 olarak belirtilmiş) resim dosyası CSRF zafiyeti barındıran sayfaya (10.10.2.156 sunucusuna) bir talepte bulunacaktır. Eğer kurbanın zafiyeti barındıran uygulamada oturumu açıksa bu talebi yapan kullanıcının oturum bilgileri ile talep gerçekleşecektir. Ancak SERVER_NAME değeri, HTTP_REFERER değeri içerisinde olmadığı için parola değişmeyecektir. Saldırganın hazırladığı sayfa içeriğinin aşağıdaki gibi olduğu durumda; kurban, web sayfasına SERVER_NAME değeri “10.10.2.156”, HTTP_REFERER değeri olarak da “http://10.10.2.128/oltalama.html” yollayacağı için “if” kontrolü içerisine girilmeyecektir.
1 2 3 4 5 6 7 8 9 |
<html> <head> <title>Saldirgan Web Sayfasi</title> </head> <body> <p>Asagidaki gizli resim CSRF zafiyeti olan sayfaya bir talep yapmaktadir. </p> <img src="http://10.10.2.156/dvwa/vulnerabilities/csrf/?password_new=Parola12345&password_conf=Parola12345&Change=Change#" width="0" height="0"> </body> </html> |
Bunun yanında saldırganın hazırladığı web sayfasının kaynak kodu değiştirilmeden; URL’i sunucu IP adresini içerecek olursa bu koruma mekanizması atlatılabilir. Yani saldırganın kurbana gönderdiği link aşağıdaki gibi olursa; SERVER_NAME değeri “10.10.2.156”, HTTP_REFERER değeri de “http://10.10.2.128/oltalama-10.10.2.156-sayfasi.html” olacağı için “if” bloğuna girilecektir. Bu durumda, eğer kurbanın zafiyeti barındıran uygulamada oturumu açıksa, bu talebi yapan kullanıcının (kurbanın) oturum bilgileri ile talep gerçekleşecek ve parola saldırganın belirlediği şekilde ayarlanmış olacaktır.
http://10.10.2.128/oltalama-10.10.2.156-sayfasi.html
Not: Referer olarak CSRF barındıran web sayfasının SERVER_NAME değeri içerecek şekilde URL kullanılabileceği gibi, alt etki alanı da kullanılabilirdi. Örneğin zafiyetli uygulama “www.websitesi.com.tr” ve saldırgana ait olan etki alanı “www.saldirgan.com.tr” ise aşağıdaki gibi bir web sayfası kurbana yollansaydı da CSRF zafiyeti istismar edilebilirdi. Çünkü HTTP_REFERER değeri, SERVER_NAME değerini içerecektir.
wWw.websitesi.COm.tR.www.saldirgan.com.tr
İlgili Kaynak Kod:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<?php if (isset($_GET['Change'])) { // Checks the http referer header if ( eregi ( $_SERVER['SERVER_NAME'], $_SERVER['HTTP_REFERER'] ) ){ // Turn requests into variables $pass_new = $_GET['password_new']; $pass_conf = $_GET['password_conf']; if ($pass_new == $pass_conf){ $pass_new = mysql_real_escape_string($pass_new); $pass_new = md5($pass_new); $insert="UPDATE `users` SET password = '$pass_new' WHERE user = 'admin';"; $result=mysql_query($insert) or die('<pre>' . mysql_error() . '</pre>' ); echo "<pre> Password Changed </pre>"; mysql_close(); } else{ echo "<pre> Passwords did not match. </pre>"; } } } ?> |
Kaynak:
https://medium.com/@dannybeton/dvwa-csrf-tutorial-medium-security-e14724ceee8a#.cikb6hdb9