zeek / spicy-analyzers

Growing collection of Spicy-based protocol and file analyzers for Zeek
Other
32 stars 9 forks source link

Integration of OPC UA grammar #79

Closed ckmk14 closed 3 years ago

ckmk14 commented 3 years ago

Hi all,

have created an OPC UA (over TCP) spicy grammar and now tried to integrate it into zeek. Unfortunately, the integration does not work. I have a dummy grammar and some pcaps to illustrate the problems:

opcua.spicy:

module OPCUA;
public type Packet = unit {    
    payload: bytes &size=3;
    on %done { print self; }
};

opcua.evt:

protocol analyzer spicy::OPCUA over TCP:
    parse with OPCUA::Packet,
    port 4840/tcp;

These are the commands for compiling and testing (t1.pcapng compressed as zip: t1 compressed.zip): spicyz -o opcua.hlto opcua.spicy opcua.evt zeek -B dpd -Cr t1.pcapng opcua.hlto Spicy::enable_print=T

This is the output from the last command

[$payload=b"HEL"]
[$payload=b"ACK"]

It looks like every OPC UA message after the acknowledge message is not parsed. The debug view shows that it is probably not working because zeek is not forwarding the data (cat debug.log | grep OPCUA):

[dpd] Registering analyzer SPICY_OPCUA for port 4840/1
[dpd]     spicy_OPCUA (enabled)
[dpd]     4840/tcp: SPICY_OPCUA 
[dpd] TCP[1] added child SPICY_OPCUA[3]
[dpd] 127.0.0.1:58410 > 127.0.0.1:4840 activated SPICY_OPCUA analyzer due to port 4840
[dpd] SPICY_OPCUA[3] DeliverStream(56, T) [HELF8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x01\x88\x13\x00\x00\x18\x00\x00\x00opc.tcp:...]
[dpd] SPICY_OPCUA[3] DeliverStream(28, F) [ACKF\x1c\x00\x00\x00\x00\x00\x00\x00\xff\xff\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00]
 dpd] SPICY_OPCUA[3] EndOfData(T)
[dpd] SPICY_OPCUA[3] EndOfData(F)

Unfortunaly, with another pcap it looks like zeek is forwarding the data but spicy is not parsing them Second PCAP and Debug.log.zip

Can anyone help me here?

Thanks, Markus

bbannier commented 3 years ago

What you are seeing here is that a single packet is parsed on they each side of the connection (HEL going to the one way, ACK coming back). This is because in your grammar a Packet parses a single message.

To instead parse all messages going back and forth over a TCP connection you need to adjust your grammar to accept multiple messages, e.g.,

# opcua.spicy

module OPCUA;
type Packet = unit {    
    payload: bytes &size=3;
    on %done { print self; }
};

public type Packets = unit {
    packets: Packet[] &eod;
};
# opcua.evt
protocol analyzer spicy::OPCUA over TCP:
    parse with OPCUA::Packets,
    port 4840/tcp;

See e.g., the HTTP analyzer in zeek/spicy-analyzers for an example of how other TCP analyzers do this.

bbannier commented 3 years ago

FTR, a documentation of the OPC UA binary format can be found here.

ckmk14 commented 3 years ago

Damn how stupid ... thanks a ton! I was developing the grammar using single opcua chunks for each opcu service type via spicy-driver. Therefore, I missed the (very important :D) fact about streams...