浅析Struts2两个安全漏洞的原理、利用与防范
2014-02-16廖文军朱晓乾
廖文军, 朱晓乾, 万 开
浅析Struts2两个安全漏洞的原理、利用与防范
廖文军, 朱晓乾, 万 开
(上海通用识别技术研究所,201112)
Struts2是一种web开发框架,当前被广泛应用到大型互联网企业、政府及金融机构的网站建设中。由于Struts2的相对底层性,导致整个web系统对其安全性的依赖程度很高。近期,Apache公司公布了Struts2的两个安全漏洞,引起业界的高度重视,本文将介绍Struts2的基本概念及这两个漏洞形成的原理,并详细介绍其利用方式及给出利用示例,同时在给出漏洞防范措施的基础上对此类安全问题的防范进行总结和思考。
Struts2;Struts2漏洞;OGNL;Webwork
0 引言
随着互联网技术的发展以及人们对web站点的功能性需求越来越高,越来越多的结构化的通用网站架构技术被提出和应用,其中Struts2就是一种典型的web站点设计框架,它采用MVC模式,用来帮助java开发者利用J2EE快速开发web应用,且因Struts2具有开源、纯pojo的Action等特点,而备受欢迎。Struts2的广泛使用为Struts2可能的漏洞利用提供了广袤的空间,同时也为用户防范Struts2及相类似的安全问题敲响了警钟。
1 Struts2基本概念
1.1 Webwork
Webwork来自一个开源组织opensymphony,且是在Xwork项目的基础上发展而来,webwork简洁且功能强大,完全从web层脱离,它提供了包括前端拦截、表单属性验证、类型转换以及强大的表达式语言OGNL等核心功能。Webwork在处理http请求和响应时使用ServletDispatcher将http请求转化为业务层、会话层和应用层范围的映射,请求参数映射为Webwork2支持的多视图表示,视图部分可以使用JSP、Velocity、FreeMarker、JasperRepots、XML等。
1.2 Struts2
Struts2架构继承了webwork的架构流程,而并未沿用Struts1的设计核心,但从处理流程上看,Struts2还是以控制器为重点,包括核心控制器和业务逻辑控制器,Struts2的一般处理流程如图1所示。
图1 Struts2的一般处理流程
Struts2核心控制器使用拦截器机制,当用户的请求到达时,核心控制器会过滤所有的请求,并将其中的请求参数解析出来,传入到Action中,然后调用相应的execute方法来处理用户的请求;Struts2业务逻辑控制器Action可由用户自定义,用户可以使用Struts2提供的Action接口来实现具体的Action类,从而增加了代码的可复用性且更易于测试。与此同时,Struts2的视图层通过大量的标签来实现,它的标签库不仅提供了数据处理的功能,而且还提供了诸如流程控制、Ajax支持等功能。
1.3 OGNL
2.2 节中阐述了Struts2使用标签库来实现很多功能,而Struts2中的标签是通过OGNL表达式作为基础的。OGNL是Object-Graph Navigation Language的缩写,是一种功能强大的表达式语言,通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。OGNL支持丰富的表达式,但语法结构却非常简单,一个简单的OGNL表达式如下:
name.toCharArray()[0].numericValue.toString()
这个表达式是按照如下步骤求值:
(1)获得OGNL Context中初始对象或者是根对象(root对象)的name对象;
(2)调用toCharArray()方法,返回一个String类型对象;(3)获得该String对象的第一个字符;
(4)获得该字符的numericValue属性(该字符为一个Character对象,该对象有一个getNumericValue()方法,该方法返回一个Integer类型值);
(5)将获得的Integer对象转换为一个String类型值(使用toString()方法)。
Struts2中的OGNL和标准OGNL的区别在于Struts2中默认将值栈(Value Stack)作为OGNL的根对象,因此在不用#标示命名空间的时候,Struts2会默认将值栈中的栈顶元素作为根对象。
2 Strcut2漏洞形成原理
近期,Struts2的两个安全漏洞被爆出,分别为远程命令执行漏洞和重定向漏洞,这两种漏洞分别利用导航前缀action及重定向前缀redirect构造时未对内容做过滤和检查,从而使得构造的数据被作为OGNL表达式执行。针对远程执行漏洞,黑客可以通过构造特殊格式的URL地址,将要执行的命令内容写入到URL中并将该URL提交,服务器端在解析该URL时会执行其中的命令,黑客可以通过执行不同的命令来进行获取目标主机的信息、执行相关系统命令、上传恶意文件、目标数据库信息操作等操作,从而达到入侵信息系统和窃取数据的目的;而针对重定向漏洞,黑客可以将希望跳转的网址嵌入到提交的URL中,使得用户在访问时自动跳转到黑客设定的目标网页,而这个网页有可能是黑客精心设计的钓鱼或挂马页面。
3 Strcut2漏洞利用
3.1 远程执行命令漏洞利用
Apache曾在其官网上公布了Struts2漏洞的POC代码,参照POC代码可以构造出初级的远程执行命令URL:http://website:port/struts2-blank/example/ HelloWorld.action?action:%25{(new+java.lang. ProcessBuilder(new+java.lang.String[]{'calc'})). start()}
在上述的URL中,whoami是要远程执行的指令,用来显示系统当前登录账户的用户名称信息。通过该示例可以明显的看出,设计合理的URL将要远程执行的命令包含其中,并加以一定的数据回传技术就能够远程执行相关程序,并在远程查看程序的执行结果。
要想进一步的提升自己在目标系统中的权限或者长期保持对目标系统的控制,需要在目标系统中植入后门,利用Struts2远程执行命令漏洞也能够实现.
首先通过getServletContext()获取目标网站的Servlet上下文对象,再通过getRealPath()获取网站的绝对路径信息,然后设法将webshell文件上传,构造的URL如下所示:
http://website:port/struts2-blank/example/ HelloWorld.action?redirect:%25{%23req%
3 d%2 3 c o n t e x t.g e t('c o m.o p e n s y m p h o n y. xwork2.dispatcher.HttpServletRequest'),%23p %3d(%23req.getRealPath(%22/%22)%2b%22webshe ll.jsp%22).replaceAll("\\","/"),new+java. io.BufferedWriter(new+java.io.FileWriter(%23p)). append(%23req.getParameter(%22content%22)).close()}&co ntent=%3c%25if(request.getParameter(%22f%22)!%3dnull) (new+java.io.FileOutputStream(application.getRealP ath(%22%2f%22)%2brequest.getParameter(%22f%22))). w r i t e(r e q u e s t.g e t P a r a m e t e r(%2 2 t%2 2). getBytes())%3b%25%3e
字符转义后为:
http://website:port/struts2-blank/example/ HelloWorld.action?redirect:${#req=
#context.get('com.opensymphony.xwork2.dispatcher. HttpServletRequest'),#p=(#req.getRealPath("/")+"webshell. j s p").r e p l a c e A l l("\\","/"),n e w+j a v a. io.BufferedWriter(new+java.io.FileWriter(#p)). a p p e n d(#r e q.g e t P a r a m e t e r("c o n t e n t")). close()}&content=<%if(request.getParameter("f")!=null)(new+java.io.FileOutputStream(application. getRealPath("%2f")+request.getParameter("f"))). write(request.getParameter("t").getBytes());%>
其中webshell.jsp为上传后保存在目标网络主机绝对路径之下的文件名,content表征要写入的文件内容,参数f表征要上传文件的文件名,参数t表征要上传的文件内容。
为便于本地操控端操作,构造简单的html页面,如图2所示:
图2 本地操作示例
这样就可以根据需要将要使用的脚本内容上传到服务器端,从而获取webshell的权限。
在漏洞爆出以后,出现了很多集成了上述原理的漏洞利用工具,便于进行快速的实施漏洞检测和利用,图3给出了使用一款漏洞利用工具实际探测到存在该漏洞某站点的相关信息。
图3 远程指令执行漏洞利用示例
3.2 开放式重定向漏洞利用
与远程执行命令漏洞会对目标站点服务器产生影响不同的是,开放式重定向漏洞更多的是针对普通用户的攻击。开放式重定向漏洞可被主要用来进行钓鱼攻击或网页挂马攻击,利用该漏洞的方式也很便捷,只需把要重定向的网络页面地址添加到重定向参数前缀之后.
图4 给出了利用重定向漏洞进行网页跳转的示意。
图4 重定向漏洞利用示例
4 Struts2漏洞防范及思考
自从Struts2被广泛使用以来,前后已经爆出多个框架式漏洞,尽管应用Struts2能够为web应用开发带来很多便捷,但Struts2的这些漏洞和缺陷给使用该框架的站点带来了很大的安全隐患。本文分析的两种Struts2漏洞皆因Struts2中的OGNL表达式的执行没有进行严格的安全检查,要想防范这一类型的安全问题,基本有两种方式,一是前端检测,这种检测对于表单提交具有一定的效用,对于URL构造难以起到较好的检测效果;另一类是后端检测,即在执行OGNL之前,对URL中用户提交的相关执行内容进行安全性检测,甚至可以构造一个威胁指令集,凡在此集合中的指令,OGNL都将不会被执行,这样将有效的杜绝类似远程执行以及重定向之类漏洞的利用。
Struts2除了本文阐述的两个漏洞之外,还存在一些其他形式的缺陷,如action属性设计缺陷、taglib设计缺陷、HTTP Parameter Pollution处理缺陷等,这些缺陷被恶意利用时就会成为威胁web站点安全的漏洞;当然,其他的web开发框架也或多或少的存在各种形式的缺陷和漏洞。人们在利用开发框架进行软件设计时是出于便捷、可拓展、可复用和结构化可配置的目的,但各类开发框架广泛应用的同时,框架本身的缺陷问题有时已经超越应用程序本身的代码和逻辑缺陷,而且一旦有框架级的缺陷和漏洞,其对整体应用系统的安全威胁将更底层、更广泛和更深远,因此在大规模使用各类开发框架进行程序设计和实施时应当权衡框架利用的利弊,并应当对开发框架进行更多的安全评估,才能更为有效的保障应用系统的安全。
5 结束语
本文在简单介绍Struts2框架的基本概念和知识之后,重点阐述了Struts2的两种漏洞,并分析和阐述了这两种漏洞的利用方式,同时给出了针对存在该漏洞的某站点的实际利用结果示例,最后基于Struts2框架存在的各类缺陷和漏洞,以及各类web开发框架被广泛应用的事实,对应用程序开发使用通用开发框架的利弊进行总结和分析,并指出在使用这些框架时,应对其进行更多的安全考量和评估。
[1] [美]多雷.Struts基础教程[M].铁手译.北京:人民邮电出版社,2007.
[2] 武宝珠,梁声灼,牛德雄.基于Struts2+Spring+Hibernate架构构建Web应用系统[J].计算机与现代化,2009(8):43-46.
[3] 黄宇,付琨,吴一戎.大规模目标解译本体存储映射模式的研究[J].计算机工程,2009(15):79-81.
Analysis of two Struts2 Security vulnerabilities Principle,Utilization and Protection
Liao Wenjun,Zhu Xiaoqian,Wan kai
(Shanghai General Recognition Technology Institute,201112)
Structs2 is a web development framework widely applied to website building in large internet companies,the government and financial institutions.As a website bottom template,the whole web system is heavily dependent on its safety.Recently Apache has revealed two security vulnerabilities of Structs2, drawing much attention.This paper introduces Structs2’s basic concept and the forming principle of its two vulnerabilities,illustrates how to utilize them with examples,and concludes with the way to prevent them.
Struts2;Struts2 vulnerabilities;OGNL;Webwork