0x01 前言
java因为语言上面的特性,在关键词上面始终很难再去做到免杀。比如Class.forName、getMethod、setAccessable、invoke、newInstance等一些方法。所以我认为在免杀中最需要突破的两个方向就是:1、java对象的生成。[这里不管是用各种类去调用他们的defineClass也好,还是类配合上方法或者构造器生成出的对象也好]2、关键词的绕过,不知道js中是否有这样的特性可以支持将这些函数给绕过。
0x02 正文
1、免杀
直接上免杀马分析。
1 | <%@ page import="javax.script.ScriptEngine" %> |
再考虑之前的步骤,一些关键点还是需要着重强调一下。主要分为:1、 js和java在转换上面不兼容的问题。2、attempted duplicate class definition for name
1 | try { |
这里的马漏了定义Class U的声明。这里的defineClass,每次define的都是类名为U的class,所以会导致loader的父类WebAppClassLoader每次都是去定义Class u,所以第二次定义的时候会报错:attempted duplicate class definition for name。冰蝎的解决方案是每次都使用不同的classLoader去定义Class U这个类。(等会考证一下)
第二次生成的U对象。
第一次生成的U对象
可以看到每次传入的classloader都不相同。
一个类的url和签名组成了这个类的CodeSource,根据policy文件的配置,一个CodeSource有一定的权限。policy文件根据类的url和类的签名
来确定类,指定权限。而一个类的ProtectionDomain在这个类加载的时候初始化,也就是上图的内容。也可以看到protectionDomain是preDefineClass的方法中传过来的,并且两个参数都为null。并且在这一步赋值[ClassLoader中的方法]。
所以出错的关键在这里
1 | var defineClassMethod = java.lang.ClassLoader.class.getDeclaredMethod( |
应该改为
1 | var defineClassMethod =U.getClass().getDeclaredMethod( |
2、 混淆
简单概括:
1、 控制流平坦化
2、 利用java ast技术结合数组和加密算法对混淆的实现。
具体参考引用的第三篇文章
引用
https://xz.aliyun.com/t/9715 这篇主要是在本文思路的关键。