Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Version 0.3 #4

Merged
merged 26 commits into from
Nov 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
e2a01a6
Optimized for Encryption and Decryption
Anof-cyber Oct 22, 2023
fc96bea
Updated Parameter and Func names
Anof-cyber Oct 22, 2023
d2daab8
Optimizting String enc/dec string class
Anof-cyber Oct 28, 2023
bb1619c
Fixed Error in enc/dec string from optimization
Anof-cyber Oct 28, 2023
f036bba
Optimized DecryptRequest for Menu
Anof-cyber Oct 29, 2023
99371ce
Optimized the EncryptRequest and DecryptRequest
Anof-cyber Oct 29, 2023
cf58f75
EncryptRequest,DecryptRequest support editor tab
Anof-cyber Oct 30, 2023
239473b
Updated request editor tab to use same encrypt/decrypt method as othe…
Anof-cyber Oct 30, 2023
1dd63e0
Fixed Python subprocess fail to run Pycript in MacOS and Linux (Witho…
Anof-cyber Nov 14, 2023
1e6cb48
Fixed - 1. Space in File path causing errors, 2. Macos permission err…
Anof-cyber Nov 14, 2023
520ae88
added new stderr and stdout logger for debugging
Anof-cyber Nov 14, 2023
fb36246
added stderr to debug loggger (Without MacOS Verification)
Anof-cyber Nov 14, 2023
5445e85
Fixed new line issues
Anof-cyber Nov 14, 2023
0dd7bc3
fixed few error causing messeage editor tab doesn't show up at same t…
Anof-cyber Nov 16, 2023
4d478e1
Added Include exclude parameters (UI Only)
Anof-cyber Nov 16, 2023
786f3a9
Added validation for Exclude and include parameter functions.
Anof-cyber Nov 16, 2023
69ad24a
added some more validation for include exclude parameter
Anof-cyber Nov 16, 2023
158a225
integrated Request include exclue parameter
Anof-cyber Nov 17, 2023
e724ab4
1. Added Support for include exclude for json key and value
Anof-cyber Nov 17, 2023
0149d1b
1. Added New Resource TAB
Anof-cyber Nov 18, 2023
a1ae861
1. Added new Delete Row menu for Decrypted request table
Anof-cyber Nov 18, 2023
7ee9154
1. Fixed Request enc file is loaded for response encryption from burp…
Anof-cyber Nov 18, 2023
daf39b5
1. Added Command Execution Validation
Anof-cyber Nov 20, 2023
76315d4
Fixed Errors in string encrpytion decryption
Anof-cyber Nov 20, 2023
ef5fa8b
version 0.3
Anof-cyber Nov 20, 2023
2e93f9f
Release v0.3
Anof-cyber Nov 20, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -139,3 +139,4 @@ Django/
Android/
images/

.vscode/settings.json
14 changes: 8 additions & 6 deletions BappDescription.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<p>Pycript enables users to encrypt and decrypt requests and response for manual and automated application penetration testing. It also allows users to create custom encryption and decryption logic using JavaScript, Python and Java, allowing for a tailored encryption/decryption process for specific needs.</p>

<p>Features</p>
<p><strong>Features</strong></p>
<ul>
<li>Encrypt &amp; Decrypt the Selected Strings from Request Response</li>
<li>View and Modify the encrypted request in plain text</li>
Expand All @@ -11,10 +11,12 @@
<li>Ability to handle encryption and decryption even with Key and IV in Request Header or Body</li>
</ul>

<p>Requirements</p>
<p><strong>Requirements</strong></p>
<p>Node JS / Python / Java</p>

<p>PyCript Help</p><br>
<p>PyCript encryption and decryption code <a href="https://github.com/Anof-cyber/PyCript-Template">PyCript Template</a>
<br>
<a href="https://pycript.souravkalal.tech/">PyCript Documentation </a></p>
<p><strong>PyCript Help</strong></p>
<ul>
<li><a href="https://www.youtube.com/watch?v=J8KE5VR8yDk">PyCript Video Tutorial </a></li>
<li>PyCript encryption and decryption code <a href="https://github.com/Anof-cyber/PyCript-Template">PyCript Template</a></li>
<li><a href="https://pycript.souravkalal.tech/">PyCript Documentation </a></li>
</ul>
645 changes: 500 additions & 145 deletions pycript.py

Large diffs are not rendered by default.

704 changes: 227 additions & 477 deletions pycript/Reqcheck.py

Large diffs are not rendered by default.

49 changes: 21 additions & 28 deletions pycript/Requesttab.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
from burp import IMessageEditorTab
import json
from .decryption import Jsonvaluedecrypt,Customrequestdecrypt
from .encryption import Jsonvalueencrypt,Customrequestencrypt
from collections import OrderedDict
from requestvalidator import decrypt,encrypt
from .Reqcheck import DecryptRequest
from pycript.Reqcheck import DecryptRequest,EncryptRequest


class CriptInputTab(IMessageEditorTab):
def __init__(self, extender, controller, editable):
Expand All @@ -26,25 +22,16 @@ def getUiComponent(self):

return self._txtInput.getComponent()


def isEnabled(self, content, isRequest):

if content and isRequest:
if str(self._extender.selectedrequesttpye) == "None":
if isRequest:
if content is None:
return False

elif str(self._extender.reqresponsecombobox.getSelectedItem()) == "Response":
if str(self._extender.selectedrequesttpye) == "None" or str(self._extender.reqresponsecombobox.getSelectedItem()) == "Response":
return False

else:
request = self._extender.helpers.analyzeRequest(self.controller.getHttpService(),self.controller.getRequest())
if self._extender.callbacks.isInScope(request.getUrl()):
return True
else:
return False



return True
return False


def setMessage(self, content, isRequest):
Expand All @@ -56,25 +43,31 @@ def setMessage(self, content, isRequest):

else:
if isRequest:



output = decrypt(self._extender,content)
self._txtInput.setText(output)
self._txtInput.setEditable(True)
if self.controller.getHttpService() is not None:

url = self._extender.helpers.analyzeRequest(self.controller.getHttpService(), self.controller.getRequest()).getUrl()
if self._extender.callbacks.isInScope(url):
request = self._extender.helpers.analyzeRequest(content)
output = DecryptRequest(self._extender,content,request)
else:
output = "URL is not added in Scope"
self._txtInput.setEditable(False)
self._txtInput.setText(output)
self._txtInput.setEditable(True)


self._currentMessage = content
return



def getMessage(self):

# determine whether the user modified the data
if self._txtInput.isTextModified():
# reserialize the data
editabedbyte = self._txtInput.getText()
output = encrypt(self._extender,editabedbyte)
req = self._extender.helpers.analyzeRequest(editabedbyte)
output = EncryptRequest(self._extender,editabedbyte,req)
return output


Expand Down
194 changes: 31 additions & 163 deletions pycript/Responsetab.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from burp import IMessageEditorTab
from .decryption import Jsonvaluedecrypt,Customrequestdecrypt
from .encryption import Jsonvalueencrypt,Customrequestencrypt
import json
from .decryption import Parameterdecrypt
from .encryption import Parameterencrypt
from .response_handler import encrypt_decrypt_response


class ResponeCriptInputTab(IMessageEditorTab):
Expand All @@ -20,115 +20,50 @@ def getTabCaption(self):


def getUiComponent(self):

return self._txtInput.getComponent()



def isEnabled(self, content, isRequest):
if content and not isRequest:
if str(self._extender.selectedresponsetpye) == "None":
return False

elif str(self._extender.reqresponsecombobox.getSelectedItem()) == "Request":
return False

else:
request = self._extender.helpers.analyzeRequest(self.controller.getHttpService(),self.controller.getRequest())
self.currentresponse = self._extender.helpers.analyzeResponse(self.controller.getResponse())
self.statedminetype = self.currentresponse.getStatedMimeType()
self.getInferredMimeType = self.currentresponse.getInferredMimeType()

if self._extender.callbacks.isInScope(request.getUrl()):
if self.statedminetype == "JSON" or self.getInferredMimeType == "JSON":
return True
else:
return False
else:
if content is None or isRequest:
return False

if str(self._extender.selectedresponsetpye) == "None" or str(self._extender.reqresponsecombobox.getSelectedItem()) == "Request":
return False



return True





def setMessage(self, content, isRequest):

if content is None:
# clear our display

self._txtInput.setText(None)
self._txtInput.setEditable(False)

else:
if not isRequest:
self.currentresponse = self._extender.helpers.analyzeResponse(content)
self.selectedlang = self._extender.languagecombobox.getSelectedItem()
self.decryptionresponsepath = self._extender.responsedecryptionfilepath



self.bodyoffset = self.currentresponse.getBodyOffset()
self.currentresponsestring = self._extender.helpers.bytesToString(content)
self.bytebody = self.currentresponsestring[self.bodyoffset:len(self.currentresponsestring)]
self.stringbody = self._extender.helpers.bytesToString(self.bytebody).decode("utf-8")


if str(self._extender.selectedresponsetpye) == "Complete Body":

decryptedvalue = Jsonvaluedecrypt(self.selectedlang, self.decryptionresponsepath, self.stringbody)
output = self._extender.helpers.stringToBytes(decryptedvalue)
self._txtInput.setText(output)
self._txtInput.setEditable(True)


if str(self._extender.selectedresponsetpye) == "JSON Value":
if self.controller.getHttpService() is not None:
url = self._extender.helpers.analyzeRequest(self.controller.getHttpService(), self.controller.getRequest()).getUrl()
if self._extender.callbacks.isInScope(url):
self.currentresponse = self._extender.helpers.analyzeResponse(content)
output = encrypt_decrypt_response(self._extender,content,self.currentresponse,Parameterdecrypt,"Decrypt")
self._txtInput.setEditable(True)

else:
output = "URL is not added in Scope"
self._txtInput.setEditable(False)
else:
output = "HTTP Request Service Missing"
self._txtInput.setEditable(False)

json_object = json.loads(self.stringbody)
for key, value in json_object.items():
if isinstance(value, dict):
for inner_key, inner_value in value.items():
value[inner_key] = Jsonvaluedecrypt(self.selectedlang, self.decryptionresponsepath, inner_value)
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] = Jsonvaluedecrypt(self.selectedlang, self.decryptionresponsepath, inner_value)
else:
value[i] = Jsonvaluedecrypt(self.selectedlang, self.decryptionresponsepath, value[i])
else:
json_object[key] = Jsonvaluedecrypt(self.selectedlang, self.decryptionresponsepath, value)


