Want to improve the security of your ecommerce website?

Learn how
how to detect successful brute force attacks

How to Detect Successful SSH Brute Force Attacks

Since the v1.5 release — our biggest release since v1.0 — the CrowdSec Security Engine Version provides even more control over your security management. 

In this blog series, I want to walk you through some of the most interesting features and explore a few use cases. In the first installment, I will explore the new capability to detect multiple-step behaviors in a single scenario using the example of a successful SSH brute force attack. 

What is brute force?

First things, first. To avoid any confusion, let’s clearly define what is a brute force attack. A brute force attack is a hacking method where an attacker attempts to gain unauthorized access to a system by systematically trying all possible combinations of passwords or encryption keys until the correct one is found.

Brute force relies on the sheer computational power to exhaustively guess credentials, without any other clues or shortcuts. While brute force attacks can be time-consuming and resource-intensive, they can be effective against weak or poorly secured systems, especially those with simple, short, or commonly used passwords.

Now, let’s see how you can use the CrowdSec Security Engine to protect your systems against brute force attacks.

Requirements

Setup the acquisition (optional)
The CrowdSec Security runs in two modes — the service mode and the replay mode. In service mode (aka the default mode), the Security Engine monitors live logs while in replay mode you can run the Security Engine against a specified log file. The replay mode is mostly used when you want to test a parser or a scenario, or when you want to detect false positives.

The acquisition configuration defines which stream of information the Security Engine must process (log file path, S3 bucket, CloudWatch log stream, etc.). This is what the acquis.yaml would look like to monitor CrowdSec SSH logs in service mode.

#/etc/crowdsec/acquis.yaml
---
Filenames:
- /var/log/auth.log
Labels:
type: syslog
---

Install the SSHD collection

You can find the collection here.

sudo cscli collections install crowdsecurity/sshd

Parse successful authentication

To detect a successful brute force attack, CrowdSec needs to parse a successful authentication log. You can refer to this documentation article to understand how to write a parser. We can do this by adding this node in the crowdsecurity/sshd-logs parser:


#/etc/crowdsec/parsers/s01-parse/sshd-logs.yaml
---
- grok:
      pattern: 'Accepted password for %{USERNAME:sshd_valid_user} from %{IP_WORKAROUND:sshd_client_ip} port d+'
      apply_on: message
      statics:
        - meta: log_type
          value: ssh_success-auth
        - meta: target_user
          expression: "evt.Parsed.sshd_valid_user"

Note: This may not cover all the SSH successful authentication messages.

The scenario

For this use case I am using the new type of scenario conditional

With this type of scenario, it is possible to access previous events that were poured into the bucket and determine where they sit on the timeline — i.e. which event happened when. Find more info about the conditional scenario here

To detect a successful brute force attack, we must check that our bucket contains at least five failed authentication logs and one successful authentication log.

Here is the condition that we will use for our conditional bucket:

