cisagov / icsnpp-bacnet

Zeek BACnet Parser - CISA ICSNPP
BSD 3-Clause "New" or "Revised" License
15 stars 11 forks source link

"Aborted (core dumped)" - terminate called after throwing an instance of 'std::length_error' #43

Open mmguero opened 5 months ago

mmguero commented 5 months ago

zeek version 6.2.1 in Docker on Debian 12, with downloaded official Zeek .deb packages. Note that these are compiled with GCC (as are the plugins installed in the docker image), and I have not yet confirmed that the bug happens when compiled with clang, so if you are using some other docker images to test you may not encounter the bug. I'm reproducing it with this PCAP.

$ docker pull ghcr.io/idaholab/malcolm/zeek:24.05.0
24.05.0: Pulling from idaholab/malcolm/zeek
Digest: sha256:0535f62d0fa59d8e44cc9b251742bf33bc9b494d0e1f7ce0def0ce2783b8edb5
Status: Image is up to date for ghcr.io/idaholab/malcolm/zeek:24.05.0
ghcr.io/idaholab/malcolm/zeek:24.05.0

$ docker run -Pit --rm --entrypoint=/bin/bash ghcr.io/idaholab/malcolm/zeek:24.05.0

root@bf4c61d245d2:/# mkdir -p /tmp/logs/bacnet
root@bf4c61d245d2:/# cd /tmp/logs/bacnet
root@bf4c61d245d2:/tmp/logs/bacnet# curl -fsSLOJ 'https://github.com/mmguero-dev/Malcolm-PCAP/raw/main/pcaps/BACnet.pcap'
root@bf4c61d245d2:/tmp/logs/bacnet# ls -l
total 41540
-rw-r--r-- 1 root root 42533652 Jun 10 15:49 BACnet.pcap

root@bf4c61d245d2:/tmp/logs/bacnet# apt-get update && apt-get -y --no-install-recommends install gdb
...
Setting up gdb (13.1-3) ...
Processing triggers for libc-bin (2.36-9+deb12u7) ...

root@bf4c61d245d2:/tmp/logs/bacnet# gdb --args zeek-offline -C -r BACnet.pcap local
GNU gdb (Debian 13.1-3) 13.1
...
Reading symbols from zeek-offline...
(No debugging symbols found in zeek-offline)
(gdb) r
Starting program: /opt/zeek/bin/zeek-offline -C -r BACnet.pcap local
...
[New Thread 0x7f62e77fe6c0 (LWP 439)]
1614578546.628877 error: string with embedded NUL: "4.0\x00"

Thread 1 "zeek-offline" received signal SIGSEGV, Segmentation fault.
0x00007f633d371800 in ?? () from /lib/x86_64-linux-gnu/libc.so.6

(gdb) bt
#0  0x00007f633d371800 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#1  0x00007f633d141633 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_append(char const*, unsigned long) ()
   from /lib/x86_64-linux-gnu/libstdc++.so.6
#2  0x00007f633a7e978b in binpac::BACNET::parse_tag[abi:cxx11](unsigned char, unsigned char, binpac::const_datastring<unsigned char>, unsigned int, unsigned int) ()
   from /opt/zeek/lib/zeek/plugins/packages/icsnpp-bacnet//lib/ICSNPP-Bacnet.linux-x86_64.so
#3  0x00007f633a7ea354 in binpac::BACNET::BACNET_Flow::process_read_property_multiple_ack(bool, unsigned char, std::vector<binpac::BACNET::BACnet_Tag*, std::allocator<binpac::BACNET::BACnet_Tag*> >*) () from /opt/zeek/lib/zeek/plugins/packages/icsnpp-bacnet//lib/ICSNPP-Bacnet.linux-x86_64.so
#4  0x00007f633a7eb971 in binpac::BACNET::Complex_ACK_PDU::Parse(unsigned char const*, unsigned char const*, binpac::BACNET::ContextBACNET*) ()
   from /opt/zeek/lib/zeek/plugins/packages/icsnpp-bacnet//lib/ICSNPP-Bacnet.linux-x86_64.so
#5  0x00007f633a7ebbed in binpac::BACNET::APDU_Header::Parse(unsigned char const*, unsigned char const*, binpac::BACNET::ContextBACNET*, int) ()
   from /opt/zeek/lib/zeek/plugins/packages/icsnpp-bacnet//lib/ICSNPP-Bacnet.linux-x86_64.so
