目录
前言:
(一)CSRF
0x01、简单介绍
0x02、实际案例
1.对 Referer 过滤不严导致的 CSRF 漏洞
2.token 可重用导致 CSRF 漏洞
3、webGoat中的CSRF
0x03 防御
3.1 STP
3.2 检查 Referer 字段
3.3 检查 Referer 字段
前言:
本篇文章将介绍二种请求伪造,第一种跨站请求伪造也就是我们的CSRF,第二种服务端请求伪造也就是我们的SSRF。
- CSRF 通俗的说就是构造payload 然后诱导受害者点击,从而利用受害者的身份去做一些事情
- SSRF 服务端请求伪造简单的来说就是,这个请求是服务端发起的,通常有的功能会存在从第三方的链接等获取资源,但是如果没有对资源来源进行一个限定那么就可以导致我们可以利用服务端来请求他本地或者他其中的内网信息
(一)CSRF
0x01、简单介绍
CSRF(Cross Site Request Forgery,跨站点请求伪造)是目前出现次数比较多的漏洞,该漏洞能够使攻击者盗用被攻击者的身份信息,去执行相关敏感操作。实际上这种方式是攻击者通过一些钓鱼等手段欺骗用户去访问一个自己曾经认证过的网站,然后执行一些操作(如后台管理、发消息、添加关注甚至是转账等行为)。由于浏览器曾经认证过,因此被访问的网站会认为是真正的用户操作而去运行。简而言之,CSRF 漏洞的工作原理是攻击者盗用了用户的身份,以用户的名义发送恶意请求。图 1-1 所示为 CSRF 漏洞的攻击原理
从图 1-1 中可以看到,一次完整的 CSRF 攻击需要具备以下两个条件。
- 用户已经登录某站点,并且在浏览器中存储了登录后的 Cookie 信息。
- 在不注销某站点的情况下,去访问攻击者构造的站点。
总的来说, CSRF 漏洞攻击是一种比较简单的攻击,利用 Web 的隐式身份验证机制来达到攻击者的攻击目的
0x02、实际案例
CSRF 攻击可能出现的场景有很多,如更改个人信息、添加 / 修改资料、关注用户或者与交易相关的操作等。CSRF 漏洞的出现通常是由于开发人员对该类型漏洞不了解,因而疏忽了对该类型漏洞的防范。通常来说,检测 CSRF 漏洞是一项比较烦琐的工作,最简单的方法就是抓取一个正常请求的 GET/POST 数据包,删除 Referer 字段后再重新提交,如果该提交操作有效,那么基本上可以确定该操作存在 CSRF 漏洞。 CSRF 漏洞一般不需要通过代码审计来发掘,业内已经有一些专门针对 CSRF 漏洞进行检测的工具,如 CSRFTester、CSRF Request Builder 等。
若要通过代码审计去挖掘 CSRF 漏洞,一般需要首先了解该开源程序的框架。CSRF 漏洞一般会在框架中存在防护方案,所以在审计 CSRF漏洞时,首先要熟悉框架对 CSRF 的防护方案,若没有防护方案,则以该框架编写的 所有 Web 程序都可能存在 CSRF 漏洞;若有防护方案,则可以首先去查看增删改请求中是否有 token、formtoken、csrf-token 等关键字,若有则可以进一步去通读该 Web程序对 CSRF 的防护源码,来判断其是否存在替换 token 值为自定义值并重复请求、重复使用 token 等漏洞。此外还要关注源程序是否对请求的 Referer 进行校验等。
1.对 Referer 过滤不严导致的 CSRF 漏洞
public class RefererInterceptor extends HandlerInterceptorAdapter {
private Boolean check = true;
@Override
public boolean preHandle(HttpServletRequest req,
HttpServletResponse resp, Object handler) throws Exception {
if (!check) {
return true;
}
String referer=request.getHeader("Referer");
if((referer!=null) &&(referer.trim().startsWith("www.testdomain.com"))){
chain.doFilter(request, response);
}else{
request.getRequestDispatcher("index.jsp").forward(request,response);
}
}
- 从用户的请求头中取得 Referer 值,判断其是否为空。
- 若为空,则跳转至首页;若不为空,则进行下一步判断。
- 判断 Referer 是否以 www.testdomain.com 开头,若不是,则跳转至首页;若是,则执行该操作请求。
2.token 可重用导致 CSRF 漏洞
String sToken = generateToken();
String pToken = req.getParameter(“csrf-token”);
if(sToken != null && pToken != null && sToken.equals(pToken)){
chain.doFilter(request, response);
}else{
request.getRequestDispatcher(index.jsp”).forward(request,response);
}
}
3、webGoat中的CSRF
- 我这里直接使用的是burp的功能,伪造一个CSRF,如图 1-3:
- 但是发现生成过程中是有问题的,当我们点击payload中的submit之后,发现burp传输过程中的数据最后面会有一个莫名其妙的等号,如图 1-4:
- 我们来查看一下我们的poc,如图 1-5
- 我们进行一下解码
<input type="hidden" name="{
"name" : "WebGoat",
"email" : "webgoat@webgoat.org",
"content" : "WebGoat is the best!!"
}" value="" />
- 仔细观察发现 这里的name value是键值对,由于value为空 所以便会出现如下这种情况
{"name":"WebGoat","email":"webgoat@webgoat.org","content":"WebGoat is the best!!" }=
- 所以我们需要对poc进行改进 ,因为无论如何都有 = 所以我们得把等号包含进去
name {"name": "WebGoat", "email": "webgoat@webgoat.org", "content": "WebGoat is the best!!", "ignoreme":"
Value 'sdfsdfdf"}
- 这样的话正常结果就是如下
{"name": "WebGoat", "email": "webgoat@webgoat.org", "content": "WebGoat is the best!!", "ignoreme":"=sdfsdfdf"}
0x03 防御
3.1 STP
STP( Synchronizer Token Pattern ,令牌同步模式),这种防御机制是当用户发送请求时,服务器端应用将 token 嵌入 HTML 表格中,并发送给客户端。客户端提交HTML 表格,会将令牌发送到服务端,令牌的验证是由服务端实行的。令牌可以通过任何方式生成,只要确保其随机性和唯一性。这样就能够确保攻击者发送请求的时候,由于没有该令牌而无法通过验证。上述第二个实例中,该源程序采用的就是这种机制来防御 CSRF 攻击,但是该源程序未保证 token 的唯一性,从而导致其CSRF 防御机制如同虚设。
3.2 检查 Referer 字段
HTTP 头中有一个 Referer 字段,这个字段用以标明请求来源于哪个地址。在处理敏感数据请求时,一般情况下,Referer 字段应该与请求地址位于同一域名下。而如果是 CSRF 攻击传递来的请求, Referer 字段会是包含恶意攻击载荷的地址(如图 1-1 中的站点 B ),通过这种判断能够识别出 CSRF 攻击。这种防御手段的关键点在于如何建立合适的校验机制。在第一个实例中,如果我们建立一个白名单来替换判断 Referer 的开头字符检测,就可以阻止攻击者绕过 Referer的判断。
3.3 检查 Referer 字段
CSRF 的本质是攻击者通过欺骗用户去访问自己设置的地址,所以如果在所有用户进行敏感操作时,要求用户浏览器提供 未 保存在 Cookie 中且攻击者无法伪造的数据作为校验,那么攻击者就无法再进行 CSRF 攻击。这种方式通常是在请求时增加一个加密的字符串 token ,当客户端提交请求时,这个字符串 token也被一并提交上去以供校验。当用户进行正常的访问时,客户端的浏览器能够正确得到并传回这个字符串 token 。而通过 CSRF 攻击的方式,攻击者无法事先获取到该token 值,服务端就会因为校验 token 的值为空或者错误,拒绝这个可疑请求,从而达到防范 CSRF 攻击的目的。