Wireshark-dev: Re: [Wireshark-dev] Dissecting TLS and non-TLS using the same ports

From: Markku Leiniö <markku@xxxxxx>
Date: Mon, 17 Jul 2023 13:46:39 +0300
I managed to solve this. I started to figure out what happens differently in the Lua dissector so that it works fine. I was then able to narrow the problem down to get_zabbix_pdu_len() where I returned 0 when the packet was not Zabbix data.


My problem was that I did the Zabbix packet validity check only in get_zabbix_pdu_len(), while I had to do that already in dissect_zabbix(), before calling tcp_dissect_pdus(). In TLS cases that then lead to incorrect dissection. By returning 0 already in dissect_zabbix() enables the TLS heuristics to work normally.


So this now works just fine (= the same TCP ports are used with both plain Zabbix and TLS+Zabbix):


    dissector_add_uint_range_with_preference("tcp.port", ZABBIX_TCP_PORTS, zabbix_handle);
    zabbix_port_range = prefs_get_range_value("Zabbix", "tcp.port");
    dissector_add_uint_range("tls.port", zabbix_port_range, zabbix_handle);


Markku


On 17.7.2023 10.43, Markku Leiniö wrote:
I'm confused. I just realized that now that I only have the "tcp.port" defined (dissector_add_uint_range_with_preference("tcp.port", ZABBIX_TCP_PORTS, zabbix_handle)), and I disable Zabbix protocol (in Analyze -> Enabled Protocols), then Wireshark sees the TLS packets properly and can decrypt the packets with the embedded secrets.


If I have Zabbix protocol enabled, then Wireshark shows only TCP protocol packets (no TLS or Zabbix).


I thought that when my Zabbix dissector (that handles the TCP 10051 packets first before any heuristic dissectors) sees that the magic bytes do not match (because of the encryption) and thus returns 0, then the TLS heuristic dissector would kick in automatically. Apparently that does not happen. Have I understood something incorrectly?


If I enable TCP protocol preference "Try heuristic sub-dissectors first", then TLS is detected correctly, but Zabbix inside the TLS is not detected (even though Zabbix protocol is enabled at this point). Should TLS try to send the data to the TCP port-based dissectors in this case?


Here is an example TLS+Zabbix capture file with embedded secrets:

https://github.com/markkuleinio/wireshark-zabbix-dissectors/raw/master/samples/zabbixagent_4.0_tls_anon_withsecrets.pcapng


Markku (and sorry for any misformatted emails, I'm still trying to find the correct way to write the emails in Thunderbird so that they format nicely in list archive as well...)


On 13.7.2023 19.14, Markku Leiniö wrote:
On 13.7.2023 18.10, John Thacker wrote:

1. Register the non TLS version in the TCP port table, have it reject packets that are not Zabbix, the TLS heuristic dissector should pick it up if all goes well and forward it along after dissecting the TLS portion. Sounds like that worked for you on Lua, so it should work here.

In my current code (https://gitlab.com/markkuleinio/wireshark/-/blob/zabbix-dissector/epan/dissectors/packet-zabbix.c btw) I return 0 as soon as I see the packet is not Zabbix (= mismatch in magic values), but apparently that does not cause the TLS dissector to kick in.

2. Register the TLS version in the TCP port and a heuristic dissector for Zabbix; if the non TLS protocol doesn't look like TLS, the TLS dissector should reject it, and your heuristic dissector should pick it up.

That's something that I will have to still try, I believe README.heuristic will help me here.

3. Register some kind of helper dissector to the TCP port that can detect whether this is straight Zabbix or TLS, calling the TLS dissector if necessary. This can end up making `pinfo->layers` have an extra entry, especially for the first TLS packet in the first pass.

Probably TMI, because the first should work for you.

Could there be some other setting here now that affects the behaviour? I do have imported my usual Wireshark profile on the development VM that runs the compiled wireshark.exe, but I don't recognize any setting that affects this dissector chaining.

Markku