CSRF与SSRF
本文最后更新于:2023年4月13日 晚上
何为CSRF
CSRF (Cross-Site Request Forgery) 即跨站请求伪造,CSRF利用的是对用户浏览器的信任,如果用户登陆了一个网站浏览器就会保存用户的cookie,以后对该域的的每一个请求都会携带用户凭证(cookie),这时攻击者发送了某个操作的链接给用户,用户点击之后,就会携带自己的cookie发起请求,完成相应的操作。
CSRF的分类[1]
GET类型
对应的csrf是通过get请求产生的,例如通过img标签:
1 |
|
当用户访问包含csrf链接的图片的页面时,就会产生get型csrf。
POST类型
对应的csrf是通过post请求产生的,通常是利用表单提交:
1 |
|
当用户访问包含csrf的表单的页面时,就会产生post型csrf。
链接类型
对应的csrf是通过点击链接产生的,通常是利用a标签:
1 |
|
当用户点击链接想去砍兄弟时,就会产生链接型csrf。
其他类型
过基础认证的csrf,通常用于路由器:
1 |
|
加载图片后,路由器会给用户一个合法的session。
CSRF的防御
验证 Referer
referer 记录了http请求的来源地址,因为csrf攻击一般都是通过跨域发起的请求,所有验证referer是否来自本域或者上一级页面能够有效防止部分csrf,但因为referer是依赖第三方来保障的(例如浏览器),所以此方法并不算安全。
token
从csrf的实现原理来看,是因为攻击者能够构造用户的请求,所以可以在http请求里以参数的形式加入一个随机的token,并在服务器建立一个拦截器验证这个token,相对于referer,token要更加安全一些。但是token的安全也是难以保证万无一失的,在一些支持用户自己发表内容的网站上,如果攻击者把个人网站发布在上面,当用户点击之后也可能携带自己的token去访问,这样攻击者就可以得到这个token。如果在添加token功能处添加判断,当通向他域的时候不添加token,攻击者也可以通过referer拿到这个token值。所以添加token的方法也并不完美。
http头自定义属性
这种形式是通过把token放置到http头自定义属性里,通过XMLHttpRequest这个类,可以一次性给所有该类请求加上csrftoken这个HTTP头属性,并把token值放入其中。这样解决了上种方法在请求中加入token的不便,同时,通过XMLHttpRequest请求的地址不会被记录到浏览器的地址栏,也不用担心token会透过Referer泄露到其他网站中去。然而这种方法的局限性非常大。XMLHttpRequest请求通常用于Ajax方法中对于页面局部的异步刷新,并非所有的请求都适合用这个类来发起,而且通过该类请求得到的页面不能被浏览器所记录下,从而进行前进,后退,刷新,收藏等操作,给用户带来不便。另外,对于没有进行CSRF防护的遗留系统来说,要采用这种方法来进行防护,要把所有请求都改为XMLHttpRequest请求,这样几乎是要重写整个网站,这代价无疑是不能接受的。
使用严格的 SameSite
Cookie 有一个 SameSite 属性,设置为严格模式(非 none 值),可以让其他网站的中跨域请求不带上 Cookie。
人机校验
加一个短信校验、邮箱校验、验证码什么的,确保是一个人在尝试发这个请求。缺点是用户体验不太好。
双重Cookie验证
利用CSRF攻击不能获取到用户Cookie的特点,我们可以要求Ajax和表单请求携带一个Cookie中的值。后端接口验证Cookie中的字段与URL参数中的字段是否一致,不一致则拒绝。
优点是可以直接通过前后端拦截的的方法自动化实现。后端校验也更加方便,只需进行请求中字段的对比,而不需要再进行查询和存储Token。
缺点是任何跨域都会导致前端无法获取Cookie中的字段(包括子域名之间),而且如果有其他漏洞(例如XSS),攻击者可以注入Cookie,那么该防御方式失效。
何为SSRF
SSRF (Server-Side Request Forgery) 即服务端请求伪造,SSRF利用的是对服务器的信任,服务器使用用户输入的URL进行资源请求时,未对该URL进行安全校验,通过伪造一个服务端请求发起攻击,攻击者借由服务端为跳板来攻击目标系统。
SSRF 发生的地点
- 社交分享功能:获取超链接的标题等内容进行显示
- 转码服务:通过URL地址把原地址的网页内容调优使其适合手机屏幕浏览
- 在线翻译:给网址翻译对应网页的内容
- 图片加载/下载:例如富文本编辑器中的点击下载图片到本地;通过URL地址加载或下载图片
- 图片/文章收藏功能:主要网站会取URL地址中title以及文本的内容作为显示以求一个好的用户体验
- 云服务厂商:它会远程执行一些命令来判断网站是否存活等,所以如果可以捕获相应的信息,就可以进行SSRF测试
- 网站采集,网站抓取的地方:一些网站会针对你输入的url进行一些信息采集工作
- 数据库内置功能:数据库的比如mongodb的copyDatabase函数
- 邮件系统:比如接收邮件服务器地址
- 编码处理, 属性信息处理,文件处理:比如ffpmg,ImageMagick,docx,pdf,xml处理器等
- 未公开的api实现以及其他扩展调用URL的功能:可以利用google 语法加上这些关键字去寻找SSRF漏洞,一些的url中的关键字:share、wap、url、link、src、source、target、u、3g、display、sourceURl、imageURL、domain……
- 从远程服务器请求资源(upload from url 如discuz!;import & expost rss feed 如web blog;使用了xml引擎对象的地方 如wordpress xmlrpc.php)
SSRF 危险函数
1 |
|
SSRF 伪协议
- file协议: 只能读取当前被攻击机的文件,内网机器文件不能读取
- dict协议:泄露安装软件版本信息,查看端口,操作内网redis服务等
- gopher协议:gopher支持发出GET、POST请求。可以先截获get请求包和post请求包,再构造成符合gopher协议的请求。gopher协议是ssrf利用中一个最强大的协议(俗称万能协议)。可用于反弹shell
- SFTP协议
- TFTP协议
- LDAP协议
SSRF的防御与绕过
防御:
- 限制域名: 匹配允许访问的网址
- 限制协议: 仅允许http和https请求。
- 限制IP: 避免应用被用来获取内网数据,攻击内网。
- 限制端口: 限制请求的端口为http常用的端口,比如,80,443,8080,8090。
- 过滤返回信息: 验证远程服务器对请求的响应是比较简单的方法。
- 统一错误信息: 免用户可以根据错误信息来判断远端服务器的端口状态
绕过:
使用
@
绕过1
http//baidu.com@1.1.1.1 // 与http://1.1.1.1效果是一样的
进制转换
1
2
3
4
5
6
7
8字符串: 10.0.0.3
二进制: 00001010 . 00000000 . 00000000 . 00000011
十六进制: 0A.00.00.03
整数: 167772163
// 8进制代替10进制,在计算机的世界里,一旦在20前面加个0就会变成8进制
十六进制: http://0x0A.0x00.0x00.0x03
八进制: http://012.00.00.03
八进制溢出: http://265.0.0.3使用
。
代替.
1
http://127。0.0.1 // http://127.0.0.1
泛域名解析
使用xip.io(37signals开发实现的定制DNS服务) 和 xip.name 绕过:1
2
3
410.0.0.1.xip.io # 解析到 10.0.0.1
www.10.0.0.2.xip.io # www 子域解析到 10.0.0.2
mysite.10.0.0.3.xip.io # mysite 子域解析到 10.0.0.3
foo.bar.10.0.0.4.xip.io # foo.bar 子域解析到 10.0.0.4127.0.0.1 绕过
1
2
3http://localhost:80
http://[::]:80
http://0/Enclosed alphanumerics
1
http://ⓔⓧⓐⓜⓟⓛⓔ.ⓒⓞⓜ // http://example.com
使用302跳转
DNS重绑