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

  • 五.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.ionslookup 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:9000nginx的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://xiahunao.cn/news/3224012.html

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

相关文章

2017年,我成为了技术博主

2017年9月&#xff0c;我已经大三了。 >>上一篇&#xff08;爪哇&#xff0c;我初窥门径&#xff09; 我大二学了很多java技术&#xff0c;看似我一会就把javaweb/ssh/ssm这些技术栈给学了。 这些技术确实不难&#xff0c;即便是我&#xff0c;我都能学会&#xff0c;…

Java字符串(String、字符串拼接、原理)

文章目录 一、String字符串1.1创建方式【直接赋值、new一个对象】1.1.1 使用字符串字面值直接赋值&#xff1a;&#xff08;1&#xff09;字符串字面量创建String对象的转换过程&#xff08;2&#xff09;一些方法&#xff08;3&#xff09;说明 1.1.2 使用new关键字创建字符串…

新手教学系列——crontab 使用不当引发的服务器性能问题

起因及症状 最近,我们的一台服务器随着运行时间的增加,逐渐出现了压力过大的问题。具体表现为数据库连接数飙升至 4000+,Redis 频繁超时,系统报错文件打开数过多等。针对这些问题,我们逐一检查了数据库连接池、Redis 连接池以及系统的 ulimit 配置,但都未能找到问题的根…

服务注册Eureka

目录 一、背景 1、概念 2、CAP 理论 3、常见的注册中心 二、Eureka 三、搭建 Eureka Server 1、搭建注册中心 四、服务注册 五、服务发现 六、Eureka 和 Zooper 的区别 一、背景 1、概念 远程调用就类似于一种通信 例如&#xff1a;当游客与景区之间进行通信&…

Linux网络命令:网络工具socat详解

目录 一、概述 二、基本用法 1、基本语法 2、常用选项 3、获取帮助 三、用法示例 1. 监听 TCP 端口并回显接收到的数据 2. 通过 TCP 端口转发数据到 UNIX 套接字 3. 将文件内容发送到 TCP 端口&#xff1a; 4. 使用伪终端进行串行通信 5、启动一个TCP服务器 6、建…

如何借助社交媒体影响者的力量,让品牌影响力倍增?

一、引言&#xff1a;为何社交媒体影响者如此关键&#xff1f; 在信息爆炸的今天&#xff0c;社交媒体已成为塑造消费者行为与品牌认知的重要渠道。社交媒体影响者&#xff0c;凭借其在特定领域的专业知识、庞大的粉丝基础及高度的互动性&#xff0c;成为了品牌传播不可忽视的…

【鸿蒙学习笔记】属性学习迭代笔记