output = self._extender.helpers.stringToBytes(json.dumps(json_object))
self._txtInput.setText(output)
self._txtInput.setEditable(True)
self._txtInput.setText(output)

if str(self._extender.selectedresponsetpye) == "JSON Key and Value":

json_object = json.loads(self.stringbody)

for key, value in json_object.items():
new_key = Jsonvaluedecrypt(self.selectedlang, self.decryptionresponsepath, key)
if isinstance(value, dict):
for inner_key, inner_value in value.items():
new_inner_key = Jsonvaluedecrypt(self.selectedlang, self.decryptionresponsepath, inner_key)
value[new_inner_key] = Jsonvaluedecrypt(self.selectedlang, self.decryptionresponsepath, inner_value)
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 = Jsonvaluedecrypt(self.selectedlang, self.decryptionresponsepath, inner_key)
value[i][new_inner_key] = Jsonvaluedecrypt(self.selectedlang, self.decryptionresponsepath, inner_value)
if inner_key != new_inner_key:
del value[i][inner_key]
else:
value[i] = Jsonvaluedecrypt(self.selectedlang, self.decryptionresponsepath, value[i])
else:
json_object[new_key] = Jsonvaluedecrypt(self.selectedlang, self.decryptionresponsepath, value)
if key != new_key:
del json_object[key]

