JA3 hashes not matching TLSv1.3

running suricata 7.0.4
Running docker jasonish/suricata

I tried matching a tls alert on a hash that came from a pcap file from TLS version 1.3 but the alert never went of changed to a pcap file where the rule matched a hash from TLS 1.2 and it worked has this something to do with the protocol or is this a suricata issue?
Used this exact same rule only changed the hash from the pcap files
alert tls any any → any any (msg:“match JA3 hash”;ja3_hash; content:“871a754af286dfb70c1b53c6887c62e0”;sid:100001;)

Can you provide the pcap and rules?

Weird enough i just tried a diffrent pcap and its detecting it

file
tls1 WORKS
tls3 WORKS
tls_mine DOESNT work here are the rules

alert tls any any → any any (msg:“ET JA3 Hash - Possible Malware - Dridex”; ja3_hash; content:“871a754af286dfb70c1b53c6887c62e0”; reference:url,trisulnsm (Trisul Network Analytics ) · GitHub>

alert tls any any → any any (msg:“match JA3 hash match”;ja3_hash; content:“a66e498c488aa0523759691248cdfb01”;sid:100011;)

alert tls any any → any any (msg:“match JA3 hash doesnt match”;ja3_hash; content:“ea39e432bc0bf3ded25f0913860a63df”;sid:100012;)

tls_mine.pcapng (4.7 KB)
tls3.pcapng (3.0 KB)
tls1.pcapng (2.7 KB)

Perhaps related to the hello retry request
image
It only shows up in your tls_mine.pcapng pcap.

But that only comes after shouldn`t the rule trigger when it sees the client hello ja3 hash?
Also i took tls1 and tls3 from the web the other one was captured by me

Not sure, just pointing out a difference. @satta any idea?

JA3 is indeed supposed to match on the Client Hello, which is also present in tls_mine.pcapng.

Here’s what caught my eye though:

  • In tls_mine.pcapng, there is no TCP handshake, so maybe the stream isn’t actually inspected as it should.
  • In tls_mine.pcapng the JA3 hash, according to Wireshark, is ea034632bc22bbd167557e4b70939465 which does not appear in any of your rules. In the others (tls3.pcapng → a66e498c488aa0523759691248cdfb01, tls1.pcapng → 871a754af286dfb70c1b53c6887c62e0) the JA3 hashes match what is in the rules. So could it be that your rule you are just looking for the wrong hash? Indeed, when I change the hash in your last rule to be
    alert tls any any -> any any (msg:"match JA3 hash doesnt match";ja3_hash; content:"ea034632bc22bbd167557e4b70939465";sid:100012;)
    
    
    then I get the correct alert:
    
      ❯ rm -f eve.json; ./src/suricata -S ja3test.rules -v -r ~/Downloads/tls_mine.pcapng -c ./suricata1.yaml -l . --set stream.midstream=true -k none
      Warning: debug: error opening file /usr/local/var/log/suricata/suricata.log: No such file or directory [SCLogInitFileOPIface:util-debug.c:854]
      Notice: suricata: This is Suricata version 8.0.0-dev (240e068b8 2024-04-16) running in USER mode [LogVersion:suricata.c:1161]
      Info: cpu: CPUs/cores online: 16 [UtilCpuPrintSummary:util-cpu.c:149]
      Info: suricata: Setting engine mode to IDS mode by default [PostConfLoadedSetup:suricata.c:2704]
      Info: suricata: Preparing unexpected signal handling [InitSignalHandler:suricata.c:2201]
      Info: logopenfile: fast output device (regular) initialized: fast.log [SCConfLogOpenGeneric:util-logopenfile.c:616]
      Info: logopenfile: eve-log output device (regular) initialized: eve.json [SCConfLogOpenGeneric:util-logopenfile.c:616]
      Info: logopenfile: stats output device (regular) initialized: stats.log [SCConfLogOpenGeneric:util-logopenfile.c:616]
      Info: detect: 1 rule files processed. 3 rules successfully loaded, 0 rules failed, 0 rules skipped [SigLoadSignatures:detect-engine-loader.c:374]
      Warning: threshold-config: Error opening file: "/usr/local/etc/suricata//threshold.config": No such file or directory [SCThresholdConfInitContext:util-threshold-config.c:177]
      Info: detect: 3 signatures processed. 0 are IP-only rules, 0 are inspecting packet payload, 3 inspect application layer, 0 are decoder event only [SigPrepareStage1:detect-engine-build.c:1848]
      Info: pcap: Starting file run for /home/satta/Downloads/tls_mine.pcapng [ReceivePcapFileLoop:source-pcap-file.c:180]
      Info: pcap: pcap file /home/satta/Downloads/tls_mine.pcapng end of file reached (pcap err code 0) [PcapFileDispatch:source-pcap-file-helper.c:163]
      Notice: threads: Threads created -> RX: 1 W: 16 FM: 1 FR: 1   Engine started. [TmThreadWaitOnThreadRunning:tm-threads.c:1899]
      Notice: suricata: Signal Received.  Stopping engine. [SuricataMainLoop:suricata.c:2839]
      Info: suricata: time elapsed 0.080s [SCPrintElapsedTime:suricata.c:1181]
      Notice: pcap: read 1 file, 6 packets, 4585 bytes [ReceivePcapFileThreadExitStats:source-pcap-file.c:388]
      Info: counters: Alerts: 1 [StatsLogSummary:counters.c:888]
    
      ❯ jq 'select(.event_type == "alert")' < eve.json | jq                                                                                           
      {
      "timestamp": "2024-04-15T15:02:05.563432+0200",
      "flow_id": 1550609236761925,
      "pcap_cnt": 3,
      "event_type": "alert",
      "src_ip": "158.64.20.39",
      "src_port": 39648,
      "dest_ip": "152.199.19.160",
      "dest_port": 443,
      "proto": "TCP",
      "pkt_src": "wire/pcap",
      "tx_id": 0,
      "alert": {
          "action": "allowed",
          "gid": 1,
          "signature_id": 100012,
          "rev": 0,
          "signature": "match JA3 hash doesnt match",
          "category": "",
          "severity": 3
      },
      "tls": {
          "sni": "az764295.vo.msecnd.net",
          "version": "TLS 1.3",
          "ja3": {
          "hash": "ea034632bc22bbd167557e4b70939465",
          "string": "771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,17513-27-35-51-23-16-11-10-13-5-65281-45-65037-18-43-0-41,29-23-24,0"
          },
          "ja3s": {
          "hash": "15af977ce25de452b96affa2addb1036",
          "string": "771,4866,43-51"
          }
      },
      "app_proto": "tls",
      "direction": "to_server",
      "flow": {
          "pkts_toserver": 2,
          "pkts_toclient": 1,
          "bytes_toserver": 1792,
          "bytes_toclient": 165,
          "start": "2024-04-15T15:02:05.557637+0200",
          "src_ip": "158.64.20.39",
          "dest_ip": "152.199.19.160",
          "src_port": 39648,
          "dest_port": 443
      }
      }
    
    Note that I also set -k none to avoid checksum issues in the pcap and --set stream.midstream=true to enable inspection without having seen a TCP session handshake.

Hi im sorry how did you get this hash ea034632bc22bbd167557e4b70939465 i dont have it in tls_mine.pcapng i do have it ending in df

Wow, this is interesting. For me it’s definitely ea034632bc22bbd167557e4b70939465:

Using Debian’s Wireshark 4.0.11 (Git v4.0.11 packaged as 4.0.11-1~deb12u1).

pyja3 also agrees with my hash:

/tmp via 🐍 v3.11.2 (test1) took 6s 
❯ pip install pyja3    
Collecting pyja3
  Downloading pyja3-1.0.0.tar.gz (4.9 kB)
  Preparing metadata (setup.py) ... done
Collecting dpkt
  Downloading dpkt-1.9.8-py3-none-any.whl (194 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 195.0/195.0 kB 468.4 kB/s eta 0:00:00
Installing collected packages: dpkt, pyja3
  DEPRECATION: pyja3 is being installed using the legacy 'setup.py install' method, because it does not have a 'pyproject.toml' and the 'wheel' package is not installed. pip 23.1 will enforce this behaviour change. A possible replacement is to enable the '--use-pep517' option. Discussion can be found at https://github.com/pypa/pip/issues/8559
  Running setup.py install for pyja3 ... done
Successfully installed dpkt-1.9.8 pyja3-1.0.0

/tmp via 🐍 v3.11.2 (test1) 
❯ tshark -F pcap -r ~/Downloads/tls_mine.pcapng -w ~/Downloads/tls_mine.pcap

/tmp via 🐍 v3.11.2 (test1) 
❯ ja3 ~/Downloads/tls_mine.pcap                                            
[
    {
        "destination_ip": "152.199.19.160",
        "destination_port": 443,
        "ja3": "771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,17513-27-35-51-23-16-11-10-13-5-65281-45-65037-18-43-0-41,29-23-24,0",
        "ja3_digest": "ea034632bc22bbd167557e4b70939465",
        "source_ip": "158.64.20.39",
        "source_port": 39648,
        "timestamp": 1713186125.557637
    }
]

Could you be using an older version of Wireshark (<= 3.6.2) which is affected by this bug?

Well that’s interesting had version 3.6.2 of wireshark installed just updated it and its working now.Thank you a lot for the help even thought wasnt suricata.

Good to see it sorted out and glad to be of help.