Giter Club home page Giter Club logo

zeek-plugin-bacnet's Introduction

Zeek Plugin BACnet

When running as part of your Zeek installation this plugin will produce a bacnet.log file containing metadata extracted from any BACnet traffic observed on UDP port 47808.

Installation and Usage

zeek-plugin-bacnet is distributed as a Zeek package and is compatible with the zkg command line tool.

Sharing and Contributing

This code is made available under the BSD-3-Clause license. Guidelines for contributing are available as well as a pull request template. A Dockerfile has been included in the repository to assist with setting up an environment for testing any changes to the plugin.

Related Work

zeek-plugin-bacnet's People

Contributors

awelzel avatar ckreibich avatar jamesiri avatar nothinrandom avatar voteblake avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

zeek-plugin-bacnet's Issues

NPCI bit-combination 0x2C should be supported

The conditionals

            else if (control == 0x08 ||
                control == 0x0c ||
                control == 0x20 ||
                control == 0x24 ||
                control == 0x28
                ) {

and

                if (control == 0x28) {

and

                if (control == 0x20 ||
                    control == 0x24 ||
                    control == 0x28) {

are missing the bit-combination 0x2C. Bit 2 is merely the data_expecting_reply parameter. The code can generally parse all possible network layer messages irrespective of bit2.

BACnet with that capitalization is industry standard

I see in the output from

/usr/local/zeek/bin/zeek -N | grep -i net
Zeek::Login - Telnet/Rsh/Rlogin analyzers (built-in)
Zeek::NetBIOS - NetBIOS analyzer support (built-in)
Zeek::BACNET - Bacnet Protocol analyzer (dynamic, no version information)

that the module name is ALL-CAPS, and the description is Initial-Cap, but BACnet with precisely that capitalization, is the only usage which is industry standard.

Can not output data when there are multiple data (Read Property Multiple)

Hi,

When there are multiple data type in "Confirmed Service Request" and "Complex Acknowledge", this script can not output multiple data type (just output single data type).

In this case, there are three data type (i.e. analog-output, multi-state-output, analog-value). The output by this script is only "analog-output"
19080100_de71ae48-79d1-437d-a50d-b9042847892d_pcap

If this is a bug and you have time to fix it, I would appreciate it.

handling of optional content octets that follow the NPCI control octet

I had mentioned if (control & 0x80) { in
4f91d6a#commitcomment-42241394

but I should be more effusive, since that change cannot proceed in isolation to parse all the possible network layer messages. The code needs to relocate and revise
https://github.com/amzn/zeek-plugin-bacnet/blob/4f91d6a9fd1ec24b2e10216cbbab8081774d4686/scripts/main.zeek
lines 165-189 which are the handing of the various optional content octets that follow the NPCI control octet, and appear in network layer messages before the network_layer_message_type octet. Those statements need to be revised to perform not an exact comparison for equality, but instead bitmasking to decide based on bit5 and bit3. These can occur irrespective of the network_priority in bit1 and bit0. Additionally bit2 is an interesting case, and it is worth noting any combinations observed which are non-standard in using a bit2 polarity that contradicts the network_layer_message_type octet which follows. The parser can however, parse all possible network layer messages irrespective of bit2.

Identifier or enumerator value in enumerated type definition already exists

Hi. I'm running Zeek in a Debian container that parses pcap files.

After installing the bacnet plugin the follow error messages occur when a pcap is parsed:

error in /usr/local/zeek/share/zeek/site/packages/./zeek-plugin-bacnet/./main.zeek, line 12: identifier or enumerator value in enumerated type definition already exists
error in /usr/local/zeek/lib/zeek/plugins/packages/zeek-plugin-bacnet/scripts/./main.zeek, line 28: already defined (Bacnet::log_bacnet)
error in /usr/local/zeek/lib/zeek/plugins/packages/zeek-plugin-bacnet/scripts/./main.zeek, line 36 and /usr/local/zeek/share/zeek/site/packages/./zeek-plugin-bacnet/./main.zeek, line 37: already defined (Bacnet::ports)
error in /usr/local/zeek/lib/zeek/plugins/packages/zeek-plugin-bacnet/scripts/./main.zeek, line 46: already defined (Bacnet::bytes_to_count)
fatal error in error: BroType::AsFuncType (error/func) (error)

Any hints why this might be happening?
Thanks in advance.

Establish-Connection-To-Network message X'08' and Disconnect-Connection-To-Network message X'09'

Establish-Connection-To-Network message is indicated by a network_layer_message_type of X'08' followed by a 2-octet network number, then a 1-octet "Termination Time Value" in seconds, that the connection shall remain established in the absence of NPDUs being sent on this connection. A 1-octet value of 0 is permitted, which indicates that the connection should be considered to be relatively-permanent.

Disconnect-Connection-To-Network message is indicated by a network_layer_message_type of X'09' followed by a 2-octet network number.

Initialize-Router-Table message X'06' and Initialize-Router-Table-Ack message X'07'

Initialize-Router-Table message is indicated by a network_layer_message_type of X'06' followed by a "Number of Ports". Valid entries in this field are 0-255. Figure 6-11 specifies that Number of Ports is 1 octet. Nowhere in the prose of the standard, outside of Figure 6-11, specifies that Number of Ports is 1 octet, instead describing it as an unsigned integer. As you'll see in following paragraph, the possibility of an implementation sending a multi-octet "Number of Ports" is the least of things to worry about.

If an Initialize-Routing-Table message is sent with the Number of Ports equal to zero, the responding device shall return its complete routing table in an Initialize-Routing-Table-Ack message without updating its routing table. If an Initialize-Routing-Table message is sent with the Number of Ports greater than zero, then a routing table, an unlimited-length, standardized but extensible, content then follows. As you can immediately grasp (and gasp!) from reading that last sentence, the standards authors were awfully naive in 1995. If a router sends acknowledgment of having executed an Initialize-Routing-Table update message, which had a non-zero value in the Number of Ports field, it shall return an Initialize-Routing-Table-Ack without data.

Basically, Initialize-Routing-Table message sent with the Number of Ports equal to zero does see some utilization, for tools doing dynamic discovery of the routing topology. It is--even when performed legitimately--a strong indication of a perpetrator mapping the network, and should always be treated accordingly.

Initialize-Routing-Table message sent with the Number of Ports greater than zero might as well be called "Infect-Router-With-Payload" and should always be treated accordingly. A router which sends acknowledgment of an Initialize-Routing-Table update message, should be remarked with some amusement at the sense of humor of the virus-writer, since that packet was likely an attempt to root the router, and if it succeeds, then the router still bothering to send acknowledgment of the Initialize-Routing-Table update message, is execution of code which the hacker included.

Network Layer Message Types X'12': What-Is-Network-Number and X'13': Network-Number-Is

Clause 6.2.4 Network Layer Message Types X'12' and X'13' are seeing adoption. What seeing them should tell a protocol parser to do, is a subject worthy of its own ticket.

X'12': What-Is-Network-Number
X'13': Network-Number-Is

These two message types were invented during a transient period of BACnet history. In 2011, the original 1995 approach to cryptographic obfuscation of on-the-wire traffic which no one implemented, was "discarded" (in terms beyond even the typical BACnet renunciation of past mistakes, which are merely termed: "deprecated"), and a second transient period of BACnet history tried to specify another different cryptographic approach to obfuscation of on-the-wire traffic, which again no one implemented, and which too was then in 2019 "discarded".

But the two message types which had been invented during that transient 2011-2019 period were actually mandated in some devices, so a resigned capitulation to adding them as needless work became the path of least resistance. Every device which implements them is mandated to local broadcast emit one or the other on startup. Typically no one answers, and typically nodes do nothing with the payloads even if they do execute one or both messages. Sometimes an answer is indistinguishable from the mandated initial unilateral broadcast which occurs contemporaneously. They aren't important, as long as they appear in traffic only in this vestigial situation.

But they are either the most information-laden or very-close-to the most information-laden messages which a nefarious outsider could exploit. If they ever appear outside of the mandated initial unilateral broadcast, they are probably notice-worthy.

Error loading the plugin

Hi all,

When loading this plugin installed via zkg on source built Zeek, I get the following error when deploying via zeekctl
Duplicate &default attribute is ambiguous

The full output displays this on multiple lines of the plugin
error in /opt/zeek/share/zeek/site/packages/./zeek-plugin-bacnet/./consts.zeek, line 23: Duplicate &default attribute is ambiguous error in /opt/zeek/share/zeek/site/packages/./zeek-plugin-bacnet/./consts.zeek, line 41: Duplicate &default attribute is ambiguous error in /opt/zeek/share/zeek/site/packages/./zeek-plugin-bacnet/./consts.zeek, line 53: Duplicate &default attribute is ambiguous error in /opt/zeek/share/zeek/site/packages/./zeek-plugin-bacnet/./consts.zeek, line 88: Duplicate &default attribute is ambiguous error in /opt/zeek/share/zeek/site/packages/./zeek-plugin-bacnet/./consts.zeek, line 104: Duplicate &default attribute is ambiguous error in /opt/zeek/share/zeek/site/packages/./zeek-plugin-bacnet/./consts.zeek, line 115: Duplicate &default attribute is ambiguous error in /opt/zeek/share/zeek/site/packages/./zeek-plugin-bacnet/./consts.zeek, line 169: Duplicate &default attribute is ambiguous error in /opt/zeek/share/zeek/site/packages/./zeek-plugin-bacnet/./consts.zeek, line 543: Duplicate &default attribute is ambiguous error in /opt/zeek/share/zeek/site/packages/./zeek-plugin-bacnet/./consts.zeek, line 550: Duplicate &default attribute is ambiguous error in /opt/zeek/share/zeek/site/packages/./zeek-plugin-bacnet/./consts.zeek, line 556: Duplicate &default attribute is ambiguous error in /opt/zeek/share/zeek/site/packages/./zeek-plugin-bacnet/./consts.zeek, line 562: Duplicate &default attribute is ambiguous error in /opt/zeek/share/zeek/site/packages/./zeek-plugin-bacnet/./consts.zeek, line 570: Duplicate &default attribute is ambiguous error in /opt/zeek/share/zeek/site/packages/./zeek-plugin-bacnet/./consts.zeek, line 581: Duplicate &default attribute is ambiguous error in /opt/zeek/share/zeek/site/packages/./zeek-plugin-bacnet/./consts.zeek, line 607: Duplicate &default attribute is ambiguous error in /opt/zeek/share/zeek/site/packages/./zeek-plugin-bacnet/./consts.zeek, line 619: Duplicate &default attribute is ambiguous error in /opt/zeek/share/zeek/site/packages/./zeek-plugin-bacnet/./consts.zeek, line 762: Duplicate &default attribute is ambiguous error in /opt/zeek/share/zeek/site/packages/./zeek-plugin-bacnet/./consts.zeek, line 776: Duplicate &default attribute is ambiguous error in /opt/zeek/share/zeek/site/packages/./zeek-plugin-bacnet/./consts.zeek, line 792: Duplicate &default attribute is ambiguous error in /opt/zeek/share/zeek/site/packages/./zeek-plugin-bacnet/./consts.zeek, line 1894: Duplicate &default attribute is ambiguous

Any idea why this may be, or what I can do to get this to work properly?

EDIT - I'm actually seeing this on all of the plugins installed from the amzn repos

Data is empty (COV Notification)

Hi,

Outputs (bacnet.log) are "(empty)" even though data is contained. In this case, I think the data are "object=device" and "object=binary-input"
unconfirmedCOVNotification

The output is below by using scripts (I masked some data.).

xxxx       xxxx      xxxx   47808   xxxx   47808   Original Broadcast NPDU       37      Unconfirmed Service Request     COV Notification        (empty)

If this is a bug and you have time to fix it, I would appreciate it.

BACnet-Error-PDU treats content as an object-type and a property-identifier

The final portion object=Analog Input,property=File Size in this bacnet.log excerpt, for a ReadProperty to which an error is returned:

#path   bacnet
#open   2020-08-17-17-27-08
#fields ts      uid     id.orig_h       id.orig_p       id.resp_h       id.resp_p       bvlc_function   bvlc_len        apdu_type       service_choice  data
#types  time    string  addr    port    addr    port    string  count   string  string  vector[string]
1268366195.673739       Cy4KGo4hgYRs3svnF5      159.99.4.160    47808   159.99.3.158    47808   Original Unicast NPDU   20      Confirmed Service Request       Read Property   object=Device,property=Object List
1268366195.674361       Cy4KGo4hgYRs3svnF5      159.99.4.160    47808   159.99.3.158    47808   Original Unicast NPDU   13      Error   Read Property   object=Analog Input,property=File Size
#close  2020-08-17-17-27-08

is entirely an inaccurate decoding. Actually the BACnet-Error-PDU contains at those content-positions, after the BACnetConfirmedServiceChoice, an Error Class and an Error Code, both of which are Enumerated. There is no object-type and no property-identifier content in the BACnet-Error-PDU. Here is an illustrative excerpt from the standard where DeleteObject service was initiated, of the decoding of BACnet-Error-PDU:

X'50'			PDU Type=5 (BACnet-Error-PDU)
X'58'			Original Invoke ID=88
X'0B'			Error Choice=11 (DeleteObject)
X'91'			Application Tag 9 (Enumerated, L=1) (Error Class)
X'01'			1 (OBJECT)
X'91'			Application Tag 9 (Enumerated, L=1) (Error Code)
X'17'			23 (OBJECT_DELETION_NOT_PERMITTED)

when negative-ack is TRUE, representing BACnet-SegmentACK-PDU would be usefully diagnostic

When negative-ack is FALSE, which is the overwhelmingly frequent case, it is fine to output nothing, as code currently does. But when negative-ack is TRUE, representing that would be usefully diagnostic.

BACnet-SegmentACK-PDU ::= SEQUENCE {
	pdu-type		Unsigned (0..15), high 4 bits, thus 0x40, 41, 42 or 43 for this PDU type
	reserved		Unsigned (0..3), -- shall be set to zero
	negative-ack		BOOLEAN, -- bit1
	server			BOOLEAN, -- bit0
	original-invoke-id	Unsigned (0..255),
	sequence-number		Unsigned (0..255),
	reserved		Unsigned (0..1), -- highest bit shall be zero
	actual-window-size	Unsigned (1..127)

weird things at Network Layer

The loop construct in network_layer_message processing, for any observed amount of network_number content, is the proper way to capture what is in the actual packet. After provisioning for the 1-octet in Reject-Message-To-Network X'03' where 1-octet reason precedes network_number, odd-length in the remainder of the packet for many of the network_layer_message_types must indicate a malformed 1-octet network number.

There are some odd exceptions, however, as I-Could-Be-Router-To-Network message X'02' where after network number, there is a 1-octet "Performance Index". Establish-Connection-To-Network message X'08' where after network number, there is a 1-octet "Termination Time Value" in seconds. Network-Number-Is X'13' where after network number, there is a 1-octet flag, where a value of 1 indicates that the network number was "configured", and a value of 0 "learned".

Except for those, an odd-length in the remainder of the packet after the network_layer_message_type octet, is a malformed 1-octet final network number in the network_layer_message_types == X'00', X'01', X'04', X'05', plus X'09' and X'12'. And in the above odd exceptions conversely, even-length in the remainder of the packet after the network_layer_message_type octet, that too must indicate a malformed 1-octet network number, because the one odd 1-octet field is required.

In addition to a 1-octet network number being malformed, violations of the network_number content can occur due to presence/absence/count-limit violations. These should be noted:

if (network_layer_message_type == 0x00), the content can be zero or one network number (both situations are stipulated in the standard) and yet is still properly well-formed. if (network_layer_message_type == 0x01), the content can be one or more than one network number (both situations are stipulated in the standard) and yet is still properly well-formed. if (network_layer_message_type == 0x02) or the (network_layer_message_type == 0x03) or the (network_layer_message_type == 0x08) or the (network_layer_message_type == 0x09) or the (network_layer_message_type == 0x12) or the (network_layer_message_type == 0x13), the content is required to be exactly one network number to be properly well-formed. if (network_layer_message_type == 0x04) or the (network_layer_message_type == 0x05), the content can be any count (zero or more) network numbers (situations are stipulated in the standard) and yet is still properly well-formed.

Also Devices shall ignore Network-Number-Is and What-Is-Network-Number messages that contain any SNET/SADR or DNET/DADR information in the NPCI. Also Devices shall ignore Network-Number-Is that are sent with any unicast address. Protocol decoders are advised to highlight if these encodings are observed.

https://www.researchgate.net/profile/Steffen_Wendzel/publication/261550187_Towards_Suppressing_Attacks_on_and_Improving_Resilience_of_Building_Automation_Systems_-_an_Approach_Exemplified_Using_BACnet/links/00463534929aeb1ce1000000/Towards-Suppressing-Attacks-on-and-Improving-Resilience-of-Building-Automation-Systems-an-Approach-Exemplified-Using-BACnet.pdf?origin=publication_detail
also has in its section 5 entitled Traffic Normalization for BACnet, a litany of things that it says it will drop or normalize, which if observed in network traffic are definitely weird.

Reject-Message-To-Network single octet as uint8, then the network number parameters as uint16

Reject-Message-To-Network differs from the other Network Layer messages, that it has as its parameters first: a reject reason single octet as uint8. Then the network number parameters (each is uint16) until the UDP/BVLC-Length.

http://www.bacnet.org/Addenda/Add-135-2010ao.pdf page 5 documents the 7 defined values of the reject reason single octet. Don't worry about understanding code value 5: "source message was rejected due to a BACnet security error and that error cannot be forwarded to the source device. See Clause 24.12.1.1 for more details on the generation of Reject-Message-To-Network messages indicating this reason." The entirety of clause 24 has subsequently been removed from the standard.

six Network Layer messages should be implemented

There are six Network Layer messages:
X'00': Who-Is-Router-To-Network
X'01': I-Am-Router-To-Network
X'02': I-Could-Be-Router-To-Network
X'03': Reject-Message-To-Network
X'04': Router-Busy-To-Network
X'05': Router-Available-To-Network

which are in common use, and two more defined, which are deprecated:
X'06': Initialize-Routing-Table
X'07': Initialize-Routing-Table-Ack

These are at network level, thus below, so differently encoded from any APDU.

enumerated treatment beyond case 2: action, 25: limit enable, 107: segmentation support, 112: system status

Curious that current code has confined the Read-Property-Response enumerated treatment to solely:

                                        switch(property_identifier) {
                                            case 2: ##! action
                                                data[data_index] = fmt("value=%s", action[value]);
                                                break;
                                            case 25: ##! limit enable
                                                data[data_index] = fmt("value=%s", limit_enable[value]);
                                                break;
                                            case 107: ##! segmentation support
                                                data[data_index] = fmt("value=%s", segmentation_supports[value]);
                                                break;
                                            case 112: ##! system status
                                                data[data_index] = fmt("value=%s", system_statuses[value]);
                                                break;
                                            default:
                                                data[data_index] = fmt("value=%d", value);
                                                break;

Those are all good choices. But I wonder by what criteria those were selected, and why only those?

BVLC Layer 6 thru 8 messages should be implemented

In the bvlc_function layer atop UDP which your work identified and which zeek-plugin-bacnet has handled:
switch(bvlc_function) {
case 0x00: ##! BVLC_RESULT
case 0x05: ##! REGISTER_FOREIGN_DEVICE
case 0x01, ##! WRITE_BROADCAST_DISTRIBUTION_TABLE
0x02, ##! READ_BROADCAST_DISTRIBUTION_TABLE
0x03: ##! READ_BROADCAST_DISTRIBUTION_TABLE_ACK
case 0x04, ##! FORWARDED_NPDU
0x09, ##! DISTRIBUTE_BROADCAST_TO_NETWORK
0x0a, ##! ORIGINAL_UNICAST_NPDU
0x0b: ##! ORIGINAL_BROADCAST_NPDU

You have a comment there in the consts.zeek:
[5] = "Register Foreign Device",
##! 6-8 is not assigned for IPv4?
[9] = "Distribute Broadcast To Network",
but they are assigned, as follows:

BVLC Function: 1-octet X'06' Read-Foreign-Device-Table
BVLC Length: 2-octets X'0004' Length, in octets, of the BVLL message

BVLC Function: 1-octet X'07' Read-Foreign-Device-Table-Ack
BVLC Length: 2-octets L Length L, in octets, of the BVLL message
List of FDT Entries: N*10-octets

BVLC Function: 1-octet X'08' Delete-Foreign-Device-Table-Entry
BVLC Length: 2-octets X'000A' Length, in octets, of the BVLL message
FDT Entry: 6-octets

The standard in 135-2016 edition, starting advocating a new and different methodology to achieve those functions, but most of the installed base are older. These designate themselves using a network-visible Protocol_Revision and if that is 16 or less, then they are still implementations which will use the older method.

already defined (Bacnet::log_bacnet)

Hello, I'm running Zeek on Centos 8 installed as it's explained in https://www.ericooi.com/zeekurity-zen-part-i-how-to-install-zeek-on-centos-8/, so both zeek and zkg are owned by user zeek which has no root permisions.
After installing the plugin, I try to run Zeek with zeekctl deploy and I'm getting a bucnh of warnings and then this:

error in /opt/zeek/share/zeek/site/packages/./zeek-plugin-bacnet/./main.zeek, line 12: identifier or enumerator value in enumerated type definition already exists
error in /opt/zeek/lib/zeek/plugins/packages/zeek-plugin-bacnet/scripts/./main.zeek, line 28: already defined (Bacnet::log_bacnet)
error in /opt/zeek/lib/zeek/plugins/packages/zeek-plugin-bacnet/scripts/./main.zeek, line 36 and /opt/zeek/share/zeek/site/packages/./zeek-plugin-bacnet/./main.zeek, line 37: already defined (Bacnet::ports)
error in /opt/zeek/lib/zeek/plugins/packages/zeek-plugin-bacnet/scripts/./main.zeek, line 46: already defined (Bacnet::bytes_to_count)
fatal error in error: BroType::AsFuncType (error/func) (error)

It seems to be the same issue described here ( #5 ), but I can't handle to solve it.
The plugin is in path /opt/zeek/share/zeek/site/packages/zeek-plugin-bacnet/

By the way, i'm getting this output for find / -name zeek-plugin-bacnet

/home/zeek/.zkg/scratch/zeek-plugin-bacnet
/home/zeek/.zkg/clones/package/zeek-plugin-bacnet
/opt/zeek/share/zeek/site/packages/zeek-plugin-bacnet
/opt/zeek/share/zeek/site/zeek-plugin-bacnet
/opt/zeek/lib/zeek/plugins/packages/zeek-plugin-bacnet

That's my local.zeek

https://pastebin.com/reMwvL6x

Why is Zeek loading twice the plugin and how can I solve that?

Reject-Message-To-Network as 'Rorschach'

This ticket raises a conceptual enhancement entirely distinct from #12. Resolution there will successfully implement a loop construct as the proper way to capture what is in the actual packet (after provisioning for the 'reason' octet that is specified only in 0x03 and with proper handling for a potential malformed 1-octet final network number in all network_layer_message_types 0x00 through 0x05).

This 'Rorschach' additionally gives an excellent opportunity for our design to decide its architecture for something that goes beyond weirdness/malformed.

This discussion arises because there are six defined reasons, plus Other, as described in http://www.bacnet.org/Addenda/Add-135-2010ao.pdf

6.4.4 Reject-Message-To-Network
This message is indicated by a Message Type of X'03' followed by an octet indicating the reason for the rejection and a 2- octet network number (see Figure 6-7). It is directed to the node that originated the message being rejected, as indicated by the source address information in that message. The rejection reason octet shall contain an unsigned integer with one of the following values:
0: Other error.
1: The router is not directly connected to DNET and cannot find a router to DNET on any directly connected network using Who-Is-Router-To-Network messages.
2: The router is busy and unable to accept messages for the specified DNET at the present time.
3: It is an unknown network layer message type. The DNET returned in this case is a local matter. 
4: The message is too long to be routed to this DNET.
5. The source message was rejected due to a BACnet security error and that error cannot be forwarded to the source device. See Clause 24.12.1.1 for more details on the generation of Reject-Message-To-Network messages indicating this reason.
6. The source message was rejected due to errors in the addressing. The length of the DADR or SADR was determined to be invalid.

The rectilinearity of that table belies a very asymmetric tendency for implementations to emit those different 'reason' codes. Every quality BACnet router implementation has code that emits reason 1 and that emits reason 2. Those are respectively, the mechanism for dynamically updating router tables at run-time, and a mandate for throttling traffic rates to avoid router buffer exhaustion which would produce dropped packets.

In ordinary BACnet network traffic there will be Reject-Message-To-Network messages (message Type of X'03') followed by an octet indicating the reason 1, in any network traffic where there is a media or connectivity failure. In ordinary BACnet network traffic there will be Reject-Message-To-Network messages with reason 2, in any network traffic which spikes in volume to the point where a router needs to temporarily and proactively do the right thing to reduce packet dropping. But in ordinary BACnet network traffic there won't be Reject-Message-To-Network messages with the other described reasons. If one or more of those are ever observed, the reason is more likely pathological (or a genuine report of a deficient implementation) than benign. They are so rare that the things that might make a coder raise an accusation that the peer is a deficient implementation, are as likely to be a flaw in the reasoning of the accuser as they are to be an actual flaw in the implementation which sent the traffic that produced the accusation. That is why I term it 'Rorschach'. What one coder sees as a flaw in the sender, another coder might see as: "try things that might not work, with code as a fall-back triggering on the Reject response".

What seeing any of these could motivate a protocol parser and policy framework to decide to do, is a subject worthy of discussion and here I set a place to hold that discussion.

unsupported byte length for bytestring_to_count

Plugin is working, but when testing on internal PCAP's does emit an error for certain packets. This is not a critical error which prevents Zeek from continuing.

1218932832.035836 error in /opt/bro/lib/zeek/plugins/packages/zeek-bacnet/scripts/./main.zeek, line 153: unsupported byte length for bytestring_to_count (bytestring_to_count(Bacnet::rest_of_data[(coerce Bacnet::rest_of_data_index to int), (coerce Bacnet::rest_of_data_index + Bacnet::len to int)], F))

new unconfirmedServiceChoices who-Am-I (13), you-Are (14)

BACnetUnconfirmedServiceChoice ::= ENUMERATED {
...
who-Am-I (13), 
you-Are (14)

The packet structures are:

Who-Am-I-Request ::= SEQUENCE {
 vendorID Unsigned, 
 modelName CharacterString, 
 serialNumber CharacterString
}

You-Are-Request ::= SEQUENCE {
 vendorID Unsigned, 
 modelName CharacterString, 
 serialNumber CharacterString
 deviceIdentifier BACnetObjectIdentifier  OPTIONAL,
 deviceMACAddress OctetString OPTIONAL 
}

These are so new, in PROTOCOL REVISION 22 (currently the latest) as Addendum 135-2016bz , approved by ASHRAE and by the American National Standards Institute on November 18, 2019 that there hasn't been time for the industry to decide whether to embrace or ignore these. In some niche scenarios, I expect adoption. And for completeness (because they cause the equivalent of a DHCP operation) they merit coverage.

Add Vendor to Output

It would be useful to have the Vendor for a device included in the output, especially for networks with a diverse number of devices to help sort inter-device communication downstream.

vendor proprietary Network Layer Message if network_layer_message_type in the range X'80' - X'FF'

Vendor Proprietary Network Layer Message is specified if Bit 7 of the control octet is 1 and the network_layer_message_type octet contains a value in the range X'80' - X'FF'. For vendor proprietary Network Layer Messages, it is mandated that a Vendor_ID field appears after the network_layer_message_type as a two octet value, high octet first. The remaining UDP/BLVC/NPDU content that follows, if any, is vendor defined.

SNAP frame of BACnet/MSTP shows up in weird.log

SNAP frame of BACnet/MSTP is a little bit off the beaten path, but not so far off that it deserves to go in weird.log

#path   weird
#open   2020-08-17-20-24-08
#fields ts      uid     id.orig_h       id.orig_p       id.resp_h       id.resp_p       name    addl    notice  peer
#types  time    string  addr    port    addr    port    string  string  bool    string
0.000000        -       -       -       -       -       non_ip_packet_in_ethernet       -       F       zeek
#close  2020-08-17-20-24-08

BACnet-Reject-PDU and BACnet-Abort-PDU to be supported

BACnet-Reject-PDU ::= SEQUENCE {
 	pdu-type 		Unsigned (0..15), -- high four bits, 0x60 for this PDU type
 	reserved 			Unsigned (0..15), -- low four bits, always 0 for this PDU type
 	original-invokeID 	Unsigned (0..255), -- matching what was in the ConfirmedRequest to which this is response
 	reject-reason 		One octet containing the BACnetRejectReason

and the BACnetRejectReason enumerated is:{
other (0),
buffer-overflow (1),
inconsistent-parameters (2),
invalid-parameter-data-type (3),
invalid-tag (4),
missing-required-parameter (5),
parameter-out-of-range (6),
too-many-arguments (7),
undefined-enumeration (8),
unrecognized-service (9),

BACnet-Abort-PDU ::= SEQUENCE {
	pdu-type		Unsigned (0..15), -- high 4 bits, thus 0x70 or 0x71 for this PDU type
	server			Unsigned (0..15) -- BOOLEAN 0 == FALSE, 1 == TRUE,
	original-invoke-id	Unsigned (0..255), -- matching what was in the ConfirmedRequest to which this is response
	abort-reason		One octet containing the BACnetAbortReason

and the BACnetAbortReason enumerated is: {
other (0),
buffer-overflow (1),
invalid-apdu-in-this-state (2),
preempted-by-higher-priority-task (3),
segmentation-not-supported (4),
security-error (5),
insufficient-security (6),
window-size-out-of-range (7),
application-exceeded-reply-time (8),
out-of-resources (9),
tsm-timeout (10),
apdu-too-long (11),

Note that unlike the BACnet-Error-PDU, in these two the ServiceChoice is not present.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.