condition: |
  count(queue.Queue, #.Meta.log_type == 'ssh_failed-auth') > 5 and count(queue.Queue, #.Meta.log_type == 'ssh_success-auth') > 0

This checks that the buckets contain at least five failed authentication logs and one successful authentication log.

And here is the full scenario that detects successful SSH brute force:


#/etc/crowdsec/scenarios/successful-ssh-bf.yaml
---
type: conditional
name: crowdsecurity/successful-ssh-bf
description: "Detect successful ssh bruteforce"
filter: "evt.Meta.service == 'ssh'"
leakspeed: "10s"
cache_size: 15
capacity: -1
condition: |
  count(queue.Queue, #.Meta.log_type == 'ssh_failed-auth') > 5 and count(queue.Queue, #.Meta.log_type == 'ssh_success-auth') > 0
groupby: evt.Meta.source_ip
blackhole: 1m
labels:
  remediation: true

Test with CrowdSec replay mode

To check that everything works properly, we can now test this scenario with the CrowdSec replay mode.

Here are some logs that represent a successful brute force:


#ssh_bf.log
---
Apr 11 15:53:50 myvps sshd[834901]: Failed password for root from 1.2.3.4 port 1042 ssh2
Apr 11 15:53:51 myvps sshd[834901]: Failed password for root from 1.2.3.4 port 1042 ssh2
Apr 11 15:53:51 myvps sshd[834901]: Failed password for root from 1.2.3.4 port 1042 ssh2
Apr 11 15:53:52 myvps sshd[835121]: Failed password for root from 1.2.3.4 port 1042 ssh2
Apr 11 15:53:53 myvps sshd[835121]: Failed password for root from 1.2.3.4 port 1042 ssh2
Apr 11 15:53:54 myvps sshd[835121]: Failed password for root from 1.2.3.4 port 1042 ssh2
Apr 11 15:53:54 myvps sshd[835241]: Accepted password for root from 1.2.3.4 port 1042 ssh2

We can run the CrowdSec Replay mode with the following command:

$ sudo crowdsec -dsn file://ssh_bf.log -type syslog -no-api
INFO[11-04-2023 19:23:41] single file mode : log_media=stdout daemonize=false 
INFO[11-04-2023 19:23:41] Enabled feature flags: none                
INFO[11-04-2023 19:23:41] Crowdsec v1.5.0-rc3-6-g169b8442-linux-169b84421227a4a2cab1c680863df958862bc615 
WARN[11-04-2023 19:23:41] MaxOpenConns is 0, defaulting to 100         
INFO[11-04-2023 19:23:41] Loading prometheus collectors                
WARN[11-04-2023 19:23:41] Exprhelpers loaded without database client.  
INFO[11-04-2023 19:23:41] Loading grok library /etc/crowdsec/patterns  
INFO[11-04-2023 19:23:41] Loading enrich plugins                       
INFO[11-04-2023 19:23:41] Successfully registered enricher 'GeoIpCity' 
INFO[11-04-2023 19:23:41] Successfully registered enricher 'GeoIpASN'  
INFO[11-04-2023 19:23:41] Successfully registered enricher 'IpToRange' 
INFO[11-04-2023 19:23:41] Successfully registered enricher 'reverse_dns' 
INFO[11-04-2023 19:23:41] Successfully registered enricher 'ParseDate' 
INFO[11-04-2023 19:23:41] Successfully registered enricher 'UnmarshalJSON' 
INFO[11-04-2023 19:23:41] Loading parsers from 5 files                 
INFO[11-04-2023 19:23:41] Loaded 2 parser nodes                         file=/etc/crowdsec/parsers/s00-raw/syslog-logs.yaml stage=s00-raw
INFO[11-04-2023 19:23:41] Loaded 1 parser nodes                         file=/etc/crowdsec/parsers/s01-parse/sshd-logs.yaml stage=s01-parse
INFO[11-04-2023 19:23:41] Loaded 1 parser nodes                         file=/etc/crowdsec/parsers/s02-enrich/dateparse-enrich.yaml stage=s02-enrich
INFO[11-04-2023 19:23:41] Loaded 1 parser nodes                         file=/etc/crowdsec/parsers/s02-enrich/geoip-enrich.yaml stage=s02-enrich
INFO[11-04-2023 19:23:41] Loaded 1 parser nodes                         file=/etc/crowdsec/parsers/s02-enrich/whitelists.yaml stage=s02-enrich
INFO[11-04-2023 19:23:41] Loaded 6 nodes from 3 stages                 
INFO[11-04-2023 19:23:41] No postoverflow parsers to load              
INFO[11-04-2023 19:23:41] Loading 1 scenario files                     
INFO[11-04-2023 19:23:41] Adding conditional bucket                     cfg=proud-resonance file=/etc/crowdsec/scenarios/successfull-ssh-bf.yaml name=crowdsecurity/successful-ssh-bf
WARN[11-04-2023 19:23:41] Loaded 1 scenarios                           
INFO[11-04-2023 19:23:41] Adding file ssh_bf.log to filelist            type="file://ssh_bf.log"
INFO[11-04-2023 19:23:41] Starting processing data                     
INFO[11-04-2023 19:23:41] reading ssh_bf.log at once                    type="file://ssh_bf.log"
WARN[11-04-2023 19:23:41] prometheus: listen tcp 127.0.0.1:6060: bind: address already in use 
WARN[11-04-2023 19:23:41] Acquisition is finished, shutting down       
INFO[11-04-2023 19:23:42] Ip 1.2.3.4 performed 'crowdsecurity/successful-ssh-bf' (7 events over 1h29m51.947340934s) at 2023-04-11 15:53:54 +0000 UTC 
INFO[11-04-2023 19:23:42] Killing parser routines                      
INFO[11-04-2023 19:23:43] Bucket routine exiting                       
INFO[11-04-2023 19:23:44] crowdsec shutdown

And there you have it — CrowdSec detected the successful brute force!

Demo

Now it is time to check if our new scenario works in real-time. For this demo, I will use Hydra to perform the brute force and I will target the user demo using a server that I own.

Note: Before we get started with this step, please make sure to restart the Security Engine since we have edited some parsers and scenarios and added context to alerts.

Once you restart the Security Engine, run Hydra.

$ hydra -l demo -P pass.txt DEMO_IP ssh -t 4
Hydra v9.2 (c) 2021 by van Hauser/THC & David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway).

Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2023-04-25 15:04:44
[DATA] max 4 tasks per 1 server, overall 4 tasks, 9 login tries (l:1/p:9), ~3 tries per task
[DATA] attacking ssh://DEMO_IP:22/
[22][ssh] host: DEMO_IP   login: demo   password: Password123
1 of 1 target successfully completed, 1 valid password found

We managed to find the password of the demo user, and we can see in the Security Engine logs that the scenario has been triggered:

time="25-04-2023 13:04:49" level=info msg="Ip demo_ip performed 'crowdsecurity/successful-ssh-bf' (10 events over 5.015762151s) at 2023-04-25 13:04:49.671649049 +0000 UTC"
time="25-04-2023 13:04:49" level=info msg="(ff7bfc7d3d8043188b90b8ca80edd29cEo2BtePh5aKyvESP/crowdsec) crowdsecurity/successful-ssh-bf by ip demo_ip (FR/5410) : 4h ban on Ip demo_ip"

Conclusion

As we saw in this article, the conditional bucket feature introduced in CrowdSec Security Engine 1.5 helps you detect more advanced behaviors. Check out part II of this series where I’ll show you how to use the same feature to detect the impossible travel behavior (same account connecting from two different countries within a short timeframe). 

WRITTEN BY

You may also like

am i under attack
Product Updates

Am I Under Attack: Cut Through the Noise to Detect Sophisticated and Targeted Attacks with CrowdSec’s New feature

Am I Under Attack leverages advanced AI algorithms to detect anomalies in your logs indicating more sophisticated or targeted attacks.

new and advanced ip lookup search
Product Updates

Introducing the New and Advanced IP Lookup Search

In a previous article, we introduced the CTI Report, this time, we are taking it a step further and introducing new and advanced search options for our IP lookup.  You now have access to multiple search options to accurately and effectively explore the CrowdSec CTI.   Let’s take a look. IP lookup search These new search […]

Discover CrowdSec’s Free Third-Party Blocklists
Product Updates

Discover CrowdSec’s Free Third-Party Blocklists

In case you missed it, we recently announced the new Blocklists Catalog in the CrowdSec Console. In the catalog, you can find several blocklists centralized in one place, including third-party blocklists that are free to all users.  All users on the CrowdSec Console can subscribe their Security Engines to third-party blocklists to secure their systems […]