Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
20 changes: 20 additions & 0 deletions src/main/java/com/pycript/ui/ConfigTab.java
Original file line number Diff line number Diff line change
Expand Up @@ -778,6 +778,26 @@ private JLayeredPane createAdditionalSettingsPane()
JButton selectLanguageButton = new JButton("Select Language Binary Path");
JButton clearLanguageButton = new JButton("Clear Language Selected");

selectLanguageButton.addActionListener(e -> {
JFileChooser fileChooser = new JFileChooser();
fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
fileChooser.setDialogTitle("Select Language Binary");
int userSelection = fileChooser.showDialog(null, "Select");
if (userSelection == JFileChooser.APPROVE_OPTION) {
File selectedFile = fileChooser.getSelectedFile();
if (selectedFile != null) {
String filePath = selectedFile.getAbsolutePath();
languageTextField.setText(filePath);
api.persistence().preferences().setString("pycript.language.path", filePath);
}
}
});

clearLanguageButton.addActionListener(e -> {
languageTextField.setText("");
api.persistence().preferences().setString("pycript.language.path", "");
});

JLabel methodLabel = new JLabel("Encryption Decryption Method");
methodLabel.setFont(new java.awt.Font("Segoe UI", java.awt.Font.BOLD, 12));
methodLabel.setForeground(new Color(0xFF, 0x66, 0x33));
Expand Down
29 changes: 29 additions & 0 deletions src/main/java/com/pycript/ui/ResourceTab.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,35 @@ private String getHTMLContent()
<body>
<h1 style="color: rgb(237, 121, 5)">Documentation for PyCript</h1>

<h2>Getting Started</h2>
<h3>Select Encryption and Decryption Files</h3>
<ul>
<li>PyCript expects you to provide encryption and decryption files as per your application requirements</li>
<li>You can write encryption/decryption code in any language: Bash, PowerShell, C, Python, JavaScript, etc.</li>
<li>PyCript expects the code in a specific format. Get example scripts from <a href="https://github.com/Anof-cyber/PyCript-Template">PyCript Template Repository</a></li>
<li>For custom code documentation, visit <a href="https://pycript.souravkalal.tech/latest/Scripts/">Writing Custom Scripts</a></li>
</ul>

<h3>Configure Language Binary</h3>
<ul>
<li>For interpreted languages (Python, Node.js, Ruby, etc.), provide the interpreter path (e.g., C:\\python\\python.exe, /usr/bin/node)</li>
<li>For compiled binaries (EXE, C, C#, Go, etc.), keep the language path empty</li>
<li>For shell scripts (Bash, PowerShell), provide the shell path or keep empty if executable directly</li>
</ul>

<h3>Select Request/Response Type</h3>
<ul>
<li><strong>Complete Body:</strong> Use when your encryption/decryption script handles the full raw request body and headers. PyCript will not parse any parameters. Useful when the whole body is encrypted</li>
<li><strong>Parameter Value:</strong> Extension will handle parsing of parameters from the request body or URL and send only values to your script. Useful when only parameter values are encrypted (e.g., JSON body)</li>
<li><strong>Parameter Key and Value:</strong> Extension will handle parsing of parameters and send both keys and values to your script when both are encrypted in the request</li>
</ul>

<h3>Debug and Monitor</h3>
<ul>
<li>Use the <strong>Log</strong> tab to see how the extension runs your encryption/decryption script</li>
<li>View the command executed, script output, and any errors from your script</li>
</ul>

<h2>Articles</h2>
<ul>
<li><a href="https://medium.com/bugbountywriteup/manipulating-encrypted-traffic-using-pycript-b637612528bb">Manipulating Encrypted Traffic using PyCript</a></li>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,14 @@ public class WebSocketMessageEditor implements ExtensionProvidedWebSocketMessage
{
private final RawEditor editor;
private final MontoyaApi api;
private final boolean isReadOnly;

public WebSocketMessageEditor(MontoyaApi api, EditorCreationContext creationContext)
{
this.api = api;
this.isReadOnly = creationContext.editorMode() == EditorMode.READ_ONLY;

if (creationContext.editorMode() == EditorMode.READ_ONLY)
if (isReadOnly)
{
editor = api.userInterface().createRawEditor(EditorOptions.READ_ONLY);
}
Expand Down Expand Up @@ -58,14 +60,15 @@ public ByteArray getMessage() {

@Override
public void setMessage(WebSocketMessage message) {
// Check if the WebSocket upgrade request is in scope
if (message.upgradeRequest() == null || !api.scope().isInScope(message.upgradeRequest().url())) {
editor.setEditable(false);
editor.setContents(ByteArray.byteArray(api.utilities().byteUtils().convertFromString("WebSocket is out of scope")));
return;
}

editor.setEditable(true);
if (!isReadOnly) {
editor.setEditable(true);
}

if (!ConfigTab.webSocketEnabled || ConfigTab.webSocketDecryptionFile == null || ConfigTab.webSocketDecryptionFile.isBlank()) {
editor.setContents(message.payload());
Expand Down
Loading