From 47f548bd6594c32fdb0d20d6cc6c604dbdf2c2d4 Mon Sep 17 00:00:00 2001 From: Dan Negrea Date: Thu, 24 Mar 2022 14:27:21 +0100 Subject: [PATCH] Replaced Nashorn with Rhino JS Engine Signed-off-by: Dan Negrea --- README.md | 19 ++++++++++--------- build.gradle | 24 +++++++++++++++--------- src/burp/BurpExtender.java | 2 +- src/tokenJar/DataModel.java | 30 ++++++++++++++++++------------ src/tokenJar/RegexWindow.java | 33 +++++++++++++++++++++------------ 5 files changed, 65 insertions(+), 43 deletions(-) diff --git a/README.md b/README.md index 7da883b..c9f1b09 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,19 @@ -# TokenJar v2.1 +# TokenJar v2.2 Burp Suite extension. Useful for managing tokens like anti-CSRF, CSurf, Session values. Can be used to set params that require random numbers or params that are computed based on application response. Here is just brief information. More details are on plugin GitHub [page](https://dannegrea.github.io/TokenJar/) Please report issues using [GitHub Issues](https://github.com/DanNegrea/TokenJar/issues) +## Changelog +Replaced NashornScriptEngine (deprecated) library with Mozilla Rhino +Update other dependencies + ## Requirements for usage -* Burp Suite Free or Pro -* JRE or JDK 1.8+ - -### Notice -* Tested with JDK 11 (End of Premier Support [September 2023](https://www.oracle.com/java/technologies/java-se-support-roadmap.html)) -* JS Engine (NashornScriptEngine) is set to be deprecated (still available in [JRE 13](https://docs.oracle.com/en/java/javase/13/docs/api/jdk.scripting.nashorn/jdk/nashorn/api/scripting/NashornScriptEngine.html)) +* Burp Suite Free or Pro 2022.3.1+ ## Requirements for building -* Google Guava 28.2 -* Google Gson 2.8.6 +* JDK 16 +* Google Guava 31.1-jre +* Google Gson 2.9.0 +* Mozilla Rhino 1.7.14 diff --git a/build.gradle b/build.gradle index 5273b30..d76e709 100644 --- a/build.gradle +++ b/build.gradle @@ -1,12 +1,24 @@ -apply plugin: 'java' +plugins { + id 'java' +} + +jar { + archiveBaseName = 'TokenJar' + archiveVersion = '2.2' + duplicatesStrategy(DuplicatesStrategy.EXCLUDE) + from { + configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } + } +} repositories { mavenCentral() } dependencies { - compile 'com.google.guava:guava:28.2-jre' - compile 'com.google.code.gson:gson:2.8.6' + implementation group: 'com.google.guava', name: 'guava', version: '31.1-jre' + implementation group: 'com.google.code.gson', name: 'gson', version: '2.9.0' + implementation group: 'org.mozilla', name: 'rhino', version: '1.7.14' } sourceSets { @@ -25,9 +37,3 @@ processResources { from('src/tokenJar/RegexWindow.form') from('src/tokenJar/Tab.form') } - -task fatJar(type: Jar) { - baseName = project.name + '-all' - from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } - with jar -} diff --git a/src/burp/BurpExtender.java b/src/burp/BurpExtender.java index 5304edb..cd5f3b1 100644 --- a/src/burp/BurpExtender.java +++ b/src/burp/BurpExtender.java @@ -10,7 +10,7 @@ public class BurpExtender implements IBurpExtender, IHttpListener, IProxyListener, IExtensionStateListener { public static final String NAME="TokenJar"; - public static final String VERSION=" 2.1 "; //always 5 chars + public static final String VERSION=" 2.2 "; //always 5 chars private IBurpExtenderCallbacks callbacks; private IExtensionHelpers helpers; private Tab tab; diff --git a/src/tokenJar/DataModel.java b/src/tokenJar/DataModel.java index b18bf2c..0cfb68c 100644 --- a/src/tokenJar/DataModel.java +++ b/src/tokenJar/DataModel.java @@ -15,11 +15,11 @@ import java.util.List; import java.util.Set; import java.util.regex.Pattern; -import javax.script.ScriptEngine; -import javax.script.ScriptEngineManager; -import javax.script.ScriptException; import javax.swing.table.DefaultTableModel; +import org.mozilla.javascript.Context; +import org.mozilla.javascript.Scriptable; +import org.mozilla.javascript.ScriptableObject; /** * @@ -41,16 +41,12 @@ public class DataModel { private IBurpExtenderCallbacks callbacks; private final PrintWriter stderr; - private final ScriptEngine JSengine; private boolean[] valueUpdated; public DataModel(DefaultTableModel tableModel, IBurpExtenderCallbacks callbacks){ this.tableModel = tableModel; this.callbacks = callbacks; - stderr = new PrintWriter(callbacks.getStderr()); - - ScriptEngineManager manager = new ScriptEngineManager(); - JSengine = manager.getEngineByName("JavaScript"); + stderr = new PrintWriter(callbacks.getStderr()); } public void init() { @@ -179,11 +175,19 @@ public Pattern getPattern(int rowId) { } public void setValue(Integer rowId, String[] grpValues) { + Context cx = Context.enter(); try { String evalJS = tableModel.getValueAt(rowId, 8).toString(); - JSengine.put("grp", grpValues); - String value = JSengine.eval( evalJS ).toString(); //compute the value by evaluating JavaScript + 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, 7); //set the actual value @@ -194,9 +198,11 @@ public void setValue(Integer rowId, String[] grpValues) { for (byte type=0; type<=4; type++) // do this for each param type if (isUpdatable(rowId, type)) tokensByType.get(type).put(paramName, rowId); - } catch (ScriptException ex) { + } catch (Exception ex) { callbacks.printError(ex.getMessage()); - } + } finally { + Context.exit(); + } } /*The value was updated in the DataModel*/ diff --git a/src/tokenJar/RegexWindow.java b/src/tokenJar/RegexWindow.java index ce07967..ee94c8d 100644 --- a/src/tokenJar/RegexWindow.java +++ b/src/tokenJar/RegexWindow.java @@ -9,13 +9,14 @@ import java.io.PrintWriter; import java.util.regex.Matcher; import java.util.regex.Pattern; -import javax.script.ScriptEngine; -import javax.script.ScriptEngineManager; -import javax.script.ScriptException; + import javax.swing.text.BadLocationException; import javax.swing.text.DefaultHighlighter; import javax.swing.text.Highlighter; +import org.mozilla.javascript.Context; +import org.mozilla.javascript.Scriptable; +import org.mozilla.javascript.ScriptableObject; /** * * @author DanNegrea @@ -24,7 +25,6 @@ public class RegexWindow extends javax.swing.JFrame { private final Tab parent; private int selectedRow; - private ScriptEngine JSengine; private PersistSettings persistSettings; private IBurpExtenderCallbacks callbacks; @@ -74,10 +74,6 @@ public RegexWindow(Tab parent, int selectedRow, IBurpExtenderCallbacks callbacks regexField.addItem( (String) exprs[i]); } regexField.setSelectedItem( regex ); - - - ScriptEngineManager manager = new ScriptEngineManager(); - JSengine = manager.getEngineByName("JavaScript"); } /** @@ -358,16 +354,29 @@ private void testRegexActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIR grpValues[i]= matcher.group(i); debug.append("grp["+i+"]=").append(grpValues[i]).append("\n"); } + + Context cx = Context.enter(); try { - JSengine.put("grp", grpValues); - String value = JSengine.eval( evalJS ).toString(); //compute the value by evaluating JavaScript + 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); + + valueField.setText(value); //set the actual value - } catch (ScriptException ex) { + } 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*/