参考
参考视频:
Web渗透技术零基础入门
CSRF
一、CSRF
1.1、什么是CSRF?
Cross-site request forgery 简称为“CSRF”
在CSRF的攻击场景中,攻击者会伪造一个请求(这个请求一般是一个链接)
然后欺骗用户进行点击,用户一旦点击了这个请求,整个攻击也就完成了。
所以CSRF攻击也称为“one click”攻击。
这里我们抓住一个最关键的点,就是为什么一定要用户点击这个请求呢?
用户使用正确账号与密码成功登录网站,一段时间内,它的cookie信息是会被保存在浏览器中,即便关掉了网站页面,再次访问,也能直接进去。
攻击者想要访问这个网站的话,本来应该先进入登录页面的。
但是攻击者直接借助用户存储在浏览器上的cookie信息修改用户的账号密码,让浏览器误以为现在是用户在修改自己的账号密码。
也就是说,用户A带着个人的cookie信息访问网站B,也就是说,个人信息存储在网站中。但是这时候用户被诱使点击了某个链接,链接中攻击者向网站发送请求,执行了一个“修改个人密码”的操作。因为用户A是带有个人的身份认证信息的,所以网站认为这就是用户自己在执行修改操作,因而同意了这个操作。这样,攻击者伪造成用户A的这个行为就无疑是成功的。
这是比较正式的解释:
跨站请求伪造(CSRF,Cross-site request forgery)是指利用受害者尚未失效的身份认证信息(cookie,会话等),诱骗其点击恶意链接或者访问包含攻击代码的页面,在受害人不知情的情况下以受害者的身份向(身份认证信息所对应的)服务器发送请求,从而完成非法操作(如转账改密等)。
关于成功进行跨站请求伪造有两个关键的条件:
- 1、网站没有对一些关键信息修改的请求进行防CSRF处理,导致该请求容易被伪造。
- 2、用户在登录了后台的情况下,点击了恶意链接。如果用户根本不处于登录状态,或者用户根本没有点击这个链接,则攻击不会成功。
XSS(跨站脚本攻击)与CSRF(跨站请求伪造)最大的区别在于:攻击者利用XSS直接盗取用户的信息,自己登录到后台;而CSRF中,攻击者并不知道用户的信息,也没有权限。但是可以直接利用用户的权限(伪装成用户)进行危险操作。
1.2、如何确认Web站点存在CSRF漏洞?
1.3、CSRF测试
1.3.1 GET型
进入pikachu平台CSRF相关栏目
提示中给了用户登录信息。我们登录一下。
现在我们处于成功登录状态。
我们修改一下个人信息
提交请求前,使用burpsite抓包,对网站发向后端的数据包进行分析
使用GET请求。以及一些参数。我们把GET请求的内容复制下来。
/pika/vul/csrf/csrfget/csrf_get_edit.php
?sex=111&phonenum=222&add=333&email=444&submit=submit
如果我们放包,界面会变成这样子
正常情况下,在没有登录的情况下就访问这个页面
会跳转到登录页面
现在我们已经是登录状态了,然后我们突然遇到链接,并且点击了这个链接。但实际上,它会诱使我们访问这样一个链接
http://127.0.0.1/pika/vul/csrf/csrfget/csrf_get_edit.php?sex=000&phonenum=000&add=000&email=000&submit=submit
我们点击这个链接,跳转到该页面就会发现信息被修改了。
虽然修改密码的攻击者C,但是用户A被攻击者C欺骗,以自己的身份信息去执行了攻击者C提供的链接里面的操作,浏览器也会认为这是用户A执行的操作。这就是最简单的GET型的。
1.3.2 POST型
依旧是抓包分析。修改个人信息,抓包。
GET从URL上面获取值,但是POST是向服务器提交值,自然无法在URL上操作。
所以,这里我们首先需要解决的问题是,如何修改POST中的值?
首先来看一段简单的代码
加载出来的页面是这样子的。我们所填入的内容作为要POST的内容提交给服务器。比如我们随便添点东西。
点击提交。然后跳转到show.php这个文件内。它显示了我们刚才输入的信息。
也就是说,我们可以通过填入参数来修改POST的值。
但是问题来了,假如用户被诱使点了某个链接,很大程度上,它并不会submit自己的信息。
所以,我们需要POST表单自动提交这个方法。
如图。这是修改后的代码
能够实现表单自动提交
输入127.0.0.1/post1.php
,会直接跳转到show.php这个页面
我们抓包分析一下,网页到底向后台提交了什么内容。
现在两个参数都是空值,我们修改一下
放包
但是我们总不能一直在burpsite上面修改。
所以,我们可以添加一个value字段。当type为text的时候,value定义输入字段的初始值。
我们再次抓包,网页向服务器提交的POST中的内容为user="user"&password="password"
回到最先的话题,在后台使用POST提交表单的情况下,我们如何利用CSRF漏洞进行攻击?
首先,得有一个自动提交的表单,表单上面有我们想要修改的东西。
然后用户不小心点到了这个链接,便以自己的身份提交了表单,导致关键信息的修改、删除等。
总共有五个参数。编写恶意代码。这是恶意链接中的代码:
网址上输入恶意链接127.0.0.1/post.php
后
构造跳转链接
点击“安全的链接”。
但是这里还有一个问题,就是这种跳转页面有一秒钟显示了post.php页面,用户肯定会发觉自己被攻击了。所以如何让用户不发现自己在攻击他们,也是攻击者需要考虑的问题(也许可以构造一个跳转到404的页面)。
这是源代码
//post.php
<html>
<head>
<script>
window.onload = function(){
document.getElementById("postsubmit").click();
}
</script>
</head>
<body>
<form action="http://127.0.0.1/pika/vul/csrf/csrfpost/csrf_post_edit.php" method="post">
性别:<input type="text" name="sex" value="qq">
手机:<input type="text" name="phonenum" value="ww">
住址:<input type="text" name="add" value="ee">
邮箱:<input type="text" name="email" value="rr">
<input id="postsubmit" type="submit" name="submit" value="submit">
</form>
</body>
</html>
//link.php
<a href=http://127.0.0.1/post.php>很安全的链接</a>
1.3.3 通过Token防范CSRF漏洞
-
CSRF漏洞的主要问题是敏感操作的链容易被伪造,那么如何让这个链接不容易被伪造呢?
每次请求,都刷新一个随机码(需要足够随机,不容易被伪造), 后台每次对这个随机码进行验证! 这个随机码就是token。 每次表单渲染时都会生成唯一的token值,刷新后token值会改变。
我们用pikachu演示
抓包
这里加上了token值
token=303526280fb3e1b7e8747349474
如果我们不修改token值,直接放包,那么就会修改成功
但是如果修改token值呢?
正常的token
去掉末尾的09
放包。发现没有跳转到个人信息页面
信息也没有修改成功
通过查看源码可知,我们在点击“修改个人信息”的时候,是会跳转到token_get_edit.php这个页面上的。
我们打开这个页面。查看源码。
刷新页面。token值变了。
我们可以大胆猜测,后端生成了一个token值,比如"123";然后将这个token值传到前端,此时前端的session里面存储了token值"123",当我们提交表单时,会附上自己的token值"123",后端将它那里存储的token值与前端传过来的token值作比较。相同则执行下面的操作,不相同则不执行。
比如,用户现在的token值是这样的
不小心点击了恶意链接后什么事情都没有发生
这是因为攻击者不知道token值,token值不一致,就没法证明伪造身份。
未曾改变这是源码
所以,在看了源码之后,我们发现,这是不是也可以绕过?
比如,现在我们知道了网页现在存储的token值。
然后,更换token值
用户点击了恶意链接后。
修改成功。
抓包分析,攻击者提交的token值是正确的。
总结一下,就是用户访问token_get_edit.php这个页面后,网页会刷新一个token值。而成功提交请求后,token值没有刷新(除非再次访问这个页面才能刷新。)
攻击者如果能够获得用户在访问这个页面生成的token值,只有用户不再次访问那个页面,token值就可以被攻击者利用,乃至带着这个token值进行伪造。
所以最好的防范措施还是要求用户输入现在的密码,并进行验证。还有,要求用户输入验证码才能进行相关操作。
以及同源策略(不同源的客户端,在没有明确的授权下不能读取对方的资源),跨域(只要域名、端口任一不相同,即构成跨域)访问限制。