作者:sunshinena | 来源:互联网 | 2023-09-15 05:17
DVWA下的CSRF通关是怎样的,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。
CSRF跨站点请求伪造(Cross—Site Request Forgery):
跟XSS攻击一样,存在巨大的危害性,你可以这样来理解:
攻击者盗用了你的身份,以你的名义发送恶意请求,对服务器来说这个请求是完全合法的,但是却完成了攻击者所期望的一个操作,比如以你的名义发送邮件、发消息,盗取你的账号,添加系统管理员,甚至于购买商品、虚拟货币转账等。 如下:其中Web A为存在CSRF漏洞的网站,Web B为攻击者构建的恶意网站,User C为Web A网站的合法用户。
CSRF攻击攻击原理及过程如下:
1. 用户C打开浏览器,访问受信任网站A,输入用户名和密码请求登录网站A;
2.在用户信息通过验证后,网站A产生COOKIE信息并返回给浏览器,此时用户登录网站A成功,可以正常发送请求到网站A;
3. 用户未退出网站A之前,在同一浏览器中,打开一个TAB页访问网站B;
4. 网站B接收到用户请求后,返回一些攻击性代码,并发出一个请求要求访问第三方站点A;
5. 浏览器在接收到这些攻击性代码后,根据网站 B 的请求,在用户不知情的情况下携带 COOKIE 信息,向网站 A 发出请求。网站 A 并不知道该请求其实是由 B 发起的,所以会根据用户 C 的 COOKIE 信息以 C 的权限处理该请求,导致来自网站 B 的恶意代码被执行。
与XSS的区别:
XSS是通过修改页面Javascript等代码后,发给用户从而实现盗取COOKIE信息,之后利用COOKIE进行登陆网站等操作。非法操作是黑客。
CSRF并没有盗取COOKIE信息,而是通过用户直接利用COOKIE进行操作。非法操作并不是黑客,而是用户本身。
1、low级别
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( '' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '
' );
// Feedback for the user
echo "Password Changed.
";
}
else {
// Issue with passwords matching
echo "Passwords did not match.
";
}
((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}
?>
可以看到,源码中的mysql_real_escape_string() 函数有防护sql注入的作用,然后就只进行了$pass_new == $pass_conf判断,没有进行任何的验证。
在新密码和确认密码之处填写123456
burp suite抓包发现,通过get请求执行
http://172.21.98.85/DVWA-master/vulnerabilities/csrf/?password_new=123456&password_cOnf=123456&Change=Change#
根据上面的url,进行构造payload:
http://172.21.98.85/DVWA-master/vulnerabilities/csrf/?password_new=test&password_cOnf=test&Change=Change#
这样的payload,一般人都可以看出来存在陷进,往往不会去点击,因此我们还需要进一步伪装,把它缩短。
得到一个短的url:http://r6d.cn/9rGy,提醒一句,以后但凡看见很短的url,然后以很不常见的格式出现,千万别着急点击浏览。
现在的密码已经变成test,不再是123456。
我们还可以编辑一个页面,填好payload,等正常用户浏览访问就执行了。
后缀改成.html.就行了。
真实情况下,这个html文件的表象应该具备各种诱惑力,例如,如何一夜暴富、xxx照等等,让你情不自禁的想去浏览访问。
正当你想开喷时,说好的惊喜呢,怎么是404,哈哈,但其实你已经将你的密码从test修改为password了。
2、medium
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( '' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '
' );
// Feedback for the user
echo "Password Changed.
";
}
else {
// Issue with passwords matching
echo "Passwords did not match.
";
}
}
else {
// Didn't come from a trusted source
echo "That request didn't look correct.
";
}
((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}
?>
先看看里面几个重要的函数
eregi()函数: 匹配符合条件的字符串,已经被preg_match() 替代,加i不区分大小写。
stripos函数:返回字符串在另一字符串中第一次出现的位置,如果没有找到字符串则返回 FALSE。
$_SERVER['HTTP_REFERER'] #链接到当前页面的前一页面的 URL 地址。
$_SERVER['SERVER_NAME'] #当前运行脚本所在服务器主机的名称。
同样的内容,换成1.html
但是实际上没修改完成,因为这个级别的增加了Referer认证,那么将http包头的Referer参数的值中包含主机名就行了。
3、High级别
先放弃,这个token值我一直绕不过去,表示先放弃了,大概绕过的思路知道就行,不求甚解!
4、mpossible级别
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 = mysql_real_escape_string( $pass_curr );
$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 = mysql_real_escape_string( $pass_new );
$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
echo "
Password Changed.
";
}
else {
// Issue with passwords matching
echo "Passwords did not match or current password incorrect.
";
}
}
// Generate Anti-CSRF token
generateSessionToken();
?>
也是采用PDO技术防护了,根据现实情况,一般防护csrf的办法最常见的就是增加原始密码验证,短信验证、验证码验证,这样基本就很难进行scrf攻击了。
看完上述内容,你们掌握DVWA下的CSRF通关是怎样的的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注编程笔记行业资讯频道,感谢各位的阅读!