SSRF&CSRF
SSRF是什么
- SSRF(Server-Side Request Forgery)
是指:攻击者能控制服务器去“主动发起请求”访问任意 URL,包括内网 本地服务 云元数据接口(是一个位于 固定内网 IP 的 HTTP 服务,用于向云主机提供 身份信息、实例信息、临时访问凭证。可以在里面找目录的关键信息)等。(怎么有点被迫代理的感觉)能做到探测内网服务(最常见)访问本地服务 协议扩展
哪种情况能遇到
文章里写了很多常见的漏洞场景 其实总结起来就是服务器会根据用户输入,主动去访问一个地址 / 主机 / URL 根本上说 对于后端函数的使用不当(好吧这样说不好)限制不当
- file_get_contents():将整个文件或一个url所指向的文件读入一个字符串中。
- readfile():输出一个文件的内容。
- fsockopen():打开一个网络连接或者一个Unix 套接字连接。
- curl_exec():初始化一个新的会话,返回一个cURL句柄,供curl_setopt(),curl_exec()和curl_close() 函数使用。
- fopen():打开一个文件文件或者 URL。
常用漏洞
- 读取内网文件(file协议)将服务器上的本地文件及网站源码读取出来比如
?url=file:///var/www/html/flag.php - 探测内网主机存活 原理也就是一个网段里面自己访问得通不
- 端口探测 类似的 看回显版本不(这个payload是这样的)dict协议
1 | ssrf.php?url=dict://192.168.52.131:6379/info // redis |
- Gopher协议(太强了 单开)支持发出GET、POST请求,我们可以先截获GET请求包和POST请求包,再构造成符合Gopher协议请求的payload进行SSRF利用
- Gopher协议格式
1 | URL: gopher://<host>:<port>/<gopher-path>_后接TCP数据流 |
- 利用Gopher协议发送HTTP GET请求
抓取或构造HTTP数据包 比如
1 | GET /echo.php?whoami=Bunny HTTP/1.1 |
脚本搬运一下
1 | mport urllib.parse |
注意事项
注意这几个问题:
- 问号(?)需要转码为URL编码,也就是%3f
- 回车换行要变为%0d%0a,但如果直接用工具转,可能只会有%0a
- 在HTTP包的最后要加%0d%0a,代表消息结束(具体可研究HTTP包结束)
gopher://47.xxx.xxx.72:80/_GET%20/echo.php%3Fwhoami%3DBunny%20HTTP/1.1%0D%0AHost%3A%2047.xxx.xxx.72%0D%0A生成之后
- 利用Gopher协议发送HTTP POST请求
1 | POST /echo.php HTTP/1.1 |
注意:上面那四个HTTP头是POST请求必须的,即POST、Host、Content-Type和Content-Length。如果少了会报错的,而GET则不用。并且,特别要注意Content-Length应为字符串“whoami=Bunny”的长度。
脚本
1 | mport urllib.parse |
相关绕过姿势
先写限制一般有几种
限制请求的端口只能为Web端口,只允许访问HTTP和HTTPS的请求。
限制域名只能为http://www.xxx.com
限制不能访问内网的IP,以防止对内网进行攻击。
屏蔽返回的详细信息。
- 对于- 限制域名只能为
http://www.xxx.com的 采用HTTP基本身份认证的方式绕过www.baidu.com@127.0.0.1则会跳转的127.0.0.1 文章里面说谷歌浏览器是这样 但是我的火狐谷歌都可以。 - 进制转换 绕过内网限制 php脚本可以一键转换:
1 | <?php |
还有一些本地的替换
1 | http://localhost/ # localhost就是代指127.0.0.1 |
- 302跳转绕过 重定向 这一点很妙啊
短地址跳转绕过 文章给的神奇网站已经没了 开始疯狂寻找 https://clck.ru/ 经过多次实验 这个生成的最快且免费 毛子做的
xip.io - 浏览器请求
http://127.0.0.1.xip.io/flag.phpDNS 查询
127.0.0.1.xip.io → 127.0.0.1TCP 连接
connect(127.0.0.1:80)HTTP 请求(非常关键):
GET /flag.php HTTP/1.1 Host: 127.0.0.1.xip.io
- DNS rebinding
在网站 SSRF 漏洞处访问精心构造的域名。网站第一次解析域名,获取到的IP地址为A;
经过网站后端服务器的检查,判定此IP为合法IP。
网站获取URL对应的资源(在一次网络请求中,先根据域名服务器获取IP地址,再向IP地址请求资源),第二次解析域名。此时已经过了ttl的时间,解析记录缓存IP被删除。第二次解析到的域名为被修改后的 IP 即为内网IP B;
攻击者访问到了内网IP。
时间差对应DNS中的机制是TTL。TTL表示DNS里面域名和IP绑定关系的Cache在DNS上存活的最长时间。即请求了域名与iP的关系后,请求方会缓存这个关系,缓存保持的时间就是TTL。而缓存失效后就会删除,这时候如果重新访问域名指定的IP的话会重新建立匹配关系及cache。
在不同的语言,不同服务器中也存在差异
- java中DNS请求成功的话默认缓存30s(字段为networkaddress.cache.ttl,默认情况下没有设置),失败的默认缓存10s。(缓存时间在 /Library/Java/JavaVirtualMachines/jdk /Contents/Home/jre/lib/security/java.security 中配置)
- 在php中则默认没有缓存。
- Linux默认不会进行DNS缓存,mac和windows会缓存(所以复现的时候不要在mac、windows上尝试)
- 有些公共DNS服务器,比如114.114.114.114还是会把记录进行缓存,但是8.8.8.8是严格按照DNS协议去管理缓存的,如果设置TTL为0,则不会进行缓存。
这种脚本网上可以找到很多 先挂上链
https://security.tencent.com/index.php/blog/msg/179
- SSRF新型攻击手法—When TLS Hacks You
理解了好久 自己的理解写了又删 还是搬下来原文了
1 | 当客户端和服务器端初次建立TLS握手时(例如浏览器访问HTTPS网站),需要双方建立一个完整的TLS连接,该过程为了保证数据的传输具有完整性和机密性,需要做很多事情,如密钥协商出会话密钥,数字签名身份验证,消息验证码MAC等。这个过程是非常消耗资源的,而且当下一次客户端访问同一个HTTPS网站时,这个过程需要再重复一次,这无疑会造成大量的资源消耗。 |
只能说太巧妙了 后面寒假去试试复现的 文章链接在上面 to do
CSRF
放在一起的原因是 我觉得和SSRF非常非常相似了 攻击条件很类似于xss
什么是CSRF
CSRF,跨站请求伪造,是一种利用用户已登录状态,诱导浏览器在不知情的情况下向目标站点发送请求的攻击方式。身份用的是用户的 执行的行为是我想执行的
GET请求
<img src="https://xiexie/logout">
当受害者访问该页面时,浏览器会自动向这个url发起一次 GET 请求。
实际请求就是
1 | GET /logout HTTP/1.1 |
浏览器中有大量自动触发 GET 请求的标签
<img><iframe><script><link>
在xss里面的学习也都挺熟悉的了 页面加载即执行
POST请求
1 | <form action="http://bank.example/withdraw" method="POST"> |
<form> 是浏览器原生支持的请求构造机制
action→ 目标接口method→ 请求方式input→ 请求参数hidden参数的攻击意义 用户不可见document.forms[0].submit();按这个 form 的定义,立刻发一个 HTTP 请求
也就是说这个
1 | POST /withdraw HTTP/1.1 |
钓鱼链接
这种其实还是挺有意思的 起码在同学恶搞里面出现的比较多…
如果说想要往出题的方向靠的话 那就做个傻傻的机器人去点所有可以点击的链接
1 | <a href="http://test.com/csrf/withdraw.php?amount=1000&for=hacker" taget="_blank"> |
防御
- 关于同源策略 同源策略是浏览器的安全策略,不是服务器的
只有“同源”的页面,才能互相读取数据;
不同源的页面,默认只能“发请求”,不能“读响应”
三个条件必须全部相同 才能叫同源 协议 域名 端口 ai写了个例子https://www.example.com:443这个与下面的三个都不同源
1 | http://www.example.com:443 |
- 哪些行为被同源策略禁止
- 读取跨源响应内容 比如
1 | fetch("https://bank.example/api/balance") |
请求时能发出的 只是收不到响应
2. 访问跨域页面的 DOM(DOM在xss里面学习过概念 DOM 是浏览器“理解并正在使用的页面结构”)
- 同源:可以访问 DOM 比如
1 | <!-- parent.html --> |
跨源会直接报错的
3. 跨源 Cookie 的 JS 访问 这个很好理解了console.log(document.cookie["bank.example"]); 能这样直接读别人的cookie吗
这里贴一下文章里面的跨站请求带cookie的情况
- 上面是关于外域的访问限制 那么想一下CSRF的关键就是直接用了用户的cookie 但其实没有去管cookie怎么来的?你是你吗?之类的逻辑 为了验证你是你自己 而不是哪个坏坏的黑客 文章里面提到的操作都挺妙的 如果我是程序猿的话 大概率只能想到个笨笨的验证码
- token验证
比如我们可以加一个一次性生成的token,根据浏览器的同源策略这个token并不能被csrf获取让每个请求带上这个token并进行验证(这里的token可以放在http请求的参数里),这样的话,CSRF无法获取Token从而隔绝攻击,当然实战渗透测试的时候可能有些网站会有token但并无作用 我怎么感觉有一个这个就够了?(单说这一种CSRF)除了上面说的摆设token 或是生成方式比较简陋有规律的那种 其实很难再进攻了 - 双重cookie 就是请求中要带着cookie里的参数 这个刚开始看了文章我很疑惑 这个不是说了会自动取出cookie吗 为什么还能防御 也不需要攻击者知道cookie啊 感觉没什么作用 肤浅了..
我以为是服务端直接拿出cookie拼在每个请求里面….. 明明是前端读取的 如果是攻击者的话 得到的cookie就不一样了 我在想什么 局限是下面
1 | 由于任何跨域都会导致前端无法获取Cookie中的字段(包括子域名之间),于是发生了如下情况: |
文章https://h0lm2pyudgf.feishu.cn/wiki/XyAXwiKkNi62bLk67GMcOeTYnOg



