SSRF绕过姿势
SSRF(Server-Side Request Forgery,服务器端请求伪造):是一种由攻击者构造形成由服务器端发起请求的一个漏洞。
SSRF 攻击的目标是从外网无法访问的内部系统
漏洞成因 服务端提供了从其他服务器应用获取数据的功能且没有对目标地址作过滤和限制。
0x01 SSRF的危害
攻击者可利用SSRF绕过防火墙,接触内部网络
攻击者可以利用 SSRF 实现的攻击主要有 5 种:
可以对外网、服务器所在内网、本地进行端口扫描,获取一些服务的 banner 信息
攻击运行在内网或本地的应用程序(比如溢出)
对内网 WEB 应用进行指纹识别,通过访问默认文件实现
攻击内外网的 web 应用,主要是使用 GET 参数就可以实现的攻击(比如 Struts2,sqli 等)
利用 file 协议读取本地文件等
0x02 SSRF出现场景
能够对外发起网络请求的地方,就可能存在 SSRF 漏洞
从远程服务器请求资源(Upload from URL,Import & Export RSS Feed)
数据库内置功能(Oracle、MongoDB、MSSQL、Postgres、CouchDB)
Webmail 收取其他邮箱邮件(POP3、IMAP、SMTP)
文件处理、编码处理、属性信息处理(ffmpeg、ImageMagic、DOCX、PDF、XML)
0x03 常见防御及绕过方法
一、检查IP是否为内网IP
很多开发者认为,只要检查一下请求url的host不为内网IP,即可防御SSRF。
通常使用正则过滤以下5个IP段:
192.168.0.0/16
10.0.0.0/8
172.16.0.0/12
127.0.0.0/8
0.0.0.0/8 #在Linux下,127.0.0.1与0.0.0.0都指向本地
这种防御方法通常可以用IP地址进制转换绕过
利用八进制IP地址绕过 0177.0.0.1
利用十进制的IP地址绕过 2130706433
可以看到实际请求都是127.0.0.1,但他们一个都匹配不上正则表达式。
二、Host获取与DNS绕过
检查获取到的Host是否是内网IP防御SSRF
这种防御方法可以用DNS解析绕过
Host可能是IP形式,也可能是域名形式。
如果Host是域名形式,我们是没法直接比对的,只要其解析到内网IP上,就可以绕过。
网上有个神奇域名 http://xip.io (有墙),www.127.0.0.1.xip.io,会自动解析到127.0.0.1
三、通过各种协议
GOPHER:通过GOPHER我们在一个URL参数中构造Post或者Get请求,从而攻击内网应用,例如Redis服务。
File:用File协议访问本地计算机中的文件,例如file:///etc/password.
四、利用URL解析器滥用问题
某些情况下,后端程序可能会对访问的URL进行解析,对解析出来的host地址进行过滤。
这时候可能会出现对URL参数解析不当,导致可以绕过过滤
http://www.baidu.com@127.0.0.1
当后端程序通过不正确的正则表达式,对上述URL的内容解析的时候
会认为访问URL的host为www.baidu.com,而实际上请求的是127.0.0.1上的内容
0x04 实验URL解析器滥用
搭建实验环境
Github上有一个SSRF防御的safe_code:https://github.com/chengable/safe_code/blob/master/ssrf_check.php
木有远程机器,本地搭建测试一下吧
将下面修改后的代码保存为index.php
<?php
highlight_file(__FILE__);
function check_inner_ip($url)
{
$match_result=preg_match('/^(http|https|gopher|dict)?:\/\/.*(\/)?.*$/',$url);
if (!$match_result)
{
die('url fomat error');
}
try
{
$url_parse=parse_url($url);
}
catch(Exception $e)
{
die('url fomat error');
return false;
}
$hostname=$url_parse['host'];
$ip=gethostbyname($hostname);
$int_ip=ip2long($ip);
return ip2long('127.0.0.0')>>24 == $int_ip>>24 || ip2long('10.0.0.0')>>24 == $int_ip>>24 || ip2long('172.16.0.0')>>20 == $int_ip>>20 || ip2long('192.168.0.0')>>16 == $int_ip>>16;
}
function safe_request_url($url)
{
if (check_inner_ip($url))
{
echo $url.' is inner ip';
}
else
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
$output = curl_exec($ch);
$result_info = curl_getinfo($ch);
if ($result_info['redirect_url'])
{
safe_request_url($result_info['redirect_url']);
}
curl_close($ch);
var_dump($output);
}
}
$url = $_POST['url'];
if(!empty($url)){
safe_request_url($url);
}
?>
新建一个flag.php,写一串字符串当作flag
程序对用户传来的数据,会先使用 safe_request_url 函数对URL的合法性进行判断。
而在 safe_request_url 函数中,使用 check_inner_ip 函数判断用户请求的IP是否为内部IP地址
如果是内部IP,则拒绝该请求;否则使用curl进行请求,并将请求结果进行输出。
利用URL解析器之间的差异处理,参考Orange师傅的PPT
构造payload:
curl -d "url=http://foo@127.0.0.1:80@www.baidu.com/flag.php" "http://192.168.43.157"
原文地址:https://www.cnblogs.com/wintrysec/p/11887455.html
- android中AVD的使用
- ASP.NET MVC 2示例Tailspin Travel UI层分析
- CSS 命名之Dialog, Modal, Popup, Popover, Lightbox 等的区别
- Eclipse JAVA文件注释乱码
- 2018年小程序的红利趋势预测,懂的来……或许你将成为下个富翁
- VUE 入门基础(6)
- 五年换4高管,6000员工裁95%剩300人,王健林为何抛弃万达网科?
- Android Permission中英对照
- 你知道人脸识别技术是如何实现的吗?
- WordPress REST API 定制化输出
- ASP.NET MVC的Action Filter
- Android LayoutInflater详解
- 在Android中实现service动态更新UI界面
- VUE 入门基础(5)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Laravel 自带的Auth验证登录方法
- laravel实现上传图片的两种方式小结
- Laravel开启跨域请求的方法
- Laravel 5.4前后台分离,通过不同的二级域名访问方法
- Yii框架数据库查询、增加、删除操作示例
- 在laravel5.2中实现点击用户头像更改头像的方法
- laravel 多图上传及图片的存储例子
- Laravel 添加多语言提示信息的方法
- Laravel框架表单验证操作实例分析
- Thinkphp5.0框架视图view的模板布局用法分析
- laravel5环境隐藏index.php后缀(apache)的方法
- php实现对文件压缩简单的方法
- laravel实现Auth认证,登录、注册后的页面回跳方法
- php 实现银联商务H5支付的示例代码
- Yii2.0框架behaviors方法使用实例分析