From 46b8b8ccce79829b14d720b885fcbdba24f7825e Mon Sep 17 00:00:00 2001 From: Anof-cyber Date: Tue, 2 Jul 2024 02:14:01 +0530 Subject: [PATCH 1/5] Added Dynamic Path and binray script support #8 --- pycript.py | 39 +++++++++++++++++++++++++++---------- pycript/Reqcheck.py | 4 ++-- pycript/execution.py | 12 ++++-------- pycript/response_handler.py | 2 +- pycript/stringcrypto.py | 2 +- 5 files changed, 37 insertions(+), 22 deletions(-) diff --git a/pycript.py b/pycript.py index 2d9d7dc..e9ff1cd 100644 --- a/pycript.py +++ b/pycript.py @@ -235,10 +235,21 @@ def registerExtenderCallbacks(self, callbacks): self.AdditionalSettinglabel.setFont(Font("Segoe UI", 1, 14)) self.languagelabel = JLabel(); - self.languagelabel.setText("Language"); + self.languagelabel.setText("Language Binary(ie python.exe emptydirect executable for enc/dec)"); - self.langdata = ("JavaScript", "Python", "Java Jar") - self.languagecombobox = JComboBox(self.langdata) + + #self.langdata = ("JavaScript", "Python", "Java Jar") + self.languagejpanel = JPanel() #JComboBox(self.langdata) + self.language_select_button = JButton("Select Language Binary Path") + self.language_select_button.addActionListener(self.select_language_file_path) + + + + self.languagepath = JTextField(20) + self.languagepath.setText("C:/Program Files/nodejs/node.exe") + self.languagejpanel.add(self.languagepath,BorderLayout.NORTH) + self.languagejpanel.add(self.language_select_button,BorderLayout.NORTH) + self.reqmethodlabel = JLabel(); @@ -675,7 +686,7 @@ def registerExtenderCallbacks(self, callbacks): self.additionallayerpane.setBorder(BorderFactory.createLineBorder(Color(0, 0, 0))); self.additionallayerpane.setLayer(self.AdditionalSettinglabel, JLayeredPane.DEFAULT_LAYER); self.additionallayerpane.setLayer(self.languagelabel, JLayeredPane.DEFAULT_LAYER); - self.additionallayerpane.setLayer(self.languagecombobox, JLayeredPane.DEFAULT_LAYER); + self.additionallayerpane.setLayer(self.languagejpanel, JLayeredPane.DEFAULT_LAYER); self.additionallayerpane.setLayer(self.reqmethodlabel, JLayeredPane.DEFAULT_LAYER); self.additionallayerpane.setLayer(self.reqmethodcombobox, JLayeredPane.DEFAULT_LAYER); self.additionallayerpane.setLayer(self.reqresponselabel, JLayeredPane.DEFAULT_LAYER); @@ -695,7 +706,7 @@ def registerExtenderCallbacks(self, callbacks): .addGroup(self.additionallayerpaneLayout.createSequentialGroup() .addComponent(self.languagelabel) .addGap(18, 18, 18) - .addComponent(self.languagecombobox, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))) + .addComponent(self.languagejpanel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addComponent(self.reqmethodcombobox, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) .addGroup(self.additionallayerpaneLayout.createSequentialGroup() @@ -712,7 +723,8 @@ def registerExtenderCallbacks(self, callbacks): .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) .addGroup(self.additionallayerpaneLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) .addComponent(self.languagelabel) - .addComponent(self.languagecombobox, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + .addComponent(self.languagejpanel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addGap(0, 40, 40)) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addGroup(self.additionallayerpaneLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) .addComponent(self.reqmethodlabel) @@ -1095,8 +1107,15 @@ def importdecryptionjsfile(self,e): self.requestdecryptionpath.setText(self.decryptionfilepath) self.callbacks.saveExtensionSetting("requestdecryptionfilesave", self.decryptionfilepath) - - + # handle language binrary path + def select_language_file_path(self,e): + chooseFile = JFileChooser() + ret = chooseFile.showDialog(self.tab, "Choose file") + if ret == JFileChooser.APPROVE_OPTION: + fileLoad = chooseFile.getSelectedFile() + self.languagefullpath = fileLoad.getAbsolutePath() + self.languagepath.setText(self.languagefullpath) + # Returning the Extension Tab name to burp ITAB def getTabCaption(self): return "PyCript" @@ -1256,7 +1275,7 @@ def encryptstring(self,invocation): output = StringCrypto(self,encpath,query,http_request_response) encryptedstring = output.encrypt_string_request() else: - encryptedstring = Parameterencrypt(self.languagecombobox.getSelectedItem(), encpath, query) + encryptedstring = Parameterencrypt(self.languagepath.getText(), encpath, query) #JOptionPane.showInputDialog(None, "Encrypted String", "Decryption", JOptionPane.PLAIN_MESSAGE, None, None, encryptedstring) #JOptionPane.showMessageDialog(None, encryptedstring, "String", JOptionPane.INFORMATION_MESSAGE) showEditableDialog(encryptedstring, "Encrypted String") @@ -1301,7 +1320,7 @@ def decryptstring(self,invocation): output = StringCrypto(self,encpath,query,http_request_response) decryptedstring = output.decrypt_string_request() else: - decryptedstring = Parameterdecrypt(self.languagecombobox.getSelectedItem(), encpath, query) + decryptedstring = Parameterdecrypt(self.languagepath.getText(), encpath, query) showEditableDialog(decryptedstring, "Decryted String") diff --git a/pycript/Reqcheck.py b/pycript/Reqcheck.py index 189a5d1..0111513 100644 --- a/pycript/Reqcheck.py +++ b/pycript/Reqcheck.py @@ -9,7 +9,7 @@ def EncryptRequest(extender, currentreq,req): encryptionpath = extender.encryptionfilepath - selectedlang = extender.languagecombobox.getSelectedItem() + selectedlang = extender.languagepath.getText() selected_method = extender.reqmethodcombobox.getSelectedItem() parameters = req.getParameters() header = req.getHeaders() # Get Array/last format header from burp header api (used for Custom Request) @@ -44,7 +44,7 @@ def EncryptRequest(extender, currentreq,req): ## Function to decrypt request when Burp Menu to decrypt request is triggered def DecryptRequest(extender, currentreq,req): decryptionpath = extender.decryptionfilepath - selectedlang = extender.languagecombobox.getSelectedItem() + selectedlang = extender.languagepath.getText() selected_method = extender.reqmethodcombobox.getSelectedItem() selected_request_inc_ex_ctype = extender.selected_request_inc_ex_ctype listofparam = extender.requestparamlist.getText().split(',') diff --git a/pycript/execution.py b/pycript/execution.py index 3a43633..505859d 100644 --- a/pycript/execution.py +++ b/pycript/execution.py @@ -1,17 +1,13 @@ import subprocess from .gui import logerrors - +import os def execute_command(selectedlang, path, data, headervalue=None): try: command = [] - if selectedlang == "JavaScript": - command.extend(["node", '"' + path + '"']) # Surround path with double quotes - elif selectedlang == "Python": - command.extend(["python", '"' + path + '"']) # Surround path with double quotes - elif selectedlang == "Java Jar": - command.extend(["java", "-jar", '"' + path + '"']) # Surround path with double quotes + if selectedlang: + command.append('"' + selectedlang + '"') - command.extend(["-d", data]) + command.extend(['"' + path + '"',"-d", data]) if headervalue is not None: command.extend(["-h", headervalue]) diff --git a/pycript/response_handler.py b/pycript/response_handler.py index d2d92fc..2abf76b 100644 --- a/pycript/response_handler.py +++ b/pycript/response_handler.py @@ -5,7 +5,7 @@ def encrypt_decrypt_response(extender,currentresp,response,enc_dec,enc_dec_type): - selectedlang = extender.languagecombobox.getSelectedItem() + selectedlang = extender.languagepath.getText() if enc_dec_type== "Decrypt": enc_dec_file_path = extender.responsedecryptionfilepath else: diff --git a/pycript/stringcrypto.py b/pycript/stringcrypto.py index 48b09b7..bbeab1f 100644 --- a/pycript/stringcrypto.py +++ b/pycript/stringcrypto.py @@ -6,7 +6,7 @@ def __init__(self, extender, encpath, query, http_request_response): self._extender = extender self._selectedmessage = query self.message = http_request_response - self.selectedlang = extender.languagecombobox.getSelectedItem() + self.selectedlang = extender.languagepath.getText() self.encpath = encpath self.header = self.get_headers() self.headers_str = self.get_headers_str() From 5b19667c443a34f1983d8c8d8c41bc016e014a50 Mon Sep 17 00:00:00 2001 From: Anof-cyber Date: Wed, 3 Jul 2024 20:32:12 +0530 Subject: [PATCH 2/5] fixed jar support --- pycript.py | 2 +- pycript/execution.py | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/pycript.py b/pycript.py index e9ff1cd..6dac855 100644 --- a/pycript.py +++ b/pycript.py @@ -24,7 +24,7 @@ errorlogtextbox = None errorlogcheckbox = None -VERSION = "Version 0.3" +VERSION = "Version 0.4" class BurpExtender(IBurpExtender, ITab,IMessageEditorTabFactory,IContextMenuFactory, IMessageEditorController, AbstractTableModel,IHttpListener): diff --git a/pycript/execution.py b/pycript/execution.py index 505859d..e28fac1 100644 --- a/pycript/execution.py +++ b/pycript/execution.py @@ -7,6 +7,10 @@ def execute_command(selectedlang, path, data, headervalue=None): if selectedlang: command.append('"' + selectedlang + '"') + if path.endswith(".jar"): + command.extend(["-jar"]) + + command.extend(['"' + path + '"',"-d", data]) if headervalue is not None: From 2cc4c25f7d524e28d91fb031f31ab67304e78333 Mon Sep 17 00:00:00 2001 From: Anof-cyber Date: Wed, 3 Jul 2024 20:47:41 +0530 Subject: [PATCH 3/5] added temp file support to fix command line limit --- pycript/execution.py | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/pycript/execution.py b/pycript/execution.py index e28fac1..510dfa4 100644 --- a/pycript/execution.py +++ b/pycript/execution.py @@ -1,8 +1,23 @@ import subprocess from .gui import logerrors -import os +import tempfile +from os import remove +import json + def execute_command(selectedlang, path, data, headervalue=None): try: + + content = { + "data": data + } + if headervalue is not None: + content["header"] = headervalue + + with tempfile.NamedTemporaryFile(delete=False, mode='w') as temp_file: + json.dump(content, temp_file) + temp_file_path = temp_file.name + + command = [] if selectedlang: command.append('"' + selectedlang + '"') @@ -11,10 +26,10 @@ def execute_command(selectedlang, path, data, headervalue=None): command.extend(["-jar"]) - command.extend(['"' + path + '"',"-d", data]) + command.extend(['"' + path + '"',"-d", temp_file_path]) - if headervalue is not None: - command.extend(["-h", headervalue]) + #if headervalue is not None: + # command.extend(["-h", headervalue]) command_str = ' '.join(command) logerrors("$ " + command_str) @@ -27,6 +42,7 @@ def execute_command(selectedlang, path, data, headervalue=None): universal_newlines=True ) output, error = process.communicate() + remove(temp_file_path) if process.returncode != 0: logerrors(error.strip()) From 89d13b315442bc14ff18ca029a9484b57e38e0d5 Mon Sep 17 00:00:00 2001 From: Anof-cyber Date: Wed, 3 Jul 2024 22:00:43 +0530 Subject: [PATCH 4/5] fixed command line error #5 --- pycript/execution.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/pycript/execution.py b/pycript/execution.py index 510dfa4..4f2712a 100644 --- a/pycript/execution.py +++ b/pycript/execution.py @@ -25,12 +25,8 @@ def execute_command(selectedlang, path, data, headervalue=None): if path.endswith(".jar"): command.extend(["-jar"]) - command.extend(['"' + path + '"',"-d", temp_file_path]) - #if headervalue is not None: - # command.extend(["-h", headervalue]) - command_str = ' '.join(command) logerrors("$ " + command_str) From a5e51d35489023d53cd7f554a6037fa73965d52a Mon Sep 17 00:00:00 2001 From: Anof-cyber Date: Wed, 3 Jul 2024 22:45:24 +0530 Subject: [PATCH 5/5] fixed JSON additional space #7 --- pycript/Reqcheck.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pycript/Reqcheck.py b/pycript/Reqcheck.py index 0111513..2b37610 100644 --- a/pycript/Reqcheck.py +++ b/pycript/Reqcheck.py @@ -107,7 +107,7 @@ def decrypt_and_update_parameters(extender, currentreq, decryptionpath, selected elif param.getType() == IParameter.PARAM_JSON: json_object = loads(body) json_object = update_json_value(json_object, selectedlang, decryptionpath,Parameterdecrypt,selected_request_inc_ex_ctype,listofparam) - output = extender.helpers.stringToBytes(dumps(json_object)) + output = extender.helpers.stringToBytes(dumps(json_object,separators=(',', ':'))) currentreq = extender.helpers.buildHttpMessage(header, output) break @@ -129,7 +129,7 @@ def decrypt_and_update_parameters(extender, currentreq, decryptionpath, selected if selected_method == "BOTH" and param.getType() == IParameter.PARAM_JSON: json_object = loads(body) json_object = update_json_value(json_object, selectedlang, decryptionpath,Parameterdecrypt,selected_request_inc_ex_ctype,listofparam) - output = extender.helpers.stringToBytes(dumps(json_object)) + output = extender.helpers.stringToBytes(dumps(json_object,separators=(',', ':'))) currentreq = extender.helpers.buildHttpMessage(header, output) break return currentreq @@ -153,7 +153,7 @@ def decrypt_and_update_parameter_keys_and_values(extender, currentreq, decryptio elif param.getType() == IParameter.PARAM_JSON: json_object = loads(body) json_object = update_json_key_value(json_object, selectedlang, decryptionpath,Parameterdecrypt,selected_request_inc_ex_ctype,listofparam) - output = extender.helpers.stringToBytes(dumps(json_object)) + output = extender.helpers.stringToBytes(dumps(json_object,separators=(',', ':'))) currentreq = extender.helpers.buildHttpMessage(header, output) break @@ -179,7 +179,7 @@ def decrypt_and_update_parameter_keys_and_values(extender, currentreq, decryptio if selected_method == "BOTH" and param.getType() == IParameter.PARAM_JSON: json_object = loads(body) json_object = update_json_key_value(json_object, selectedlang, decryptionpath,Parameterdecrypt,selected_request_inc_ex_ctype,listofparam) - output = extender.helpers.stringToBytes(dumps(json_object)) + output = extender.helpers.stringToBytes(dumps(json_object,separators=(',', ':'))) currentreq = extender.helpers.buildHttpMessage(header, output) break @@ -199,7 +199,7 @@ def encrypt_and_update_parameters(extender, currentreq, encryptionpath, selected elif param.getType() == IParameter.PARAM_JSON: json_object = loads(body) json_object = update_json_value(json_object, selectedlang, encryptionpath, Parameterencrypt,selected_request_inc_ex_ctype,listofparam) - output = extender.helpers.stringToBytes(dumps(json_object)) + output = extender.helpers.stringToBytes(dumps(json_object,separators=(',', ':'))) currentreq = extender.helpers.buildHttpMessage(header, output) break @@ -219,7 +219,7 @@ def encrypt_and_update_parameters(extender, currentreq, encryptionpath, selected if selected_method == "BOTH" and param.getType() == IParameter.PARAM_JSON: json_object = loads(body) json_object = update_json_value(json_object, selectedlang, encryptionpath, Parameterencrypt,selected_request_inc_ex_ctype,listofparam) - output = extender.helpers.stringToBytes(dumps(json_object)) + output = extender.helpers.stringToBytes(dumps(json_object,separators=(',', ':'))) currentreq = extender.helpers.buildHttpMessage(header, output) break @@ -245,7 +245,7 @@ def encrypt_and_update_parameter_keys_and_values(extender, currentreq, encryptio elif param.getType() == IParameter.PARAM_JSON: json_object = loads(body) json_object = update_json_key_value(json_object, selectedlang, encryptionpath,Parameterencrypt,selected_request_inc_ex_ctype,listofparam) - output = extender.helpers.stringToBytes(dumps(json_object)) + output = extender.helpers.stringToBytes(dumps(json_object,separators=(',', ':'))) currentreq = extender.helpers.buildHttpMessage(header, output) break @@ -271,7 +271,7 @@ def encrypt_and_update_parameter_keys_and_values(extender, currentreq, encryptio if selected_method == "BOTH" and param.getType() == IParameter.PARAM_JSON: json_object = loads(body) json_object = update_json_key_value(json_object, selectedlang, encryptionpath,Parameterencrypt,selected_request_inc_ex_ctype,listofparam) - output = extender.helpers.stringToBytes(dumps(json_object)) + output = extender.helpers.stringToBytes(dumps(json_object,separators=(',', ':'))) currentreq = extender.helpers.buildHttpMessage(header, output) break