#6  0x00007f633a7ebe17 in binpac::BACNET::NPDU_Header::Parse(unsigned char const*, unsigned char const*, binpac::BACNET::ContextBACNET*, int) ()
   from /opt/zeek/lib/zeek/plugins/packages/icsnpp-bacnet//lib/ICSNPP-Bacnet.linux-x86_64.so
#7  0x00007f633a7ec4d4 in binpac::BACNET::BVLC_Header::Parse(unsigned char const*, unsigned char const*, binpac::BACNET::ContextBACNET*, int) ()
   from /opt/zeek/lib/zeek/plugins/packages/icsnpp-bacnet//lib/ICSNPP-Bacnet.linux-x86_64.so
#8  0x00007f633a7ec642 in binpac::BACNET::BACNET_Flow::NewData(unsigned char const*, unsigned char const*) ()
   from /opt/zeek/lib/zeek/plugins/packages/icsnpp-bacnet//lib/ICSNPP-Bacnet.linux-x86_64.so
#9  0x00007f633a7eda3e in analyzer::BACNET::BACNET_Analyzer::DeliverPacket(int, unsigned char const*, bool, unsigned long, zeek::IP_Hdr const*, int) ()
   from /opt/zeek/lib/zeek/plugins/packages/icsnpp-bacnet//lib/ICSNPP-Bacnet.linux-x86_64.so
#10 0x00005638b65f3eea in zeek::analyzer::Analyzer::NextPacket(int, unsigned char const*, bool, unsigned long, zeek::IP_Hdr const*, int) ()
#11 0x00005638b65f411e in zeek::analyzer::Analyzer::ForwardPacket(int, unsigned char const*, bool, unsigned long, zeek::IP_Hdr const*, int) ()
#12 0x00005638b6924130 in zeek::packet_analysis::UDP::UDPAnalyzer::DeliverPacket(zeek::Connection*, double, bool, int, zeek::Packet*) ()
#13 0x00005638b6922013 in zeek::packet_analysis::IP::IPBasedAnalyzer::AnalyzePacket(unsigned long, unsigned char const*, zeek::Packet*) ()
#14 0x00005638b691f343 in zeek::packet_analysis::IP::IPAnalyzer::AnalyzePacket(unsigned long, unsigned char const*, zeek::Packet*) ()
#15 0x00005638b68fad1c in zeek::packet_analysis::Manager::ProcessPacket(zeek::Packet*) ()
#16 0x00005638b6d43472 in zeek::run_state::detail::dispatch_packet(zeek::Packet*, zeek::iosource::PktSrc*) ()
#17 0x00005638b6a1c2fc in zeek::iosource::PktSrc::Process() ()
#18 0x00005638b6d43d47 in zeek::run_state::detail::run_loop() ()
#19 0x00005638b64e821a in main ()

Note that in that image due to me setting some special capabilities on /opt/zeek/bin/zeek you'll run /opt/zeek/bin/zeek-offline but the binaries are identical.

I am trying to confirm if it only happens with GCC-compiled Zeek, and will post here when I know. I know there are some weird things in that BACnet traffic, maybe (see all the error: string with embedded NUL: "SWITC\x0c\x00\x00\x09\x10\x1e"-style errors) but either way it should handle them gracefully and not crash.

mmguero commented 5 months ago

the bug does not appear to reproduce in my clang-compiled build-from-source images. I'm compiling my gcc image external to Malcolm to see if it reproduces there, which I assume it will because I don't know what would be different in that from the default packages.

mmguero commented 5 months ago

Hmmm I'm having a difficult time reproducing it now outside of the Malcolm container, even building from source. Not sure why yet, I'll try to keep investigating.

mmguero commented 5 months ago

It actually seems to go away if I remove other plugins that have nothing to do with bacnet. I'm thinking it's something memory related, but that it is a bug.

this parse_tag function seems to be the issue, but I'm not sure about the input there that causes it yet.

mmguero commented 5 months ago

Okay, if I install the other plugins and run it I get this error line:

1614578568.044456 error: string with embedded NUL: "\x00 ... \x00: 32776"

The length of that line is 124,927 bytes. The line of error output immediately before that is:

1614578546.628877 error: string with embedded NUL: "4.0\x00"

in both cases (in my instance where it crashes and instances where it doesn't. I'm pretty sure this is the input that's causing it to crash. Will this be enough information to address the bug and avoid the segfault?

I've attached bacnet_out.txt where you can see the error output on line 59.