漏洞:CVE-2021-31805——升级struts版本2.0.6-2.5.30

漏洞:CVE-2021-31805——升级struts版本2.0.6-2.5.30,第1张

漏洞:CVE-2021-31805——升级struts版本2.0.6-2.5.30
  • 一、切换jar包更改配置
  • 二、页面标签修改
  • 三、异常原因分析

漏洞描述

Apache struts2部分版本存在漏洞,对不受信任的用户输入使用强制OGNL可能导致远程代码执行,黑客可利用该漏洞控制服务器。
一、切换jar包更改配置

切换jar包:

struts2-core-2.5.30.jar
struts2-spring-plugin-2.5.30.jar
删除 xwork-2.0.4  这个包已经包含在了struts2-core-2.5.30.jar中
commons-fileupload-1.4.jar
commons-io-2.6.jar

修改web.xml配置

<filter>
		<filter-name>struts2filter-name>
		<filter-class>
			org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter
		filter-class>
filter>

启动报错:java.lang.NoClassDefFoundError: org/apache/logging/log4j/LogManager

引入jar包:log4j-api-2.12.4.jar

启动报错:java.lang.NoClassDefFoundError: org/apache/commons/lang3/StringUtils

引入jar包:commons-lang3-3.8.1.jar

启动报错:java.lang.NoSuchMethodError: ognl.SimpleNode.isEvalChain(Lognl/OgnlContext;)Z

升级jar包:ognl-2.6.11.jar ---> ognl-3.1.29.jar

启动报错:java.lang.NoClassDefFoundError: freemarker/template/Version

升级jar包:freemarker-2.3.10.jar ---> freemarker-2.3.31.jar

访问主页面报错,时而好使时而不好使

ERROR DefaultDispatcherErrorHandler Exception occurred during processing request: null
 java.lang.NullPointerException
	at com.opensymphony.xwork2.validator.DelegatingValidatorContext.makeTextProvider(DelegatingValidatorContext.java:212)
	at com.opensymphony.xwork2.validator.DelegatingValidatorContext.<init>(DelegatingValidatorContext.java:65)
	at com.opensymphony.xwork2.validator.AnnotationActionValidatorManager.validate(AnnotationActionValidatorManager.java:127)
	at com.opensymphony.xwork2.validator.AnnotationActionValidatorManager.validate(AnnotationActionValidatorManager.java:123)
	at com.opensymphony.xwork2.validator.ValidationInterceptor.doBeforeInvocation(ValidationInterceptor.java:227)

DOCTYPE validators PUBLIC
        "-//OpenSymphony Group//XWork Validator Config 1.0//EN"
        "http://www.opensymphony.com/xwork/xwork-validator-config-1.0.dtd">

---改为--->

DOCTYPE validators PUBLIC
        "-//Apache Struts//XWork Validator Definition 1.0//EN"
        "http://struts.apache.org/dtds/xwork-validator-definition-1.0.dtd">

如果还不好使,检查validator配置的自定义类中是否引入了某些已被删除的包

<constant name="struts.enable.DynamicMethodInvocation" value="true" />


DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
        "http://struts.apache.org/dtds/struts-2.0.dtd">
改为:
DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
        "http://struts.apache.org/dtds/struts-2.5.dtd">





<package name="xx" extends="struts-default"  strict-method-invocation="false"  namespace="/xxx">
    <global-allowed-methods>regex:.*global-allowed-methods>
	<action name="xxx" class="xxx" method="xxx">
			<result name="success">
				/pages/xxx/xxx.jsp
			result>
	 action>
package>

如果页面访问有问题可以尝试进行下面修改

