⚠️ 流程不一定具有普适性,仅抛砖引玉。可能存在Bug,大佬们轻拍。
网上有不少文章也是提到过用Arthas做手工排查,但几乎都停留在把Filter之类的列出来,一个个看。在某些场景下是否有捷径呢。
攻击工具:shiro_attack-4.5-SNAPSHOT-all.jar + Behinder_v3.0_Beta_11.t00ls
测试流程:CommonsBeanutils1_192链->AllEcho回显->BehinderFilter内存马->冰蝎连接->冰蝎命令执行->冰蝎反弹shell(执行失败)->修改ShiroKey(执行失败)
手工排查Trick
- 打开Arthas直奔classloader,可以立刻发现异常,即TransletClassloader和BehinderFilter。
classloader -l
可以获取到hash,可以用此快速查询加载关系。
- 加载关系查询
- 类基本信息查询
- dump+反编译可疑类分析code即可。
分析示例
【这组结果的测试过程中由于在冰蝎中多次执行了命令,导致多个RunCMD的注入】
[1][HIGH] - Behinder.RunCMD - 序列6
ClassName: org.urhfml.kbkm.Mldrqqyja
ClassLoader: com.summersec.x.BehinderFilter
RiskInfo: [No ClassFile, Common High-Risk Malicious Code Snippets, Dangerous SubClass]
[2][HIGH] - Behinder.RunCMD - 序列6
ClassName: sun.sqa.Yxrlub
ClassLoader: com.summersec.x.BehinderFilter
RiskInfo: [No ClassFile, Common High-Risk Malicious Code Snippets, Dangerous SubClass]
[3][HIGH] - Behinder.RunCMD - 序列6
ClassName: com.zyr.Fuzayjv
ClassLoader: com.summersec.x.BehinderFilter
RiskInfo: [No ClassFile, Common High-Risk Malicious Code Snippets, Dangerous SubClass]
[4][HIGH] - Behinder.RunCMD - 序列6
ClassName: org.dzwjjy.psznmm.okjqp.Bzil
ClassLoader: com.summersec.x.BehinderFilter
RiskInfo: [No ClassFile, Common High-Risk Malicious Code Snippets, Dangerous SubClass]
[5][HIGH] - Behinder.RunCMD - 序列6
ClassName: sun.ygwhg.dyne.rprd.Hponerrk
ClassLoader: com.summersec.x.BehinderFilter
RiskInfo: [No ClassFile, Common High-Risk Malicious Code Snippets, Dangerous SubClass]
[6][HIGH] - Behinder.RunCMD - 序列6
ClassName: org.ivomwm.qmpecc.sco.Fjyiv
ClassLoader: com.summersec.x.BehinderFilter
RiskInfo: [No ClassFile, Common High-Risk Malicious Code Snippets, Dangerous SubClass]
[7][HIGH] - Behinder.RunCMD - 序列6
ClassName: com.rrnckzs.ixfjcjs.kjztoj.Szdssch
ClassLoader: com.summersec.x.BehinderFilter
RiskInfo: [No ClassFile, Common High-Risk Malicious Code Snippets, Dangerous SubClass]
[8][HIGH] - Behinder.RunCMD - 序列6
ClassName: sun.wkkt.Jfzpi
ClassLoader: com.summersec.x.BehinderFilter
RiskInfo: [No ClassFile, Common High-Risk Malicious Code Snippets, Dangerous SubClass]
[9][HIGH] - Behinder.RunCMD - 序列6
ClassName: com.meuicbu.Azki
ClassLoader: com.summersec.x.BehinderFilter
RiskInfo: [No ClassFile, Common High-Risk Malicious Code Snippets, Dangerous SubClass]
[10][HIGH] - Behinder.RunCMD - 序列6
ClassName: com.kpyk.cndtyrf.hnti.Lberajy
ClassLoader: com.summersec.x.BehinderFilter
RiskInfo: [No ClassFile, Common High-Risk Malicious Code Snippets, Dangerous SubClass]
[11][HIGH] - Behinder.RunCMD - 序列6
ClassName: net.rjykxz.Lsoqzclznb
ClassLoader: com.summersec.x.BehinderFilter
RiskInfo: [No ClassFile, Common High-Risk Malicious Code Snippets, Dangerous SubClass]
[12][HIGH] - Behinder.BasicInfo - 序列5
ClassName: net.rbtzqii.Rwdpkv
ClassLoader: com.summersec.x.BehinderFilter
RiskInfo: [No ClassFile, Dangerous SubClass]
[13][HIGH] - Behinder.Echo - 序列4
ClassName: com.nvtkfw.jxkb.Ecerpaprz
ClassLoader: com.summersec.x.BehinderFilter
RiskInfo: [No ClassFile, Dangerous SubClass]
[14][HIGH] - 用于冰蝎连接的filter内存马 - 序列3
ClassName: com.summersec.x.BehinderFilter
ClassLoader: com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl$TransletClassLoader
RiskInfo: [No ClassFile, Suspicious Class Name, Dangerous ClassLoader, Common High-Risk Malicious Code Snippets]
[15][HIGH] - 反序列化攻击痕迹 - InjectMemTool - 序列2 - 负责加载BehinderFilter
ClassName: com.summersec.x.Test13503889287361
ClassLoader: com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl$TransletClassLoader
RiskInfo: [No ClassFile, Dangerous ClassLoader, Common High-Risk Malicious Code Snippets]
[16][HIGH] - 反序列化攻击痕迹 - AllEcho - 序列1
ClassName: com.summersec.x.Test13473692431012
ClassLoader: com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl$TransletClassLoader
RiskInfo: [No ClassFile, Dangerous ClassLoader, Common High-Risk Malicious Code Snippets]
测试流程
【攻击测试过程中出现了亿点点的事故,在使用冰蝎的反弹shell功能时往JVM里ddos了387个ReversePortMap,估计是死循环bug之类的,虽然我用冰蝎测完就立马关掉了。】
shiro_attack
需要先填key或爆破出key,就是正常的poc式测试,这一步分析省略。
1. 利用链检测
2. 利用链爆破
对库中所支持的利用链+回显排列组合,逐一尝试。
该情景下CB1_192+AllEcho测试成功,此时会直接通过反序列化向内存define一个用于回显的AllEcho:
[1][HIGH] - 反序列化攻击痕迹 - AllEcho - 序列1
ClassName: com.summersec.x.Test20192865287774
ClassLoader: com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl$TransletClassLoader
RiskInfo: [No ClassFile, Dangerous ClassLoader, Common High-Risk Malicious Code Snippets]
3. 执行注入
[2][HIGH] - 反序列化攻击痕迹 - InjectMemTool - 序列2 - 负责加载BehinderFilter
ClassName: com.summersec.x.Test22479024922353
ClassLoader: com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl$TransletClassLoader
RiskInfo: [No ClassFile, Dangerous ClassLoader, Common High-Risk Malicious Code Snippets]
[3][HIGH] - 用于冰蝎连接的filter内存马 - 序列3
ClassName: com.summersec.x.BehinderFilter
ClassLoader: com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl$TransletClassLoader
RiskInfo: [No ClassFile, Suspicious Class Name, Dangerous ClassLoader, Common High-Risk Malicious Code Snippets]
这两个类的define实际在一次请求中,详见AttackService.injectMem中的逻辑,filter内存马的字节序列编码后放置在请求的参数中。即该工具每进行一次内存马注入,都会生成一个x.Testxxxxxx和其注入的内存马。
x.Testxxxxxx获取请求参数中内存马的字节码编码,并解码对内存马进行define,调用内存马类的equals函数处会执行对应内存马的注册流程。
Behinder
当double-click某个shell的时,会调用MainController.openShell,随后触发ShellService.echo和ShellService.getBasicInfo�的调用。
有意思的是,冰蝎会间隔一段时间(未知是否规律)去调用一次ShellService.echo,而每一次调用,JVM中都会新增一个Echo(net.rebeyond.behinder.payload.java.Echo)类。
在执行命令时,每次会触发ShellService.runCmd的调用,且每次调用,JVM中都会新增一个Cmd(net.rebeyond.behinder.payload.java.Cmd)�类。
例如分别执行了两次命令,runCmd会被触发两次:
暂未解决的疑问
- 冰蝎不定时进行echo的心跳检测是必要的吗?每次执行某个操作都会向JVM新define一个类是否属于敏感操作?是否必要?如何优化?会不会触发一些类似RASP安全设备的告警?是否会在某些类中暴露可溯源信息?
- 针对以classloader入手/作为特征的检测方式,反序列化攻击和内存马植入有什么规避手段?