-
Notifications
You must be signed in to change notification settings - Fork 167
Description
The Zeek implementation of JA4 is not conform the spec, when the first ALPN is an empty string.
The following snippet is from the Zeekscript source, that first checks if the alpns field is present and subsequently checks if there are any alpns in the list.
local alpn: string = "00";
if (c$fp$client_hello?$alpns && |c$fp$client_hello$alpns| > 0) {
alpn = c$fp$client_hello$alpns[0][0] + c$fp$client_hello$alpns[0][-1];
}
Now consider a situation where alpns is a list with an empty string, [""]. This passes the check and results in alpn = "" instead of alpn = "00".
The result is a malformed JA4 hash that is two characters short in the first section.
The Python implementation does include a len(alpn) > 2 check, but only to truncate ALPNs that are too long. The Python impl is therefore probably also prone to this bug.
alpn = '00'
if 'alpn_list' in x:
if isinstance(x['alpn_list'], list):
alpn = x['alpn_list'][0]
else:
alpn = x['alpn_list']
if len(alpn) > 2:
alpn = f"{alpn[0]}{alpn[-1]}"
if ord(alpn[0]) > 127:
alpn = '99'Unfortunately, I cannot share a PCAP with sample traffic at the moment.
While digging into this issue, I also found that:
- The alpn = "99" case for non-ASCII values is not implemented in Zeek
- The case of ALPN values that are just one character is mishandled in Zeek and Python as well. The spec is unclear on this.
- Handling of non-ascii charactors in ALPN #178 is also not properly handled in the Zeek plugin