diff --git a/pycript.py b/pycript.py index 8507de2..82df1fd 100644 --- a/pycript.py +++ b/pycript.py @@ -1,4 +1,4 @@ -from burp import (IBurpExtender, ITab,IMessageEditorTabFactory,IMessageEditorTab,IContextMenuFactory, IContextMenuInvocation,IMessageEditorController,IHttpListener) +from burp import (IBurpExtender, ITab,IMessageEditorTabFactory,IMessageEditorTab,IContextMenuFactory, IContextMenuInvocation,IMessageEditorController,IHttpListener,IExtensionStateListener) from java.awt import (BorderLayout,Font,Color) from javax.swing import (JTabbedPane,JPanel ,JRadioButton,ButtonGroup,JRadioButton,JLabel,BorderFactory,JLayeredPane,JComboBox,JTextArea, JSeparator,JButton,JToggleButton,JCheckBox,JScrollPane,GroupLayout,LayoutStyle,JFileChooser,JMenuItem,JOptionPane,JTable,JSplitPane,JPopupMenu,JTextField,JEditorPane) @@ -9,7 +9,7 @@ import sys from threading import Thread,Lock from java.awt.event import MouseAdapter -from java.awt import Desktop +from java.awt import Desktop, ComponentOrientation from java.net import URI from java.io import IOException from javax.swing.event import HyperlinkListener @@ -21,18 +21,23 @@ from pycript.Reqcheck import DecryptRequest,EncryptRequest from pycript.stringcrypto import StringCrypto from pycript.gui import create_third_tab_elements - +from pycript.gethelpers import set_helpers +from pycript.temp_file import create_temp_dir, delete_temp_folder errorlogtextbox = None errorlogcheckbox = None -VERSION = "Version 0.4" +VERSION = "Version 1.0" -class BurpExtender(IBurpExtender, ITab,IMessageEditorTabFactory,IContextMenuFactory, IMessageEditorController, AbstractTableModel,IHttpListener): +class BurpExtender(IBurpExtender, ITab,IMessageEditorTabFactory,IContextMenuFactory, IMessageEditorController, AbstractTableModel,IHttpListener,IExtensionStateListener): def registerExtenderCallbacks(self, callbacks): self.callbacks = callbacks self.helpers = callbacks.getHelpers() + + ## Passing Helper to set helper, To access it globally, all data passes through helper string <--> byte conversion method + set_helpers(self.helpers) self.tooltypelist = [] + create_temp_dir() # Allowing debugging sys.stdout = callbacks.getStdout() @@ -47,7 +52,7 @@ def registerExtenderCallbacks(self, callbacks): callbacks.printOutput("Documentation - https://pycript.souravkalal.tech/") callbacks.registerContextMenuFactory(self) - + callbacks.registerExtensionStateListener(self) # delete the temp folder when done #Some Config and data related variables self._log = list() self._lock = Lock() @@ -64,9 +69,11 @@ def registerExtenderCallbacks(self, callbacks): self.tab.add("Center", self.tabbedPane) # Creating First Tab as Config Tab - self.firstTab = JPanel() - self.firstTab.layout = BorderLayout() - self.tabbedPane.addTab("Config", self.firstTab) + self.firstTab_UI = JPanel() + layout = GroupLayout(self.firstTab_UI) + self.firstTab = JScrollPane(self.firstTab_UI) + + self.tabbedPane.addTab("Config", self.firstTab_UI) # Creating Second Tab as Decrypted Request Tab self.secondTab = JPanel() @@ -179,22 +186,33 @@ def registerExtenderCallbacks(self, callbacks): self.paramkeyvalueRadio.setText("Parameter Key and Value"); self.paramkeyvalueRadio.addActionListener(self.requestypelistner) - self.CustomRequestRadio = JRadioButton(); - self.RequestTypeRadioGroup.add(self.CustomRequestRadio); - self.CustomRequestRadio.setText("Custom Request"); - self.CustomRequestRadio.addActionListener(self.requestypelistner) + #self.CustomRequestRadio = JRadioButton(); + #self.RequestTypeRadioGroup.add(self.CustomRequestRadio); + #self.CustomRequestRadio.setText("Custom Request"); + #self.CustomRequestRadio.addActionListener(self.requestypelistner) - self.CustomRequestheaderRadio = JRadioButton(); - self.RequestTypeRadioGroup.add(self.CustomRequestheaderRadio); - self.CustomRequestheaderRadio.setText("Custom Request (Edit Header)"); - self.CustomRequestheaderRadio.addActionListener(self.requestypelistner) + #self.CustomRequestheaderRadio = JRadioButton(); + #self.RequestTypeRadioGroup.add(self.CustomRequestheaderRadio); + #self.CustomRequestheaderRadio.setText("Custom Request (Edit Header)"); + #self.CustomRequestheaderRadio.addActionListener(self.requestypelistner) self.RequestTypeNoneRadio = JRadioButton(); self.RequestTypeRadioGroup.add(self.RequestTypeNoneRadio); self.RequestTypeNoneRadio.setText("None"); self.RequestTypeNoneRadio.setSelected(True) self.RequestTypeNoneRadio.addActionListener(self.requestypelistner) - + + self.selected_req_type = callbacks.loadExtensionSetting('selected_req_type') + if self.selected_req_type == "Complete Body": + self.CustomBodyRadio.setSelected(True) + elif self.selected_req_type == "Parameter Value": + self.parametervalueRadio.setSelected(True) + elif self.selected_req_type == "Parameter Key and Value": + self.paramkeyvalueRadio.setSelected(True) + elif self.selected_req_type == "None": + self.RequestTypeNoneRadio.setSelected(True) + self.selectedrequesttpye = self.selected_req_type + # Response Type UI self.responslayerpane = JLayeredPane(); @@ -224,7 +242,17 @@ def registerExtenderCallbacks(self, callbacks): self.ResponseTypeNoneRadio.setText("None"); self.ResponseTypeNoneRadio.setSelected(True) self.ResponseTypeNoneRadio.addActionListener(self.responsetypelister) - + + self.selected_resp_type_config = callbacks.loadExtensionSetting('selected_resp_type_config') + if self.selected_resp_type_config == "Complete Body": + self.responseCustomBodyRadio.setSelected(True) + elif self.selected_resp_type_config == "JSON Value": + self.responsejsonvalueradio.setSelected(True) + elif self.selected_resp_type_config == "JSON Key and Value": + self.responsejsonkeyvalueradio.setSelected(True) + elif self.selected_resp_type_config == "None": + self.ResponseTypeNoneRadio.setSelected(True) + self.selectedresponsetpye =self.selected_resp_type_config #Additional Setting UI @@ -249,9 +277,18 @@ def registerExtenderCallbacks(self, callbacks): 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.languagepath_config = callbacks.loadExtensionSetting('languagepath_config') + + if not self.languagepath_config == None: + self.languagepath.setText(self.languagepath_config) - + self.language_clear_button = JButton("Clear Language Selection") + self.language_clear_button.addActionListener(self.language_clear_button_listner) + self.languagejpanel.add(self.language_clear_button,BorderLayout.NORTH) + + self.reqmethodlabel = JLabel(); self.reqmethodlabel.setText("Encryption and Decryption Method(Only for Request)"); @@ -580,53 +617,57 @@ def registerExtenderCallbacks(self, callbacks): # Config Tab UI Placement options + # Set the border and layers for components in the requestlayerpane + # Set the border and layers for components in the requestlayerpane self.requestlayerpane.setBorder(BorderFactory.createLineBorder(Color(0, 0, 0))); self.requestlayerpane.setLayer(self.Requestypelabel, JLayeredPane.DEFAULT_LAYER); self.requestlayerpane.setLayer(self.CustomBodyRadio, JLayeredPane.DEFAULT_LAYER); self.requestlayerpane.setLayer(self.parametervalueRadio, JLayeredPane.DEFAULT_LAYER); self.requestlayerpane.setLayer(self.paramkeyvalueRadio, JLayeredPane.DEFAULT_LAYER); - self.requestlayerpane.setLayer(self.CustomRequestRadio, JLayeredPane.DEFAULT_LAYER); - self.requestlayerpane.setLayer(self.CustomRequestheaderRadio, JLayeredPane.DEFAULT_LAYER); self.requestlayerpane.setLayer(self.RequestTypeNoneRadio, JLayeredPane.DEFAULT_LAYER); + # Layout for the requestlayerpane self.requestlayerpaneLayout = GroupLayout(self.requestlayerpane); self.requestlayerpane.setLayout(self.requestlayerpaneLayout); + + # Set the horizontal group for left-to-right arrangement self.requestlayerpaneLayout.setHorizontalGroup( self.requestlayerpaneLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(self.requestlayerpaneLayout.createSequentialGroup() - .addContainerGap() - .addGroup(self.requestlayerpaneLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(self.Requestypelabel) - .addGroup(self.requestlayerpaneLayout.createSequentialGroup() - .addGroup(self.requestlayerpaneLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(self.CustomBodyRadio) - .addComponent(self.paramkeyvalueRadio) - .addComponent(self.CustomRequestheaderRadio)) - .addGap(2, 2, 2) - .addGroup(self.requestlayerpaneLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addComponent(self.RequestTypeNoneRadio) - .addComponent(self.CustomRequestRadio) - .addComponent(self.parametervalueRadio)))) - .addContainerGap(53, Short.MAX_VALUE)) + .addGroup(self.requestlayerpaneLayout.createSequentialGroup() + .addContainerGap() + .addGroup(self.requestlayerpaneLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(self.Requestypelabel) + .addGroup(self.requestlayerpaneLayout.createSequentialGroup() + .addGroup(self.requestlayerpaneLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(self.CustomBodyRadio) + .addComponent(self.paramkeyvalueRadio) + ) + .addGroup(self.requestlayerpaneLayout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addComponent(self.RequestTypeNoneRadio) + .addComponent(self.parametervalueRadio) + ) + ) + ) + .addContainerGap(53, Short.MAX_VALUE) + ) ); + + # Set the vertical group for top-to-bottom arrangement self.requestlayerpaneLayout.setVerticalGroup( - self.requestlayerpaneLayout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(self.requestlayerpaneLayout.createSequentialGroup() + self.requestlayerpaneLayout.createSequentialGroup() .addContainerGap() .addComponent(self.Requestypelabel) .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) .addGroup(self.requestlayerpaneLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) .addComponent(self.CustomBodyRadio) - .addComponent(self.parametervalueRadio)) + .addComponent(self.parametervalueRadio) + ) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addGroup(self.requestlayerpaneLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) .addComponent(self.paramkeyvalueRadio) - .addComponent(self.CustomRequestRadio)) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(self.requestlayerpaneLayout.createParallelGroup(GroupLayout.Alignment.LEADING) .addComponent(self.RequestTypeNoneRadio) - .addComponent(self.CustomRequestheaderRadio)) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ) + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) ); @@ -636,6 +677,8 @@ def registerExtenderCallbacks(self, callbacks): + + self.responslayerpane.setBorder(BorderFactory.createLineBorder(Color(0, 0, 0))); self.responslayerpane.setLayer(self.Responsetypelabel1, JLayeredPane.DEFAULT_LAYER); self.responslayerpane.setLayer(self.responseCustomBodyRadio, JLayeredPane.DEFAULT_LAYER); @@ -916,55 +959,45 @@ def registerExtenderCallbacks(self, callbacks): - layout = GroupLayout(self.firstTab); - self.firstTab.setLayout(layout); + #layout = GroupLayout(self.firstTab); + #self.firstTab.setLayout(layout); layout.setHorizontalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() + layout.createSequentialGroup() # This ensures components are placed horizontally (left to right) .addContainerGap() - .addGroup(layout.createParallelGroup(GroupLayout.Alignment.TRAILING) - .addGroup(GroupLayout.Alignment.LEADING, layout.createSequentialGroup() - .addComponent(self.requestlayerpane, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(self.responslayerpane, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(self.additionallayerpane)) - .addGroup(layout.createSequentialGroup() - .addComponent(self.autoencryptlayerpane) - .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) - .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING, False) - .addComponent(self.requestscriptfilelayerpane) - .addComponent(self.responescriptfilelayerpane))) - .addGroup(GroupLayout.Alignment.LEADING, layout.createSequentialGroup() - .addComponent(Requestparamlist, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addGap(18, 18, 18) - .addComponent(Responseparamlist, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addGap(0, 0, Short.MAX_VALUE))) - .addGap(18, 18, 18)) - ); - layout.setVerticalGroup( - layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addGap(18, 18, 18) - .addGroup(layout.createParallelGroup(GroupLayout.Alignment.TRAILING) + .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) # Align components to the left + .addComponent(self.requestlayerpane) .addComponent(self.responslayerpane, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING, False) - .addComponent(self.additionallayerpane) - .addComponent(self.requestlayerpane))) - .addGap(31, 31, 31) - .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING, False) - .addComponent(self.autoencryptlayerpane, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addGroup(layout.createSequentialGroup() - .addComponent(self.requestscriptfilelayerpane) - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addComponent(self.responescriptfilelayerpane, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))) + .addComponent(self.additionallayerpane) + .addComponent(self.autoencryptlayerpane) + .addComponent(self.requestscriptfilelayerpane) + .addComponent(self.responescriptfilelayerpane) + .addComponent(Requestparamlist, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(Responseparamlist, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + ) + .addGap(18, 18, 18) # Optional gap at the end of the horizontal layout + ) + + layout.setVerticalGroup( + layout.createSequentialGroup() # Stack components vertically (top to bottom) + .addGap(18, 18, 18) # Optional gap from the top + .addComponent(self.requestlayerpane, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(self.responslayerpane, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(self.additionallayerpane) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(self.autoencryptlayerpane, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(self.requestscriptfilelayerpane) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addComponent(self.responescriptfilelayerpane, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) - .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING, False) + .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) # Align the next row (left to right) .addComponent(Requestparamlist) - .addComponent(Responseparamlist)) - .addContainerGap(657, Short.MAX_VALUE)) - ); - + .addComponent(Responseparamlist) + ) + .addContainerGap(657, Short.MAX_VALUE) # Optional gap at the bottom + ) @@ -977,13 +1010,16 @@ def responsetypelister(self,e): if None not in (self.responsedecryptionfilepath,self.responseencryptionfilepath): self.ResponseTypeNoneRadio.setSelected(False) self.selectedresponsetpye = selected.getText() + self.callbacks.saveExtensionSetting("selected_resp_type_config",selected.getText()) else: JOptionPane.showMessageDialog(None, "Response Encryption and Decryption File Required to Start") self.ResponseTypeNoneRadio.setSelected(True) self.selectedresponsetpye = "None" + self.callbacks.saveExtensionSetting("selected_resp_type_config","None") elif selected.getText() == "None": self.selectedresponsetpye = "None" self.ResponseTypeNoneRadio.setSelected(True) + self.callbacks.saveExtensionSetting("selected_resp_type_config","None") if selected.getText() not in ["JSON Value", "JSON Key and Value"]: self.responseparamnonebutton.setSelected(True); @@ -1000,6 +1036,7 @@ def requestypelistner(self, e): #self.Autoencryptonoffbutton.setEnabled(True) self.RequestTypeNoneRadio.setSelected(False) self.selectedrequesttpye = selected.getText() + self.callbacks.saveExtensionSetting('selected_req_type',selected.getText()) if self.AutoencryptTooltypeScanner.isSelected() or self.AutoencryptTooltypeExtender.isSelected() or self.AutoencryptTooltypeRepeater.isSelected() or self.AutoencryptTooltypeProxy.isSelected() or self.AutoencryptTooltypeIntruder.isSelected() == True: self.Autoencryptonoffbutton.setEnabled(True) else: @@ -1009,10 +1046,12 @@ def requestypelistner(self, e): self.Autoencryptonoffbutton.setEnabled(False) self.Autoencryptonoffbutton.setSelected(False) self.selectedrequesttpye = "None" + self.callbacks.saveExtensionSetting('selected_req_type',"None") elif selected.getText() == "None": self.selectedrequesttpye = "None" self.Autoencryptonoffbutton.setEnabled(False) self.Autoencryptonoffbutton.setSelected(False) + elf.callbacks.saveExtensionSetting('selected_req_type',"None") if selected.getText() not in ["Parameter Value", "Parameter Key and Value"]: self.Requestparamnonebutton.setSelected(True); @@ -1119,6 +1158,12 @@ def select_language_file_path(self,e): fileLoad = chooseFile.getSelectedFile() self.languagefullpath = fileLoad.getAbsolutePath() self.languagepath.setText(self.languagefullpath) + self.callbacks.saveExtensionSetting("languagepath_config",self.languagefullpath) + + def language_clear_button_listner(self,e): + self.languagepath.setText("") + self.callbacks.saveExtensionSetting("languagepath_config","") + # Returning the Extension Tab name to burp ITAB def getTabCaption(self): @@ -1277,9 +1322,9 @@ def encryptstring(self,invocation): if self.selectedrequst: output = StringCrypto(self,encpath,query,http_request_response) - encryptedstring = output.encrypt_string_request() + encryptedstring, _ = output.encrypt_string_request() else: - encryptedstring = Parameterencrypt(self.languagepath.getText(), 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") @@ -1322,9 +1367,10 @@ def decryptstring(self,invocation): if self.selectedrequst: output = StringCrypto(self,encpath,query,http_request_response) - decryptedstring = output.decrypt_string_request() + decryptedstring, _ = output.decrypt_string_request() else: - decryptedstring = Parameterdecrypt(self.languagepath.getText(), encpath, query) + ## response does not need header to be passed hence its always empty for response + decryptedstring, _ = Parameterdecrypt(self.languagepath.getText(), encpath, query) showEditableDialog(decryptedstring, "Decryted String") @@ -1440,6 +1486,9 @@ def delete_selected_items_handler(self,event): self._log.pop(modelRowIndex) self.fireTableDataChanged() + def extensionUnloaded(self): + # delete temp folders + delete_temp_folder() #Message Editor Hanlder for Decrpyted Request Messages def getHttpService(self): diff --git a/pycript/Reqcheck.py b/pycript/Reqcheck.py index 2b37610..bfd9f5c 100644 --- a/pycript/Reqcheck.py +++ b/pycript/Reqcheck.py @@ -1,10 +1,10 @@ -from .decryption import Parameterdecrypt, Customrequestdecrypt,Customeditrequestdecrypt -from .encryption import Parameterencrypt, Customrequestencrypt,Customeditrequestencrypt +from .decryption import Parameterdecrypt +from .encryption import Parameterencrypt from json import loads, dumps from burp import IParameter -from .utils import update_json_value, update_json_key_value,process_custom_headers, extract_body_and_headers +from .utils import update_json_value, update_json_key_value,process_custom_headers, extract_body_and_headers,update_raw_value,update_raw_key_value def EncryptRequest(extender, currentreq,req): @@ -20,25 +20,18 @@ def EncryptRequest(extender, currentreq,req): if str(extender.selectedrequesttpye) == "Complete Body": - encryptedvalue = Parameterencrypt(selectedlang, encryptionpath, body) - output = extender.helpers.stringToBytes(encryptedvalue) - return extender.helpers.buildHttpMessage(header, output) + encryptedvalue, updated_header = Parameterencrypt(selectedlang, encryptionpath, body,headers_str) + headerlist = process_custom_headers(updated_header) + return extender.helpers.buildHttpMessage(headerlist, encryptedvalue) + #output = extender.helpers.stringToBytes(encryptedvalue) + #return extender.helpers.buildHttpMessage(header, output) elif str(extender.selectedrequesttpye) == "Parameter Value": - return encrypt_and_update_parameters(extender, currentreq, encryptionpath, selected_method, selectedlang, body, parameters, header,selected_request_inc_ex_ctype,listofparam) + return encrypt_and_update_parameters(extender, currentreq, encryptionpath, selected_method, selectedlang, body, parameters, header,selected_request_inc_ex_ctype,listofparam,headers_str) elif str(extender.selectedrequesttpye) == "Parameter Key and Value": - return encrypt_and_update_parameter_keys_and_values(extender, currentreq, encryptionpath, selected_method, selectedlang, body, parameters, header,selected_request_inc_ex_ctype,listofparam) + return encrypt_and_update_parameter_keys_and_values(extender, currentreq, encryptionpath, selected_method, selectedlang, body, parameters, header,selected_request_inc_ex_ctype,listofparam,headers_str) - elif str(extender.selectedrequesttpye) == "Custom Request": - extender.callbacks.printOutput(str(header)) - output = Customrequestencrypt(selectedlang, encryptionpath, str(header), body) - return extender.helpers.buildHttpMessage(header, output) - - elif str(extender.selectedrequesttpye) == "Custom Request (Edit Header)": - updatedheader, body = Customeditrequestencrypt(selectedlang, encryptionpath, str(headers_str), body) - headerlist = process_custom_headers(updatedheader) - return extender.helpers.buildHttpMessage(headerlist, body) ## Function to decrypt request when Burp Menu to decrypt request is triggered @@ -58,127 +51,76 @@ def DecryptRequest(extender, currentreq,req): body, headers_str = extract_body_and_headers(request_inst, req) if str(extender.selectedrequesttpye) == "Complete Body": - decrypted_value = Parameterdecrypt(selectedlang, decryptionpath, body) - output = extender.helpers.stringToBytes(decrypted_value) - return extender.helpers.buildHttpMessage(header, output) + # Byte arrays will be passed for body instead of strings to allow non ascii and binary data + decrypted_value, updated_header = Parameterdecrypt(selectedlang, decryptionpath, body,headers_str) + headerlist = process_custom_headers(updated_header) + return extender.helpers.buildHttpMessage(headerlist, decrypted_value) + #output = extender.helpers.stringToBytes(decrypted_value) + #return extender.helpers.buildHttpMessage(header, output) elif str(extender.selectedrequesttpye) == "Parameter Value": # Handle "Parameter Value" case - return decrypt_and_update_parameters(extender, currentreq, decryptionpath, selected_method, selectedlang,body,parameters,header,selected_request_inc_ex_ctype,listofparam) + return decrypt_and_update_parameters(extender, currentreq, decryptionpath, selected_method, selectedlang,body,parameters,header,selected_request_inc_ex_ctype,listofparam,headers_str) elif str(extender.selectedrequesttpye) == "Parameter Key and Value": - return decrypt_and_update_parameter_keys_and_values(extender, currentreq, decryptionpath, selected_method, selectedlang, body, parameters, header,selected_request_inc_ex_ctype,listofparam) - - - elif str(extender.selectedrequesttpye) == "Custom Request": - extender.callbacks.printOutput(str(header)) - output = Customrequestdecrypt(selectedlang, decryptionpath, str(header), body) - return extender.helpers.buildHttpMessage(header, output) + return decrypt_and_update_parameter_keys_and_values(extender, currentreq, decryptionpath, selected_method, selectedlang, body, parameters, header,selected_request_inc_ex_ctype,listofparam,headers_str) - elif str(extender.selectedrequesttpye) == "Custom Request (Edit Header)": - updatedheader, body = Customeditrequestdecrypt(selectedlang, decryptionpath, str(headers_str), body) - headerlist = process_custom_headers(updatedheader) - return extender.helpers.buildHttpMessage(headerlist, body) - - - # Decrypt parameters -def decrypt_and_update_parameters(extender, currentreq, decryptionpath, selected_method, selectedlang, body, parameters,header,selected_request_inc_ex_ctype,listofparam): +def decrypt_and_update_parameters(extender, currentreq, decryptionpath, selected_method, selectedlang, body, parameters,header,selected_request_inc_ex_ctype,listofparam,headers_str): # Go through all parameters for param in parameters: # Only decrypt GET parameters if Selected method is GET - if selected_method == "GET" and param.getType() == IParameter.PARAM_URL: - decrypted_param = Parameterdecrypt(selectedlang, decryptionpath, param.getValue()) + if (selected_method == "GET" or selected_method == "BOTH") and param.getType() == IParameter.PARAM_URL: + decrypted_param = update_raw_value(param,selectedlang, decryptionpath, Parameterdecrypt,selected_request_inc_ex_ctype,listofparam,headers_str) currentreq = extender.helpers.updateParameter(currentreq, extender.helpers.buildParameter(param.getName(), decrypted_param, param.getType())) # If Selected Method is Body, exlcude GET parameter (Should exclude cookie param as well) - elif selected_method == "BODY" and param.getType() != IParameter.PARAM_URL: + elif (selected_method == "BODY" or selected_method == "BOTH") and param.getType() == IParameter.PARAM_BODY: # First Udpate the form body - if param.getType() == IParameter.PARAM_BODY: - decrypted_param = Parameterdecrypt(selectedlang, decryptionpath, param.getValue()) - currentreq = extender.helpers.updateParameter(currentreq, extender.helpers.buildParameter(param.getName(), decrypted_param, param.getType())) - # If json then update json - 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,separators=(',', ':'))) - currentreq = extender.helpers.buildHttpMessage(header, output) - break - - # if BOTH is selected first update GET param values, then form body - else: - if param.getType() == IParameter.PARAM_URL: - decrypted_param = Parameterdecrypt(selectedlang, decryptionpath, param.getValue()) - currentreq = extender.helpers.updateParameter(currentreq, extender.helpers.buildParameter(param.getName(), decrypted_param, param.getType())) + decrypted_param = update_raw_value(param,selectedlang, decryptionpath, Parameterdecrypt,selected_request_inc_ex_ctype,listofparam,headers_str) + currentreq = extender.helpers.updateParameter(currentreq, extender.helpers.buildParameter(param.getName(), decrypted_param, param.getType())) - elif param.getType() == IParameter.PARAM_BODY: - decrypted_param = Parameterdecrypt(selectedlang, decryptionpath, param.getValue()) - currentreq = extender.helpers.updateParameter(currentreq, extender.helpers.buildParameter(param.getName(), decrypted_param, param.getType())) # get the updated parameters from the update request parameters = extender.helpers.analyzeRequest(currentreq).getParameters() header = extender.helpers.analyzeRequest(currentreq).getHeaders() for param in parameters: - if selected_method == "BOTH" and param.getType() == IParameter.PARAM_JSON: + if (selected_method == "BODY" or 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) + json_object = update_json_value(json_object, selectedlang, decryptionpath,Parameterdecrypt,selected_request_inc_ex_ctype,listofparam,headers_str) output = extender.helpers.stringToBytes(dumps(json_object,separators=(',', ':'))) currentreq = extender.helpers.buildHttpMessage(header, output) break return currentreq -def decrypt_and_update_parameter_keys_and_values(extender, currentreq, decryptionpath, selected_method, selectedlang, body, parameters, header,selected_request_inc_ex_ctype,listofparam): +def decrypt_and_update_parameter_keys_and_values(extender, currentreq, decryptionpath, selected_method, selectedlang, body, parameters, header,selected_request_inc_ex_ctype,listofparam,headers_str): for param in parameters: - if selected_method == "GET" and param.getType() == IParameter.PARAM_URL: - decrypted_param_name = Parameterdecrypt(selectedlang, decryptionpath, param.getName()) - decrypted_param_value = Parameterdecrypt(selectedlang, decryptionpath, param.getValue()) + if (selected_method == "GET" or selected_method == "BOTH") and param.getType() == IParameter.PARAM_URL: + decrypted_param_name, decrypted_param_value = update_raw_key_value(param,selectedlang, decryptionpath, Parameterdecrypt,selected_request_inc_ex_ctype,listofparam,headers_str) currentreq = extender.helpers.removeParameter(currentreq, param) new_param = extender.helpers.buildParameter(decrypted_param_name, decrypted_param_value, param.getType()) currentreq = extender.helpers.addParameter(currentreq, new_param) - elif selected_method == "BODY" and param.getType() != IParameter.PARAM_URL: - if param.getType() == IParameter.PARAM_BODY: - decrypted_param_name = Parameterdecrypt(selectedlang, decryptionpath, param.getName()) - decrypted_param_value = Parameterdecrypt(selectedlang, decryptionpath, param.getValue()) - currentreq = extender.helpers.removeParameter(currentreq, param) - new_param = extender.helpers.buildParameter(decrypted_param_name, decrypted_param_value, param.getType()) - currentreq = extender.helpers.addParameter(currentreq, new_param) - 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,separators=(',', ':'))) - currentreq = extender.helpers.buildHttpMessage(header, output) - break - - else: - if param.getType() == IParameter.PARAM_URL: - decrypted_param_name = Parameterdecrypt(selectedlang, decryptionpath, param.getName()) - decrypted_param_value = Parameterdecrypt(selectedlang, decryptionpath, param.getValue()) - currentreq = extender.helpers.removeParameter(currentreq, param) - new_param = extender.helpers.buildParameter(decrypted_param_name, decrypted_param_value, param.getType()) - currentreq = extender.helpers.addParameter(currentreq, new_param) - - elif param.getType() == IParameter.PARAM_BODY: - decrypted_param_name = Parameterdecrypt(selectedlang, decryptionpath, param.getName()) - decrypted_param_value = Parameterdecrypt(selectedlang, decryptionpath, param.getValue()) - currentreq = extender.helpers.removeParameter(currentreq, param) - new_param = extender.helpers.buildParameter(decrypted_param_name, decrypted_param_value, param.getType()) - currentreq = extender.helpers.addParameter(currentreq, new_param) + elif (selected_method == "BODY" or selected_method == "BOTH") and param.getType() == IParameter.PARAM_BODY: + decrypted_param_name, decrypted_param_value = update_raw_key_value(param,selectedlang, decryptionpath, Parameterdecrypt,selected_request_inc_ex_ctype,listofparam,headers_str) + currentreq = extender.helpers.removeParameter(currentreq, param) + new_param = extender.helpers.buildParameter(decrypted_param_name, decrypted_param_value, param.getType()) + currentreq = extender.helpers.addParameter(currentreq, new_param) parameters = extender.helpers.analyzeRequest(currentreq).getParameters() header = extender.helpers.analyzeRequest(currentreq).getHeaders() for param in parameters: - if selected_method == "BOTH" and param.getType() == IParameter.PARAM_JSON: + if (selected_method == "BODY" or 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) + json_object = update_json_key_value(json_object, selectedlang, decryptionpath,Parameterdecrypt,selected_request_inc_ex_ctype,listofparam,headers_str) output = extender.helpers.stringToBytes(dumps(json_object,separators=(',', ':'))) currentreq = extender.helpers.buildHttpMessage(header, output) break @@ -186,91 +128,50 @@ def decrypt_and_update_parameter_keys_and_values(extender, currentreq, decryptio return currentreq -def encrypt_and_update_parameters(extender, currentreq, encryptionpath, selected_method, selectedlang, body, parameters, header,selected_request_inc_ex_ctype,listofparam): +def encrypt_and_update_parameters(extender, currentreq, encryptionpath, selected_method, selectedlang, body, parameters, header,selected_request_inc_ex_ctype,listofparam,headers_str): for param in parameters: - if selected_method == "GET" and param.getType() == IParameter.PARAM_URL: - encrypted_param_value = Parameterencrypt(selectedlang, encryptionpath, param.getValue()) + if (selected_method == "GET" or selected_method == "BOTH") and param.getType() == IParameter.PARAM_URL: + encrypted_param_value = update_raw_value(param,selectedlang, Parameterencrypt, Parameterdecrypt,selected_request_inc_ex_ctype,listofparam,headers_str) currentreq = extender.helpers.updateParameter(currentreq, extender.helpers.buildParameter(param.getName(), encrypted_param_value, param.getType())) - elif selected_method == "BODY" and param.getType() != IParameter.PARAM_URL: - if param.getType() == IParameter.PARAM_BODY: - encrypted_param_value = Parameterencrypt(selectedlang, encryptionpath, param.getValue()) - currentreq = extender.helpers.updateParameter(currentreq, extender.helpers.buildParameter(param.getName(), encrypted_param_value, param.getType())) - 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,separators=(',', ':'))) - currentreq = extender.helpers.buildHttpMessage(header, output) - break - - else: - if param.getType() == IParameter.PARAM_URL: - decrypteedparam = Parameterencrypt(selectedlang, encryptionpath, param.getValue()) - currentreq = extender.helpers.updateParameter(currentreq, extender.helpers.buildParameter(param.getName(), decrypteedparam, param.getType())) - - elif param.getType() == IParameter.PARAM_BODY: - decrypteedparam = Parameterencrypt(selectedlang, encryptionpath, param.getValue()) - currentreq = extender.helpers.updateParameter(currentreq, extender.helpers.buildParameter(param.getName(), decrypteedparam, param.getType())) + elif (selected_method == "BODY" or selected_method == "BOTH") and param.getType() == IParameter.PARAM_BODY: + encrypted_param_value = update_raw_value(param,selectedlang, Parameterencrypt, Parameterdecrypt,selected_request_inc_ex_ctype,listofparam,headers_str) + currentreq = extender.helpers.updateParameter(currentreq, extender.helpers.buildParameter(param.getName(), encrypted_param_value, param.getType())) parameters = extender.helpers.analyzeRequest(currentreq).getParameters() header = extender.helpers.analyzeRequest(currentreq).getHeaders() for param in parameters: - if selected_method == "BOTH" and param.getType() == IParameter.PARAM_JSON: + if (selected_method == "BODY" or 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) + json_object = update_json_value(json_object, selectedlang, encryptionpath, Parameterencrypt,selected_request_inc_ex_ctype,listofparam,headers_str) output = extender.helpers.stringToBytes(dumps(json_object,separators=(',', ':'))) currentreq = extender.helpers.buildHttpMessage(header, output) break return currentreq -def encrypt_and_update_parameter_keys_and_values(extender, currentreq, encryptionpath, selected_method, selectedlang, body, parameters, header,selected_request_inc_ex_ctype,listofparam): +def encrypt_and_update_parameter_keys_and_values(extender, currentreq, encryptionpath, selected_method, selectedlang, body, parameters, header,selected_request_inc_ex_ctype,listofparam,headers_str): for param in parameters: - if selected_method == "GET" and param.getType() == IParameter.PARAM_URL: - encrypted_param_name = Parameterencrypt(selectedlang, encryptionpath, param.getName()) - encrypted_param_value = Parameterencrypt(selectedlang, encryptionpath, param.getValue()) + if (selected_method == "GET" or selected_method == "BOTH") and param.getType() == IParameter.PARAM_URL: + encrypted_param_name, encrypted_param_value = update_raw_key_value(param,selectedlang, Parameterencrypt, Parameterdecrypt,selected_request_inc_ex_ctype,listofparam,headers_str) currentreq = extender.helpers.removeParameter(currentreq, param) new_param = extender.helpers.buildParameter(encrypted_param_name, encrypted_param_value, param.getType()) currentreq = extender.helpers.addParameter(currentreq, new_param) - elif selected_method == "BODY" and param.getType() != IParameter.PARAM_URL: - if param.getType() == IParameter.PARAM_BODY: - encrypted_param_name = Parameterencrypt(selectedlang, encryptionpath, param.getName()) - encrypted_param_value = Parameterencrypt(selectedlang, encryptionpath, param.getValue()) - currentreq = extender.helpers.removeParameter(currentreq, param) - new_param = extender.helpers.buildParameter(encrypted_param_name, encrypted_param_value, param.getType()) - currentreq = extender.helpers.addParameter(currentreq, new_param) - - 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,separators=(',', ':'))) - currentreq = extender.helpers.buildHttpMessage(header, output) - break - - else: - if param.getType() == IParameter.PARAM_URL: - encrypted_param_name = Parameterencrypt(selectedlang, encryptionpath, param.getName()) - encrypted_param_value = Parameterencrypt(selectedlang, encryptionpath, param.getValue()) - currentreq = extender.helpers.removeParameter(currentreq, param) - new_param = extender.helpers.buildParameter(encrypted_param_name, encrypted_param_value, param.getType()) - currentreq = extender.helpers.addParameter(currentreq, new_param) - - elif param.getType() == IParameter.PARAM_BODY: - encrypted_param_name = Parameterencrypt(selectedlang, encryptionpath, param.getName()) - encrypted_param_value = Parameterencrypt(selectedlang, encryptionpath, param.getValue()) - currentreq = extender.helpers.removeParameter(currentreq, param) - new_param = extender.helpers.buildParameter(encrypted_param_name, encrypted_param_value, param.getType()) - currentreq = extender.helpers.addParameter(currentreq, new_param) + elif (selected_method == "BODY" or selected_method == "BOTH") and param.getType() == IParameter.PARAM_BODY: + encrypted_param_name, encrypted_param_value = update_raw_key_value(param,selectedlang, Parameterencrypt, Parameterdecrypt,selected_request_inc_ex_ctype,listofparam,headers_str) + currentreq = extender.helpers.removeParameter(currentreq, param) + new_param = extender.helpers.buildParameter(encrypted_param_name, encrypted_param_value, param.getType()) + currentreq = extender.helpers.addParameter(currentreq, new_param) parameters = extender.helpers.analyzeRequest(currentreq).getParameters() header = extender.helpers.analyzeRequest(currentreq).getHeaders() for param in parameters: - if selected_method == "BOTH" and param.getType() == IParameter.PARAM_JSON: + if (selected_method == "BODY" or 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) + json_object = update_json_key_value(json_object, selectedlang, encryptionpath,Parameterencrypt,selected_request_inc_ex_ctype,listofparam,headers_str) output = extender.helpers.stringToBytes(dumps(json_object,separators=(',', ':'))) currentreq = extender.helpers.buildHttpMessage(header, output) break diff --git a/pycript/decoding.py b/pycript/decoding.py deleted file mode 100644 index ec78c5b..0000000 --- a/pycript/decoding.py +++ /dev/null @@ -1,4 +0,0 @@ -from base64 import b64decode - -def decode_base64(data): - return b64decode(data.encode('utf-8')) diff --git a/pycript/decryption.py b/pycript/decryption.py index 036e589..3e74fb9 100644 --- a/pycript/decryption.py +++ b/pycript/decryption.py @@ -1,42 +1,19 @@ from . import encoding, decoding from .execution import execute_command - +from .gethelpers import string_to_bytes, bytes_to_string #Parameterdecrypt --> Parameterdecrypt -def Parameterdecrypt(selectedlang, path, data): - data2 = encoding.encode_base64(data) - output = execute_command(selectedlang, path, data2) - if output is not False: - return output.decode('utf-8') - else: - return data - - -def Customrequestdecrypt(selectedlang, path, header, body): - body2 = encoding.encode_base64(body) - output = execute_command(selectedlang, path, body2, encoding.encode_base64(header)).decode('utf-8') - if output is not False: - return output.decode('utf-8') +def Parameterdecrypt(selectedlang, path, data,headers_str=None): + body_parameter_byte = list(string_to_bytes(data)) + result = execute_command(selectedlang, path, body_parameter_byte,headers_str) + if result is not False: + body, header = result + string_body = bytes_to_string(body) + return string_body,header else: - return body - + return data,headers_str -def Customeditrequestdecrypt(selectedlang, path, header, body): - body2 = encoding.encode_base64(body) - header2 = encoding.encode_base64(header) - - output = execute_command(selectedlang, path, body2, header2) - if output is not False: - lines = output.splitlines() - headerbase64, bodybase64 = lines[0], lines[1] - - header = decoding.decode_base64(headerbase64).decode('utf-8') - body = decoding.decode_base64(bodybase64).decode('utf-8') - return (header, body) - else: - - return (header, body) diff --git a/pycript/encoding.py b/pycript/encoding.py deleted file mode 100644 index 6b6d6c2..0000000 --- a/pycript/encoding.py +++ /dev/null @@ -1,4 +0,0 @@ -from base64 import b64encode - -def encode_base64(data): - return b64encode(data).decode('utf-8') diff --git a/pycript/encryption.py b/pycript/encryption.py index e7c50bd..316db06 100644 --- a/pycript/encryption.py +++ b/pycript/encryption.py @@ -1,40 +1,16 @@ from . import encoding, decoding from .execution import execute_command - +from .gethelpers import string_to_bytes, bytes_to_string #Jsonvalueencrypt --> Parameterencrypt -def Parameterencrypt(selectedlang, path, data): - output = execute_command(selectedlang, path, str(encoding.encode_base64(data))) - - if output is not False: - return output.decode('utf-8') - else: - return data - +def Parameterencrypt(selectedlang, path, data,headers_str=None): + body_parameter_byte = str(list(string_to_bytes(data))) + result = execute_command(selectedlang, path, body_parameter_byte,headers_str) -def Customrequestencrypt(selectedlang, path, header, body): - output = execute_command(selectedlang, path, encoding.encode_base64(body), encoding.encode_base64(header)) - - if output is not False: - return output.decode('utf-8') + if result is not False: + body, header = result + string_body = bytes_to_string(body) + return string_body,header else: - return body - - - -def Customeditrequestencrypt(selectedlang, path, header, body): - body2 = encoding.encode_base64(body) - header2 = encoding.encode_base64(header) - - output = execute_command(selectedlang, path, body2, header2) - if output is not False: - lines = output.splitlines() - headerbase64, bodybase64 = lines[0], lines[1] - header = decoding.decode_base64(headerbase64).decode('utf-8') - body = decoding.decode_base64(bodybase64).decode('utf-8') - return (header, body) - else: - return (header, body) - - \ No newline at end of file + return data,headers_str diff --git a/pycript/execution.py b/pycript/execution.py index 4f2712a..a41f732 100644 --- a/pycript/execution.py +++ b/pycript/execution.py @@ -2,51 +2,41 @@ from .gui import logerrors import tempfile from os import remove -import json +from .temp_file import parse_temp_file_output, create_temp_file 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 - + try: + temp_file_path = create_temp_file(data,headervalue) + #temp_file_path = temp_file.name command = [] if selectedlang: - command.append('"' + selectedlang + '"') + command.append(selectedlang) # Add the selected language executable directly if path.endswith(".jar"): command.extend(["-jar"]) - command.extend(['"' + path + '"',"-d", temp_file_path]) + command.extend([path, "-d", temp_file_path]) - command_str = ' '.join(command) + # Log the command for debugging + command_str = ' '.join('"{0}"'.format(arg) if ' ' in arg else arg for arg in command) logerrors("$ " + command_str) - process = subprocess.Popen( - command_str, - shell=True, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - universal_newlines=True - ) - output, error = process.communicate() - remove(temp_file_path) - - if process.returncode != 0: - logerrors(error.strip()) - return False - else: + try: + output = subprocess.check_output(command, stderr=subprocess.PIPE) logerrors(output.strip()) - output = output.strip() - return output if output else False + body, header = parse_temp_file_output(data, headervalue, temp_file_path) + remove(temp_file_path) + if body: + return body, header + else: + return False + except subprocess.CalledProcessError as e: + logerrors("Command failed with return code: {}, Error: {}".format(e.returncode, e.output)) + remove(temp_file_path) + + except Exception as e: logerrors(str(e)) + #remove(temp_file_path) return False diff --git a/pycript/gethelpers.py b/pycript/gethelpers.py new file mode 100644 index 0000000..ef9b516 --- /dev/null +++ b/pycript/gethelpers.py @@ -0,0 +1,26 @@ +from java.util import Arrays; +from java.lang import String + +_helpers = None # Private variable to hold the helpers reference. + +def set_helpers(helpers): + """Set the helpers instance.""" + global _helpers + _helpers = helpers + +def get_helpers(): + """Get the helpers instance.""" + if _helpers is None: + raise RuntimeError("Helpers not initialized. Call `set_helpers` first.") + return _helpers + +def string_to_bytes(string): + """Convert a string to bytes using helpers.""" + return get_helpers().stringToBytes(string) + +def bytes_to_string(byte_data): + """Convert bytes to string using helpers.""" + byte_data_clean = byte_data.strip('[]') + byte_data2 = [int(code.strip()) for code in byte_data_clean.split(',')] + #return get_helpers().bytesToString(byte_data2) # for some reason helper API gives error or remove some non ascii data from string results in wrong string for non ascii or binary data + return ''.join(chr(code) for code in byte_data2) diff --git a/pycript/response_handler.py b/pycript/response_handler.py index 2abf76b..796fd1c 100644 --- a/pycript/response_handler.py +++ b/pycript/response_handler.py @@ -1,5 +1,5 @@ -from .decryption import Parameterdecrypt,Customrequestdecrypt -from .encryption import Parameterencrypt,Customrequestencrypt +from .decryption import Parameterdecrypt +from .encryption import Parameterencrypt from json import loads, dumps from .utils import update_json_value, update_json_key_value @@ -16,7 +16,7 @@ def encrypt_decrypt_response(extender,currentresp,response,enc_dec,enc_dec_type) listofparam = extender.responseparamlist1.getText().split(',') if str(extender.selectedresponsetpye) == "Complete Body": - decryptedvalue = enc_dec(selectedlang, enc_dec_file_path, stringbody) + decryptedvalue, _ = enc_dec(selectedlang, enc_dec_file_path, stringbody) output = extender.helpers.stringToBytes(decryptedvalue) return extender.helpers.buildHttpMessage(header, output) diff --git a/pycript/stringcrypto.py b/pycript/stringcrypto.py index bbeab1f..8ac59b2 100644 --- a/pycript/stringcrypto.py +++ b/pycript/stringcrypto.py @@ -1,5 +1,5 @@ -from .decryption import Parameterdecrypt, Customrequestdecrypt,Customeditrequestdecrypt -from .encryption import Parameterencrypt, Customrequestencrypt,Customeditrequestencrypt +from .decryption import Parameterdecrypt +from .encryption import Parameterencrypt class StringCrypto: def __init__(self, extender, encpath, query, http_request_response): @@ -26,33 +26,15 @@ def get_headers_str(self): body_offset = request_info.getBodyOffset() headers_str = request_str[:body_offset].strip() return headers_str - + ### String Encryption Decryption Cannot Modify the header, Can read headers only for string from request def encrypt_string_request(self): - if self._extender.selectedrequesttpye == "Custom Request": - encrypted = Customrequestencrypt(self.selectedlang, self.encpath, str(self.header), self._selectedmessage) - return encrypted - - elif self._extender.selectedrequesttpye == "Custom Request (Edit Header)": - encrypted = Customeditrequestencrypt(self.selectedlang, self.encpath, str(self.headers_str), self._selectedmessage) - return encrypted - - else: - encrypted = Parameterencrypt(self.selectedlang, self.encpath, self._selectedmessage) - return encrypted + encrypted, header = Parameterencrypt(self.selectedlang, self.encpath, self._selectedmessage,self.headers_str) + return encrypted,header def decrypt_string_request(self): - if self._extender.selectedrequesttpye == "Custom Request": - decrypted = Customrequestdecrypt(self.selectedlang, self.encpath, str(self.header), self._selectedmessage) - return decrypted - - elif self._extender.selectedrequesttpye == "Custom Request (Edit Header)": - decrypted = Customeditrequestdecrypt(self.selectedlang, self.encpath, str(self.headers_str), self._selectedmessage) - return decrypted - - else: - decrypted = Parameterdecrypt(self.selectedlang, self.encpath, self._selectedmessage) - return decrypted \ No newline at end of file + decrypted, header = Parameterdecrypt(self.selectedlang, self.encpath, self._selectedmessage,self.headers_str) + return decrypted,header \ No newline at end of file diff --git a/pycript/temp_file.py b/pycript/temp_file.py new file mode 100644 index 0000000..2fb20dc --- /dev/null +++ b/pycript/temp_file.py @@ -0,0 +1,62 @@ +import os +import tempfile +import random +import string +import shutil + +from .gui import logerrors + +user_home = os.path.expanduser("~") +pycript_dir = os.path.join(user_home, ".pycript") + +def parse_temp_file_output(original_data, original_header, temp_file_path): + with open(temp_file_path, 'rb') as temp_file: + file_content = temp_file.read() + body_end_marker = b'\n--BODY_END--\n' + + logerrors("User Script Created File Output:") + logerrors(file_content) + + # Split the file content using the marker + parts = file_content.split(body_end_marker, 1) + + # Extract body data + body_data = parts[0] + + # Extract header data if present, otherwise use the original header + if len(parts) > 1 and parts[1].strip(): # Check if header exists and is not empty + header_data = parts[1].strip() + else: + header_data = original_header + return body_data, header_data + + +def create_temp_file(data, headervalue=None): + # Get the temp directory path + random_file_name = ''.join([random.choice(string.ascii_letters + string.digits) for _ in range(12)]) + file_path = os.path.join(pycript_dir, random_file_name) + + # Write data to the file + with open(file_path, "wb") as file: + file.write(bytes(data)) # Write the byte array directly to the file + file.write(b'\n--BODY_END--\n') # Write the binary body end marker + if headervalue is not None: + file.write(headervalue.encode('utf-8')) + + return file_path + + +def create_temp_dir(): + + if not os.path.exists(pycript_dir): + os.makedirs(pycript_dir) + temp_dir = tempfile.mkdtemp(dir=pycript_dir) + + +def delete_temp_folder(): + if os.path.exists(pycript_dir): + shutil.rmtree(pycript_dir) # Remove the directory and all its contents + print("Temporary directory and its contents have been deleted.") + else: + print("Directory does not exist.") + \ No newline at end of file diff --git a/pycript/utils.py b/pycript/utils.py index 4f3613d..453fc84 100644 --- a/pycript/utils.py +++ b/pycript/utils.py @@ -3,40 +3,40 @@ from java.util import ArrayList ## update json key and value both -def update_json_key_value(json_obj, selectedlang, decryptionpath,enc_dec ,selected_request_response_inc_ex_ctype,listofparam): +def update_json_key_value(json_obj, selectedlang, decryptionpath,enc_dec ,selected_request_response_inc_ex_ctype,listofparam,headers_str=None): if selected_request_response_inc_ex_ctype is None: for key, value in json_obj.items(): - new_key = enc_dec(selectedlang, decryptionpath, key) + new_key , _ = enc_dec(selectedlang, decryptionpath, key,headers_str) if isinstance(value, dict): for inner_key, inner_value in value.items(): - new_inner_key = enc_dec(selectedlang, decryptionpath, inner_key) - value[new_inner_key] = enc_dec(selectedlang, decryptionpath, inner_value) + new_inner_key , _ = enc_dec(selectedlang, decryptionpath, inner_key,headers_str) + value[new_inner_key] , _ = enc_dec(selectedlang, decryptionpath, inner_value,headers_str) if inner_key != new_inner_key: del value[inner_key] elif isinstance(value, list): for i in range(len(value)): if isinstance(value[i], dict): for inner_key, inner_value in value[i].items(): - new_inner_key = enc_dec(selectedlang, decryptionpath, inner_key) - value[i][new_inner_key] = enc_dec(selectedlang, decryptionpath, inner_value) + new_inner_key , _ = enc_dec(selectedlang, decryptionpath, inner_key,headers_str) + value[i][new_inner_key] , _ = enc_dec(selectedlang, decryptionpath, inner_value,headers_str) if inner_key != new_inner_key: del value[i][inner_key] else: - value[i] = enc_dec(selectedlang, decryptionpath, value[i]) + value[i] , _ = enc_dec(selectedlang, decryptionpath, value[i],headers_str) else: - json_obj[new_key] = enc_dec(selectedlang, decryptionpath, value) + json_obj[new_key] , _ = enc_dec(selectedlang, decryptionpath, value,headers_str) if key != new_key: del json_obj[key] elif selected_request_response_inc_ex_ctype == "Include Parameters": for key, value in json_obj.items(): if key in listofparam: - new_key = enc_dec(selectedlang, decryptionpath, key) + new_key , _ = enc_dec(selectedlang, decryptionpath, key,headers_str) if isinstance(value, dict): for inner_key, inner_value in value.items(): if inner_key in listofparam: - new_inner_key = enc_dec(selectedlang, decryptionpath, inner_key) - value[new_inner_key] = enc_dec(selectedlang, decryptionpath, inner_value) + new_inner_key , _ = enc_dec(selectedlang, decryptionpath, inner_key,headers_str) + value[new_inner_key] , _ = enc_dec(selectedlang, decryptionpath, inner_value,headers_str) if inner_key != new_inner_key: del value[inner_key] elif isinstance(value, list): @@ -44,28 +44,28 @@ def update_json_key_value(json_obj, selectedlang, decryptionpath,enc_dec ,select if isinstance(value[i], dict): for inner_key, inner_value in value[i].items(): if inner_key in listofparam: - new_inner_key = enc_dec(selectedlang, decryptionpath, inner_key) - value[i][new_inner_key] = enc_dec(selectedlang, decryptionpath, inner_value) + new_inner_key , _ = enc_dec(selectedlang, decryptionpath, inner_key,headers_str) + value[i][new_inner_key] , _ = enc_dec(selectedlang, decryptionpath, inner_value,headers_str) if inner_key != new_inner_key: del value[i][inner_key] else: if i in listofparam: - value[i] = enc_dec(selectedlang, decryptionpath, value[i]) + value[i] , _ = enc_dec(selectedlang, decryptionpath, value[i],headers_str) else: if key in listofparam: - json_obj[new_key] = enc_dec(selectedlang, decryptionpath, value) + json_obj[new_key] , _ = enc_dec(selectedlang, decryptionpath, value,headers_str) if key != new_key: del json_obj[key] elif selected_request_response_inc_ex_ctype == "Exclude Parameters": for key, value in json_obj.items(): if key not in listofparam: - new_key = enc_dec(selectedlang, decryptionpath, key) + new_key , _ = enc_dec(selectedlang, decryptionpath, key,headers_str) if isinstance(value, dict): for inner_key, inner_value in value.items(): if inner_key not in listofparam: - new_inner_key = enc_dec(selectedlang, decryptionpath, inner_key) - value[new_inner_key] = enc_dec(selectedlang, decryptionpath, inner_value) + new_inner_key , _ = enc_dec(selectedlang, decryptionpath, inner_key,headers_str) + value[new_inner_key] , _ = enc_dec(selectedlang, decryptionpath, inner_value,headers_str) if inner_key != new_inner_key: del value[inner_key] elif isinstance(value, list): @@ -73,103 +73,38 @@ def update_json_key_value(json_obj, selectedlang, decryptionpath,enc_dec ,select if isinstance(value[i], dict): for inner_key, inner_value in value[i].items(): if inner_key not in listofparam: - new_inner_key = enc_dec(selectedlang, decryptionpath, inner_key) - value[i][new_inner_key] = enc_dec(selectedlang, decryptionpath, inner_value) + new_inner_key , _ = enc_dec(selectedlang, decryptionpath, inner_key,headers_str) + value[i][new_inner_key] , _ = enc_dec(selectedlang, decryptionpath, inner_value,headers_str) if inner_key != new_inner_key: del value[i][inner_key] else: if i not in listofparam: - value[i] = enc_dec(selectedlang, decryptionpath, value[i]) + value[i] , _ = enc_dec(selectedlang, decryptionpath, value[i],headers_str) else: if key not in listofparam: - json_obj[new_key] = enc_dec(selectedlang, decryptionpath, value) + json_obj[new_key] , _ = enc_dec(selectedlang, decryptionpath, value,headers_str) if key != new_key: del json_obj[key] return json_obj -def update_raw_value(parameter_value, selectedlang, encryptionpath, enc_dec, selected_request_response_inc_ex_ctype,listofparam): - # Check if selectedreq_incexctype is None - param_name = parameter_value.getName() - param_value = parameter_value.getValue() - - if selected_request_response_inc_ex_ctype is None: - # Process all parameters in the parameter_valueect - new_value = enc_dec(selectedlang, encryptionpath, param_value) - - else: - # Process parameters based on selectedparamtertype - if selected_request_response_inc_ex_ctype == "Include Parameters": - if isinstance(str(param_name), str): - if param_name in listofparam: - new_value = enc_dec(selectedlang, encryptionpath, param_value) - else: - new_value = param_value - else: - if param_name in listofparam: - new_value = enc_dec(selectedlang, encryptionpath, param_value) - - elif selected_request_response_inc_ex_ctype == "Exclude Parameters": - if isinstance(str(param_name), str): - if param_name not in listofparam: - new_value = enc_dec(selectedlang, encryptionpath, param_value) - else: - new_value = param_value - else: - if param_name not in listofparam: - new_value = enc_dec(selectedlang, encryptionpath, param_value) - - return new_value - -def update_raw_key_value(param, selectedlang, encryptionpath, enc_dec ,selected_request_response_inc_ex_ctype,listofparam): - if selected_request_response_inc_ex_ctype is None: - new_param = param.getName() - new_value = param.getValue() - encrypted_param_name = enc_dec(selectedlang, encryptionpath, new_param) - encrypted_param_value = enc_dec(selectedlang, encryptionpath, new_value) - - elif selected_request_response_inc_ex_ctype == "Include Parameters": - if param.getName() in listofparam: - new_param = param.getName() - new_value = param.getValue() - encrypted_param_name = enc_dec(selectedlang, encryptionpath, new_param) - encrypted_param_value = enc_dec(selectedlang, encryptionpath, new_value) - else: - encrypted_param_name = param.getName() - encrypted_param_value = param.getValue() - - elif selected_request_response_inc_ex_ctype == "Exclude Parameters": - if param.getName() not in listofparam: - new_param = param.getName() - new_value = param.getValue() - encrypted_param_name = enc_dec(selectedlang, encryptionpath, new_param) - encrypted_param_value = enc_dec(selectedlang, encryptionpath, new_value) - else: - encrypted_param_name = param.getName() - encrypted_param_value = param.getValue() - else: - encrypted_param_name = param.getName() - encrypted_param_value = param.getValue() - return encrypted_param_name, encrypted_param_value - - -def update_json_value(json_obj, selectedlang, decryptionpath, enc_dec, selected_request_response_inc_ex_ctype,listofparam): +def update_json_value(json_obj, selectedlang, decryptionpath, enc_dec, selected_request_response_inc_ex_ctype,listofparam,headers_str=None): # Check if selectedreq_incexctype is None if selected_request_response_inc_ex_ctype is None: # Process all parameters in the JSON object for key, value in json_obj.items(): if isinstance(value, dict): for inner_key, inner_value in value.items(): - value[inner_key] = enc_dec(selectedlang, decryptionpath, inner_value) + value[inner_key] , _ = enc_dec(selectedlang, decryptionpath, inner_value,headers_str) elif isinstance(value, list): for i in range(len(value)): if isinstance(value[i], dict): for inner_key, inner_value in value[i].items(): - value[i][inner_key] = enc_dec(selectedlang, decryptionpath, inner_value) + value[i][inner_key] , _ = enc_dec(selectedlang, decryptionpath, inner_value,headers_str) else: - value[i] = enc_dec(selectedlang, decryptionpath, value[i]) + value[i] , _ = enc_dec(selectedlang, decryptionpath, value[i],headers_str) else: - value = enc_dec(selectedlang, decryptionpath, value) + value , _ = enc_dec(selectedlang, decryptionpath, value,headers_str) json_obj[key] = value else: @@ -179,42 +114,74 @@ def update_json_value(json_obj, selectedlang, decryptionpath, enc_dec, selected_ if isinstance(value, dict): for inner_key, inner_value in value.items(): if inner_key in listofparam: - value[inner_key] = enc_dec(selectedlang, decryptionpath, inner_value) + value[inner_key] , _ = enc_dec(selectedlang, decryptionpath, inner_value,headers_str) elif isinstance(value, list): for i in range(len(value)): if isinstance(value[i], dict): for inner_key, inner_value in value[i].items(): if inner_key in listofparam: - value[i][inner_key] = enc_dec(selectedlang, decryptionpath, inner_value) + value[i][inner_key] , _ = enc_dec(selectedlang, decryptionpath, inner_value,headers_str) else: if i in listofparam: - value[i] = enc_dec(selectedlang, decryptionpath, value[i]) + value[i] , _ = enc_dec(selectedlang, decryptionpath, value[i],headers_str) else: if key in listofparam: - value = enc_dec(selectedlang, decryptionpath, value) + value , _ = enc_dec(selectedlang, decryptionpath, value,headers_str) json_obj[key] = value elif selected_request_response_inc_ex_ctype == "Exclude Parameters": for key, value in json_obj.items(): if isinstance(value, dict): for inner_key, inner_value in value.items(): if inner_key not in listofparam: - value[inner_key] = enc_dec(selectedlang, decryptionpath, inner_value) + value[inner_key] , _ = enc_dec(selectedlang, decryptionpath, inner_value,headers_str) elif isinstance(value, list): for i in range(len(value)): if isinstance(value[i], dict): for inner_key, inner_value in value[i].items(): if inner_key not in listofparam: - value[i][inner_key] = enc_dec(selectedlang, decryptionpath, inner_value) + value[i][inner_key] , _ = enc_dec(selectedlang, decryptionpath, inner_value,headers_str) else: if i not in listofparam: - value[i] = enc_dec(selectedlang, decryptionpath, value[i]) + value[i] , _ = enc_dec(selectedlang, decryptionpath, value[i],headers_str) else: if key not in listofparam: - value = enc_dec(selectedlang, decryptionpath, value) + value , _ = enc_dec(selectedlang, decryptionpath, value,headers_str) json_obj[key] = value return json_obj +def update_raw_value(param, selectedlang, encryptionpath, enc_dec, selected_request_response_inc_ex_ctype,listofparam,headers_str=None): + param_name = param.getName() + param_value = param.getValue() + + if selected_request_response_inc_ex_ctype is None: + param_value , _ = enc_dec(selectedlang, encryptionpath, param_value,headers_str) + elif selected_request_response_inc_ex_ctype == "Include Parameters" and param_name in listofparam: + param_value , _ = enc_dec(selectedlang, encryptionpath, param_value,headers_str) + + elif selected_request_response_inc_ex_ctype == "Exclude Parameters" and param_name not in listofparam: + param_value , _ = enc_dec(selectedlang, encryptionpath, param_value,headers_str) + + return param_value + + +def update_raw_key_value(param, selectedlang, encryptionpath, enc_dec ,selected_request_response_inc_ex_ctype,listofparam,headers_str=None): + + param_name = param.getName() + param_value = param.getValue() + if selected_request_response_inc_ex_ctype is None: + param_name, _ = enc_dec(selectedlang, encryptionpath, param_name,headers_str) + param_value, _ = enc_dec(selectedlang, encryptionpath, param_value,headers_str) + + elif selected_request_response_inc_ex_ctype == "Include Parameters" and param_name in listofparam: + param_name , _ = enc_dec(selectedlang, encryptionpath, param_name,headers_str) + param_value , _ = enc_dec(selectedlang, encryptionpath, param_value,headers_str) + + elif selected_request_response_inc_ex_ctype == "Exclude Parameters" and param_name not in listofparam: + param_name , _ = enc_dec(selectedlang, encryptionpath, param_name,headers_str) + param_value , _ = enc_dec(selectedlang, encryptionpath, param_value,headers_str) + + return param_name, param_value def process_custom_headers(updated_header): @@ -233,3 +200,4 @@ def extract_body_and_headers(request_inst, req): body = request_inst[getody:] headers_str = request_inst[:getody].strip() return body, headers_str +