CSRF
1、挖洞经验:
(1)黑盒:CSRF主要是用于越权操作,管理后台、会员中心、论坛帖子以及交易管理等,这几个场景里面,管理后台又是最高危的地方。我们在挖掘CSRF的时候可以先搭建好环境,打开几个有非静态操作的页面,抓包看看有没有token,如果没有token的话,再直接请求这个页面,不带referer。如果返回的数据还是一样的话,那说明很有可能有CSRF漏洞了。
(2)白盒:只要读代码的时候看看几个核心文件里面有没有验证token和referer相关的代码,这里的核心文件指的是被大量文件引用的基础文件,或者直接搜”token”这个关键字也能找,如果在核心文件没有,再去看看你比较关心的功能点的代码有没有验证。
可以看YzmCMS v5.7审计的那个CSRF漏洞,那个cms虽然做了CSRF处理,但可以绕过,用哪个场景更能理解,天目MVC v1.381中的CSRF如下面的场景一般,跟本没有检测referer和token。虽可以复现但做完也可能让人摸不着头脑。
2、搜索关键词
token,referer,common
前端
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>login</title></head><body><form action="./login.php" method="post">账号:<input type="text" name="username"><br >密码:<input type="password" name="passwd"> <br ><input type="submit" value="提交" name="login"></form></body></html>
后端登录验证
<?phpheader("content-type:text/html;charset=utf-8");if (!isset($_POST['login'])){echo '<script>';echo 'window.location.href="login.html"';echo '</script>';exit("非法访问");}else{$username = $_POST['username'];$passwd = $_POST['passwd'];$connect = mysql_connect("127.0.0.1","root","123456");mysql_select_db("admin",$connect);$sql = "SELECT * FROM user WHERE username = '$username' and passwd = '$passwd'";$result = mysql_query($sql);mysql_close();if($row = mysql_fetch_array($result)){session_start();$_SESSION['username'] = $row['username'];echo $_SESSION['username'].'欢迎登录';echo "<a href = 'reg.php'>添加用户</a>";}else{echo "fale!";}}
后端注册
<?php
session_start();
header("content-type:text/html;charset=utf-8");
if(!isset($_SESSION['username'])){
echo '<script>';
echo 'alert("请登入用户");window.location.href="login.php"';
echo '</script>';
exit();
}
if(!empty($_POST['submit'])){
$username = addslashes($_POST['username']);
$passwd = addslashes($_POST['passwd']);
$connect = mysql_connect("127.0.0.1","root","123456");
mysql_select_db("admin",$connect);
$sql = "INSERT INTO user (username,passwd) VALUE ('$username','$passwd');";
$result = mysql_query($sql) or die("执行命令失败".mysql_error());
mysql_close();
if($result){
echo "regist success!";
}else{
echo "regist fail!";
}
}else{
echo "not POST!";
}
?>
<form action="reg.php" method="POST">
username: <input type="text" name="username"><br>
passwd: <input type="password" name="passwd"><br>
<input type="submit" name="submit" value="提交">
</form>
3、修复方案
• 验证码
• 添加 Referer 验证
• 添加 Token 验证
• 修改密码之类的功能验证原密码
token验证
< ? php
session_start();
function set_token() {
$_SESSION['token'] = md5 (time ()+rand ( 1 , 1000 ));
}
function check_token () {
if (isset ($_POST['token'] ) &&$_POST['token'] === $_SESSION['token'])
{
return true ;
}
else{
return false;
}
}
if (isset ( $_SESSION['token'] ) &&check_token ()) {
echo "success" ;
}
else{
echo "failed";
}
set_token ();? >
<form method="post">
<input type="hidden" name="token" value="< ? =$_SESSION['token'] ? >">
<input type="submit"/>
</form>
