[备份]加载恶意字节码Webshell的检测

0x00 背景

最近在研究免杀Webshell的检测

发现最强Webshell检测WAF某斯盾在处理BCELClassLoader和自定义ClassLoader的情况下是直接通杀,而不是真正分析其中的字节码,一定程度上可能存在误报

例如以下的BCELClassLoaderWebshell

恶意对象的构造方法传入cmd命令将回显结果保存在局部变量res中通过toString返回

这种情况下被检测到Webshell是正常情况

但是我发现如果把字节码改为非法或非恶意的情况,还是可以检测出Webshell

是否可以深入字节码做进一步的分析来判断是否属于Webshell

参考上一篇文章,总体检测过程分为下面这四步

第四步具体的内容

 

0x01 效果

正常的BCEL Webshell

首先分析了JSP内容然后分析字节码发现是Webshell

img

如果这里的BCEL字节码是普通的一个类(例如这样一个工具类)

分析字节码后发现没有问题,认为不是Webshell

img

如果设置成非法的字节码

程序发现这是非法字节码会停下,那么自然查不出问题

img

 

0x02 分析类加载

检测的基本原理是用ASM模拟JVM栈帧操作实现污点分析

首先取到其中的BCEL ByteCode

图示如下

img

对应代码结合图片来看会很简单

判断是否调用到new ClassLoader().loadClass(bytecode)

调用构造方法的字节码如下

图片表示为

img

当执行完NEW指令后压入一个对象引用,执行时候弹出一个这时剩余的一个对象就是被初始化后

保存至局部变量表第6位,我们将这个对象标记为黄色

代码中表示如下

调用loadClass的字节码如下

图示如下

img

代码如下

可以进一步判断ClassLoader是不是黄色的

换句话来说也就是判断是否包含new-bcel-classloader这个flag

 

0x03 分析字节码

得到Class后续还会有反射调用等情况,这里就不做进一步的分析了,如果恶意的字节码被加载到JVM那么99%可以确定这个JSP脚本有问题,重点在于分析这个字节码本身

通过上文的初步分析,可以得到一个结果data数组,正常情况下应该包含两个元素

上文其实有一处细节:没有选择Utility这个JDK自带的类来做解码,因为在高版本JDK中不包含这个类,防止出现意外情况所以我从Utility里扣出来decode方法写入自己的BcelUtil

在具体的字节码分析中,需要做的是遍历每一个方法而不仅仅对构造方法和静态代码块做分析

在分析具体每一个方法的时候,认为除了this参数以外的任何参数都是可控变量source

分析其中是否包含了Runtime.getRuntime这样的调用

注意:这只是一种情况,不过是最多的情况,比如反射等方式,暂不考虑更多的情况

上面代码有两个问题,直接看毫无思路,但是结合字节码和图片就会一目了然

图片表示如下

img

在初始化局部变量表的时候,将除了第0位的this以外的所有参数都设置为taint也就是图中的黄色,在Runtime.exec这个过程中参数会被压栈

这就解释了上文代码中为什么要取第0位第1位判断以及分别的逻辑是怎样的

 

0x04 总结

一些问题和思考