Friday, December 1, 2017

Bro and Spicy for WebSockets Network Analysis, Part 2

In Part 1,  I covered the WebSockets protocol basics and the Spicy script I wrote to parse it. Here I'll cover some of the Bro scripts I wrote to use the parsed protocol.

Types of scripts and their roles in the process

The Plugin:

Using Spicy with Bro to produce WebSockets data in Bro logs involves installing the Spicy/Bro plug-in to add support for Spicy grammars to Bro. For instructions on installing the plugin, see http://www.icir.org/hilti/spicy/bro/index.html.
Once the plugin is installed, the process requires four different types of scripts. These four types are the Bro signature script (*.sig), the Spicy parsing script (*.spicy), the Bro protocol analyzer definition script (*.evt), and the Bro logging script (*.bro) (Sommer, 2016).


*.sig

The Bro signature script (*.sig) can be used to activate a protocol analyzer via a signature instead of relying on the port the traffic is using. The file will define the signature by the IP protocol (TCP or UDP), a key identifying factor of the payload (such as a regular expression), and if it is the traffic originator or responder (optional). It then specifies which protocol analyzer to enable.
I actually had trouble getting the *.sig piece to work without specifying the ports to watch. At some point I will need to go back and figure this out.


*.spicy

The Spicy script (*.spicy) is used to automatically generate the protocol parser at runtime by the Spicy framework. The parser performs its actions on the data coming in from the wire just after Bro parses the lower layers including the TCP header.


*.evt

The Bro protocol analyzer definition script (*.evt) provides the interface between Bro and the Spicy script. It specifies the grammar file that contains the Spicy script and where to hook into Bro’s traffic processing. It then defines the Bro events to create based on the parsed data.


*.bro

The Bro logging scripts (*.bro) are where an analyst can customize what information will be logged. Logs can provide protocol information about each connection, such as logging the WebSockets opcode, masking key, and payload length, or can be narrowed down to provide precise data in the WebSockets payload.


ws_handshake.evt 

This script defines significant events within the WebSockets communication. The events are triggered when a particular unit gets parsed in the Spicy script and events can pass along information about the connection. The ws_handshake.evt script defines events for:

  • when a WebSockets handshake is requested, 
  • when a WebSockets handshake receives a successful response, 
  • and when WebSockets messages are detected. 

The message events provide different information when the WebSockets data is masked, when the data is not masked, and when there is no data.


ws_handshake.bro 

This script takes the WebSockets connection parsed by the Spicy script and focuses on exposing the WebSockets protocol fields and payload data. The messages are separated into three different types:

  • masked (from the client), 
  • unmasked (from the server), 
  • and no data (control messages from either host) for processing within the script, 

but all three log to the same file. The log file contains connection information:
the unique identifier, the client IP address, the server IP address, and the server port 

The entire connection record is passed to the events used in this script so that any connection field could be logged. The file also contains WebSockets information (OpCode, mask key, and payload data).
Since it was not possible to unmask the client data within Spicy, it needed to be done in Bro. Unfortunately, although Bro does have the looping capability that Spicy does not have, Bro does not have the XOR functionality. Github user JustBeck wrote an elegant solution to this same problem with his bintools.bro module (2013). His module is simply a complete lookup table for each hex byte and its corresponding XOR byte. His module was used for this research so that the masked data could be unmasked and evaluated further. As it is, the ws_message.bro Bro script and resulting log file would be inefficient and unnecessary in production but was extremely useful for testing the parser and visualizing the data.


ws_messagenotnormal.bro 

This script demonstrates logging unexpected server responses in WebSockets data. With knowledge of the application being monitored, a regular expression was created that matches only expected responses. After a WebSockets message event is triggered, this Bro script uses the URI field from the connection and its corresponding regular expression to determine if the actual response is expected. If not, it creates a log entry. This technique was used with the DVWS Command Execution, Reflected XSS, and Error Based SQL Injection pages.

The ws_messagenotnormal.bro script also evaluates the request from the client for malicious content. It reviews input to the Error Based SQL Injection and Blind SQL injection pages attempting to identify SQL injection. It scores the message based on the number of SQL keywords it matches in the data. If the maximum threshold is surpassed, a log entry is created. The same technique is used with the Stored XSS page creating the score based on HTML keywords found in the input.