output = self._extender.helpers.stringToBytes(json.dumps(json_object))
self._txtInput.setText(output)
self._txtInput.setEditable(True)


self._currentMessage = content
Expand All @@ -139,75 +74,8 @@ def getMessage(self):

if self._txtInput.isTextModified():
editabedbyte = self._txtInput.getText()
self.editedstring = self._extender.helpers.bytesToString(editabedbyte)
self.selectedlang = self._extender.languagecombobox.getSelectedItem()
self.encryptionresponsepath = self._extender.responseencryptionfilepath

self.currentresponse = self._extender.helpers.analyzeResponse(self._currentMessage)

self.header = self.currentresponse.getHeaders()





if str(self._extender.selectedresponsetpye) == "Complete Body":
encrypted = Jsonvalueencrypt(self.selectedlang, self.encryptionresponsepath, self.editedstring)
output = self._extender.helpers.stringToBytes(encrypted)
return self._extender.helpers.buildHttpMessage(self.header,output)

if str(self._extender.selectedresponsetpye) == "JSON Value":

json_object = json.loads(self.editedstring)

for key, value in json_object.items():
if isinstance(value, dict):
for inner_key, inner_value in value.items():
value[inner_key] = Jsonvalueencrypt(self.selectedlang, self.encryptionresponsepath, inner_value)
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] = Jsonvalueencrypt(self.selectedlang, self.encryptionresponsepath, inner_value)
else:
value[i] = Jsonvalueencrypt(self.selectedlang, self.encryptionresponsepath, value[i])
else:
json_object[key] = Jsonvalueencrypt(self.selectedlang, self.encryptionresponsepath, value)

output = self._extender.helpers.stringToBytes(json.dumps(json_object))
return self._extender.helpers.buildHttpMessage(self.header, output)


if str(self._extender.selectedresponsetpye) == "JSON Key and Value":
json_object = json.loads(self.editedstring)



for key, value in json_object.items():
new_key = Jsonvalueencrypt(self.selectedlang, self.encryptionresponsepath, key)
if isinstance(value, dict):
for inner_key, inner_value in value.items():
new_inner_key = Jsonvalueencrypt(self.selectedlang, self.encryptionresponsepath, inner_key)
value[new_inner_key] = Jsonvalueencrypt(self.selectedlang, self.encryptionresponsepath, inner_value)
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 = Jsonvalueencrypt(self.selectedlang, self.encryptionresponsepath, inner_key)
value[i][new_inner_key] = Jsonvalueencrypt(self.selectedlang, self.encryptionresponsepath, inner_value)
if inner_key != new_inner_key:
del value[i][inner_key]
else:
value[i] = Jsonvalueencrypt(self.selectedlang, self.encryptionresponsepath, value[i])
else:
json_object[new_key] = Jsonvalueencrypt(self.selectedlang, self.encryptionresponsepath, value)
if key != new_key:
del json_object[key]

output = self._extender.helpers.stringToBytes(json.dumps(json_object))
return self._extender.helpers.buildHttpMessage(self.header, output)
self.currentresponse = self._extender.helpers.analyzeResponse(editabedbyte)
return encrypt_decrypt_response(self._extender,editabedbyte,self.currentresponse,Parameterencrypt,"Encrypt")
else:
return self._currentMessage

Expand Down
4 changes: 4 additions & 0 deletions pycript/decoding.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from base64 import b64decode

def decode_base64(data):
return b64decode(data.encode('utf-8'))
Loading