什么是csrf
csrf通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。尽管听起来像跨站脚本(XSS),但它与XSS非常不同,并且攻击方式几乎相左。XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站。与XSS攻击相比,CSRF攻击往往不大流行(因此对其进行防范的资源也相当稀少)和难以防范,所以被认为比XSS更具危险性。
csrf的攻击方式
攻击者盗用了你的身份,以你的名义发送恶意请求。CSRF能够做的事情包括:以你名义发送邮件,发消息,盗取你的账号,甚至于购买商品,虚拟货币转账......造成的问题包括:个人隐私泄露以及财产安全。
完成一次csrf攻击必须要有的条件
登录受信任的网站A,在本地生成Cookie,在不登出A的情况下,访问危险网站B,
下面有例子:
1.http://www.mybank.com/Transfer.phptoBankId=11&money=1000
使用GET请求更新资源,在访问危险网站B的之前没有登出A,而B中的<'img'>以GET的方式请求第三方资源,
2.使用POST请求完成转账操作,
表单如下
<form action="Transfer.php" method="POST">
<p>ToBankId: <input type="text" name="toBankId" /></p>
<p>Money: <input type="text" name="money" /></p>
<p><input type="submit" value="Transfer" /></p>
</form>
后台处理php
<?php
session_start();
if (isset($_REQUEST['toBankId'] && isset($_REQUEST['money']))
{
buy_stocks($_REQUEST['toBankId'], $_REQUEST['money']);
}
?>
这样依旧会让网站存在csrf漏洞,
银行后台使用了$_REQUEST去获取请求的数据,而$_REQUEST既可以获取GET请求的数据,也可以获取POST请求的数据,这就造成了在后台处理程序无法区分这到底是GET请求的数据还是POST请求的数据。在PHP中,可以使用$_GET和$_POST分别获取GET请求和POST请求的数据。在JAVA中,用于获取请求数据request一样存在不能区分GET请求数据和POST数据的问题。依旧可以使用GET完成请求资源的操作,达到恶意攻击
3.经过$_GET,$_REQUEST请求之后,依旧出现了漏洞,使用$_POST来请求资源,
php代码如下:
<?php
session_start();
if (isset($_POST['toBankId'] && isset($_POST['money']))
{
buy_stocks($_POST['toBankId'], $_POST['money']);
}
?>
此时的危险B网站,也构造了一个form表单,使用javascript自动提交表单,请求资源
<html>
<head>
<script type="text/javascript">
function steal()
{
iframe = document.frames["steal"];
iframe.document.Submit("transfer");
}
</script>
</head>
<body onload="steal()">
<iframe name="steal" display="none">
<form method="POST" name="transfer" action="http://www.myBank.com/Transfer.php">
<input type="hidden" name="toBankId" value="11">
<input type="hidden" name="money" value="1000">
</form>
</iframe>
</body>
</html>
总结一下上面3个例子,CSRF主要的攻击模式基本上是以上的3种,其中以第1,2种最为严重,因为触发条件很简单,一个<'img'>就可以了,而第3种比较麻烦,需要使用JavaScript,所以使用的机会会比前面的少很多,但无论是哪种情况,只要触发了CSRF攻击,后果都有可能很严重。
csrf的防御方法
-
服务端进行CSRF防御
服务端的CSRF方式方法很多样,但总的思想都是一致的,就是在客户端页面增加伪随机数。
1.Cookie Hashing(所有表单都包含同一个伪随机值):
这可能是最简单的解决方案了,因为攻击者不能获得第三方的Cookie(理论上),所以表单中的数据也就构造失败了:>
2.这个方案的思路是:每次的用户提交都需要用户在表单中填写一个图片上的随机字符串,厄....这个方案可以完全解决CSRF,但个人觉得在易用性方面似乎不是太好,还有听闻是验证码图片的使用涉及了一个被称为MHTML的Bug,可能在某些版本的微软IE中受影响。
3.可以证件Token值,使用加密的方式,用session的方式进行,验证,避免csrf漏洞。
4.referer
因为伪造的请求一般是从第三方网站发起的,所以第一个防御方法就是判断 referer 头,如果不是来自本网站的请求,就判定为CSRF攻击。但是该方法只能防御跨站的csrf攻击,不能防御同站的csrf攻击(虽然同站的csrf更难)。
什么是ssrf
服务器端请求伪造,是一种有攻击者构造形成有服务器发起的攻击,一般是外网无法访问的内网。
ssrf形成的原因
由于服务端提供了其他服务器应用获取数据的功能且没有对目标地址做过滤与限制,比如从制定的URL地址获取网页文本内容,加载指定的地址图片,下载等
其中成因与php相关的函数
- file_get_content()
<?php
if (isset($_POST['url']))
{
$content = file_get_contents($_POST['url']);
$filename ='./images/'.rand().';img1.jpg';
file_put_contents($filename, $content);
echo $_POST['url'];
$img = "<img src=\"".$filename."\"/>";
}
echo $img;
?>
这段代码使用file_get_contents函数从用户指定的url获取图片。然后把它用一个随即文件名保存在硬盘上,并展示给用户。
- curl-curl_exec()
<?php
if (isset($_POST['url']))
{
$link = $_POST['url'];
$curlobj = curl_init();
curl_setopt($curlobj, CURLOPT_POST, 0);
curl_setopt($curlobj,CURLOPT_URL,$link);
curl_setopt($curlobj, CURLOPT_RETURNTRANSFER, 1);
$result=curl_exec($curlobj);
curl_close($curlobj);
$filename = './curled/'.rand().'.txt';
file_put_contents($filename, $result);
echo $result;
}
?>
这段代码使用fsockopen函数实现获取用户制定url的数据(文件或者html)。这个函数会使用socket跟服务器建立tcp连接,传输原始数据。
- socket-fsockopen()
<?php
function GetFile($host,$port,$link)
{
$fp = fsockopen($host, intval($port), $errno, $errstr, 30);
if (!$fp) {
echo "$errstr (error number $errno) \n";
} else {
$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;
}
}
?>
ssrf利用方式
- 可以对外网,服务器所在内网,本地端口扫描,获取一些服务的banner信息
- 攻击运行在内网或本地的应用程序(溢出攻击)
- 对内网web应用进行指纹识别,通过默认文件实现,
- 攻击内外网web应用,只要是使用get参数就可以是实现的攻击(比如struts2,sqli等)
- 利用file协议读取本地文件
ssrf漏洞如何挖掘
1.从web功能上寻找
1.分享:通过URl地址分享网页内容
2.转码服务:通过URL地址吧原地址的网页内容调优,时期适合手机屏幕浏览
3.在线翻译:通过URL地址翻译对应文本内容
4.图片的加载与下载:通过URL地址加载或下载图片
5.图片,文章收藏功能
2.从URL关键字中寻找
share,wap,url,link,src,source,target,u,
3g,display,sourceURl,imageURL,domain
排除法
- 在网页上,右键图片的链接地址,打开图片,如果URL栏中的地址是www.baidu.com/img/bd_logo1.png,证明没有ssrf漏洞
- 使用burp抓包工具来判断是否不是ssrf,首先ssrf是由服务器发起的请求,因此在加载图片的时候是有服务器发起的请求,所以在本地浏览器的请求中就不应该存在图片的请求,再次例子中,如果刷新当前页面,有如下请求,侧可判断不是ssrf(前提设置burpsuite截断图片的请求,默认是放行的)
验证是否可以探测内网 - 在经过简单的排除验证之后,我们就要验证看看次URL是否可以来请求对应的内网地址,首先我们要获取内网存在的hhtp服务且存在facicon.ico文件的地址,才能验证是否是ssrf漏洞。
- 从漏洞平台中的历史漏洞寻找泄露的存在web应用内网地址
- 通过二级户名暴力猜解工具模糊内网地址
利用方式 - 利用@
1.http://A.com@10.10.10.10
2.http://A.com:B@10.10.10.10 - ip地址转换成进制
1.115.239.210.26 = 16373751032
2.127.0.0.1 = 2130706433 - 使用地址生成内网地址
1.http://10.10.116.11 http://t.cn/RwbLKDx - 端口绕过
- xip.io
1.http://tp.chinaso.com/web?url=http://www.10.10.0.179.xip.io&fr=client
2.10.0.0.1.xip.io 10.0.0.1
3.www.10.0.0.1.xip.io 10.0.0.1
4.mysite.10.0.0.1.xip.io 10.0.0.1 - 通过js跳转
ssrf防御
1.过滤返回信息,验证远程服务器对请求时的响应是比较容易的方式,如果web应用是去获取某一种类型文件,那么在把返回结果展示给用户之前先验证返回的信息是否符合标准,
2.统一错误信息,避免用户可以根据错误信息来判断远程服务器的端口状态
3.限制请求的端口为http常用端口,比如,80,443,8080,8090
4.黑名单内网ip,避免应用被用来获取获取内网数据,攻击内网
5.禁用不需要的协议,仅仅永续http和https请求
可以通过burpsuite插件自动化监测ssrf漏洞,
实例:
weblogic配置不当,天生ssrf漏洞
discuz x2.5/x3.0/x3.1/x3.2 ssrf漏洞
CVE-2016-1897/8 - FFMpeg
CVE-2016-3718 - ImageMagick