zl程序教程

您现在的位置是:首页 >  其他

当前栏目

404星链计划 | ysomap : Java反序列化利用框架

2023-03-20 14:52:54 时间
YSOMAP

Ysomap是一款适配于各类实际复杂环境的Java反序列化利用框架,可动态配置具备不同执行效果的Java反序列化利用链payload。

随着利用链的补充,ysomap同样可作为一款Java反序列化利用链教学库。目前,ysomap支持Java原生反序列化利用链、fastjson利用链、hessian利用链、xmldecoder、xstream等等。

另外,ysomap具备exploit模块,用于充分调动反序列化利用链。目前,ysomap已支持RMI、JNDI、JMX、shiro、xmlrpc等exploits。

YSOMAP解决了什么痛点?

Java反序列化漏洞是Java语言中最严重的漏洞之一,此种类型漏洞常被用于渗透、某行动中,其中最出名的莫过于weblogic的T3/IIOP反序列化漏洞。从2015年反序列化漏洞被提出,到如今仍然有各类著名中间件出现此类问题,这都使得此种类型漏洞成为安全研究人员的研究热点之一。

然而,在实际碰到的漏洞环境中,我们常会发现目前存在的两款工具(ysoserial、marshalsec)均无法很好的进行利用。这是因为实际环境是复杂的,我们需要通过各种“技巧”来达到真正exploit的效果。

