SSH rule not working

So, a relative newbie to suricata, but I am having problems with a rule. Even when I make this the only signature in a ruleset, the engine never fires this alert.

alert ssh any any → any any (msg:“Corporate policy violation, detected SSH protocol”; content:“SSH-”; target:dest_ip; sid:1000013; rev:1;)

I have also tried:

alert ssh any any → any any (msg:“Corporate policy violation, SSH traffic not allowed on OT network”; ssh.proto; content:“SSH-”; nocase; sid:1000013; rev:1;)

and:

alert ssh any any → any any (msg:“match SSH software string”; ssh.software; content:“openssh”; nocase; sid:1000020;)

all to no avail. In wireshark I can verify that the packet is SSH and does contain the content “SSH-” and other bits I am testing for:

Any ideas?

What version are you running?
How does your config look like?
How do you run Suricata?

Can you share the test pcap to reproduce it?

Running the Scirius Community Edition, part of the Stamus SELKS stack. Stock suricata.yaml file
suricata.yaml (80.2 KB)

The pcap is a test file to see if the rule works.
portscan.pcap (169.0 KB)

Like so it alerts.

alert ssh any any -> any any (msg:"Corporate policy violation, SSH traffic not allowed on OT network"; ssh.software; content:"SSH"; nocase; sid:1000015; rev:1;)
{
  "timestamp": "2023-02-24T21:19:27.840078+0100",
  "flow_id": 172574400024287,
  "pcap_cnt": 2085,
  "event_type": "alert",
  "src_ip": "192.168.1.13",
  "src_port": 22,
  "dest_ip": "192.168.1.111",
  "dest_port": 52784,
  "proto": "TCP",
  "tx_id": 0,
  "alert": {
    "action": "allowed",
    "gid": 1,
    "signature_id": 1000015,
    "rev": 1,
    "signature": "Corporate policy violation, SSH traffic not allowed on OT network",
    "category": "",
    "severity": 3
  },
  "ssh": {
    "client": {
      "proto_version": "1.5",
      "software_version": "NmapNSE_1.0"
    },
    "server": {
      "proto_version": "2.0",
      "software_version": "OpenSSH_8.7"
    }
  },
  "app_proto": "ssh",
  "flow": {
    "pkts_toserver": 4,
    "pkts_toclient": 3,
    "bytes_toserver": 292,
    "bytes_toclient": 227,
    "start": "2023-02-24T21:19:27.823007+0100"
  }
}

I do not see ssh- in the software version anywhere though. Note the diff between software version and proto version in the alert app proto metadata.

jq 'select(.event_type=="alert")' logs/eve.json |jq .ssh.client.software_version | uniq -c 
      1 "NmapNSE_1.0"
      1 null
      2 "Nmap-SSH2-Hostkey"
      1 "Nmap-SSH1-Hostkey"
      8 "Nmap-SSH2-Hostkey"
      1 "Nmap-SSH1-Hostkey"
      2 "Nmap-SSH2-Hostkey"
      
jq 'select(.event_type=="alert")' logs/eve.json |jq .ssh.server.software_version | uniq -c 
     16 "OpenSSH_8.7"
     
jq 'select(.event_type=="alert")' logs/eve.json |jq .ssh.server.proto_version | uniq -c 
     16 "2.0"
     
jq 'select(.event_type=="alert")' logs/eve.json |jq .ssh.client.proto_version | uniq -c 
      1 "1.5"
      1 null
      2 "2.0"
      1 "1.5"
      8 "2.0"
      1 "1.5"
      2 "2.0"
1 Like

Peter, thanks for the help. Sorry I didn’t reply sooner but I was out last week. I still seem to have a problem, as even if I cut and paste your rule and make it the ONLY rule on the system, it does not seem to fire. Any ideas on how to further troubleshoot?

Can you give me a link to the pcap you are testing against?

Did you push/update the rule from Scirius , Suricata actions?
I see it alerting here:

