Java代码审计——URL 跳转漏洞

目录

(一)URL 跳转漏洞简介

(二)URL 重定向

1.通过 ModelAndView 方式

2.通过返回 String 方式

3.使用 sendRedirect 方式

4.使用 RedirectAttributes 方式

5.通过设置 Header 来进行跳转

(三)URL 跳转漏洞审计

 (四)修复

小结


(一)URL 跳转漏洞简介


        URL 跳转漏洞也叫作 URL 重定向漏洞,由于服务端未对传入的跳转地址进行检查和控制,从而导致攻击者可以构造任意一个恶意地址,诱导用户跳转至恶意站点。因为是从用户可信站点跳转出去的,用户会比较信任该站点,所以 URL 跳转漏洞常用于钓鱼攻击,通过转到攻击者精心构造的恶意网站来欺骗用户输入信息,从而盗取用户的账号和密码等敏感信息,更甚者会欺骗用户进行金钱交易
        URL 跳转漏洞的成因并不复杂,主要是服务端未对传入的跳转 URL 变量进行检查和控制,或者对传入的跳转 URL 变量过滤不严格导致的,图 1 -1  所示为一次 URL跳转攻击
Java代码审计——URL 跳转漏洞_第1张图片 图 1-1 一次 URL 跳转攻击

 

        攻击者首先精心构造一个钓鱼站点 A ,然后利用 URL 跳转漏洞修改目的跳转地址,使原本应跳转到可信任站点 C 的地址变成钓鱼站点 A 。由于用户信任站点B,而钓鱼站点 A 又是从可信任站点 B 中重定向的,因此可能对钓鱼站点 A 同样信任。用户一旦用户输入相关的敏感信息,就可能被攻击者窃取。
        一般来讲,对于 URL 跳转漏洞在黑盒测试时主要的关注点为:注意 URL 中是否带有return、 redirect url jump goto target link 等参数值,并注意观察后跟的 URL 地址的具体格式,再构造相应的 payload 尝试跳转。在白盒审计中我们则会重点关注可以进行URL 跳转的相关方法。

(二)URL 重定向


         Spring MVC 中使用重定向的场景很多,一般有以下几种方法来进行 URL 重定向

1.通过 ModelAndView 方式

public ModelAndView testforward(HttpServletRequest req, HttpServletResponse resp) throws Exception { 
     String url =req.getParameter("url"); 
     String url = "redirect: "+url; 
             return new ModelAndView(url); 
}
        URL 跳转使用方式: http://www.any.com/index.jsp?url=http://www.xxx.com

2.通过返回 String 方式

public String redirect(@RequestParam("url") String url) { 
     return "redirect:" + url; 
 }
        URL 跳转使用方式: http://www.any.com/index.jsp?url=http://www.xxx.com

3.使用 sendRedirect 方式

public static void sendRedirect(HttpServletRequest request, HttpServletResponse response) throws 
IOException{ 
 String url = request.getParameter("url"); 
 response.sendRedirect(url); 
}

4.使用 RedirectAttributes 方式

        对于一般的 URL 跳转,使用 redirect 即可满足要求。如果需要进行参数拼接,则一般使用 RedirectAttributes
@RequestMapping("/RedirectAttributes") 
public String test4(RedirectAttributes redirectAttributes) { 
     redirectAttributes.addAttribute("id","2"); 
         return "redirect:/test/index"; 
}
        URL 跳转使用方式: http://www.any.com/RedirectAttributes
@RequestMapping("/RedirectAttributes") 在方法前面要说明 URL 访问是通过
http://192.168.88.2:8080/RedirectAttributes 来访问,代码中“return "redirect:/test/index";”
就会重定向到 http://192.168.88.2:8080/test/index 这 个 URL ,通过“ redirectAttributes.
addAttribute("id","2") ”传递了 id=2 这个参数,所以最终访问的其实是 http://192.168.88.2:
8080/test/index?id=2 这个 URL 地址。 RequestMapping 的执行效果如图 1 -2  所示
Java代码审计——URL 跳转漏洞_第2张图片 图 1-2 RequestMapping 执行效果

5.通过设置 Header 来进行跳转

 

public static void setHeader(HttpServletRequest request, HttpServletResponse response){ 
 String url = request.getParameter("url"); 
     response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY); 
     response.setHeader("Location", url); 
}
        通过“response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY) 设置返回的状态码,“SC_MOVED_PERMANENTLY 301 永久重定向, SC_MOVED_TEMPORARILY” 302 临时重定向。
        URL 跳转使用方式: http://www.any.com/index.jsp?url=http://www.xxx.com
        通过上面这些方法可以总结出 URL 跳转漏洞一些常见的关键字如下:
