[WIP] WebSocket active scan infrastructure
This pull request its part of WebSocket Active Scan project which described in issue #4276.
[WS-Active-Scan] WebSocket active scan infrastructure
(on early stage yet)
This commit introduces a new active scanner feature on WebSocket add-on. The WebSocket scanner infrastructure based on WebSocket Treemap and Structure analyzer which are introduced in zaproxy/zap-extensions #1742.
Short Intro
WebSocket Protocol comes with many differences in reference to Http protocol. The most common one is the format of the messages/payloads. In contrast with HTTP, WebSocket protocol does not define the specific format of the messages will be transmitted over the TCP connection. That means at the same connection may be transferred messages with a different format. In addition, WebSocket protocol keeps the TCP connection opened in order to offer us a full duplex client/server communication in contrast with the classic request/response technique. Those are the most challenging parts which are tried to overcome by this PR. In any other case, this implementation attempts to emulate the existing HTTP active scanner.
The concept
There as some utility classes which are managed the whole scanning process.
-
WebSocketActiveScanManager: The class which manage the scans and links the active scanner with the rest functionality of WebSocket Add-on. This class can be used in order to add a newWebSocketActivePlugin(Explained above) and start a new Active Scan. Note: The scan will not run if there is another scan was already running. -
WebSocketPluginFactory: Used for storing and loading plugins. -
WebSocketTarget: Stores the basic information about the active scan targets. -
WebSocketScanner: Implements the runnable class. This class is responsible to separate the targets onto different host process (if there are more than two). That could be happened when the user selects to scan all nodes under the root. In addition, if there are available threadsWebSocketScannercan create different tasks for those different hosts in order to run scans in parallel. Finally, If the user selects a leaf node (ex.MessageNode) theWebSocketScannerwill create a new HostProcess in order to handle the communication with the server. -
WebSocketHostProcess: The host process represents a scan on a specific host. It has to distribute the targets over the appropriate plugins. In addition,WebSocketHostProcessoffers to the plugins some basic utilities. Those utilities help plugins to establish a new WebSocket Connection, send messages, receive the response messages from the appropriate channel etc. I should note that every plugin has to open a new channel, so every time a new message received the WebSocketHostProcess be able to inform the appropriate plugin. TheWebSocketScannerhas many host process (which could be running on a different thread).
All those classes aim to support the scanning plugins. Every plugin have to test the application (either on server site or client site) in order to find a set of vulnerabilities. To simplify the whole process I create some abstracts class (as the HTTP active scanner does). In order to write a new plugin, we should extend the following classes. An important note: The plugins are categorized in such a way in order to test the different "parts" of the WebSocket Connection. This means that a plugin must scan some specific node's type. That depends on the class you extend. Finally, the target is defined by "user" (either from UI or API). Target could be either recursive or not. The target (which reached to the plugin) could be any available (except folder) under the HostFolder. The WebSocketActivePlugin is the class which is responsible to iterate over the nodes.
-
WebSocketActivePlugin: This is the superclass of all plugin. You typically will not extend this class directly but provides key methods that you will need to use and abstract methods that will need to be implemented. (exactly asAbstractPlugin).WebSocketActivePluginiterates over the targets, "ask" the scanner if it is interested to scan this target (byapplyScanmethod) and then gives them the target to scan it. Implementboolean applyScan(StructuralWebSocketNode structuralWebSocketNode)in order to choose which nodes you to apply scan andvoid canNode(StructuralWebSocketNode structuralWebSocketNode)to scan it. It is able to apply scans on nodes: {HANDSHAKE,MESSAGE_OBJECT,MESSAGE_TEXT} -
WebSocketActiveHandshakeScan: Extend this class in order to perform some tests on the handshake process. Implementboolean applyScanToHandshake(HttpMessage handshake)in order to choose which handshakes you want to scan. And of course, implementscanHandshake(HttpMessage handshake)in order to scan the handshake.WebSocketActivePluginis able to apply scans on nodes with type: {HANDSHAKE} -
WebSocketMessageNodeScan: Extend this class in order to perform scans on nodes.WebSocketMessageNodesstores theWebSocketMessages,PayloadAnalyzers,PayloadStructureetc. Implementboolean applyScan(WebSocketMessageNode messageNode)in order to choose in which nodes you want to apply your scan andvoid scanMessageNode(WebSocketMessageNode messageNode)to scan it. It is able to apply scans on nodes with type: {MESSAGE_OBJECT,MESSAGE_TEXT} -
WebSocketMessageDTOScan: Extend this class in order to perform a scan on Messages. Implementboolean applyScan(WebSocketMessageDTO message)in order to choose in which Messages you want to apply your scan andscanMessage(WebSocketMessageDTO message)to scan it. It is able to apply scans on nodes with type: {MESSAGE_OBJECT,MESSAGE_TEXT} -
WebSocketPayloadScan: Extend this class in order to perform scans on Payloads. Implementboolean applyScan(Object message)in order to choose in which andscanPayload(Object message)to scan it. It is able to apply scans on nodes: {MESSAGE_OBJECT,MESSAGE_TEXT} -
WebSocketStructureScan: Extend this class in order to perform scans on Paylaod Structure. This scan based on Payload Structure which introduced on zaproxy/ zap-extensions #1742. Payload structure exported fromPayloadAnalyzers. Those interfaces aim to analyze the WebSocket message in a structural format (expressed as a data structure). You can implement those in order to adjust it in your test case. The basic idea behind that is to create a formal structure in order to iterate over the different parameter (keys and values). If your messages can be mapped in aPayloadStructureyou can use it to scan different parameters and create your own attacks vectors with analyzers. (In an abstract wayPayloadAnalyzershas the role to deserialize/serialize the payloads). Implementboolean applyScan(PayloadAnalyzer analyzer, PayloadStructure structure)in order to choose in which andscanMessageStructure(PayloadAnalyzer analyzer, PayloadStructure structure)to scan it.PayloadAnalyzerandPayloadStructureshould not be null. It is able to apply scans on nodes with type: {MESSAGE_OBJECT,MESSAGE_TEXT} -
WebSocketMessageParamScan: Extend this class in order to perform scans on parameters. This plugin scanning a target parameter by parameter.PayloadAnalyzerandPayloadStructureshould not be null. It is able to apply scans on nodes with type: {MESSAGE_OBJECT,MESSAGE_TEXT}.
All Plugins have to implement and the following methods:
-
void messageReceived(WebSocketMessageDTO message): Notify the plugin that a new message received over the channel -
void connectionStateChanged(WebSocketProxy.State state, WebSocketProxy proxy):State of connection changed -
String getName()Return the name of the plugin -
int getCode()returns the unique ID of the plugin
Plugins
-
ScriptWebSocketMessageActivePlugin: This class extends WebSocketMessageNodeScan and uses the ExtensionScript. Calls the script is written by the user. Implement in your script the WebSocket ActiveMessageScript interface in order to create an active scan. -
WebSocketActiveMessageScript: Should be implemented by active scan scripts- [Optional]
boolean applyScan(WebSocketMessageNode webSocketMessageNode)return true by default -
scan(WebSocketMessageNode webSocketMessageNode, ScriptWebSocketMessageActivePlugin parent); -
void messageReceived(WebSocketMessageDTO message) - [Optional]
void connectionStateChanged(WebSocketProxy.State state)
- [Optional]
-
WebsocketActiveScanTemplate.js is a template script
User Interface
Gives the ability to user to select the starting node.
Issues
- [ ] Address the concurrency issues
- [ ] ....
TODO
- [ ] Clean up the code
- [ ] Add documentation
- [ ] ...
(Not ready for code Review yet)
This pull request introduces 9 alerts when merging 9da329a6057d94debfffee336f445daa7aabbfc3 into b33ac46d6bb7db10ed20d53a51ff48dd8d3010de - view on LGTM.com
new alerts:
- 2 for Equals on incomparable types
- 2 for Implicit conversion from array to string
- 1 for Container contents are never accessed
- 1 for Inconsistent equals and hashCode
- 1 for Type mismatch on container modification
- 1 for Reference equality test of boxed types
- 1 for Dereferenced variable may be null
Comment posted by LGTM.com
This pull request introduces 9 alerts when merging 9da329a6057d94debfffee336f445daa7aabbfc3 into de4537e305d018e8a185c0b7feb5f87576f021c9 - view on LGTM.com
new alerts:
- 2 for Equals on incomparable types
- 2 for Implicit conversion from array to string
- 1 for Container contents are never accessed
- 1 for Inconsistent equals and hashCode
- 1 for Type mismatch on container modification
- 1 for Reference equality test of boxed types
- 1 for Dereferenced variable may be null
Comment posted by LGTM.com
This pull request introduces 9 alerts when merging 4ec16be53b694cac55a7019c6b6ddf2be0eb74be into 0ceff13117188accffd473b5c36075b6d79ef55a - view on LGTM.com
new alerts:
- 2 for Equals on incomparable types
- 2 for Implicit conversion from array to string
- 1 for Container contents are never accessed
- 1 for Inconsistent equals and hashCode
- 1 for Type mismatch on container modification
- 1 for Reference equality test of boxed types
- 1 for Dereferenced variable may be null
Comment posted by LGTM.com
Conflicts Resolved, and branch rebased on latest change of #1742
This pull request introduces 4 alerts when merging 99a97ca3d1d1e68e0d517dda9e99a906ba1c2042 into 0ceff13117188accffd473b5c36075b6d79ef55a - view on LGTM.com
new alerts:
- 1 for Container contents are never accessed
- 1 for Equals on incomparable types
- 1 for Type mismatch on container modification
- 1 for Expression always evaluates to the same value
Comment posted by LGTM.com
The pull request is now updated (after build changes, zaproxy/zaproxy#5302).
This pull request introduces 3 alerts when merging 7e43047bb703cfc57bbb6cf1e6d5a96d08591aa5 into a2b44c5ce80cfd0e8b2031606dead1ba836c943e - view on LGTM.com
new alerts:
- 1 for Equals on incomparable types
- 1 for Type mismatch on container modification
- 1 for Expression always evaluates to the same value
Comment posted by LGTM.com