引入jar包:javassist-3.20.0-GA.jar


    <filter-mapping>
            <filter-name>struts2filter-name>
            <url-pattern>/struts/*url-pattern>
        filter-mapping>
    <filter-mapping>
改为:     
	<filter-name>struts2filter-name>
		<url-pattern>/struts/*.actionurl-pattern>
	filter-mapping>
	<filter-mapping>
		<filter-name>struts2filter-name>
		<url-pattern>/struts/*.jspurl-pattern>
	filter-mapping>

菜单无法加载或显示html标签问题


改为:


二、页面标签修改

两个版本的ognl标签有很多改动,需要调整页面


<%@page import="org.apache.derby.impl.sql.catalog.SYSCHECKSRowFactory"%>

常用标签用法




 




    



    不好使   
    
    
    



    ${index+1 }
    


   
--改为-->  

    

    
    ">
    
    
    
	
    
	      
    	  
    


三、异常原因分析

ERROR DefaultDispatcherErrorHandler Exception occurred during processing request: null

跟源码发现:AnnotationActionValidatorManager中的属性textProviderFactory为null
继续跟进发现:

  1. 项目启动时,strut2 使用@Inject注入依赖,而且属性注入顺序完全随机且在for循环中处理,
  2. 当某个属性注入失败时,会停止该类的属性注入,也就是说,这个类只有注入失败前的属性有值,后面的属性直接初始化为null,而且没有异常抛出
//源码:construct
class ContainerImpl implements Container {
    ...
    Object construct(InternalContext context, Class<? super T> expectedType) {
        ... 
        //injectors: @Inject注解标识的属性
        for (Injector injector : injectors) {
              injector.inject(context, t);
        }
        ...
    }
    ...
}
  1. 反复debug发现 AnnotationActionValidatorManager在 ```validatorFactory``这个属性注入时总会莫名其妙的跳出循环,开始处理加载其他类信息

  2. ValidatorFactory这个类是一个接口,只有一个实现类 DefaultValidatorFactory,这个类有个比较坑的初始化方法init

    public class DefaultValidatorFactory implements ValidatorFactory, Initializable {
        ...
        protected ValidatorFileParser validatorFileParser;
        @Override
        public void init() {
            parseValidators();
        }
        private void parseValidators() {
            ...
            // Parse default validator configurations
            String resourceName = "com/opensymphony/xwork2/validator/validators/default.xml";
            retrieveValidatorConfiguration(resourceName);
    
            // Overwrite and extend defaults with application specific validator configurations
            resourceName = "validators.xml";
            retrieveValidatorConfiguration(resourceName);
            ...
        }
        private void retrieveValidatorConfiguration(String resourceName) {
            InputStream is = ClassLoaderUtil.getResourceAsStream(resourceName, DefaultValidatorFactory.class);
            if (is != null) {
                validatorFileParser.parseValidatorDefinitions(validators, is, resourceName);
            }
        }
    }
    
    public class DefaultValidatorFileParser implements ValidatorFileParser {
        ...
     	public void parseValidatorDefinitions(Map<String, String> validators, InputStream is, String resourceName) {
    
            InputSource in = new InputSource(is);
            in.setSystemId(resourceName);
    
            Map<String, String> dtdMappings = new HashMap<>();
            dtdMappings.put("-//Apache Struts//XWork Validator Config 1.0//EN", "xwork-validator-config-1.0.dtd");
            dtdMappings.put("-//Apache Struts//XWork Validator Definition 1.0//EN", "xwork-validator-definition-1.0.dtd");
    		/*********************/
            Document doc = DomHelper.parse(in, dtdMappings);
    
            if (doc != null) {
                NodeList nodes = doc.getElementsByTagName("validator");
    
                for (int i = 0; i < nodes.getLength(); i++) {
                    Element validatorElement = (Element) nodes.item(i);
                    String name = validatorElement.getAttribute("name");
                    String className = validatorElement.getAttribute("class");
    
                    try {
                        // catch any problems here
                        objectFactory.buildValidator(className, new HashMap<String, Object>(), ActionContext.getContext().getContextMap());
                        validators.put(name, className);
                    } catch (Exception e) {
                        throw new ConfigurationException("Unable to load validator class " + className, e, validatorElement);
                    }
                }
            }
        }
        ...
    }
    
    1. 这个方法中加载了两个配置文件com/opensymphony/xwork2/validator/validators/default.xmlvalidators.xml

      第一个文件是jar包中自己的配置文件,没问题

      第二个文件就比较坑了,他在系统的resources目录下查找文件,找到则加载

      因为我的文件是老版本的配置文件,因此在Document doc = DomHelper.parse(in, dtdMappings);这一步格式化时,格式化报错了,这个时候抛出一个有意思的异常java.net.ConnectException: Connection timed out: connect

      接着一路上抛,在这个位置打印了一个LOG.warn, 而我的后台风平浪静。。。。

      public class InterceptorBuilder {
          ...
          public static List<InterceptorMapping> constructInterceptorReference(InterceptorLocator interceptorLocator,
                                                                               String refName, Map<String,String> refParams, Location location, ObjectFactory objectFactory) throws ConfigurationException {
              ...
              if (referencedConfig instanceof InterceptorConfig) {
                      InterceptorConfig config = (InterceptorConfig) referencedConfig;
                      Interceptor inter;
                      try {
                          inter = objectFactory.buildInterceptor(config, refParams);
                          result.add(new InterceptorMapping(refName, inter, refParams));
                      } catch (ConfigurationException ex) {
                    	    LOG.warn(new ParameterizedMessage("Unable to load config class {} at {} probably due to a missing jar, which might be fine if you never plan to use the {} interceptor",
                                  config.getClassName(), ex.getLocation(), config.getName()), ex);
                      }
      
                  }
              ...
          }
          ...
      }
      
    2. struts2-core-2.5.30版本依赖了log4j-api-2.12.4, 这与老版本的log4j-1.2.13貌似不兼容,引入log4j-core-2.12.4.jar是否会打印,有待验证,log4j-core在2.16版本前的都有漏洞,暂时不处理

    3. 对比com/opensymphony/xwork2/validator/validators/default.xmlvalidators.xml两个文件发现头部标签不一致,修改后加载正常

    4. 如果还不好使,检查validator配置的自定义类中是否引入了某些已被删除的包

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/789273.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-05
下一篇 2022-05-05

发表评论

登录后才能评论

评论列表(0条)