作者:wh1t3p1g
项目地址:https://github.com/wh1t3p1g/ysomap
Ysomap是一款适配于各类实际复杂环境的Java反序列化利用框架,可动态配置具备不同执行效果的Java反序列化利用链payload。
随着利用链的补充,ysomap同样可作为一款Java反序列化利用链教学库。目前,ysomap支持Java原生反序列化利用链、fastjson利用链、hessian利用链、xmldecoder、xstream等等。
另外,ysomap具备exploit模块,用于充分调动反序列化利用链。目前,ysomap已支持RMI、JNDI、JMX、shiro、xmlrpc等exploits。
Java反序列化漏洞是Java语言中最严重的漏洞之一,此种类型漏洞常被用于渗透、某行动中,其中最出名的莫过于weblogic的T3/IIOP反序列化漏洞。从2015年反序列化漏洞被提出,到如今仍然有各类著名中间件出现此类问题,这都使得此种类型漏洞成为安全研究人员的研究热点之一。
然而,在实际碰到的漏洞环境中,我们常会发现目前存在的两款工具(ysoserial、marshalsec)均无法很好的进行利用。这是因为实际环境是复杂的,我们需要通过各种“技巧”来达到真正exploit的效果。
譬如,XStream的LazyValue具备任意调用静态函数的利用效果,而实际想要利用,我们必须找一个切实可用的函数来利用。在之前的文章中我找了javax.naming.InitialContext.doLookup
进行利用,可以对外发起jndi连接。那么,实际环境会那么简单吗?答案当然是否定的,我们经常会遇到目标环境是不出网的情况,那么又该如何去进一步利用呢?这里提一个简单的解决方案,依赖spring框架我们可以找到函数org.springframework.util.SerializationUtils.deserialize
来进行二次反序列化。此时,原本的XStream的payload就进一步转化为了Java原生反序列化的利用。(这里提到的案例是真实存在于某开源框架的)
那么问题就来了,如何在实际利用中快速配置此类“技巧”呢?
ysomap的存在就是为了解决此类问题,采用模块化的思想,ysomap将具备动态组合利用链和利用效果的能力。对于遇到的不同环境,根据特定的组合来达成实际利用。
为此,我将原本的利用链切分成了两个部分payload和bullet:
举个例子,CommonsCollection1和3,在分析时我们可以看到实际1和3的区别在于1使用的是InvokerTransformer
,而3使用的是templatesImpl
的方式。那么提取相同的前序payload部分,我们只需写两个不同的bullet即可。而且这两个bullet也同样能被用于其他的payload。
实际还有就是我在写RMIRegistryExploit时,也有这种可将不变部分重用的地方,而无需2,3之类的出现。
另外,ysomap本身具备可扩展的属性,你可以通过编写自己的payload、bullet、exploit来扩展ysomap本身的功能。
在谈如何使用ysomap之前,假设使用者有一定的Java反序列化利用的前置知识,以及一些常见利用的原理,如rmi、ldap等。
由于XStream的几个payload依赖JDK8的环境,所以后续的使用均在JDK8的环境下编译并运行
mvn clean package -DskipTests
正常编译不出错,可在cli/target
目录找到ysomap.jar
当然,你也可以直接下载release,但还是推荐自行clone后编译,因为大版本的更新将积攒一批利用链后才会发布release。
经过几次迭代,目前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 <type> list exploits, bullets and payloads
ysomap支持多种类型的exploits、payloads、bullets,使用list命令可以查看当前支持的所有内容
比如list exploits 查看所有的exploit
同理可查看payload、bullet
show <type> show payload/bullet/exploit details
show操作同list有点类似,其主要作用是查看当前选择的payload/bullet/exploit的细节,后续举例子时会用到。
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 <type> <name> choose a exploit/payload/bullet
use操作用于选择对应的exploit、payload、bullet
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 current session
在配置完具体的内容后,使用run操作来运行或生成相应的序列化数据/exploit
接下来,介绍以下两种流程
当你需要使用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
文件
当你需要使用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主要由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这两款工具。
ysomap 现已加入 404星链计划
加入404星链计划社群,请扫码识别运营菜菜子二维码,添加时备注“星链计划”。
本文由 Seebug Paper 发布,如需转载请注明来源。本文地址:https://paper.seebug.org/1766/