{
  "timestamp": "2023-02-25T01:05:52.622286+0100",
  "flow_id": 1071503355427674,
  "pcap_cnt": 9,
  "event_type": "alert",
  "src_ip": "192.168.1.13",
  "src_port": 22,
  "dest_ip": "192.168.1.111",
  "dest_port": 50436,
  "proto": "TCP",
  "tx_id": 0,
  "alert": {
    "action": "allowed",
    "gid": 1,
    "signature_id": 1000015,
    "rev": 1,
    "signature": "Corporate policy violation, SSH traffic not allowed on OT network",
    "category": "",
    "severity": 3
  },
  "ssh": {
    "client": {
      "proto_version": "2.0",
      "software_version": "OpenSSH_8.7"
    },
    "server": {
      "proto_version": "2.0",
      "software_version": "OpenSSH_8.7"
    }
  },
  "app_proto": "ssh",
  "flow": {
    "pkts_toserver": 5,
    "pkts_toclient": 4,
    "bytes_toserver": 1719,
    "bytes_toclient": 293,
    "start": "2023-02-25T01:05:52.605018+0100"
  }
}

OK, so the only rule running on the system is:
alert ssh any any → any any (msg:“Corporate policy violation, SSH traffic not allowed on OT network”; ssh.software; content:“SSH”; nocase; sid:1000013; rev:1;)

I have built and pushed the rule. When I ran the pcap I sent you, I still get no alerts in Evebox.

Is there something in the SELKS configuration that could be causing this?

If the rules is uploaded , i can think of two options to check/try:
1 - restart the Suricata docker
docker-compose restart suricata
then give it cpl of minutes to start and run the test again
2 - check in containers-data/suricata/logs/suricata.log for any errors for example

Just an additional piece of information.

When I run

alert ssh any any -> any any (  content:"SSH"; )

on the pcap I get nothing,

but when I run

alert tcp any any -> any any (  content:"SSH"; )

…I get alerts. So maybe it’s not being picked up as SSH and the buffers aren’t being filled.

Maybe related to checksums? I’m new to all this.

27/3/2023 -- 01:06:39 - <Info> - Alerts: 0
27/3/2023 -- 01:06:39 - <Notice> - This is Suricata version 6.0.10 RELEASE running in USER mode
27/3/2023 -- 01:06:39 - <Info> - CPUs/cores online: 2
27/3/2023 -- 01:06:39 - <Info> - fast output device (regular) initialized: fast.log
27/3/2023 -- 01:06:39 - <Info> - eve-log output device (regular) initialized: eve.json
27/3/2023 -- 01:06:39 - <Info> - stats output device (regular) initialized: stats.log
27/3/2023 -- 01:06:39 - <Info> - 1 rule files processed. 1 rules successfully loaded, 0 rules failed
27/3/2023 -- 01:06:39 - <Info> - Threshold config parsed: 0 rule(s) found
27/3/2023 -- 01:06:39 - <Info> - 1 signatures processed. 0 are IP-only rules, 1 are inspecting packet payload, 0 inspect application layer, 0 are decoder event only
27/3/2023 -- 01:06:39 - <Notice> - all 3 packet processing threads, 4 management threads initialized, engine started.
27/3/2023 -- 01:06:39 - <Info> - Starting file run for /content/stapackage/soundthealarm/test/scp.pcap
27/3/2023 -- 01:06:39 - <Info> - More than 1/10th of packets have an invalid checksum, assuming checksum offloading is used (717/1000)
27/3/2023 -- 01:06:39 - <Info> - pcap file /content/stapackage/soundthealarm/test/scp.pcap end of file reached (pcap err code 0)
27/3/2023 -- 01:06:39 - <Notice> - Signal Received.  Stopping engine.
27/3/2023 -- 01:06:39 - <Info> - time elapsed 0.056s
27/3/2023 -- 01:06:39 - <Notice> - Pcap-file module read 1 files, 3676 packets, 4465710 bytes
27/3/2023 -- 01:06:39 - <Info> - Alerts: 3
27/3/2023 -- 01:06:39 - <Info> - cleaning up signature grouping structure... complete

You can add -k none to your commandline to ignore checksums.

@vjulien How do we do that in a Suricata rule running as part of the SELKS stack?

You can also set this in the Suricata configuration file:

capture:
  check-sum-validation: none

OK, that works, but why is the checksum wrong for these SSH messages?

The packet checksums originate in the pcap. It’s not uncommon for the checksums to be wrong/missing. This is an artifact of the way the pcap was created and/or edited.