redirect 
sendRedirect 
ModelAndView 
Location 
addAttribute
引发 URL 跳转漏洞的原因有很多,但大多是以下几点
  • 开发人员不具备安全意识,编写代码时没有考虑任意 URL 跳转漏洞;
String url = request.getParameter("url"); 
response.sendRedirect(url);

  • 开发人员具有一定的安全意识,但是编写代码时考虑不够缜密,采用取关键字、取后缀等方法简单判断要跳转的地址,使代码逻辑可被绕过;
String trustUrl = "www.domain.com"; 
String url = request.getParameter("returnUrl"); 
if (url.substring(0,trustUrl.length()) == trustUrl) 
{ 
 response.sendRedirect(url); 
}
此处开发者认为只要判定传入的 URL 地址前若干位为其事先设置好的白名单的地址,则认为该地址是安全和可信的地址,并执行跳转。但对于上述字符串检测操作,均可以采用欺骗手法或者配合 URL 的各种特性符号绕过判断,如下所示
www.test.com/?redirectUrl=http://www.domain.com.hacker.net。
www.test.com/?redirectUrl=http://www.domain.com/www.hacker.net。
www.test.com/?redirectUrl=http://www.domain.com?www.hacker.net。
www.test.com/?redirectUrl=http://[email protected]。
www.test.com/?redirectUrl=http://www.domain.com#www.hacker.net。
  • 开发人员对于传入的 URL地址进行切割、拼接,导致攻击者可以利用其代码本身的逻辑进行绕过;
  • 由于使用的开发语言的特性、服务器/容器特性、浏览器特性等对标准 URL 协议解析处理等差异性导致被绕过;
  • 由于使用的开发语言的某些判断域名的函数库出现逻辑漏洞或者意外特性,导致被绕过。

(三)URL 跳转漏洞审计


        这次的审计示例,笔者用实际 Java 漏洞代码案例来进行演示。与之前类似,我们先搜索 URL 跳转常见关键字,定位到可能存在问题的代码段,如图 3 -1  所示
Java代码审计——URL 跳转漏洞_第3张图片 图 3-1 定位到可能存在问题的代码段

      

    通过搜索我们不难找到 RedirectController.java 文件中存在 sendRedirect 关键字,接着我们只需和 XSS 漏洞一样查看前后逻辑以及参数是否可控。这里可以清晰地看见程序是通过 GET 方法获得 url 参数,随后拼入 sendRedirect 方法进行跳转的,如图 3-2 所示

图 3-2 拼入 sendRedirect 方法进行跳转

 

        整个漏洞的产生十分简单,因此我们的漏洞利用也相对简单。只需根据 Spring MVC的 RequestMapping 找到对应路由并拼入 url 参数,将 url 参数值改为需要跳转的地址即可,在真实情况下一般为钓鱼页面,通过 url 参数传入“ http://www.xxx.com ”后,发现302 已经跳转到了“ http://www.xxx.com ”这个地址,如图 3 -3  所示
Java代码审计——URL 跳转漏洞_第4张图片 图 3-3 漏洞利用

 (四)修复


针对跳转逻辑的漏洞有很多修复方式,具体如下
  • 若跳转的 URL 事先是可以确定的,那么设置好白名单,并且采用全匹配的方式去检索关键字/域名;也可以先配置好相关参数,只需传对应 URL 的索引即可通过索引找到对应的具体 URL,然后再进行跳转。
  • 若事先无法确定跳转的 URL,且并不是由用户通过参数传入的,那么可以首先生成跳转链接,然后进行签名,只有通过验证签名才能进行跳转。
  • 若跳转的 URL 事先无法确定,并且是由用户通过参数传入的,则必须在跳转时对传入的 URL 进行详细校验,包括但不局限于:是否是白名单内的 URL,是否包含有相关特殊字符,是否处理好不规则协议、不规则地址的请求等方式。

小结


        URL 跳转漏洞容易被安全人员忽视,认为其仅能够进行钓鱼攻击,但其实在各种复杂的实际场景中,URL 跳转漏洞也可以引起 XSS 等漏洞,因此绝不可以忽视其危害性。目前若发现此类型漏洞并汇报给国外厂商,汇报者可以获得几十到几百美元不等的报酬,可以看出厂商对于此类型漏洞的重视。对于安全审计人员来说,审计该类型漏洞时,不仅要重点关注上文中提到的关键参数和关键函数,还应对开发者编写的跳转限制规则进行 fuzzing 测试,判断是否有可用的特殊字符或者特殊编码来绕过限制

你可能感兴趣的:(渗透与攻防,安全,网络,系统安全,安全威胁分析,网络攻击模型)