欢迎光临
我们一直在努力

DVWA Medium CSRF安全测试与防护分析

注意:有关CSRF漏洞的基础知识与原理已在上篇文章指出,此处不再解释。
可参考该文章https://www.cnblogs.com/lky-sec/articles/21412117
本文仅用于网络安全学习与防御研究。所有测试均在本人本地部署、合法授权的 DVWA 靶场中进行,禁止将相关方法用于任何未授权系统。

一 测试范围与环境

本次测试目标为本地DVWA靶场中的CSRF模块。

项目配置
测试环境 本地 DVWA 靶场
安全等级 Medium
测试系统 Kali Linux
测试工具 Firefox、Burp Suite
测试方式 黑盒测试、源码审计
授权情况 本人本地靶场,合法授权

二 页面与请求分析

1. 设置难度等级

进入DVWA Security,将安全等级设置为Medium,随后进入CSRF模块。
image

2. 观察模块正常功能

CSRF模块提供密码修改功能,需要分别输入新密码和确认密码。
在两个输入框中输入相同的新密码后点击Change,页面提示密码修改成功。
image
由此可以确定,该功能会根据用户提交的新密码参数修改当前登录账户的密码

3. 使用Burp Suite进行抓包分析

开启Burp Suite Proxy模块进行拦截,正常修改一次密码并观察HTTP请求。
image

可以观察到请求头中存在:

Referer: http://localhost:8080/vulnerabilities/csrf/?password_new=1&password_conf=1&Change=Change

Referer 用于表示当前请求由哪个页面跳转或发起。此处不仅包含目标主机 localhost:8080,还保留了上一次访问 CSRF 页面时 URL 中的密码修改参数。

三 手工黑盒测试

1. 使用Repeater模块

右键请求发送至Burp Suite Repeater。
image

2. 测试Low难度利用方式

将刚才的URL的密码1修改为2,复制此URL,在相同浏览器重新打开此URL。发现DVWA靶场被重新打开,但返回结果显示That request didn't look correct.
image
image

3. 尝试绕过请求来源限制

将刚才同时拦截的密码2的请求中,粘贴来自密码1请求的Referer,发现密码更改成功。
image
image
此后经过不断尝试,即便Referer中的新密码值与密码确认值不一致,也可修改密码成功。
image
image
继续尝试,发现只要Referer保留有http://localhost,即可修改成功。
image
image

四 黑盒测试结果分析

测试方式测试结果结果分析
直接使用Low难度URL修改密码 修改失败,返回That request didn't look correct. Medium等级增加了额外的请求来源校验,Low难度直接构造URL的方式失效
使用正常DVWA请求中的Referer 密码修改成功 Referer会影响服务器对请求合法性的判断
Referer中的密码值与实际请求密码不同 仍可修改成功 服务器并未校验Referer中的密码参数,其具体参数内容不是判断依据
Referer中的新密码与确认密码不一致 仍可修改成功 Referer中的密码参数不会参与实际密码一致性校验
将Referer简化为http://localhost 密码修改成功 判断Medium等级主要校验Referer中是否包含目标主机相关内容

五 代码审计

1. 查看Medium源码

点击view source查看源码。

<?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);
}

?>

2. 源码分析

Medium 等级首先通过:

if( stripos( $_SERVER[ 'HTTP_REFERER' ] ,$_SERVER[ 'SERVER_NAME' ]) !== false )

检查请求头中的 Referer 是否包含当前服务器名称。

其中:
$_SERVER['HTTP_REFERER']表示请求来源地址。
而:$_SERVER['SERVER_NAME']表示当前服务器名称。在本地 DVWA 环境中为:localhost stripos() 用于进行不区分大小写的字符串查找,因此只要 Referer 中包含localhost,就会通过来源检查。这与前面黑盒测试中将Referer简化为:http://localhost仍然能够修改密码的现象一致。
通过来源检查后,程序获取新密码和确认密码:

$pass_new = $_GET[ 'password_new' ];
$pass_conf = $_GET[ 'password_conf' ];

并判断两次输入是否一致:

if( $pass_new == $pass_conf )

随后对密码进行数据库转义并使用 md5() 计算哈希值:

$pass_new = mysqli_real_escape_string(…);
$pass_new = md5( $pass_new );

最后更新当前用户密码:

$insert = "UPDATE `users` SET password = '$pass_new'
WHERE user = '" . dvwaCurrentUser() . "';";

Medium相比Low增加了Referer来源校验,但这种方式仅检查来源字符串中是否包含服务器名称,并没有使用随机的CSRF Token验证请求真实性,因此仍然存在绕过可能。
因此,该漏洞的主要原因是:程序仅依赖可绕过的Referer来源检查进行CSRF防护,没有使用不可预测的CSRF Token对敏感操作进行有效验证。

3. 修复方案

1)为密码修改等敏感请求加入随机且不可预测的CSRF Token。
2)在服务端严格验证CSRF Token,并与当前用户会话绑定。
3)不应将Referer作为唯一的CSRF防护手段。
4)密码修改等状态变更操作应使用POST请求,而不是通过GET参数完成。
5)对重要账户操作增加当前密码验证或二次身份认证。
6)为Session Cookie 配置合理的SameSite 属性,降低跨站请求携带 Cookie 的风险。
7)使用安全的密码哈希算法保存密码,避免继续使用 MD5。
8)对异常密码修改请求和来源异常行为进行日志记录与安全监控。

六 Low与Medium差异

对比项LowMedium
请求方式 GET GET
参数获取 password_new、password_conf password_new、password_conf
密码一致性校验
请求来源校验
来源校验方式 检查HTTP_REFERER中是否包含SERVER_NAME
校验函数 stripos()
是否使用CSRF Token
是否依赖Referer
Low难度直接构造URL 可直接利用 通常会被来源校验拦截
Referer绕过 不需要 可通过构造包含服务器名称的Referer绕过
密码处理 mysqli_real_escape_string() + md5() mysqli_real_escape_string() + md5()
数据库更新方式 直接执行UPDATE修改当前用户密码 通过来源校验后执行相同UPDATE操作
CSRF漏洞 存在 仍然存在
主要防护措施 无明显CSRF防护 增加Referer来源检查
主要安全问题 未验证请求真实性 仅依赖可绕过的Referer检查,未使用CSRF Token
根本修复方式 使用CSRF Token等可靠请求验证机制 使用CSRF Token等可靠请求验证机制,避免将Referer作为唯一防护手段
赞(0)
未经允许不得转载:171主机测评 » DVWA Medium CSRF安全测试与防护分析
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址