这里写目录标题 TextImageColumnRow Text Entry Component struct PracExample {build() {Row() {Text(文本描述).fontSize(40)// 字体大小.fontWeight(FontWeight.Bold)// 加粗.fontColor(Color.Blue)// 字体颜色.backgroundColor(Color.Red)// 背景颜色.width(50%)// 组件宽…

【LLM】三、open-webui+ollama搭建自己的聊天机器人

系列文章目录 往期文章回顾&#xff1a; 【LLM】二、python调用本地的ollama部署的大模型 【LLM】一、利用ollama本地部署大模型 目录 前言 一、open-webui是什么 二、安装 1.docker安装 2.源码安装 三、使用 四、问题汇总 总结 前言 前面的文章&#xff0c;我们已经…

【Python的pip配置、程序运行、生成exe文件】

Python的pip配置、程序运行、生成exe文件 一、安装Python 通过官网下载对应的版本&#xff0c;安装即可。 下载地址&#xff1a;https://www.python.org/downloads/ Python标准库查看&#xff08;Python自带库&#xff09; Python 标准库文档 安装Python的时候&#xff0c…

昇思25天学习打卡营第13天 | ShuffleNet图像分类

ShuffleNet网络介绍 ShuffleNetV1是旷视科技提出的一种计算高效的CNN模型&#xff0c;和MobileNet, SqueezeNet等一样主要应用在移动端&#xff0c;所以模型的设计目标就是利用有限的计算资源来达到最好的模型精度。ShuffleNetV1的设计核心是引入了两种操作&#xff1a;Pointw…

移除元素的讲解,看这篇就够了!

一&#xff1a;题目 博主本文将用指向来形象的表示下标位的移动。 二&#xff1a;思路 1&#xff1a;两个整形&#xff0c;一个start&#xff0c;一个end&#xff0c;在一开始都 0&#xff0c;即这里都指向第一个元素。 2&#xff1a;在查到val之前&#xff0c;查一个&…

01 | 基础架构:一条SQL查询语句是如何执行的?

此系列文章为极客时间课程《MySQL 实战 45 讲》的学习笔记&#xff01; 引言 在了解 SQL 查询语句如何执行之前&#xff0c;先了解下MySQL 的基本架构示意图。 MySQL 分为 Server 层和引擎层。 Server 层包括连接器、查询缓存、分析器、优化器、执行器等&#xff0c;涵盖 M…

逆向分析之电脑端如何调试一些只能手机端浏览器才可以打开的网站

手机端浏览器的指纹和电脑端浏览器的指纹是不同的,这样只在手机端浏览器运行的网站则可以检测网站是否满足手机端浏览器指纹的要求,不满足则可以进行一些反爬措施。 例如一些公众号,其实就是使用手机端浏览器打开的H5网站,就可以进行手机端浏览器指纹检测。 这里只是讲解下…

硬盘分区读不出来的危机与数据拯救指南

在数字时代&#xff0c;硬盘作为我们存储珍贵数据的“保险箱”&#xff0c;其稳定性和可访问性至关重要。然而&#xff0c;当硬盘分区突然读不出来时&#xff0c;这份安全感瞬间化为泡影&#xff0c;让人心急如焚。本文将深入探讨硬盘分区读不出来的原因、提供两种实用的数据恢…

可以添加todo清单桌面小组件的便签哪个好?

在我们快节奏的生活中&#xff0c;有效的时间管理和任务追踪是必不可少的。为了实现这一目标&#xff0c;许多人选择使用桌面便签&#xff0c;尤其是那些具有Todo清单桌面小组件的便签。但是&#xff0c;面对市场上众多选择&#xff0c;可以添加todo清单桌面小组件的便签哪个好…

springboot中@bean注解的创建和使用

bean的创建顺序 在Spring Boot中&#xff0c;当一个配置类&#xff08;使用Configuration注解的类&#xff09;中定义了多个bean时&#xff0c;这些bean的创建顺序并不完全由它们在类中的声明顺序决定。Spring框架在创建和管理bean时&#xff0c;遵循了复杂的依赖注入和生命周…

使用微pe装系统

本文仅作为记录&#xff0c;不作为教程。 今天心血来潮想下点游戏玩玩&#xff0c;一看之前分的200gc盘已经红了&#xff0c;再加上大学之后这个笔记本已经用得很少了&#xff0c;于是打算重装电脑。 参考: 微PE辅助安装_哔哩哔哩_bilibil… 1.下载微pe和win10系统到U盘 我这…

Day65 代码随想录打卡|回溯算法篇---组合总和II

题目&#xff08;leecode T40&#xff09;&#xff1a; 给定一个候选人编号的集合 candidates 和一个目标数 target &#xff0c;找出 candidates 中所有可以使数字和为 target 的组合。 candidates 中的每个数字在每个组合中只能使用 一次 。 注意&#xff1a;解集不能包含…

JAVA的String的不可变特性

在学习JAVA的时候&#xff0c;看到了JAVA的String具有不可变的特性&#xff0c;他是说&#xff0c;JAVA的String在创建好后&#xff0c;JVM将这个String变量指向内存中的一个地址&#xff0c;当下次改变这个String变量的时候&#xff0c;改变的不是这个变量的值&#xff0c;而是…

可转债之强赎条款

摘要&#xff1a;每天学习一点金融小知识 做可转债投资&#xff0c;强赎风险是特别需要注意的&#xff0c;若投资者没有及时采取措施&#xff0c;就有可能造成很大的损失。本文从可转债的定义、强赎条款的原因及强赎的情况几个方面来介绍下可转债的强赎条款。 什么是可转换债券…