护网笔记(十)--CSRF&SSRF漏洞
本篇靶场:
pikachu
CSRF
CSRF(Cross-Site Requester Forgery
,跨站请求伪造)它是一种常见的WEB攻击方式,很多开发者对它很陌生。它在2007年曾被列为互联网20大安全隐患之一。即使大名鼎鼎的Gmail,在2007年底也存在CSRF漏洞,从而被黑客利用造成巨大损失。
利用CSRF可以让攻击者以你名义发送邮件,发消息,盗取你的账号,甚至于购买商品,虚拟货币转账......造成的问题包括:个人隐私泄露以及财产安全。
CSRF是一种对网站的恶意利用。尽管听起来像跨站脚本(XSS),但它与XSS非常不同,XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站。与XSS攻击相比,CSRF攻击往往不大流行(因此对其进行防范的资源也相当稀少)和难以防范,所以被认为比XSS更具危险性。
利用条件:
完成一次csrf攻击,受害者必须一次完成两个步骤:
1、登录信任网站A并在浏览器中保存相应的Cookie
2、在不退出网站A的情况下,访问危险网站B
一般情况下不能保证不发生:
1、你不能保证登录了一个网站后,不再打开一个tab页,在访问另一个网站。
2、你不能保证关闭浏览器后,你本地的cookie会过期,上次的会话会结束。
3、图中所谓的攻击网站,很可能是一个存在其它漏洞的可信任的且经常被人访问网站。
某些标签时可以发送HTTP GET类型的请求的,例如标签
<img src="www.baidu.com" />
浏览器渲染img标签的时候,并不知道img标签中src属性的值,到底是不是一个图片,浏览器根据src中的链接发送一个get请求,并携带上当前浏览器在目标网站上的凭证,也就是cookie,获取返回结果以图片的形式渲染。(据此特性可挟持用户携带用户凭证cookie发送任意请求)
//www下新建csrf_test.php 文件,然后浏览器访问
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<img src="http://www.A.com/change.ph?passwd=123" />
</body>
</html>
举例说明:
场景需求:
小黑想要修改大白在购物网站tianxiewww.xx.com上填写的会员地址。
先看下大白是如何修改自己的密码的:
登录---修改会员信息,提交请求---修改成功。
所以小黑想要修改大白的信息,他需要拥有:1,登录权限 2,修改个人信息的请求。
但是大白又不会把自己xxx网站的账号密码告诉小黑,那小黑怎么办?
于是他自己跑到www.xx.com上注册了一个自己的账号,
然后修改了一下自己的个人信息(比如:E-mail地址),他发现修改的请求是:
【http://www.xxx.com/edit.php?email=xiaohei@88.com&Change=Change】
于是,他实施了这样一个操作:
把这个链接伪装一下,在小白登录xxx网站后,欺骗他进行点击,
小白点击这个链接后,个人信息就被修改了,小黑就完成了攻击目的。
为啥小黑的操作能够实现呢。有如下几个关键点:
1.www.xxx.com这个网站在用户修改个人的信息时没有过多的校验,导致这个请求容易被伪造;
---因此,我们判断一个网站是否存在CSRF漏洞,其实就是判断其对关键信息(比如密码等敏感信息)的操作(增删改)是否容易被伪造。
2.小白点击了小黑发给的链接,并且这个时候小白刚好登录在购物网上;
---如果小白安全意识高,不点击不明链接,则攻击不会成功,又或者即使小白点击了链接,但小白此时并没有登录购物网站,也不会成功。
---因此,要成功实施一次CSRF攻击,需要“天时,地利,人和”的条件。
当然,如果小黑事先在xxx网的首页如果发现了一个XSS漏洞,则小黑可能会这样做:
欺骗小白访问埋伏了XSS脚本(盗取cookie的脚本)的页面,小白中招,小黑拿到小白的cookie,然后小黑顺利登录到小白的后台,小黑自己修改小白的相关信息。
---所以跟上面比一下,就可以看出CSRF与XSS的区别:CSRF是借用户的权限完成攻击,攻击者并没有拿到用户的权限,而XSS是直接盗取到了用户的权限,然后实施破坏。
因此,网站如果要防止CSRF攻击,则需要对敏感信息的操作实施对应的安全措施,防止这些操作出现被伪造的情况,从而导致CSRF。比如:
--对敏感信息的操作增加安全的token;
--对敏感信息的操作增加安全的验证码;
--对敏感信息的操作实施安全的逻辑流程,比如修改密码时,需要先校验旧密码等。
get型CSRF
输入vince
和123456
登录;
点击修改个人信息,然后尝试修改性别为girl;
使用bp抓包;
可以看到get请求表单中的内容;
可以使用Engagement tools
来构造CSRF攻击表单代码(Generate CSRF PoC
)
复制html代码到新建的csrf_test.php文件中
<html>
<!-- CSRF PoC - generated by Burp Suite Professional -->
<body>
<script>history.pushState('', '', '/')</script>
<form action="http://127.0.0.1:8888/vul/csrf/csrfget/csrf_get_edit.php">
<input type="hidden" name="sex" value="girl" />
<input type="hidden" name="phonenum" value="18626545453" />
<input type="hidden" name="add" value="chain" />
<input type="hidden" name="email" value="vince@pikachu.com" />
<input type="hidden" name="submit" value="submit" />
<input type="submit" value="Submit request" />
</form>
</body>
</html>
在脚本中修改其他内容,
关闭代理,重新登录一个用户,比如 kevin 123456 注意此时的信息。
再打开一个网页,访问csrf_test.php文件;
点击后就会发现kevin的信息被修改了;
改进: 降低交互
上述实验,触发修改还需要手动点击一下,下面使用标签再试一次:
还是先在修改信息的地方进行bp抓包,将抓到的GET路径完整的写到src属性之中,然后对手机号phonenum参数进行修改(改为110)。
回到浏览器,登录另一个账号,并看一下手机号
然后浏览恶意网页;
发现图片被正常GET请求了。
刷新用户页面即可发现数据被修改。
post型CSRF
进入post型题目;
大致流程与get型相似,本处不再演示。
CSRF防御
从漏洞原理上看
1)关键操作增加验证码(比如说支付密码)
2)验证referer
3)使用Token
从漏洞利用前提条件看
用户需要养成访问完一个网站之后,点击退出账户的好习惯。
SSRF
SSRF(Server-Side Request Forgery
:服务端请求伪造)是一种由攻击者构造形成,由服务端发起请求的一个安全漏洞。一般情况下,SSRF攻击的目标是从外网无法访问的内部系统。
怎么确认浏览器发送的请求,还是服务器端发送的请求??
bp可以抓取浏览器(客户端)发送的数据,服务器端的抓不到。
场景:很多Web应用都提供了从其他服务器上获取数据的功能。使用用户指定的URL,Web应用可以获取图片,下载文件,读取文件内容等。这个功能如果被恶意使用,可以利用存在缺陷的web应用作为代理,攻击远程和本地服务器。
SSRF可以做什么?
1)可以对外网服务器所在的内网、本地进行端口扫描,获取一些服务的banner信息。
2)攻击运行在内网或者本地的应用程序。
3)攻击内外网的web应用,sql注入、struts2、redis等。
4)利用file协议读取本地文件等。
SSRF漏洞可参考:
https://www.cnblogs.com/iors/p/9777571.html
其形成的原因大都是由于服务端提供了从其他服务器应用获取数据的功能,但又没有对目标地址做严格过滤与限制
导致攻击者可以传入任意的地址来让后端服务器对其发起请求,并返回对该目标地址请求的数据
数据流:攻击者----->服务器---->目标地址
根据后台使用的函数的不同,对应的影响和利用方法又有不一样
PHP中下面函数的使用不当会导致SSRF:
file_get_contents()
fsockopen()
curl_exec()
SSRF之 file_get_contents() 函数
1)配置文件php.ini 中allow_url_fopen 和allow_url_include都要 On 开启状态
//在www下新建 ssrf_test.php 文件
<?php
if(isset($_POST['url'])){
$content = file_get_contents($_POST['url']); //发送文件包含请求
$filename = './img.jpg';
file_put_contents($filename,$content); //将读取的内容写入指定文件
}
?>
//在www下新建1.txt 文件 用来远程包含
hello hello world~
浏览器访问ssrf_test.php,并开启bp抓包,然后bp右键Change request method ,修改请求类型(GET 改成POST)
此时使用chrom浏览器去访问根目录下的img.jpg文件,右键另存为(随便找个位置)然后打开就可以看到包含了原来1.txt中的内容(本质上也是一种文件包含)
SSRF之 fsockopen() 函数
//在www新建fsockopen.php 文件
<?php
function GetFile($host,$port,$link)
{
// fsockopen() 将返回一个文件句柄,之后被其它文件调用,
//例如 fgets() fgetss() gwrite() fclose() ,调用失败返回false
$fp = fsockopen($host,intval($port),$errno,$errstr,30);
if(!$fp){ //读取不到就输出报错信息
echo "$errstr(error number $errno)\n";
}else{ //拼接out信息
$out = "GET $link HTTP/1.1\r\n";
$out .= "Host:$host\r\n";
$out .= "Connection:Close\r\n\r\n";
$out .= "\r\n";
fwrite($fp,$out);
$contents = "";
while(!feof($fp)){ //循环获取远程读取的内容
$contents .= fgets($fp,1024);
}
fclose($fp);
return $contents;
}
}
$host = $_GET['host'];
$port = $_GET['port'];
$link = $_GET['link'];
echo GetFile($host,$port,$link);
?>
浏览器访问地址如下:
http://127.0.0.1/fsockopen.php?host=127.0.0.1&port=80&link=http://127.0.0.1/1.txt&XDEBUG_SESSION_START=PHPSTORM
进入phpstorm中调试,再循环读取$fp中文件的时候要快一点(避免超时读取)
$content会观察到每次读取1024字节,将1.txt的内容读取了出来。
SSRF之 Curl_exec()
//在www下新建curl_exec.php文件
<?php
if(isset($_POST['url'])){
$link = $_POST['url'];
$curlobj = curl_init();
//代表使用get请求进行发包
curl_setopt($curlobj,CURLOPT_POST,0);
//代表设置需要访问的url地址
curl_setopt($curlobj,CURLOPT_URL,$link);
//将curl_exec执行的结果以字符串返回
curl_setopt($curlobj,CURLOPT_RETURNTRANSFER,1);
$result = curl_exec($curlobj); //执行发包
curl_close($curlobj);
$filename = './'.rand().'.txt';
file_put_contents($filename,$result);
echo $result;
echo $filename;
}
?>
浏览器访问curl_exec.php并传参,注意函数默认用的post传参,使用bp抓包后改一下发包方式(右键--Change request method),然后发包到Repeater模块,Send发送即可进入phpstorm中调试一下
注意$resoult参数。会获取到远程文件的内容。'
SSRF漏洞挖掘
-
web功能上查找
由原理可以看出,SSRF是由于服务器端获取其它服务器的相关信息的功能形成的,因此我们可以列举几种在WEB应用中常见的从服务端获取其它服务器信息的功能。
1) 通过URL地址分享网页内容:
2)转码服务:通过URL地址把原来地址的网址内容调优使其更适合手机屏幕浏览
3)在线翻译:通过URL地址翻译对应文本的内容,提供此功能的百度、有道等。
4)图片加载与下载
从URL关键字中寻找:
share wap url link src source target
u 3g display sourceURL imageURL domain href
归根到底,其实都是和连接有关联的
- 漏洞验证
SSRF判断依据:需要确认请求是服务端发出的。
常见的限制
1)限制开头的域名
例如 www.xxx.com 开头的域名
可采用http基本身份认证的方式绕过。即@
http://www.xxx.com@www.baidu.com
2)限制请求IP不为内网地址
①采用短网址绕过
短网址地址
https://www.ft12.com/
https://3w.cn/app/shorturl.html
//www下新建short_url.php文件
<?php
if(isset($_GET['url'])){
$content = file_get_contents($_GET['url']); //发送文件包含请求
echo $content;
}
?>
将生成的短连接,放在url后面即可访问
②采取进制转换
IP地址转换成十进制:
127.0.0.1=2130706433 16进制 7F000001 也可以
在线转换网址 http://www.ab126.com/system/2859.html
cmd中ping测试(16进制要加上0x)
③采用特殊域名①
localhost是一个域名,通常情况下localhost默认解析为127.0.0.1。
要求:此脚本同时限制了域名,而且127.0.0.1也不让使用,如果不能使用短连接,那么怎么能够访问本地资源
3)限制请求只为http协议
①采用302跳转
②采用短地址
修复方案
1、统一错误信息,避免用户可以根据错误信息来判断远程服务器端口状态
2、限制请求的端口为HTTP常用端口,比如80,443,8080,8088等
3、黑名单内网ip
4、禁用不需要的协议,仅仅允许http和https
本文来自作者:CK_0ff,转载请注明原文链接:https://www.cnblogs.com/Ck-0ff/p/15805785.html