目前很多大型厂商都选择使用Java进行Web项目的开发,近年来随着各种JAVA指定环境RCE漏洞的出现,JavaWeb的安全逐渐被人们所重视,与漏洞相关的还有用于后期维持权限的Webshell。与PHP不同的是,JSP的语言特性较为严格,属于强类型语言,并且在JDK9以前并没有所谓的eval函数。一般而言JSP的变形免杀较为困难,但是依旧存在很多的"黑魔法"。
不知攻,焉知防。阿里云安骑士Webshell检测系统在迭代升级过程中,除了内部的不断绕过尝试以外,也长期邀请大量白帽子进行持续的绕过测试。经过不断总结沉淀在JSPWebshell查杀引擎方面我们形成了基于字节码跟反汇编代码的检测方式,可以有效对抗云上高强度对抗性样本。
本文分为函数调用篇/战略战术篇/内存马篇/降维打击篇四个部分,将从攻击者的角度与大家一起分享JSPWebshell的攻击姿势。
关于JSPJSP全称"JavaServerPage",其本质是一种JavaServlet。
JSP在第一次被访问的时候会先被翻译成Java文件,这个步骤由Tomcat等web容器完成;接着Java文件会被编译成JVM可以识别的class文件,这个步骤由JDK完成。
函数调用篇直接调用常见的直接调用是通过java.lang.Runtime#exec和java.lang.ProcessBuilder#start
java.lang.Runtimejava.lang.ProcessBuilder反射调用反射可以说是Java中最强大的技术,很多优秀的框架都是通过反射完成的。一般的类都是在编译期就确定下来并装载到JVM中,但是通过反射我们就可以实现类的动态加载。如果查阅源码可以发现,图中提到的很多命令执行方式的底层都是反射。
因为反射可以把我们所要调用的类跟函数放到一个字符串的位置,这样我们就可以利用各种字符串变形甚至自定义的加解密函数来实现对恶意类的隐藏。
除此以外,反射可以直接调用各种私有类方法,文章接下来的部分会让大家进一步体会到反射的强大。
加载字节码说到加载字节码就必须提到java.lang.ClassLoader这个抽象类,其作用主要是将class文件加载到jvm虚拟机中去,里面有几个重要的方法。
loadClass(),加载一个类,该方法会先查看目标类是否已经被加载,查看父级加载器并递归调用loadClass(),如果都没找到则调用findClass()。
findClass(),根据类的名称或位置加载.class字节码文件,获取字节码数组,然后调用defineClass()。
defineClass(),将字节码加载到jvm中去,转化为Class对象
更详细的说明可以参考这篇文章: