SSRF利用gopher协议攻击 fcgi

0x00 环境配置

  • 安装Net_Gopher

在pecl下载Net_Gopher,然后改36行:

原因: 新版php将类型接口改变了,需要改下源码。 https://bugs.php.net/bug.php?id=61479

  • curl版本重新安装

倒腾半天,在SSRF测试时,对curl版本有所限制。所以需要重新编译安装。参考: http://pavelpolyakov.com/2014/11/17/updating-php-curl-on-ubuntu/

  • Docker环境

然后有了Dockerfile:

docker-compose.yml 启动所需环境:

可以在phpinfo中看到gopher协议enable。curl版本为7.49.0

0x01 fcgi 攻击

  • 安装go语言环境,编译exp源码,有空可以看看源码。

go语言官网需要翻墙,国内有个下载:

将go的bin路径加到bash环境中(跟java很像~):

编译下:

  • 攻击原理

漏洞细节请看:

有个关键有趣的地方,是动态修改php的配置:

auto_prepend_file这个配置值,代表自动加载在php文件前面的代码。 例如:

这里设置的是php://input,代表用户请求上传的数据作为php代码,加载到文件之前。相当于任意php代码执行了。

  • 攻击验证

写个shell到指定目录下:

看源码(fcgi_exp.go)可知,当执行system命令时,会这样拼凑代码:

于是有了上述POC,单引号和$符号均需要转义一下。

攻击条件:

  • fcgi暴露端口9000
  • 知道一个php文件的绝对路径

0x02 SSRF配合gopher协议攻击

https://blog.chaitin.com/gopher-attack-surfaces/

存在SSRF漏洞代码:

测试下gopher协议是否可用:

  • 在自己服务器上写个302跳转,测试是否可以支持gopher协议。

如下:

访问http://angelwhu.com:8083/SSRF.php?url=http://121.42.175.111:8080/1.php,在2333端口得到test请求:

获取payload,构造gopher协议:

接收到发送的payload,进行url编码,如下构造gopher协议:

urlencode.py:

得到gopher协议为:

只需在url编码,前面加上下划线_即可。

访问SSRF漏洞页面,通过302跳转,成功写入shell。

0x03 问题

  • 确实发现curl版本问题,会产生截断,重新倒腾编译半天成7.49.0
  • 需要设置下curl可以302跳转。

摘自长亭科技文章,有局限性。

经过测试发现 Gopher 的以下几点局限性:

  • 大部分 PHP 并不会开启 fopen 的 gopher wrapper
  • file_get_contents 的 gopher 协议不能 URLencode
  • file_get_contents 关于 Gopher 的 302 跳转有 bug,导致利用失败
  • PHP 的 curl 默认不 follow 302 跳转
  • curl/libcurl 7.43 上 gopher 协议存在 bug(%00 截断),经测试 7.49 可用

更多有待补充。
另外,并不限于 PHP 的 SSRF。当存在 XXE、ffmepg SSRF 等漏洞的时候,也可以进行利用。

0x04 参考

https://blog.chaitin.com/gopher-attack-surfaces/
http://zone.wooyun.org/content/1060