From 9be82c110f37c68b8b6139927aa27a8031bb1ec3 Mon Sep 17 00:00:00 2001 From: zeno Date: Tue, 7 Jun 2022 13:48:36 +0200 Subject: [PATCH] Removed ide settings and convert tabs to spaces --- .classpath | 12 - .project | 34 - .settings/org.eclipse.buildship.core.prefs | 13 - .settings/org.eclipse.jdt.core.prefs | 4 - src/burp/BurpExtender.java | 910 ++++++++--------- src/tokenJar/DataModel.java | 518 +++++----- src/tokenJar/GettingStartedDialog.java | 72 +- src/tokenJar/PersistSettings.java | 336 +++---- src/tokenJar/RegexWindow.java | 828 +++++++-------- src/tokenJar/Tab.java | 1052 ++++++++++---------- 10 files changed, 1856 insertions(+), 1923 deletions(-) delete mode 100644 .classpath delete mode 100644 .project delete mode 100644 .settings/org.eclipse.buildship.core.prefs delete mode 100644 .settings/org.eclipse.jdt.core.prefs diff --git a/.classpath b/.classpath deleted file mode 100644 index 52d6183..0000000 --- a/.classpath +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/.project b/.project deleted file mode 100644 index 570b895..0000000 --- a/.project +++ /dev/null @@ -1,34 +0,0 @@ - - - token-jar - Project token-jar created by Buildship. - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.buildship.core.gradleprojectbuilder - - - - - - org.eclipse.jdt.core.javanature - org.eclipse.buildship.core.gradleprojectnature - - - - 1653564835640 - - 30 - - org.eclipse.core.resources.regexFilterMatcher - node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ - - - - diff --git a/.settings/org.eclipse.buildship.core.prefs b/.settings/org.eclipse.buildship.core.prefs deleted file mode 100644 index ce8cabb..0000000 --- a/.settings/org.eclipse.buildship.core.prefs +++ /dev/null @@ -1,13 +0,0 @@ -arguments= -auto.sync=false -build.scans.enabled=false -connection.gradle.distribution=GRADLE_DISTRIBUTION(LOCAL_INSTALLATION(/usr/share/java/gradle)) -connection.project.dir= -eclipse.preferences.version=1 -gradle.user.home= -java.home=/usr/lib/jvm/java-18-openjdk -jvm.arguments= -offline.mode=false -override.workspace.settings=true -show.console.view=true -show.executions.view=true diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index 65de196..0000000 --- a/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,4 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.targetPlatform=16 -org.eclipse.jdt.core.compiler.compliance=16 -org.eclipse.jdt.core.compiler.source=16 diff --git a/src/burp/BurpExtender.java b/src/burp/BurpExtender.java index e657487..2222c16 100644 --- a/src/burp/BurpExtender.java +++ b/src/burp/BurpExtender.java @@ -10,462 +10,462 @@ import tokenJar.*; public class BurpExtender implements IBurpExtender, IHttpListener, IProxyListener, IExtensionStateListener { - public static final String NAME="TokenJar"; - public static final String VERSION=" 2.2 "; //always 5 chars - private IBurpExtenderCallbacks callbacks; - private IExtensionHelpers helpers; - private Tab tab; - private DataModel dataModel; - - @Override - public void registerExtenderCallbacks(final IBurpExtenderCallbacks callbacks){ - this.callbacks = callbacks; - helpers = callbacks.getHelpers(); - - // Set extension name - callbacks.setExtensionName(NAME+" "+VERSION); - - tab = new Tab(callbacks); - dataModel = tab.getDataModel(); - - callbacks.customizeUiComponent(tab); - callbacks.addSuiteTab(tab); - - // Register as listener - callbacks.registerHttpListener(this); - callbacks.registerProxyListener(this); - callbacks.registerExtensionStateListener(this); - } - - /* - // IExtensionStateListener implementation - */ - @Override - public void extensionUnloaded(){ - ;//dataModel is no longer accessible at this point - } - - - /* - // IProxyListener implementation - */ - @Override - public void processProxyMessage(boolean isRequest, IInterceptedProxyMessage message){ - //EXIT if Master Enable button is disabled - if (dataModel.getMasterEnable()==false) - return; - if (dataModel.getMasterProxy()==false) - return; - - IHttpRequestResponse OLD_message = message.getMessageInfo(); - if (isRequest) { - processRequestMessage(IBurpExtenderCallbacks.TOOL_PROXY, OLD_message); - } else { - processResponseMessage(OLD_message); - } - message.setInterceptAction(IInterceptedProxyMessage.ACTION_FOLLOW_RULES); - } - - /* - // IHttpListener implementation - */ - @Override - public void processHttpMessage(int toolFlag, boolean isRequest, IHttpRequestResponse message){ - //EXIT, it was already proccessed by PROXY - if (toolFlag == IBurpExtenderCallbacks.TOOL_PROXY) - return; - - //EXIT if Master Enable button is disabled - if (dataModel.getMasterEnable()==false) - return; - if (dataModel.getMasterIntruder()==false && toolFlag == IBurpExtenderCallbacks.TOOL_INTRUDER) - return; - if (dataModel.getMasterRepeater()==false && toolFlag == IBurpExtenderCallbacks.TOOL_REPEATER) - return; - - if (isRequest){ - processRequestMessage(toolFlag, message); - } else { - processResponseMessage(message); - } - } - - /* - // Response message - */ - private void processResponseMessage(IHttpRequestResponse HTTP_message) - { - try{ - - //Obtaining path - IRequestInfo requestInfo = helpers.analyzeRequest(HTTP_message); - String path = requestInfo.getUrl().getPath(); - - //Debug enabled - if (dataModel.getMasterDebug()){ - callbacks.printOutput(""); - callbacks.printOutput("<<< Processing Response Message"); - callbacks.printOutput(". Path=" + path); - if (HTTP_message.getComment()==null) - HTTP_message.setComment(NAME+":"); - } - - String HTTP_response = null; - //get all ids for token that 'listen' for this response - Set ids = dataModel.getByPath( path ); - - for(Integer id: ids){ - if (!dataModel.getFromResponse(id)) { - callbacks.printOutput("Not getting from Response, skipping"); - return; - } - //Get only the first time the response - if (HTTP_response==null) HTTP_response = new String(HTTP_message.getResponse()); - String value = null; - - Matcher matcher = dataModel.getPattern(id).matcher( HTTP_response ); - int grpCount = matcher.groupCount()+1; - - if (matcher.find()) { //do I need to test for && grpCount >=0 ? - /*Debug enabled*/ - if (dataModel.getMasterDebug()) { - HTTP_message.setComment( HTTP_message.getComment() + " match:"+dataModel.getName(id)); - callbacks.printOutput(". Match for "+dataModel.getName(id)+" (rule "+id+") for Regex=" + dataModel.getRegex(id)); - } - String[] grpValues = new String[grpCount]; - - for (int i=0; i oParameters = requestInfo.getParameters(); - List nParameters = new ArrayList<>(); - - Integer id; - int deltaRequest=0; - int deltaContentLen=0; - int delta; //work variable - - - //Debug enabled - if (dataModel.getMasterDebug()){ - callbacks.printOutput(""); - callbacks.printOutput(">>> Processing Request Message"); - callbacks.printOutput(". Path=" + requestInfo.getUrl().getPath()); - if (HTTP_message.getComment()==null) - HTTP_message.setComment(NAME+":"); - } - - //1. Identify all params that are also in the table - //2. Calculate Content-Length delta length - for (IParameter parameter : oParameters) { - // the parameter type must be between 0 and 4 (0-> header, 1->url, 2->body, 3->cookie, 4->other) - byte parameterType = (byte) (parameter.getType() + 2); // NOTE(zeno): I add 2 here, because the header starts 2 positions later because I added 2 option before that - parameterType++; // increment with one to make room for header (0) - - if (dataModel.getMasterDebug()) {callbacks.printOutput(". Parameter["+parameter.getName()+"]="+parameter.getValue()+" of Type="+enhancedParameter.Type.get(parameterType));} /*Debug enabled*/ - - if (parameterType>9) - parameterType = 9; - - if ( (id = dataModel.getByNameType(parameter.getName(), parameterType)) !=null ) { - Boolean toProxy = dataModel.getToProxy(id); - Boolean toRepeater= dataModel.getToRepeater(id); - Boolean toIntruder = dataModel.getToIntruder(id); - if (toolFlag == IBurpExtenderCallbacks.TOOL_PROXY && !toProxy) { - return; - } - if (toolFlag == IBurpExtenderCallbacks.TOOL_REPEATER && !toRepeater) { - return; - } - if (toolFlag == IBurpExtenderCallbacks.TOOL_INTRUDER && !toIntruder) { - return; - } - - String newValue = dataModel.getValue(id); - - if (dataModel.getFromRequest(id)) { - try{ - - //Obtaining path - String path = requestInfo.getUrl().getPath(); - - //Debug enabled - if (dataModel.getMasterDebug()){ - callbacks.printOutput(""); - callbacks.printOutput("Checking Request for values to be extracted, because 'Extract from Request' was enabled"); - callbacks.printOutput(". Path=" + path); - if (HTTP_message.getComment()==null) - HTTP_message.setComment(NAME+":"); - } - - String HTTP_response = null; - - //Get only the first time the response - if (HTTP_response==null) HTTP_response = new String(HTTP_message.getRequest()); - String value = null; - - Matcher matcher = dataModel.getPattern(id).matcher( HTTP_response ); - int grpCount = matcher.groupCount()+1; - - if (matcher.find()) { //do I need to test for && grpCount >=0 ? - /*Debug enabled*/ - if (dataModel.getMasterDebug()) { - HTTP_message.setComment( HTTP_message.getComment() + " match:"+dataModel.getName(id)); - callbacks.printOutput(". Match for "+dataModel.getName(id)+" (rule "+id+") for Regex=" + dataModel.getRegex(id)); - } - String[] grpValues = new String[grpCount]; - - for (int i=0; ibody, 4->other - deltaContentLen += delta; - } - callbacks.printOutput("Replaced old value for " + parameter.getName() + " with new value: " + newValue); - //*DEBUG*/callbacks.printOutput("deltaContentLen="+deltaContentLen); - } - } - - //Content-Length preparation - List HTTP_headers = requestInfo.getHeaders(); - int oContLenStart=0, oContLenLength=0, oContLenValue=0; - boolean oContLenProccess = false; - - /*Processing headers*/ - int oCursor=0; //Assumption: headers are proccessed in top down order - for(int i=0; i p1.valueStart - p2.valueStart); - - byte[] nRequest = new byte[oRequest.length + deltaRequest]; - - int oStart = 0; - int oEnd = oRequest.length; - int nStart = 0; - int oParamStart, oParamEnd; - - //1. Update all parameters identified above - //2. Update the Content-Length - for (enhancedParameter parameter : nParameters) { - oParamStart = parameter.valueStart; - oParamEnd = parameter.valueEnd; - - //Content-Length update - if (oContLenProccess && oParamStart > oContLenStart){ //found the parameter just after Content-Length? - //copy everything before the Content-Length - delta = oContLenStart-oStart; - System.arraycopy(oRequest, oStart, nRequest, nStart, delta); - oStart+= delta; - nStart+= delta; - - //Compute and append the new Content-Length - String nContLen = "Content-Length: "+ ((int) oContLenValue + (int) deltaContentLen); - - if (dataModel.getMasterDebug()) {callbacks.printOutput("+ Content-Length="+ ((int) oContLenValue + (int) deltaContentLen));} /*Debug enabled*/ - - int nContLenLength = nContLen.length(); - System.arraycopy(nContLen.getBytes(), 0, nRequest, nStart, nContLenLength); - //*DEBUG*/callbacks.printOutput("###nStart="+nStart+", nContLenLength="+nContLenLength); - oStart+= oContLenLength; - nStart+= nContLenLength; - //Content-Lenght updated - oContLenProccess = false; - } - //end Content-Length update - - //copy everithing before the parameter - delta = oParamStart-oStart; - //*DEBUG*/callbacks.printOutput("###oStart="+oStart+", nStart="+nStart+", delta="+delta); - System.arraycopy(oRequest, oStart, nRequest, nStart, delta); - oStart+= delta; - nStart+= delta; - - //DEBUG enabled - if (dataModel.getMasterDebug()){ - callbacks.printOutput("+ Parameter["+parameter.name+"]="+parameter.newvalue+" of Type="+ enhancedParameter.Type.get(parameter.type)); - HTTP_message.setComment( HTTP_message.getComment() + " new:" + parameter.name + " "); - } - //end DEBUG - - int nParamLenght = parameter.newvalue.length(); - - //Copying new value (might be empty, smaller or larger) - System.arraycopy(parameter.newvalue.getBytes(), 0, nRequest, nStart, nParamLenght); - //A better alternative? - //Bytes.concat(byte[]... arrays); - - oStart+= oParamEnd-oParamStart; - nStart+= nParamLenght; - } - - //Copying till the end - if (oStart>0 && oStart ids = dataModel.getByPath( path ); + + for(Integer id: ids){ + if (!dataModel.getFromResponse(id)) { + callbacks.printOutput("Not getting from Response, skipping"); + return; + } + //Get only the first time the response + if (HTTP_response==null) HTTP_response = new String(HTTP_message.getResponse()); + String value = null; + + Matcher matcher = dataModel.getPattern(id).matcher( HTTP_response ); + int grpCount = matcher.groupCount()+1; + + if (matcher.find()) { //do I need to test for && grpCount >=0 ? + /*Debug enabled*/ + if (dataModel.getMasterDebug()) { + HTTP_message.setComment( HTTP_message.getComment() + " match:"+dataModel.getName(id)); + callbacks.printOutput(". Match for "+dataModel.getName(id)+" (rule "+id+") for Regex=" + dataModel.getRegex(id)); + } + String[] grpValues = new String[grpCount]; + + for (int i=0; i oParameters = requestInfo.getParameters(); + List nParameters = new ArrayList<>(); + + Integer id; + int deltaRequest=0; + int deltaContentLen=0; + int delta; //work variable + + + //Debug enabled + if (dataModel.getMasterDebug()){ + callbacks.printOutput(""); + callbacks.printOutput(">>> Processing Request Message"); + callbacks.printOutput(". Path=" + requestInfo.getUrl().getPath()); + if (HTTP_message.getComment()==null) + HTTP_message.setComment(NAME+":"); + } + + //1. Identify all params that are also in the table + //2. Calculate Content-Length delta length + for (IParameter parameter : oParameters) { + // the parameter type must be between 0 and 4 (0-> header, 1->url, 2->body, 3->cookie, 4->other) + byte parameterType = (byte) (parameter.getType() + 2); // NOTE(zeno): I add 2 here, because the header starts 2 positions later because I added 2 option before that + parameterType++; // increment with one to make room for header (0) + + if (dataModel.getMasterDebug()) {callbacks.printOutput(". Parameter["+parameter.getName()+"]="+parameter.getValue()+" of Type="+enhancedParameter.Type.get(parameterType));} /*Debug enabled*/ + + if (parameterType>9) + parameterType = 9; + + if ( (id = dataModel.getByNameType(parameter.getName(), parameterType)) !=null ) { + Boolean toProxy = dataModel.getToProxy(id); + Boolean toRepeater= dataModel.getToRepeater(id); + Boolean toIntruder = dataModel.getToIntruder(id); + if (toolFlag == IBurpExtenderCallbacks.TOOL_PROXY && !toProxy) { + return; + } + if (toolFlag == IBurpExtenderCallbacks.TOOL_REPEATER && !toRepeater) { + return; + } + if (toolFlag == IBurpExtenderCallbacks.TOOL_INTRUDER && !toIntruder) { + return; + } + + String newValue = dataModel.getValue(id); + + if (dataModel.getFromRequest(id)) { + try{ + + //Obtaining path + String path = requestInfo.getUrl().getPath(); + + //Debug enabled + if (dataModel.getMasterDebug()){ + callbacks.printOutput(""); + callbacks.printOutput("Checking Request for values to be extracted, because 'Extract from Request' was enabled"); + callbacks.printOutput(". Path=" + path); + if (HTTP_message.getComment()==null) + HTTP_message.setComment(NAME+":"); + } + + String HTTP_response = null; + + //Get only the first time the response + if (HTTP_response==null) HTTP_response = new String(HTTP_message.getRequest()); + String value = null; + + Matcher matcher = dataModel.getPattern(id).matcher( HTTP_response ); + int grpCount = matcher.groupCount()+1; + + if (matcher.find()) { //do I need to test for && grpCount >=0 ? + /*Debug enabled*/ + if (dataModel.getMasterDebug()) { + HTTP_message.setComment( HTTP_message.getComment() + " match:"+dataModel.getName(id)); + callbacks.printOutput(". Match for "+dataModel.getName(id)+" (rule "+id+") for Regex=" + dataModel.getRegex(id)); + } + String[] grpValues = new String[grpCount]; + + for (int i=0; ibody, 4->other + deltaContentLen += delta; + } + callbacks.printOutput("Replaced old value for " + parameter.getName() + " with new value: " + newValue); + //*DEBUG*/callbacks.printOutput("deltaContentLen="+deltaContentLen); + } + } + + //Content-Length preparation + List HTTP_headers = requestInfo.getHeaders(); + int oContLenStart=0, oContLenLength=0, oContLenValue=0; + boolean oContLenProccess = false; + + /*Processing headers*/ + int oCursor=0; //Assumption: headers are proccessed in top down order + for(int i=0; i p1.valueStart - p2.valueStart); + + byte[] nRequest = new byte[oRequest.length + deltaRequest]; + + int oStart = 0; + int oEnd = oRequest.length; + int nStart = 0; + int oParamStart, oParamEnd; + + //1. Update all parameters identified above + //2. Update the Content-Length + for (enhancedParameter parameter : nParameters) { + oParamStart = parameter.valueStart; + oParamEnd = parameter.valueEnd; + + //Content-Length update + if (oContLenProccess && oParamStart > oContLenStart){ //found the parameter just after Content-Length? + //copy everything before the Content-Length + delta = oContLenStart-oStart; + System.arraycopy(oRequest, oStart, nRequest, nStart, delta); + oStart+= delta; + nStart+= delta; + + //Compute and append the new Content-Length + String nContLen = "Content-Length: "+ ((int) oContLenValue + (int) deltaContentLen); + + if (dataModel.getMasterDebug()) {callbacks.printOutput("+ Content-Length="+ ((int) oContLenValue + (int) deltaContentLen));} /*Debug enabled*/ + + int nContLenLength = nContLen.length(); + System.arraycopy(nContLen.getBytes(), 0, nRequest, nStart, nContLenLength); + //*DEBUG*/callbacks.printOutput("###nStart="+nStart+", nContLenLength="+nContLenLength); + oStart+= oContLenLength; + nStart+= nContLenLength; + //Content-Lenght updated + oContLenProccess = false; + } + //end Content-Length update + + //copy everithing before the parameter + delta = oParamStart-oStart; + //*DEBUG*/callbacks.printOutput("###oStart="+oStart+", nStart="+nStart+", delta="+delta); + System.arraycopy(oRequest, oStart, nRequest, nStart, delta); + oStart+= delta; + nStart+= delta; + + //DEBUG enabled + if (dataModel.getMasterDebug()){ + callbacks.printOutput("+ Parameter["+parameter.name+"]="+parameter.newvalue+" of Type="+ enhancedParameter.Type.get(parameter.type)); + HTTP_message.setComment( HTTP_message.getComment() + " new:" + parameter.name + " "); + } + //end DEBUG + + int nParamLenght = parameter.newvalue.length(); + + //Copying new value (might be empty, smaller or larger) + System.arraycopy(parameter.newvalue.getBytes(), 0, nRequest, nStart, nParamLenght); + //A better alternative? + //Bytes.concat(byte[]... arrays); + + oStart+= oParamEnd-oParamStart; + nStart+= nParamLenght; + } + + //Copying till the end + if (oStart>0 && oStart Type; - static { - Type = new ArrayList(8); - Type.add(0, "header"); - //increment with one to make room for header (0) - Type.add(IParameter.PARAM_URL+1, "url"); - Type.add(IParameter.PARAM_BODY+1, "body"); - Type.add(IParameter.PARAM_COOKIE+1, "cookie"); - Type.add(IParameter.PARAM_XML+1, "xml"); /*other - all below types are reporesented by this type*/ - Type.add(IParameter.PARAM_XML_ATTR+1, "xml attr"); - Type.add(IParameter.PARAM_MULTIPART_ATTR+1, "multipart attr"); - Type.add(IParameter.PARAM_JSON+1, "json"); - } - - /*Construct new enhancedParam from IParam (used for Burp listed params)*/ - public enhancedParameter(IParameter IParam, String newValue){ - this.name = IParam.getName(); - this.type = IParam.getType(); - this.type++; //increment with one to make room for header (0) - this.valueStart = IParam.getValueStart(); - this.valueEnd = IParam.getValueEnd(); - this.newvalue = newValue; - } - /*Construct new enhancedParam from it's components (used for Header)*/ - public enhancedParameter(String name, byte type, int valueStart, int valueEnd, String newValue){ - this.name = name; - this.type = type; - this.valueStart = valueStart; - this.valueEnd = valueEnd; - this.newvalue = newValue; - } - public String name; - public byte type; - public int valueStart; - public int valueEnd; - public String newvalue; + public static List Type; + static { + Type = new ArrayList(8); + Type.add(0, "header"); + //increment with one to make room for header (0) + Type.add(IParameter.PARAM_URL+1, "url"); + Type.add(IParameter.PARAM_BODY+1, "body"); + Type.add(IParameter.PARAM_COOKIE+1, "cookie"); + Type.add(IParameter.PARAM_XML+1, "xml"); /*other - all below types are reporesented by this type*/ + Type.add(IParameter.PARAM_XML_ATTR+1, "xml attr"); + Type.add(IParameter.PARAM_MULTIPART_ATTR+1, "multipart attr"); + Type.add(IParameter.PARAM_JSON+1, "json"); + } + + /*Construct new enhancedParam from IParam (used for Burp listed params)*/ + public enhancedParameter(IParameter IParam, String newValue){ + this.name = IParam.getName(); + this.type = IParam.getType(); + this.type++; //increment with one to make room for header (0) + this.valueStart = IParam.getValueStart(); + this.valueEnd = IParam.getValueEnd(); + this.newvalue = newValue; + } + /*Construct new enhancedParam from it's components (used for Header)*/ + public enhancedParameter(String name, byte type, int valueStart, int valueEnd, String newValue){ + this.name = name; + this.type = type; + this.valueStart = valueStart; + this.valueEnd = valueEnd; + this.newvalue = newValue; + } + public String name; + public byte type; + public int valueStart; + public int valueEnd; + public String newvalue; } diff --git a/src/tokenJar/DataModel.java b/src/tokenJar/DataModel.java index 955c045..16d4a27 100644 --- a/src/tokenJar/DataModel.java +++ b/src/tokenJar/DataModel.java @@ -27,263 +27,263 @@ import org.mozilla.javascript.ScriptableObject; */ public class DataModel { - private final DefaultTableModel tableModel; - private List> tokensByType; - private HashMultimap tokensByPath; - private Pattern[] patterns; //precompile the patterns for performance - - private boolean masterEnable = false; - private boolean masterProxy = true; - private boolean masterIntruder = true; - private boolean masterRepeater = true; - private boolean masterDebug = false; - - private IBurpExtenderCallbacks callbacks; - private final PrintWriter stderr; - - private boolean[] valueUpdated; - - public DataModel(DefaultTableModel tableModel, IBurpExtenderCallbacks callbacks){ - this.tableModel = tableModel; - this.callbacks = callbacks; - stderr = new PrintWriter(callbacks.getStderr()); - } - - public void init() { - int rowIdCount = tableModel.getRowCount(); - - tokensByType = new ArrayList<>(10); //each parameter type has its own HashMap - tokensByType.add(0, new HashMap(rowIdCount)); //Extract from Request -> -1+1 - tokensByType.add(1, new HashMap(rowIdCount)); //Extract from Reponse -> 0+1 - tokensByType.add(2, new HashMap(rowIdCount)); //header -> 1+1 - tokensByType.add(3, new HashMap(rowIdCount)); //url -> 2+1 - tokensByType.add(4, new HashMap(rowIdCount)); //body -> 3+1 - tokensByType.add(5, new HashMap(rowIdCount)); //cookie -> 4+1 - tokensByType.add(6, new HashMap(rowIdCount)); //other -> 5+1 - tokensByType.add(7, new HashMap(rowIdCount)); //To Proxy -> 6+1 - tokensByType.add(8, new HashMap(rowIdCount)); //To Repeater -> 7+1 - tokensByType.add(9, new HashMap(rowIdCount)); //To Intruder -> 8+1 - - tokensByPath = HashMultimap.create(rowIdCount, 3*rowIdCount); - patterns = new Pattern[rowIdCount]; - //where = new boolean[rowIdCount][7]; //7 param types - valueUpdated = new boolean[rowIdCount]; - - - for(int rowId=0; rowId getByPath(String path) { - Set byPath = tokensByPath.get(path); - Set byAllPath = tokensByPath.get("*"); - byPath.addAll(byAllPath); - return byPath; - } - - public boolean getFromRequest(int rowId) { - return (boolean)tableModel.getValueAt(rowId, 2); - } - - public boolean getFromResponse(int rowId) { - return (boolean)tableModel.getValueAt(rowId, 3); - } - - public boolean getToProxy(int rowId) { - return (boolean)tableModel.getValueAt(rowId, 9); - } - - public boolean getToRepeater(int rowId) { - return (boolean)tableModel.getValueAt(rowId, 10); - } - - public boolean getToIntruder(int rowId) { - return (boolean)tableModel.getValueAt(rowId, 11); - } - - public int getRowCount(){ - return tableModel.getRowCount(); - } - - public boolean getEnable(int rowId) { - return (boolean) tableModel.getValueAt(rowId, 0); - } - - public String getName(int rowId) { - return tableModel.getValueAt(rowId, 1).toString(); - } - - public String getValue(int rowId) { - //*DEBUG*/ callbacks.printOutput("getValue("+rowId+")"); - //*DEBUG*/ callbacks.printOutput("="+tableModel.getValueAt(rowId, 6).toString()); - - return tableModel.getValueAt(rowId, 12).toString(); - } - - public String getPath(int rowId) { - return tableModel.getValueAt(rowId, 15).toString(); - } - - public String getRegex(int rowId) { - return tableModel.getValueAt(rowId, 14).toString(); - } - - public Pattern getPattern(int rowId) { - return patterns[rowId]; - } - - public void setValue(Integer rowId, String[] grpValues) { - Context cx = Context.enter(); - try { - String evalJS = tableModel.getValueAt(rowId, 13).toString(); - - Scriptable scope = cx.initStandardObjects(); - - //inject in JavaScript context the captured groups - Object jsGrpValues = Context.javaToJS(grpValues, scope); - ScriptableObject.putProperty(scope, "grp", jsGrpValues); - - //compute the value by evaluating JavaScript - Object result = cx.evaluateString(scope, evalJS, "", 1, null); - String value = Context.toString(result); - - this.valueUpdated[rowId]=true; //signal that the value was updated programatically - tableModel.setValueAt(value, rowId, 12); //set the actual value - - //the update was done for this parameter - String paramName = tableModel.getValueAt(rowId, 1).toString(); - //mark that the latest value is to be obtained from this rowId id - for (byte type=0; type<=9; type++) // do this for each param type - if (isUpdatable(rowId, type)) - tokensByType.get(type).put(paramName, rowId); - } catch (Exception ex) { - callbacks.printError(ex.getMessage()); - } finally { - Context.exit(); - } - } - - /*The value was updated in the DataModel*/ - public boolean isValueUpdated(int rowId){ - if (this.valueUpdated[rowId]){ - // signal that the value vas updated (does not need any update) - //and reset to false for next time - this.valueUpdated[rowId]=false; - return true; - } - return false; - } - public void setMasterEnable(boolean value){ - masterEnable = value; - } - - public boolean getMasterEnable(){ - return masterEnable; - } - - public void setMasterProxy(boolean value){ - masterProxy = value; - } - public boolean getMasterProxy(){ - return masterProxy; - } - - public void setMasterIntruder(boolean value){ - masterIntruder = value; - } - public boolean getMasterIntruder(){ - return masterIntruder; - } - - public void setMasterRepeater(boolean value){ - masterRepeater = value; - } - public boolean getMasterRepeater(){ - return masterRepeater; - } - - public void setMasterDebug(boolean value){ - masterDebug = value; - } - - public boolean getMasterDebug(){ - return masterDebug; - } - public boolean isUpdatable(int rowId, byte type) { - //Attention: The order of parameter columns (checkboxes) in Table is important - if (type<9) - return (boolean) tableModel.getValueAt(rowId, 2 + type ); // 2 is the position of 'header' - // header -> .getValueAt(_,2) - // ... - // cookie -> .getValueAt(_,5) - else - return (boolean) tableModel.getValueAt(rowId, 2 + 9 ); // other -> .getValueAt(_,6) - } + private final DefaultTableModel tableModel; + private List> tokensByType; + private HashMultimap tokensByPath; + private Pattern[] patterns; //precompile the patterns for performance + + private boolean masterEnable = false; + private boolean masterProxy = true; + private boolean masterIntruder = true; + private boolean masterRepeater = true; + private boolean masterDebug = false; + + private IBurpExtenderCallbacks callbacks; + private final PrintWriter stderr; + + private boolean[] valueUpdated; + + public DataModel(DefaultTableModel tableModel, IBurpExtenderCallbacks callbacks){ + this.tableModel = tableModel; + this.callbacks = callbacks; + stderr = new PrintWriter(callbacks.getStderr()); + } + + public void init() { + int rowIdCount = tableModel.getRowCount(); + + tokensByType = new ArrayList<>(10); //each parameter type has its own HashMap + tokensByType.add(0, new HashMap(rowIdCount)); //Extract from Request -> -1+1 + tokensByType.add(1, new HashMap(rowIdCount)); //Extract from Reponse -> 0+1 + tokensByType.add(2, new HashMap(rowIdCount)); //header -> 1+1 + tokensByType.add(3, new HashMap(rowIdCount)); //url -> 2+1 + tokensByType.add(4, new HashMap(rowIdCount)); //body -> 3+1 + tokensByType.add(5, new HashMap(rowIdCount)); //cookie -> 4+1 + tokensByType.add(6, new HashMap(rowIdCount)); //other -> 5+1 + tokensByType.add(7, new HashMap(rowIdCount)); //To Proxy -> 6+1 + tokensByType.add(8, new HashMap(rowIdCount)); //To Repeater -> 7+1 + tokensByType.add(9, new HashMap(rowIdCount)); //To Intruder -> 8+1 + + tokensByPath = HashMultimap.create(rowIdCount, 3*rowIdCount); + patterns = new Pattern[rowIdCount]; + //where = new boolean[rowIdCount][7]; //7 param types + valueUpdated = new boolean[rowIdCount]; + + + for(int rowId=0; rowId getByPath(String path) { + Set byPath = tokensByPath.get(path); + Set byAllPath = tokensByPath.get("*"); + byPath.addAll(byAllPath); + return byPath; + } + + public boolean getFromRequest(int rowId) { + return (boolean)tableModel.getValueAt(rowId, 2); + } + + public boolean getFromResponse(int rowId) { + return (boolean)tableModel.getValueAt(rowId, 3); + } + + public boolean getToProxy(int rowId) { + return (boolean)tableModel.getValueAt(rowId, 9); + } + + public boolean getToRepeater(int rowId) { + return (boolean)tableModel.getValueAt(rowId, 10); + } + + public boolean getToIntruder(int rowId) { + return (boolean)tableModel.getValueAt(rowId, 11); + } + + public int getRowCount(){ + return tableModel.getRowCount(); + } + + public boolean getEnable(int rowId) { + return (boolean) tableModel.getValueAt(rowId, 0); + } + + public String getName(int rowId) { + return tableModel.getValueAt(rowId, 1).toString(); + } + + public String getValue(int rowId) { + //*DEBUG*/ callbacks.printOutput("getValue("+rowId+")"); + //*DEBUG*/ callbacks.printOutput("="+tableModel.getValueAt(rowId, 6).toString()); + + return tableModel.getValueAt(rowId, 12).toString(); + } + + public String getPath(int rowId) { + return tableModel.getValueAt(rowId, 15).toString(); + } + + public String getRegex(int rowId) { + return tableModel.getValueAt(rowId, 14).toString(); + } + + public Pattern getPattern(int rowId) { + return patterns[rowId]; + } + + public void setValue(Integer rowId, String[] grpValues) { + Context cx = Context.enter(); + try { + String evalJS = tableModel.getValueAt(rowId, 13).toString(); + + Scriptable scope = cx.initStandardObjects(); + + //inject in JavaScript context the captured groups + Object jsGrpValues = Context.javaToJS(grpValues, scope); + ScriptableObject.putProperty(scope, "grp", jsGrpValues); + + //compute the value by evaluating JavaScript + Object result = cx.evaluateString(scope, evalJS, "", 1, null); + String value = Context.toString(result); + + this.valueUpdated[rowId]=true; //signal that the value was updated programatically + tableModel.setValueAt(value, rowId, 12); //set the actual value + + //the update was done for this parameter + String paramName = tableModel.getValueAt(rowId, 1).toString(); + //mark that the latest value is to be obtained from this rowId id + for (byte type=0; type<=9; type++) // do this for each param type + if (isUpdatable(rowId, type)) + tokensByType.get(type).put(paramName, rowId); + } catch (Exception ex) { + callbacks.printError(ex.getMessage()); + } finally { + Context.exit(); + } + } + + /*The value was updated in the DataModel*/ + public boolean isValueUpdated(int rowId){ + if (this.valueUpdated[rowId]){ + // signal that the value vas updated (does not need any update) + //and reset to false for next time + this.valueUpdated[rowId]=false; + return true; + } + return false; + } + public void setMasterEnable(boolean value){ + masterEnable = value; + } + + public boolean getMasterEnable(){ + return masterEnable; + } + + public void setMasterProxy(boolean value){ + masterProxy = value; + } + public boolean getMasterProxy(){ + return masterProxy; + } + + public void setMasterIntruder(boolean value){ + masterIntruder = value; + } + public boolean getMasterIntruder(){ + return masterIntruder; + } + + public void setMasterRepeater(boolean value){ + masterRepeater = value; + } + public boolean getMasterRepeater(){ + return masterRepeater; + } + + public void setMasterDebug(boolean value){ + masterDebug = value; + } + + public boolean getMasterDebug(){ + return masterDebug; + } + public boolean isUpdatable(int rowId, byte type) { + //Attention: The order of parameter columns (checkboxes) in Table is important + if (type<9) + return (boolean) tableModel.getValueAt(rowId, 2 + type ); // 2 is the position of 'header' + // header -> .getValueAt(_,2) + // ... + // cookie -> .getValueAt(_,5) + else + return (boolean) tableModel.getValueAt(rowId, 2 + 9 ); // other -> .getValueAt(_,6) + } } diff --git a/src/tokenJar/GettingStartedDialog.java b/src/tokenJar/GettingStartedDialog.java index d8c3e27..103dea6 100644 --- a/src/tokenJar/GettingStartedDialog.java +++ b/src/tokenJar/GettingStartedDialog.java @@ -18,36 +18,36 @@ import javax.swing.JDialog; */ public class GettingStartedDialog extends javax.swing.JDialog { - private final Tab parent; - + private final Tab parent; + /** * Creates new form GettingStartedDialog */ public GettingStartedDialog(Tab parent, boolean modal) { //super(null, modal); this.setModal(true); - + this.parent = parent; initComponents(); - + this.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); this.setTitle("Getting Started"); - + //stop 'New here message' parent.eraseNewHereLabel(); - + initCloseButton(); } - + private void initCloseButton(){ closeButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent ae) { - dispose(); + dispose(); } - }); + }); } - + /** * This method is called from within the constructor to initialize the form. @@ -85,38 +85,38 @@ public class GettingStartedDialog extends javax.swing.JDialog { javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); jPanel1.setLayout(jPanel1Layout); jPanel1Layout.setHorizontalGroup( - jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() - .addGap(19, 653, Short.MAX_VALUE) - .addComponent(jLabel1) - .addGap(18, 18, 18) - .addComponent(closeButton)) - .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)) - .addContainerGap()) - ); + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() + .addGap(19, 653, Short.MAX_VALUE) + .addComponent(jLabel1) + .addGap(18, 18, 18) + .addComponent(closeButton)) + .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)) + .addContainerGap()) + ); jPanel1Layout.setVerticalGroup( - jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() - .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 621, Short.MAX_VALUE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(closeButton) - .addComponent(jLabel1)) - .addContainerGap()) - ); + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 621, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(closeButton) + .addComponent(jLabel1)) + .addContainerGap()) + ); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jPanel1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - ); + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jPanel1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + ); layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - ); + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + ); pack(); }// //GEN-END:initComponents diff --git a/src/tokenJar/PersistSettings.java b/src/tokenJar/PersistSettings.java index c91d252..aea9166 100644 --- a/src/tokenJar/PersistSettings.java +++ b/src/tokenJar/PersistSettings.java @@ -22,172 +22,172 @@ import java.util.Vector; * @author DanNegrea */ public class PersistSettings { - public static final String DEFAULT_LINE = "[[false,\"csrf\",false,false,true,false,false,false,false,false\"\",\"grp[1]\",\"csrf\\u003d([a-zA-Z0-9]*)\",\"*\"]]"; - private EvictingQueue evalQueue; - private EvictingQueue regexQueue; - private int queueMaxSize; - - private final IBurpExtenderCallbacks callbacks; - - public PersistSettings(IBurpExtenderCallbacks callbacks){ - this(callbacks, 50); - queueMaxSize = 50; - } - - public PersistSettings(IBurpExtenderCallbacks callbacks, int expMaxSize){ - this.queueMaxSize = expMaxSize; - this.evalQueue = EvictingQueue.create(queueMaxSize); - this.regexQueue = EvictingQueue.create(queueMaxSize); - this.callbacks = callbacks; - } - - public void save(Vector dataInTable){ - try{ - Gson gson = new Gson(); - String dataToStore = gson.toJson(dataInTable); - //Save version fist (5 chars) - dataToStore = VERSION + dataToStore; - callbacks.saveExtensionSetting(NAME+".dataInTable", dataToStore); - //Signal that old format up to TokenJar 2.0 is no longer in use - callbacks.saveExtensionSetting("dataInTable", ""); - } catch (Exception ex) { - PrintWriter stderr = new PrintWriter(callbacks.getStderr()); - ex.printStackTrace(stderr); - } - - save(evalQueue, "evalQueue"); - save(regexQueue, "regexQueue"); - } - private void save(EvictingQueue queue, String queueName){ - try{ - Gson gson = new Gson(); - String dataToStore = gson.toJson(queue); - callbacks.saveExtensionSetting(NAME+"."+queueName, dataToStore); - } catch (Exception ex) { - PrintWriter stderr = new PrintWriter(callbacks.getStderr()); - ex.printStackTrace(stderr); - } - } - public void saveLastConfigPath(String path){ - callbacks.saveExtensionSetting(NAME+".lastConfigPath", path); - } - - public Vector restore(){ - Vector restoredDataInTable = null; - Vector dataInTable = new Vector(); - - /*Attempt to restore data from version TokenJar 2.0*/ - String tableData= callbacks.loadExtensionSetting("dataInTable"); - //if old setting still in settings store - if (!Strings.isNullOrEmpty(tableData)){ - //*DEBUG*/callbacks.printOutput("!Strings.isNullOrEmpty(tableData)"); - try ( - ByteArrayInputStream byteArrIn = new ByteArrayInputStream(tableData.getBytes()); - ObjectInputStream objectIn = new ObjectInputStream(byteArrIn); - ){ - //get data in table from the serialized object - dataInTable = (Vector) objectIn.readObject(); - } catch (IOException | ClassNotFoundException ex) { - PrintWriter stderr = new PrintWriter(callbacks.getStderr()); - ex.printStackTrace(stderr); - } - } - - /*Attempt to restore data from newer version*/ - if (dataInTable.size()==0) { - //*DEBUG*/callbacks.printOutput("dataInTable.size()==0"); - try - { - String strObj = callbacks.loadExtensionSetting(NAME+".dataInTable"); - - if (!Strings.isNullOrEmpty(strObj) && strObj.length()>5){ - //TODO To be used in future version to check the settings format version number - strObj = strObj.substring(5); //Skip version information (5 chars) - } else { - /*Demo line if empty*/ - strObj = DEFAULT_LINE; - } - - Gson gson = new Gson(); - restoredDataInTable = (Vector) gson.fromJson(strObj, Vector.class); - - //The respored data is a Vector of ArrayLists, the result should be a Vector of Vectors. - for (int i=0; i restore(EvictingQueue queue, String queueName){ - EvictingQueue newQueue= EvictingQueue.create(queueMaxSize); - try{ - String storedStr= callbacks.loadExtensionSetting(NAME+"."+queueName); - if (Strings.isNullOrEmpty(storedStr)) return queue; - - Gson gson = new Gson(); - String[] storedQueue = gson.fromJson(storedStr, String[].class); - - for (int i=0; i0) - return evalQueue.toArray(); - else - return new Object[0]; - } - public void pushRegex(String expression){ - if( !Strings.isNullOrEmpty(expression) ){ - //if expression is contained, remove it and add it fresh - if (regexQueue.contains(expression)) - regexQueue.remove(expression); - regexQueue.add(expression); - } - } - public Object[] getRegex(){ - if (regexQueue.size()>0) - return regexQueue.toArray(); - else - return new Object[0]; - } + public static final String DEFAULT_LINE = "[[false,\"csrf\",false,false,true,false,false,false,false,false\"\",\"grp[1]\",\"csrf\\u003d([a-zA-Z0-9]*)\",\"*\"]]"; + private EvictingQueue evalQueue; + private EvictingQueue regexQueue; + private int queueMaxSize; + + private final IBurpExtenderCallbacks callbacks; + + public PersistSettings(IBurpExtenderCallbacks callbacks){ + this(callbacks, 50); + queueMaxSize = 50; + } + + public PersistSettings(IBurpExtenderCallbacks callbacks, int expMaxSize){ + this.queueMaxSize = expMaxSize; + this.evalQueue = EvictingQueue.create(queueMaxSize); + this.regexQueue = EvictingQueue.create(queueMaxSize); + this.callbacks = callbacks; + } + + public void save(Vector dataInTable){ + try{ + Gson gson = new Gson(); + String dataToStore = gson.toJson(dataInTable); + //Save version fist (5 chars) + dataToStore = VERSION + dataToStore; + callbacks.saveExtensionSetting(NAME+".dataInTable", dataToStore); + //Signal that old format up to TokenJar 2.0 is no longer in use + callbacks.saveExtensionSetting("dataInTable", ""); + } catch (Exception ex) { + PrintWriter stderr = new PrintWriter(callbacks.getStderr()); + ex.printStackTrace(stderr); + } + + save(evalQueue, "evalQueue"); + save(regexQueue, "regexQueue"); + } + private void save(EvictingQueue queue, String queueName){ + try{ + Gson gson = new Gson(); + String dataToStore = gson.toJson(queue); + callbacks.saveExtensionSetting(NAME+"."+queueName, dataToStore); + } catch (Exception ex) { + PrintWriter stderr = new PrintWriter(callbacks.getStderr()); + ex.printStackTrace(stderr); + } + } + public void saveLastConfigPath(String path){ + callbacks.saveExtensionSetting(NAME+".lastConfigPath", path); + } + + public Vector restore(){ + Vector restoredDataInTable = null; + Vector dataInTable = new Vector(); + + /*Attempt to restore data from version TokenJar 2.0*/ + String tableData= callbacks.loadExtensionSetting("dataInTable"); + //if old setting still in settings store + if (!Strings.isNullOrEmpty(tableData)){ + //*DEBUG*/callbacks.printOutput("!Strings.isNullOrEmpty(tableData)"); + try ( + ByteArrayInputStream byteArrIn = new ByteArrayInputStream(tableData.getBytes()); + ObjectInputStream objectIn = new ObjectInputStream(byteArrIn); + ){ + //get data in table from the serialized object + dataInTable = (Vector) objectIn.readObject(); + } catch (IOException | ClassNotFoundException ex) { + PrintWriter stderr = new PrintWriter(callbacks.getStderr()); + ex.printStackTrace(stderr); + } + } + + /*Attempt to restore data from newer version*/ + if (dataInTable.size()==0) { + //*DEBUG*/callbacks.printOutput("dataInTable.size()==0"); + try + { + String strObj = callbacks.loadExtensionSetting(NAME+".dataInTable"); + + if (!Strings.isNullOrEmpty(strObj) && strObj.length()>5){ + //TODO To be used in future version to check the settings format version number + strObj = strObj.substring(5); //Skip version information (5 chars) + } else { + /*Demo line if empty*/ + strObj = DEFAULT_LINE; + } + + Gson gson = new Gson(); + restoredDataInTable = (Vector) gson.fromJson(strObj, Vector.class); + + //The respored data is a Vector of ArrayLists, the result should be a Vector of Vectors. + for (int i=0; i restore(EvictingQueue queue, String queueName){ + EvictingQueue newQueue= EvictingQueue.create(queueMaxSize); + try{ + String storedStr= callbacks.loadExtensionSetting(NAME+"."+queueName); + if (Strings.isNullOrEmpty(storedStr)) return queue; + + Gson gson = new Gson(); + String[] storedQueue = gson.fromJson(storedStr, String[].class); + + for (int i=0; i0) + return evalQueue.toArray(); + else + return new Object[0]; + } + public void pushRegex(String expression){ + if( !Strings.isNullOrEmpty(expression) ){ + //if expression is contained, remove it and add it fresh + if (regexQueue.contains(expression)) + regexQueue.remove(expression); + regexQueue.add(expression); + } + } + public Object[] getRegex(){ + if (regexQueue.size()>0) + return regexQueue.toArray(); + else + return new Object[0]; + } } diff --git a/src/tokenJar/RegexWindow.java b/src/tokenJar/RegexWindow.java index 966901f..d0b5a5a 100644 --- a/src/tokenJar/RegexWindow.java +++ b/src/tokenJar/RegexWindow.java @@ -23,418 +23,418 @@ import org.mozilla.javascript.ScriptableObject; */ public class RegexWindow extends javax.swing.JFrame { - private final Tab parent; - private int selectedRow; - private PersistSettings persistSettings; - - private IBurpExtenderCallbacks callbacks; - /** - * Creates new form RegexTestWindow - * @param parent - * @param selectedRow - */ - public RegexWindow(Tab parent, int selectedRow, IBurpExtenderCallbacks callbacks){ - initComponents(); - - this.callbacks = callbacks; - - this.parent = parent; - this.selectedRow = selectedRow; - this.persistSettings = parent.getPersistSettings(); - - String name = parent.getCell(selectedRow, 1).toString(); - String evalJS = parent.getCell(selectedRow, 13).toString(); - Object regex = parent.getCell(selectedRow, 14); - String path = parent.getCell(selectedRow, 15).toString(); - - //Indicate in UI the name of the parameter and the path - nameField.setText(name); - pathField.setText(path); - - try{ - ; - } - catch(Exception ex){ - PrintWriter stderr = new PrintWriter(callbacks.getStderr()); - ex.printStackTrace(stderr); - } - - //Restore Eval field from persistent settings - Object[] exprs = persistSettings.getEval(); - for(int i=0; i//GEN-BEGIN:initComponents - private void initComponents() { - - jPanel1 = new javax.swing.JPanel(); - jLabel2 = new javax.swing.JLabel(); - jLabel3 = new javax.swing.JLabel(); - nameField = new javax.swing.JTextField(); - jLabel4 = new javax.swing.JLabel(); - pathField = new javax.swing.JTextField(); - testRegex = new javax.swing.JButton(); - jLabel5 = new javax.swing.JLabel(); - regexField = new javax.swing.JComboBox(); - evalField = new javax.swing.JComboBox(); - jLabel8 = new javax.swing.JLabel(); - jPanel3 = new javax.swing.JPanel(); - jLabel6 = new javax.swing.JLabel(); - jScrollPane1 = new javax.swing.JScrollPane(); - responseSnippet = new javax.swing.JTextArea(); - valueField = new javax.swing.JTextField(); - jLabel1 = new javax.swing.JLabel(); - saveOptions = new javax.swing.JButton(); - jLabel7 = new javax.swing.JLabel(); - jScrollPane2 = new javax.swing.JScrollPane(); - groupDebug = new javax.swing.JTextArea(); - - jLabel2.setText("Regex"); - - jLabel3.setText("Name"); - - nameField.setEditable(false); - nameField.setBackground(new java.awt.Color(239, 239, 239)); - - jLabel4.setText("Path"); - - pathField.setEditable(false); - pathField.setBackground(new java.awt.Color(239, 239, 239)); - pathField.setToolTipText(""); - pathField.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - pathFieldActionPerformed(evt); - } - }); - - testRegex.setText("Test"); - testRegex.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - testRegexActionPerformed(evt); - } - }); - - jLabel5.setText("Insert the regular expresion in order to obtain the Value. It needs to have one group."); - - regexField.setEditable(true); - regexField.setToolTipText(""); - - evalField.setEditable(true); - evalField.setToolTipText(""); - - jLabel8.setText("Eval"); - - javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); - jPanel1.setLayout(jPanel1Layout); - jPanel1Layout.setHorizontalGroup( - jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() - .addGap(9, 9, 9) - .addComponent(jLabel3) - .addGap(18, 18, 18) - .addComponent(nameField, javax.swing.GroupLayout.PREFERRED_SIZE, 161, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(10, 10, 10) - .addComponent(jLabel4) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(pathField, javax.swing.GroupLayout.PREFERRED_SIZE, 218, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(0, 0, Short.MAX_VALUE)) - .addGroup(jPanel1Layout.createSequentialGroup() - .addContainerGap() - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jLabel2) - .addComponent(jLabel8)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(evalField, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(regexField, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(testRegex, javax.swing.GroupLayout.PREFERRED_SIZE, 53, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(8, 8, 8)) - .addComponent(jLabel5, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) - .addGap(10, 10, 10)) - ); - jPanel1Layout.setVerticalGroup( - jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() - .addContainerGap() - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel3) - .addComponent(nameField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel4) - .addComponent(pathField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(jLabel5) - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) - .addGroup(jPanel1Layout.createSequentialGroup() - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(jLabel2) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(regexField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(18, 18, 18))) - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jLabel8) - .addComponent(evalField, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE))) - .addGroup(jPanel1Layout.createSequentialGroup() - .addGap(6, 6, 6) - .addComponent(testRegex, javax.swing.GroupLayout.PREFERRED_SIZE, 58, javax.swing.GroupLayout.PREFERRED_SIZE))) - .addContainerGap()) - ); - - jPanel1Layout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {evalField, regexField}); - - jLabel6.setText("Insert the response snippet from where the token is extracted."); - - responseSnippet.setColumns(20); - responseSnippet.setRows(5); - jScrollPane1.setViewportView(responseSnippet); - - valueField.setEditable(false); - - jLabel1.setText("Value"); - - saveOptions.setText("Save"); - saveOptions.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - saveOptionsActionPerformed(evt); - } - }); - - jLabel7.setText("Click Test and check if you obtain the desired Value"); - - groupDebug.setEditable(false); - groupDebug.setBackground(new java.awt.Color(239, 239, 239)); - groupDebug.setColumns(20); - groupDebug.setRows(3); - jScrollPane2.setViewportView(groupDebug); - - javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3); - jPanel3.setLayout(jPanel3Layout); - jPanel3Layout.setHorizontalGroup( - jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel3Layout.createSequentialGroup() - .addContainerGap() - .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel3Layout.createSequentialGroup() - .addComponent(jLabel1) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(valueField, javax.swing.GroupLayout.PREFERRED_SIZE, 421, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(saveOptions, javax.swing.GroupLayout.PREFERRED_SIZE, 75, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(0, 0, Short.MAX_VALUE)) - .addComponent(jLabel6, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(jLabel7, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.TRAILING) - .addComponent(jScrollPane2, javax.swing.GroupLayout.Alignment.TRAILING)) - .addContainerGap()) - ); - jPanel3Layout.setVerticalGroup( - jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel3Layout.createSequentialGroup() - .addComponent(jLabel6) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jLabel7) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 173, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 76, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(valueField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel1) - .addComponent(saveOptions)) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - ); - - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); - getContentPane().setLayout(layout); - layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - ); - layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - ); - - pack(); - }// //GEN-END:initComponents - - private void saveOptionsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveOptionsActionPerformed - - groupDebug.setText(groupDebug.getText() +"\n Saved"); - - //save Eval and Extract to parent window - parent.setCell(selectedRow, 13, (Object) evalField.getSelectedItem()); //evelCol - parent.setCell(selectedRow, 14, (Object) regexField.getSelectedItem()); //regexCol - - //save Eval and Extract in persistant object - String evalJS = evalField.getSelectedItem().toString(); - String regex = regexField.getSelectedItem().toString(); - - persistSettings.pushEval(evalJS); - persistSettings.pushRegex(regex); - - //Save the settings to Burp - persistSettings.save(parent.getTableModel().getDataVector()); - }//GEN-LAST:event_saveOptionsActionPerformed - - private void testRegexActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_testRegexActionPerformed - Highlighter hl = responseSnippet.getHighlighter(); - hl.removeAllHighlights(); /*Delete all higlights*/ - valueField.setText(""); /*Set empty value*/ - groupDebug.setText(""); /*Set empty value*/ - - StringBuilder debug = new StringBuilder(); - - String evalJS = evalField.getSelectedItem().toString(); - String regex = regexField.getSelectedItem().toString();//.replace("\\","\\\\"); // no need to escape \ from user input - String snippet = responseSnippet.getText(); - - Pattern pattern = Pattern.compile(regex); - Matcher matcher = pattern.matcher(snippet); - - if(matcher.find()) - { - /*Highlight what was found*/ - String responseText = responseSnippet.getText(); - String foundText = matcher.group(0); - int foundTextLen= 0; - int foundTextIndex = -1; - if (foundText!=null) //bellow cannot be null - foundTextLen = foundText.length(); - if (foundTextLen>0) //below cannot be empty - foundTextIndex = responseText.indexOf(foundText); - if(foundTextIndex >= 0){ //beloew it was find in the snippet - try { - hl.addHighlight(foundTextIndex, foundTextIndex +foundTextLen, DefaultHighlighter.DefaultPainter); - //foundTextIndex = responseText.indexOf(responseText, foundTextIndex + foundTextLen); //not needed anymore; I changed while to if - } catch (BadLocationException ex) { - /*DEBUG*/debug.append("! Exception: ").append(ex.toString()).append("\n"); - PrintWriter stderr = new PrintWriter(callbacks.getStderr()); - ex.printStackTrace(stderr); - } - } - /*end Highlight*/ - - /*Eval the value*/ - int grpCount = matcher.groupCount()+1; //if I have only group 0 it must be 1 - String[] grpValues = new String[grpCount]; - debug.append("grpCount=").append(grpCount).append("\n"); - for (int i=0; i", 1, null); - String value = Context.toString(result); - - - valueField.setText(value); //set the actual value - - } catch (Exception ex) { - /*DEBUG*/debug.append("! Exception: ").append(ex.toString()).append("\n"); - PrintWriter stderr = new PrintWriter(callbacks.getStderr()); - ex.printStackTrace(stderr); - } finally { - Context.exit(); - } - groupDebug.setText(debug.toString()); - /*end Eval the value*/ - - /*Extract - Add only once the value to the ComboBox*/ - int noIntems = regexField.getItemCount(); - boolean found = false; - - for (int i=0; i//GEN-BEGIN:initComponents + private void initComponents() { + + jPanel1 = new javax.swing.JPanel(); + jLabel2 = new javax.swing.JLabel(); + jLabel3 = new javax.swing.JLabel(); + nameField = new javax.swing.JTextField(); + jLabel4 = new javax.swing.JLabel(); + pathField = new javax.swing.JTextField(); + testRegex = new javax.swing.JButton(); + jLabel5 = new javax.swing.JLabel(); + regexField = new javax.swing.JComboBox(); + evalField = new javax.swing.JComboBox(); + jLabel8 = new javax.swing.JLabel(); + jPanel3 = new javax.swing.JPanel(); + jLabel6 = new javax.swing.JLabel(); + jScrollPane1 = new javax.swing.JScrollPane(); + responseSnippet = new javax.swing.JTextArea(); + valueField = new javax.swing.JTextField(); + jLabel1 = new javax.swing.JLabel(); + saveOptions = new javax.swing.JButton(); + jLabel7 = new javax.swing.JLabel(); + jScrollPane2 = new javax.swing.JScrollPane(); + groupDebug = new javax.swing.JTextArea(); + + jLabel2.setText("Regex"); + + jLabel3.setText("Name"); + + nameField.setEditable(false); + nameField.setBackground(new java.awt.Color(239, 239, 239)); + + jLabel4.setText("Path"); + + pathField.setEditable(false); + pathField.setBackground(new java.awt.Color(239, 239, 239)); + pathField.setToolTipText(""); + pathField.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + pathFieldActionPerformed(evt); + } + }); + + testRegex.setText("Test"); + testRegex.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + testRegexActionPerformed(evt); + } + }); + + jLabel5.setText("Insert the regular expresion in order to obtain the Value. It needs to have one group."); + + regexField.setEditable(true); + regexField.setToolTipText(""); + + evalField.setEditable(true); + evalField.setToolTipText(""); + + jLabel8.setText("Eval"); + + javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); + jPanel1.setLayout(jPanel1Layout); + jPanel1Layout.setHorizontalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGap(9, 9, 9) + .addComponent(jLabel3) + .addGap(18, 18, 18) + .addComponent(nameField, javax.swing.GroupLayout.PREFERRED_SIZE, 161, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(10, 10, 10) + .addComponent(jLabel4) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(pathField, javax.swing.GroupLayout.PREFERRED_SIZE, 218, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, Short.MAX_VALUE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel2) + .addComponent(jLabel8)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(evalField, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(regexField, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(testRegex, javax.swing.GroupLayout.PREFERRED_SIZE, 53, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(8, 8, 8)) + .addComponent(jLabel5, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) + .addGap(10, 10, 10)) + ); + jPanel1Layout.setVerticalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel3) + .addComponent(nameField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel4) + .addComponent(pathField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jLabel5) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addGroup(jPanel1Layout.createSequentialGroup() + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jLabel2) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(regexField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(18, 18, 18))) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel8) + .addComponent(evalField, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGap(6, 6, 6) + .addComponent(testRegex, javax.swing.GroupLayout.PREFERRED_SIZE, 58, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addContainerGap()) + ); + + jPanel1Layout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {evalField, regexField}); + + jLabel6.setText("Insert the response snippet from where the token is extracted."); + + responseSnippet.setColumns(20); + responseSnippet.setRows(5); + jScrollPane1.setViewportView(responseSnippet); + + valueField.setEditable(false); + + jLabel1.setText("Value"); + + saveOptions.setText("Save"); + saveOptions.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + saveOptionsActionPerformed(evt); + } + }); + + jLabel7.setText("Click Test and check if you obtain the desired Value"); + + groupDebug.setEditable(false); + groupDebug.setBackground(new java.awt.Color(239, 239, 239)); + groupDebug.setColumns(20); + groupDebug.setRows(3); + jScrollPane2.setViewportView(groupDebug); + + javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3); + jPanel3.setLayout(jPanel3Layout); + jPanel3Layout.setHorizontalGroup( + jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel3Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel3Layout.createSequentialGroup() + .addComponent(jLabel1) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(valueField, javax.swing.GroupLayout.PREFERRED_SIZE, 421, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(saveOptions, javax.swing.GroupLayout.PREFERRED_SIZE, 75, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, Short.MAX_VALUE)) + .addComponent(jLabel6, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jLabel7, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jScrollPane2, javax.swing.GroupLayout.Alignment.TRAILING)) + .addContainerGap()) + ); + jPanel3Layout.setVerticalGroup( + jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel3Layout.createSequentialGroup() + .addComponent(jLabel6) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel7) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 173, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 76, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(valueField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel1) + .addComponent(saveOptions)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + + pack(); + }// //GEN-END:initComponents + + private void saveOptionsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveOptionsActionPerformed + + groupDebug.setText(groupDebug.getText() +"\n Saved"); + + //save Eval and Extract to parent window + parent.setCell(selectedRow, 13, (Object) evalField.getSelectedItem()); //evelCol + parent.setCell(selectedRow, 14, (Object) regexField.getSelectedItem()); //regexCol + + //save Eval and Extract in persistant object + String evalJS = evalField.getSelectedItem().toString(); + String regex = regexField.getSelectedItem().toString(); + + persistSettings.pushEval(evalJS); + persistSettings.pushRegex(regex); + + //Save the settings to Burp + persistSettings.save(parent.getTableModel().getDataVector()); + }//GEN-LAST:event_saveOptionsActionPerformed + + private void testRegexActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_testRegexActionPerformed + Highlighter hl = responseSnippet.getHighlighter(); + hl.removeAllHighlights(); /*Delete all higlights*/ + valueField.setText(""); /*Set empty value*/ + groupDebug.setText(""); /*Set empty value*/ + + StringBuilder debug = new StringBuilder(); + + String evalJS = evalField.getSelectedItem().toString(); + String regex = regexField.getSelectedItem().toString();//.replace("\\","\\\\"); // no need to escape \ from user input + String snippet = responseSnippet.getText(); + + Pattern pattern = Pattern.compile(regex); + Matcher matcher = pattern.matcher(snippet); + + if(matcher.find()) + { + /*Highlight what was found*/ + String responseText = responseSnippet.getText(); + String foundText = matcher.group(0); + int foundTextLen= 0; + int foundTextIndex = -1; + if (foundText!=null) //bellow cannot be null + foundTextLen = foundText.length(); + if (foundTextLen>0) //below cannot be empty + foundTextIndex = responseText.indexOf(foundText); + if(foundTextIndex >= 0){ //beloew it was find in the snippet + try { + hl.addHighlight(foundTextIndex, foundTextIndex +foundTextLen, DefaultHighlighter.DefaultPainter); + //foundTextIndex = responseText.indexOf(responseText, foundTextIndex + foundTextLen); //not needed anymore; I changed while to if + } catch (BadLocationException ex) { + /*DEBUG*/debug.append("! Exception: ").append(ex.toString()).append("\n"); + PrintWriter stderr = new PrintWriter(callbacks.getStderr()); + ex.printStackTrace(stderr); + } + } + /*end Highlight*/ + + /*Eval the value*/ + int grpCount = matcher.groupCount()+1; //if I have only group 0 it must be 1 + String[] grpValues = new String[grpCount]; + debug.append("grpCount=").append(grpCount).append("\n"); + for (int i=0; i", 1, null); + String value = Context.toString(result); + + + valueField.setText(value); //set the actual value + + } catch (Exception ex) { + /*DEBUG*/debug.append("! Exception: ").append(ex.toString()).append("\n"); + PrintWriter stderr = new PrintWriter(callbacks.getStderr()); + ex.printStackTrace(stderr); + } finally { + Context.exit(); + } + groupDebug.setText(debug.toString()); + /*end Eval the value*/ + + /*Extract - Add only once the value to the ComboBox*/ + int noIntems = regexField.getItemCount(); + boolean found = false; + + for (int i=0; i value provided by user*/ - - Object enable = tableModel.getValueAt(rowId, 0); - - //If UPDATE and not valid row then uncheck 'Enable' - //w/o checking 'enable!=null && (boolean)enable' next time will run the function body again and again - if (enable!=null && (boolean)enable && type==TableModelEvent.UPDATE && !dataModel.checkRow(rowId, true)){ - //*DEBUG*/callbacks.printOutput("row updated, but not valid"); - tableModel.setValueAt(false, rowId, 0); - return; - } - - /* Reinit the table*/ - /* Save settings in Burp storage*/ - dataModel.init(); - Vector dataInTable = tableModel.getDataVector(); - persistSettings.save(dataInTable); - } - /* - * This method is called from within the constructor to initialize the form. - * WARNING: Do NOT modify this code. The content of this method is always - * regenerated by the Form Editor. - */ - @SuppressWarnings("unchecked") + private final DefaultTableModel tableModel; + private final DataModel dataModel; + final IBurpExtenderCallbacks callbacks; + private final PersistSettings persistSettings; + private Timer timerNewHere; + + /** + * Creates new form Panel + */ + public Tab(IBurpExtenderCallbacks callbacks) { + initComponents(); + + tokenTable.setAutoResizeMode(javax.swing.JTable.AUTO_RESIZE_OFF); + + //On window resize resize also the columns + this.addComponentListener(new ComponentAdapter() { + @Override + public void componentResized(ComponentEvent e) { + resizeColumns(); + } + }); + + this.callbacks = callbacks; + + persistSettings = new PersistSettings(callbacks, 50); + + tableModel = (DefaultTableModel) tokenTable.getModel(); + dataModel = new DataModel(tableModel, callbacks); + + //Restore table or put demo data + this.restoreTableData(persistSettings.restore()); + this.resizeColumns(); + this.setStatusColor(); + + //tokenTable.getColumnModel().removeColumn(null); //in case I want to hide some columns + + //(re)Initialize dataModel + dataModel.init(); + + //load Last Config Path from burp settings + this.lastPathConfig.setText(persistSettings.restoreLastConfigPath()); + + tokenTable.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE); + + tableModel.addTableModelListener(this); + + /*Blink the 'New Here' meesage*/ + timerNewHere = new Timer(1000, new BlinkLabel(jLabelNewHere)); + if ( "true".equals(callbacks.loadExtensionSetting("NewHere:hide"))){ + jLabelNewHere.setText(""); + } + else{ + timerNewHere.start(); + } + callbacks.addSuiteTab(this); + + } + + public DataModel getDataModel() { + return dataModel; + } + public DefaultTableModel getTableModel(){ + return tableModel; + } + + public PersistSettings getPersistSettings(){ + return persistSettings; + } + + @Override + public String getTabCaption() { + return "Token Jar"; + } + + @Override + public Component getUiComponent() { + return this; + } + + @Override + public void tableChanged(TableModelEvent e) { + //*DEBUG*/callbacks.printOutput("TableChanged() e.getType="+e.getType()+" getFirstRow=: "+e.getFirstRow()+" getLastRow="+e.getLastRow()+""); + + int type = e.getType(); + int rowId = e.getFirstRow(); + //int column = e.getColumn(); + + //No line was updated or the table was dumpped + if (rowId<0) + return; + + /*New "empty" row do just init */ + if (type==TableModelEvent.INSERT || type == TableModelEvent.DELETE){ + /* Reinit the table*/ + /* Save settings in Burp storage*/ + dataModel.init(); + Vector dataInTable = tableModel.getDataVector(); + persistSettings.save(dataInTable); + return; + } + /*Value already updated in Datamodel*/ + if (dataModel.isValueUpdated(rowId)) + return; + /*else => value provided by user*/ + + Object enable = tableModel.getValueAt(rowId, 0); + + //If UPDATE and not valid row then uncheck 'Enable' + //w/o checking 'enable!=null && (boolean)enable' next time will run the function body again and again + if (enable!=null && (boolean)enable && type==TableModelEvent.UPDATE && !dataModel.checkRow(rowId, true)){ + //*DEBUG*/callbacks.printOutput("row updated, but not valid"); + tableModel.setValueAt(false, rowId, 0); + return; + } + + /* Reinit the table*/ + /* Save settings in Burp storage*/ + dataModel.init(); + Vector dataInTable = tableModel.getDataVector(); + persistSettings.save(dataInTable); + } + /* + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") // //GEN-BEGIN:initComponents private void initComponents() { @@ -199,13 +195,13 @@ public class Tab extends javax.swing.JPanel implements ITab, TableModelListener{ tokenTable.setAutoCreateRowSorter(true); tokenTable.setModel(new javax.swing.table.DefaultTableModel( - new Object [][] { + new Object [][] { - }, - new String [] { - "Enable", "Name", "Extract from Request", "Extract from Response", "Apply to header", "Apply to url", "Apply to body", "Apply to cookie", "Apply to other", "To Proxy", "To Repeater", "To Intruder", "Value", "Eval (js code)", "Regex", "Path" - } - ) { + }, + new String [] { + "Enable", "Name", "Extract from Request", "Extract from Response", "Apply to header", "Apply to url", "Apply to body", "Apply to cookie", "Apply to other", "To Proxy", "To Repeater", "To Intruder", "Value", "Eval (js code)", "Regex", "Path" + } + ) { Class[] types = new Class [] { java.lang.Boolean.class, java.lang.String.class, java.lang.Boolean.class, java.lang.Boolean.class, java.lang.Boolean.class, java.lang.Boolean.class, java.lang.Boolean.class, java.lang.Boolean.class, java.lang.Boolean.class, java.lang.Boolean.class, java.lang.Boolean.class, java.lang.Boolean.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class }; @@ -318,389 +314,389 @@ public class Tab extends javax.swing.JPanel implements ITab, TableModelListener{ javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); jPanel2.setLayout(jPanel2Layout); jPanel2Layout.setHorizontalGroup( - jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel2Layout.createSequentialGroup() - .addContainerGap() - .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel2Layout.createSequentialGroup() - .addComponent(masterEnable) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(statusColor, javax.swing.GroupLayout.DEFAULT_SIZE, 333, Short.MAX_VALUE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(masterProxy) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(masterIntruder) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(masterRepeater) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(masterDebug) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(jLabelNewHere, javax.swing.GroupLayout.PREFERRED_SIZE, 146, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(13, 13, 13)) - .addComponent(jScrollPane2)) - .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addContainerGap() .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(importConf, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(21, 21, 21) - .addComponent(exportConf, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGroup(jPanel2Layout.createSequentialGroup() - .addGap(18, 18, 18) - .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addComponent(removeToken, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(addToken, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(openRegexWindow, javax.swing.GroupLayout.PREFERRED_SIZE, 69, javax.swing.GroupLayout.PREFERRED_SIZE)))) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(masterEnable) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(statusColor, javax.swing.GroupLayout.DEFAULT_SIZE, 333, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(masterProxy) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(masterIntruder) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(masterRepeater) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(masterDebug) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jLabelNewHere, javax.swing.GroupLayout.PREFERRED_SIZE, 146, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(13, 13, 13)) + .addComponent(jScrollPane2)) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(goToSite1, javax.swing.GroupLayout.Alignment.TRAILING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jLabel1) - .addComponent(lastPathConfig, javax.swing.GroupLayout.PREFERRED_SIZE, 71, javax.swing.GroupLayout.PREFERRED_SIZE))))) - .addContainerGap()) - ); + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(importConf, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(21, 21, 21) + .addComponent(exportConf, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel2Layout.createSequentialGroup() + .addGap(18, 18, 18) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(removeToken, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(addToken, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(openRegexWindow, javax.swing.GroupLayout.PREFERRED_SIZE, 69, javax.swing.GroupLayout.PREFERRED_SIZE)))) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(goToSite1, javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel1) + .addComponent(lastPathConfig, javax.swing.GroupLayout.PREFERRED_SIZE, 71, javax.swing.GroupLayout.PREFERRED_SIZE))))) + .addContainerGap()) + ); jPanel2Layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {addToken, openRegexWindow, removeToken}); jPanel2Layout.setVerticalGroup( - jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() - .addContainerGap() - .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(masterEnable) - .addComponent(statusColor, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(masterDebug) - .addComponent(goToSite1) - .addComponent(masterRepeater) - .addComponent(masterIntruder) - .addComponent(masterProxy) - .addComponent(jLabelNewHere))) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel2Layout.createSequentialGroup() - .addComponent(addToken) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(removeToken) - .addGap(49, 49, 49) - .addComponent(openRegexWindow) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(jLabel1) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(lastPathConfig, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(exportConf, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(importConf, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE))) - .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 409, Short.MAX_VALUE)) - .addContainerGap()) - ); + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(masterEnable) + .addComponent(statusColor, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(masterDebug) + .addComponent(goToSite1) + .addComponent(masterRepeater) + .addComponent(masterIntruder) + .addComponent(masterProxy) + .addComponent(jLabelNewHere))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addComponent(addToken) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(removeToken) + .addGap(49, 49, 49) + .addComponent(openRegexWindow) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jLabel1) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(lastPathConfig, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(exportConf, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(importConf, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 409, Short.MAX_VALUE)) + .addContainerGap()) + ); goToSite1.getAccessibleContext().setAccessibleDescription(""); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 920, Short.MAX_VALUE) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - ); + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 920, Short.MAX_VALUE) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 453, Short.MAX_VALUE) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - ); + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 453, Short.MAX_VALUE) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); }// //GEN-END:initComponents - private void addTokenActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addTokenActionPerformed - //tableModel.addRow(new Object[]{ enable, name, header, extract from request, extract from response, url, body, cookie, other, To Proxy, To Repeater, To Intruder, value, eval, regex, path }); - tableModel.addRow(new Object[]{ false, "csrf", false, true, false, false, true, false, false, false, false, false, "", "grp[1]", "csrf=([a-zA-Z0-9]*)", "*" }); - }//GEN-LAST:event_addTokenActionPerformed - - private void removeTokenActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_removeTokenActionPerformed - int dialogButton = JOptionPane.YES_NO_OPTION; - int dialogResult = JOptionPane.showConfirmDialog(this, "Are you sure you want to remove the selected line(s)?", "Warning", dialogButton); - if(dialogResult == 0) { /*0 > Yes 1 > No */ - SwingUtilities.invokeLater(new Runnable() { - public void run() { - try{ - int[] selectedRows = tokenTable.getSelectedRows(); - for (int i = 0; i < selectedRows.length; i++){ - // -i adjusts the index, it counts for already deleted rows, the rest of the rows "move" up - int selectedRow = tokenTable.convertRowIndexToModel(selectedRows[i]-i); - tableModel.removeRow(selectedRow); - } - }catch(Exception ex){ - PrintStream burpErr = new PrintStream(callbacks.getStderr()); - ex.printStackTrace(burpErr); - } - } - }); - } - }//GEN-LAST:event_removeTokenActionPerformed - - private void openRegexWindowActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_openRegexWindowActionPerformed - int selectedRow = tokenTable.getSelectedRow(); - selectedRow = tokenTable.convertRowIndexToModel(selectedRow); - RegexWindow window = new RegexWindow(this, selectedRow, callbacks); - window.setVisible(true); - }//GEN-LAST:event_openRegexWindowActionPerformed - - Object getCell(int row, int column){ - return tableModel.getValueAt(row, column); - } - boolean setCell(int row, int column, Object value){ - if (value==null) return false; - tableModel.setValueAt(value, row, column); - return true; - } - - private void masterEnableActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_masterEnableActionPerformed - //*DEBUG*/callbacks.printOutput("masterEnable..() | "+dataModel.getMasterEnable()); - if(masterEnable.isSelected()){ - dataModel.setMasterEnable(true); - }else{ - dataModel.setMasterEnable(false); - } - this.setStatusColor(); - //*DEBUG*/callbacks.printOutput("end masterEnable..() | "+dataModel.getMasterEnable()); - }//GEN-LAST:event_masterEnableActionPerformed - - private void masterDebugActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_masterDebugActionPerformed - dataModel.setMasterDebug(masterDebug.isSelected()); - this.setStatusColor(); - }//GEN-LAST:event_masterDebugActionPerformed - - private void setStatusColor(){ - if(masterEnable.isSelected()){ - if(masterDebug.isSelected()) - statusColor.setBackground(Color.yellow); - else - statusColor.setBackground(Color.green); - }else{ - statusColor.setBackground(Color.red); - } - - } - - private void exportConfActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exportConfActionPerformed - JFileChooser fileChooser = new JFileChooser(); - //use the path from Last Config - //in case of invalid path, it fails safe silently - fileChooser.setSelectedFile(new File(this.lastPathConfig.getText())); - int result = fileChooser.showSaveDialog(this); - - switch (result) { - case JFileChooser.APPROVE_OPTION: - File file = fileChooser.getSelectedFile(); - try ( - FileWriter fileOut = new FileWriter(file); - ){ - Gson gson = new Gson(); - Vector dataInTable = tableModel.getDataVector(); - String dataToStore = gson.toJson(dataInTable); - dataToStore = NAME + VERSION + dataToStore; - fileOut.write(dataToStore); - //set Last Config Path to the last loaded file - this.lastPathConfig.setText(file.getAbsolutePath()); - //save Last Config Path in burp settings - persistSettings.saveLastConfigPath(file.getAbsolutePath()); - - } catch (Exception ex) { - PrintWriter stderr = new PrintWriter(callbacks.getStderr()); - ex.printStackTrace(stderr); - } - break; - case JFileChooser.CANCEL_OPTION: - break; - case JFileChooser.ERROR_OPTION: - callbacks.printError("Error export error"); - break; - } - }//GEN-LAST:event_exportConfActionPerformed - - private void importConfActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_importConfActionPerformed - JFileChooser fileChooser = new JFileChooser(); - //use the path from Last Config - //in case of invalid path, it fails safe silently - fileChooser.setSelectedFile(new File(this.lastPathConfig.getText())); - int result = fileChooser.showOpenDialog(this); - switch (result) { - case JFileChooser.APPROVE_OPTION: - File file = fileChooser.getSelectedFile(); - - //Magic Bytes - final byte mbSerializedObj[] = {(byte)0xAC, (byte)0xED, (byte)0x00, (byte)0x05}; - byte mbFile[] = new byte[8]; - - try ( - RandomAccessFile fileIn = new RandomAccessFile(file,"r"); - ){ - //Read magic bytes - fileIn.read(mbFile, 0 , NAME.length()); - - /*Attempt to restore data from version TokenJar 2.0*/ - if (Bytes.indexOf(mbFile, mbSerializedObj)==0){ - fileIn.seek(0); - try ( - InputStream is = Channels.newInputStream(fileIn.getChannel()); - ObjectInputStream objectIn = new ObjectInputStream(is); - ){ - Vector dataInTable = (Vector) objectIn.readObject(); - restoreTableData(dataInTable); - persistSettings.save(dataInTable); - //set Last Config Path to the last loaded file - this.lastPathConfig.setText(file.getAbsolutePath()); - //save Last Config Path in burp settings - persistSettings.saveLastConfigPath(file.getAbsolutePath()); - } catch (IOException | ClassNotFoundException ex) { - callbacks.printOutput("! Error loading settings when opening the file of type serialized object"); - PrintWriter stderr = new PrintWriter(callbacks.getStderr()); - ex.printStackTrace(stderr); - } - /*Attempt to restore data from newer version*/ - } else - if (Bytes.indexOf(mbFile, NAME.getBytes())==0){ - try - { - //TODO Magic Bytes to be used in future version to check the settings format version number - - //Skip Magic Bytes and Version - int fileStart = NAME.length()+VERSION.length(); - int fileLen = (int) fileIn.length()-NAME.length()-VERSION.length(); - - byte[] fileContent = new byte[fileLen]; - - fileIn.seek(fileStart); - fileIn.read(fileContent, 0, fileLen); // wrong results with fileStart as offset - - InputStreamReader is = new InputStreamReader(new ByteArrayInputStream(fileContent)); - Gson gson = new Gson(); - Vector restoredDataInTable = (Vector) gson.fromJson(is, Vector.class); - - //The respored data is a Vector of ArrayLists, the result should be a Vector of Vectors. - Vector dataInTable = new Vector(); - for (int i=0; i columnsInTable = new Vector<>(tableModel.getColumnCount()); - for (int i=0; i2; j--){ //move last 8 elements to the right - row.setElementAt(row.elementAt(j-1), j); - } - row.setElementAt(false, 2); // "header" is set to false - //*DEBUG*/callbacks.printOutput("restored dataInTable["+i+"]="+dataInTable.elementAt(i)); - } - } - else { // Does not correspond to any format - callbacks.printOutput("! Error when importing line"+row); - callbacks.printOutput("! skipping this line"); - invalidRows.add(row); - } - } - - - //restore the DataVector - if (invalidRows.size()>0){ - dataInTable.removeAll(invalidRows); - } - tableModel.setDataVector(dataInTable, columnsInTable); - - dataModel.init(); - this.resizeColumns(); - } - - private void resizeColumns() { - tokenTable.getColumnModel().getSelectionModel().setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); - - int tableWidth = this.getWidth() - 120; - float[] columnWidthPercentage = {0.03f, 0.09f, 0.03f, 0.03f, 0.03f, 0.03f, 0.03f, 0.03f, 0.03f, 0.03f, 0.03f, 0.03f, 0.16f, 0.16f, 0.16f, 0.16f}; - - for (int i=0; i Yes 1 > No */ + SwingUtilities.invokeLater(new Runnable() { + public void run() { + try{ + int[] selectedRows = tokenTable.getSelectedRows(); + for (int i = 0; i < selectedRows.length; i++){ + // -i adjusts the index, it counts for already deleted rows, the rest of the rows "move" up + int selectedRow = tokenTable.convertRowIndexToModel(selectedRows[i]-i); + tableModel.removeRow(selectedRow); + } + }catch(Exception ex){ + PrintStream burpErr = new PrintStream(callbacks.getStderr()); + ex.printStackTrace(burpErr); + } + } + }); + } + }//GEN-LAST:event_removeTokenActionPerformed + + private void openRegexWindowActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_openRegexWindowActionPerformed + int selectedRow = tokenTable.getSelectedRow(); + selectedRow = tokenTable.convertRowIndexToModel(selectedRow); + RegexWindow window = new RegexWindow(this, selectedRow, callbacks); + window.setVisible(true); + }//GEN-LAST:event_openRegexWindowActionPerformed + + Object getCell(int row, int column){ + return tableModel.getValueAt(row, column); + } + boolean setCell(int row, int column, Object value){ + if (value==null) return false; + tableModel.setValueAt(value, row, column); + return true; + } + + private void masterEnableActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_masterEnableActionPerformed + //*DEBUG*/callbacks.printOutput("masterEnable..() | "+dataModel.getMasterEnable()); + if(masterEnable.isSelected()){ + dataModel.setMasterEnable(true); + }else{ + dataModel.setMasterEnable(false); + } + this.setStatusColor(); + //*DEBUG*/callbacks.printOutput("end masterEnable..() | "+dataModel.getMasterEnable()); + }//GEN-LAST:event_masterEnableActionPerformed + + private void masterDebugActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_masterDebugActionPerformed + dataModel.setMasterDebug(masterDebug.isSelected()); + this.setStatusColor(); + }//GEN-LAST:event_masterDebugActionPerformed + + private void setStatusColor(){ + if(masterEnable.isSelected()){ + if(masterDebug.isSelected()) + statusColor.setBackground(Color.yellow); + else + statusColor.setBackground(Color.green); + }else{ + statusColor.setBackground(Color.red); + } + + } + + private void exportConfActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exportConfActionPerformed + JFileChooser fileChooser = new JFileChooser(); + //use the path from Last Config + //in case of invalid path, it fails safe silently + fileChooser.setSelectedFile(new File(this.lastPathConfig.getText())); + int result = fileChooser.showSaveDialog(this); + + switch (result) { + case JFileChooser.APPROVE_OPTION: + File file = fileChooser.getSelectedFile(); + try ( + FileWriter fileOut = new FileWriter(file); + ){ + Gson gson = new Gson(); + Vector dataInTable = tableModel.getDataVector(); + String dataToStore = gson.toJson(dataInTable); + dataToStore = NAME + VERSION + dataToStore; + fileOut.write(dataToStore); + //set Last Config Path to the last loaded file + this.lastPathConfig.setText(file.getAbsolutePath()); + //save Last Config Path in burp settings + persistSettings.saveLastConfigPath(file.getAbsolutePath()); + + } catch (Exception ex) { + PrintWriter stderr = new PrintWriter(callbacks.getStderr()); + ex.printStackTrace(stderr); + } + break; + case JFileChooser.CANCEL_OPTION: + break; + case JFileChooser.ERROR_OPTION: + callbacks.printError("Error export error"); + break; + } + }//GEN-LAST:event_exportConfActionPerformed + + private void importConfActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_importConfActionPerformed + JFileChooser fileChooser = new JFileChooser(); + //use the path from Last Config + //in case of invalid path, it fails safe silently + fileChooser.setSelectedFile(new File(this.lastPathConfig.getText())); + int result = fileChooser.showOpenDialog(this); + switch (result) { + case JFileChooser.APPROVE_OPTION: + File file = fileChooser.getSelectedFile(); + + //Magic Bytes + final byte mbSerializedObj[] = {(byte)0xAC, (byte)0xED, (byte)0x00, (byte)0x05}; + byte mbFile[] = new byte[8]; + + try ( + RandomAccessFile fileIn = new RandomAccessFile(file,"r"); + ){ + //Read magic bytes + fileIn.read(mbFile, 0 , NAME.length()); + + /*Attempt to restore data from version TokenJar 2.0*/ + if (Bytes.indexOf(mbFile, mbSerializedObj)==0){ + fileIn.seek(0); + try ( + InputStream is = Channels.newInputStream(fileIn.getChannel()); + ObjectInputStream objectIn = new ObjectInputStream(is); + ){ + Vector dataInTable = (Vector) objectIn.readObject(); + restoreTableData(dataInTable); + persistSettings.save(dataInTable); + //set Last Config Path to the last loaded file + this.lastPathConfig.setText(file.getAbsolutePath()); + //save Last Config Path in burp settings + persistSettings.saveLastConfigPath(file.getAbsolutePath()); + } catch (IOException | ClassNotFoundException ex) { + callbacks.printOutput("! Error loading settings when opening the file of type serialized object"); + PrintWriter stderr = new PrintWriter(callbacks.getStderr()); + ex.printStackTrace(stderr); + } + /*Attempt to restore data from newer version*/ + } else + if (Bytes.indexOf(mbFile, NAME.getBytes())==0){ + try + { + //TODO Magic Bytes to be used in future version to check the settings format version number + + //Skip Magic Bytes and Version + int fileStart = NAME.length()+VERSION.length(); + int fileLen = (int) fileIn.length()-NAME.length()-VERSION.length(); + + byte[] fileContent = new byte[fileLen]; + + fileIn.seek(fileStart); + fileIn.read(fileContent, 0, fileLen); // wrong results with fileStart as offset + + InputStreamReader is = new InputStreamReader(new ByteArrayInputStream(fileContent)); + Gson gson = new Gson(); + Vector restoredDataInTable = (Vector) gson.fromJson(is, Vector.class); + + //The respored data is a Vector of ArrayLists, the result should be a Vector of Vectors. + Vector dataInTable = new Vector(); + for (int i=0; i columnsInTable = new Vector<>(tableModel.getColumnCount()); + for (int i=0; i2; j--){ //move last 8 elements to the right + row.setElementAt(row.elementAt(j-1), j); + } + row.setElementAt(false, 2); // "header" is set to false + //*DEBUG*/callbacks.printOutput("restored dataInTable["+i+"]="+dataInTable.elementAt(i)); + } + } + else { // Does not correspond to any format + callbacks.printOutput("! Error when importing line"+row); + callbacks.printOutput("! skipping this line"); + invalidRows.add(row); + } + } + + + //restore the DataVector + if (invalidRows.size()>0){ + dataInTable.removeAll(invalidRows); + } + tableModel.setDataVector(dataInTable, columnsInTable); + + dataModel.init(); + this.resizeColumns(); + } + + private void resizeColumns() { + tokenTable.getColumnModel().getSelectionModel().setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); + + int tableWidth = this.getWidth() - 120; + float[] columnWidthPercentage = {0.03f, 0.09f, 0.03f, 0.03f, 0.03f, 0.03f, 0.03f, 0.03f, 0.03f, 0.03f, 0.03f, 0.03f, 0.16f, 0.16f, 0.16f, 0.16f}; + + for (int i=0; i