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?

1 Like

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.

1 Like

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?

1 Like

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.pcapnga66e498c488aa0523759691248cdfb01, tls1.pcapng871a754af286dfb70c1b53c6887c62e0) 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.
1 Like

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
    }
]

1 Like

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

1 Like

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.

1 Like