譬如,XStream的LazyValue((https://github.com/wh1t3p1g/ysomap/blob/master/core/src/main/java/ysomap/payloads/xstream/LazyValueForXStream.java#L37))具备任意调用静态函数的利用效果,而实际想要利用,我们必须找一个切实可用的函数来利用。在之前的文章(https://blog.0kami.cn/2021/03/14/java-how-to-find-gadget-chains/)中我找了javax.naming.InitialContext.doLookup进行利用,可以对外发起jndi连接。那么,实际环境会那么简单吗?答案当然是否定的,我们经常会遇到目标环境是不出网的情况,那么又该如何去进一步利用呢?这里提一个简单的解决方案,依赖spring框架我们可以找到函数org.springframework.util.SerializationUtils.deserialize来进行二次反序列化。此时,原本的XStream的payload就进一步转化为了Java原生反序列化的利用。(这里提到的案例是真实存在于某开源框架的)

那么问题就来了,如何在实际利用中快速配置此类“技巧”呢?

ysomap的存在就是为了解决此类问题,采用模块化的思想,ysomap将具备动态组合利用链和利用效果的能力。对于遇到的不同环境,根据特定的组合来达成实际利用。

为此,我将原本的利用链切分成了两个部分payload和bullet:

  1. payload:指代利用链的前序部分
  2. bullet:指代最终利用链可达成的效果,如命令执行、jndi外链等效果

举个例子,CommonsCollection1和3,在分析时我们可以看到实际1和3的区别在于1使用的是InvokerTransformer,而3使用的是templatesImpl的方式。那么提取相同的前序payload部分,我们只需写两个不同的bullet即可。而且这两个bullet也同样能被用于其他的payload。

实际还有就是我在写RMIRegistryExploit时,也有这种可将不变部分重用的地方,而无需2,3之类的出现。

另外,ysomap本身具备可扩展的属性,你可以通过编写自己的payload、bullet、exploit来扩展ysomap本身的功能。

如何上手YSOMAP?

在谈如何使用ysomap之前,假设使用者有一定的Java反序列化利用的前置知识,以及一些常见利用的原理,如rmi、ldap等。

Jar编译

由于XStream的几个payload依赖JDK8的环境,所以后续的使用均在JDK8的环境下编译并运行

mvn clean package -DskipTests

正常编译不出错,可在cli/target目录找到ysomap.jar

当然,你也可以直接下载release(https://github.com/wh1t3p1g/ysomap/releases),但还是推荐自行clone后编译,因为大版本的更新将积攒一批利用链后才会发布release。

Jar运行

经过几次迭代,目前ysomap支持两种运行模式:终端cli模式和脚本模式

终端模式

java -jar ysomap.jar cli

脚本模式

java -jar ysomap.jar script path/to/script.yso

终端模式更易于选择和配置exploit、payload、bullet,但对于重复性的配置,终端模式显的格外繁琐。所以后续又增加了脚本模式。通过编写特定配置的yso脚本,使用ysomap进行载入调用。脚本模式在正确配置的前提下将极大的节省使用者输入重复配置的工作量,提高使用效率。同时,yso脚本也可以被分享给其他使用者进行快捷使用。

基础使用方法

ysomap > help
help                print this message
list <type>         list exploits, bullets and payloads
use <type> <name>   choose a exploit/payload/bullet
set <key> <value>   set exploit/bullet's arguments
run                 run current session
show <type>         show payload/bullet/exploit details
clear               clear current sessions
session [c|i]       recover to a session or create a new session
sessions            print current running exploit sessions
stop                stop current session
kill [uuid|all]     kill sessions, like 'kill uuid' or 'kill all'
exit                exit ysomap

使用help命令可以看到如上的一些命令,这里将依次进行介绍XD

命令均可用tab键进行补全

list操作:

list <type>         list exploits, bullets and payloads

ysomap支持多种类型的exploits、payloads、bullets,使用list命令可以查看当前支持的所有内容

比如list exploits 查看所有的exploit

同理可查看payload、bullet

show操作:

show <type>         show payload/bullet/exploit details

show操作同list有点类似,其主要作用是查看当前选择的payload/bullet/exploit的细节,后续举例子时会用到。

set操作:

set <key> <value>   set exploit/bullet's arguments

set操作主要用于配置exploit或payload的详细信息,后续举例子时会用到

这里有两个特殊的配置将用于payload生成

# 配置序列化数据生成后采用base64进行编码
set encoder base64
# 配置序列化数据生成后输出的位置,console为直接在终端输出,file为默认在当前目录生成obj.ser文件
set output console
set output file

use操作:

use <type> <name>   choose a exploit/payload/bullet

use操作用于选择对应的exploit、payload、bullet

session操作:

clear               clear current sessions
session [c|i]       recover to a session or create a new session
sessions            print current running exploit sessions
stop                stop current session
kill [uuid|all]     kill sessions, like 'kill uuid' or 'kill all'

ysomap中每一个payload或exploit的配置都会生成一个session,session用于维持当前的配置信息和运行状态

使用sessions查看当前的所有session

使用session c在保证当前session完整性的前提下,创建新的session用于配制新的payload或exploit

使用session i uuid来还原uuid所指向的session配置

另外,对于无需再运行的session,可以使用kill uuid的方式清除该session

也可以使用stop来停止当前正在运行的session

也可以使用clear来清除当前session的所有配置

run操作:

run                 run current session

在配置完具体的内容后,使用run操作来运行或生成相应的序列化数据/exploit

使用流程

接下来,介绍以下两种流程

生成序列化后的payload:

当你需要使用ysomap生成特定的序列化数据时

第一步:use payload xxxx 设置一个payload

第二步:show options获得当前payload的配置信息,会提示可以选择的bullet信息

第三步:use bullet xxxx 给当前的payload装上子弹(具体能达成的利用方式)

第四步:show options 可以看到包括payload和bullet的配置信息

第五步:set xxx xxx 设置当前需要配置的内容

第六步:run 配置完成后,执行并生成相应的序列化数据

当生成的序列化数据为json或xml时,序列化后的数据将直接打印在终端上;当生成的序列化数据为二进制数据,则会在当前目录生成一个obj.ser文件

利用exploit包进行攻击:

当你需要使用ysomap进行攻击时

第一步:use exploit xxxx 设置一个exploit

第二步:show options获得当前exploit的配置信息,会提示需要设置payload或其他配置

第三步:如果需要设置payload,过程参考上面的步骤;

第四步:如果不需要设置其他payload,或其他设置已经设置完成 set xxx xxx 设置当前需要配置的内容

第五步:run 配置完成后,执行并进行相应的攻击

实例配置:

以配置exploit RMIListener为例

使用use操作可以选择exploit为RMIListener

选择了exploit,可以通过show操作查看当前exploit需要配置的内容

这里有两个配置项,一个是exploit可能需要配置相应的利用链payload,另一个是exploit本身所需要的配置信息。通过show options可以查看推荐的payload名,此处RMIListener支持ysomap的所有gadgets。

假设此处payload选择CommonsBeanutils1,bullet选择也可以通过show options查看,这里选择TemplatesImplBullet

然后使用set操作配置内容

最后使用run操作运行,session中也能看到当前所运行的exploit的相关信息

到这里,exploit RMIListner就运行起来了

对于第一次的配置,我们可以通过终端模式的提示一步一步配置。在接下来的运行中,我们可以将执行的操作记录成yso文件,然后使用script模式进行载入

use exploit RMIListener
use payload CommonsBeanutils1
use bullet TemplatesImplBullet
set lport 1099
set body "open -a Caclulator.app"
run

如何自定义扩展YSOMAP?

从上面的介绍可以知道ysomap主要由exploit、payload、bullet组成。

扩展exploit需要继承AbstractExploit对象,并分别声明@Exploits、@Authors、@Require、@Details

@Exploits
@Authors({Authors.WH1T3P1G})
@Require(bullets = {"required payload"}, param = false)
@Details("exploit descriptions")
public class ExploitDemo extends AbstractExploit {

}

扩展payload需要继承AbstractPayload对象,并分别声明@Payloads、@Authors、@Targets、@Require、@Dependencies

@Payloads
@Authors({ Authors.WH1T3P1G })
@Targets({Targets.JDK})
@Require(bullets = {"required bullet"},param = false)
@Dependencies({"dependency"})
public class PayloadDemo extends AbstractPayload<Object> {

}

扩展bullet需要实现接口Bullet对象,并分别声明@Bullets、@Authors、@Targets、@Require、@Dependencies

@Bullets
@Targets({Targets.JDK})
@Authors({ Authors.WH1T3P1G })
@Details("指定目录文件写入")
@Dependencies({"dependency"})
public class StoreableCachingMapBullet implements Bullet<Object> {

}

其中声明@Exploits、@Payloads、@Bullets将用于寻址,未标明的exploit、payload或bullet将无法使用

具体的编写案例可以直接在项目里找一个对应的对象模仿着写,相信写过一次之后就熟悉了。当然,如果在扩展中存在什么问题可以直接提issue。

最后

ysomap目前所覆盖的利用链仍然是一小部分,还存在大量的利用链、exploit可以扩展。

后续将不定期更新已有的、我或者其他研究者发现的利用链。ysomap的使用存在一定前置门槛,我也在考虑如何降低这部分的门槛。比如script脚本模式就是我目前认为可以一键式运行或exploit的方式,当前,也许你有其他的更好的方法来提升使用体验,欢迎提issue、提PR~

最后的最后,感谢ysoserial、marshalsec这两款工具。