Splunk Search

Detecting successful login after multiple failed logins in a transaction

st1
Path Finder

I'm not very good with SPL. I currently have Linux application logs that show the IP address, user name, and if the user failed or had a successful login. 

I'm interested in finding a successful login after one or more failed login attempts. I currently have the following search. The transaction command is necessary where it is or otherwise, all the events are split up into separate events of varying line counts.

index=honeypot sourcetype=honeypotLogs
| transaction sessionID
| search "SSH2_MSG_USERAUTH_FAILURE" OR "SSH2_MSG_USERAUTH_SUCCESS"

 Below is an example event. For clarity, I replaced details/omitted details from the logs below.

[02] Tue 27Aug24 15:20:57 - (143323) Connected to 1.2.3.4
...
...
[30] Tue 27Aug24 15:20:57 - (143323) SSH2_MSG_USERAUTH_REQUEST: user: bob
[31] Tue 27Aug24 15:20:57 - (143323) SSH2_MSG_USERAUTH_FAILURE
...
[30] Tue 27Aug24 15:20:57 - (143323) SSH2_MSG_USERAUTH_REQUEST: user: bob
[02] Tue 27Aug24 15:20:57 - (143323) User "bob" logged in
[31] Tue 27Aug24 15:20:57 - (143323) SSH2_MSG_USERAUTH_SUCCESS: successful login

Any tips on getting my search to find events like this? Currently I only have field extractions for the IP (1.2.3.4), user (bob), and sessionID (143323). I can possibly create a field extraction for the SSH2 messages but I don't know if that will help or not.

Thanks!

Labels (1)
0 Karma
1 Solution

gcusello
SplunkTrust
SplunkTrust

Hi @st1 ,

don't use transaction command because it's very slow, please try something like this, adapting my solution to your use case (e.g. the thresholds in the last row):

index=honeypot sourcetype=honeypotLogs ("SSH2_MSG_USERAUTH_FAILURE" OR "SSH2_MSG_USERAUTH_SUCCESS")
| eval kind=if(searchmatch("SSH2_MSG_USERAUTH_FAILURE", "success","failure")
| stats 
     dc(kind) AS kind_count)
     count(eval(kind="success)) As success_count
     count(eval(kind="failure)) As failure_count
     BY sessionID
| where kind_count=2 AND success_count>0 AND failure_count>10

 Ciao.

Giuseppe

View solution in original post

yuanliu
SplunkTrust
SplunkTrust

Yes, SSH2 message is key.  The actual solution kind of depends on your exact use case/requirement.  If you don't particularly care if the user had multiple failures, transaction will do just fine.  Assuming your sessionID is unique for each connection and that you don't care if attempted user name is the same, simply add startswith and endswith.

index=honeypot sourcetype=honeypotLogs
| rex "\s(?<action>Connected) to (?<IP>\S+)"
| rex "\sUser \"(?<user>\S+)\" (?<action>logged in)"
| rex "\sSSH2_MSG_(?<ssh2_msg_type>\w+)"
| rex ": (?<ssh2_message>.+)"
| rex field=ssh2_message "user: (?<user>\S+)"
| transaction sessionID startswith=ssh2_msg_type=USERAUTH_FAILURE endswith=ssh2_msg_type=USERAUTH_SUCCESS

The above maybe goes a little overboard in extraction but usually, these semantic elements can be of interest.

If you care about attempted user name, you can add user to transaction.  If you care about multiple failed attempts, streamstats could be a better approach.

The following is an extended emulation; it shows that

  1. transaction will only pick up sessions with at least one USERAUTH_FAILURE, and
  2. transaction will only include the last event with USERAUTH_FAILURE.
| makeresults format=csv data="_raw
[02] Tue 27Aug24 15:20:56 - (143323) Connected to 1.2.3.4
[30] Tue 27Aug24 15:20:56 - (143323) SSH2_MSG_USERAUTH_REQUEST: user: bob
[31] Tue 27Aug24 15:20:56 - (143323) SSH2_MSG_USERAUTH_FAILURE
[30] Tue 27Aug24 15:20:57 - (143323) SSH2_MSG_USERAUTH_REQUEST: user: bob
[31] Tue 27Aug24 15:20:57 - (143323) SSH2_MSG_USERAUTH_FAILURE
[30] Tue 27Aug24 15:20:57 - (143323) SSH2_MSG_USERAUTH_REQUEST: user: bob
[02] Tue 27Aug24 15:20:57 - (143323) User \"bob\" logged in
[31] Tue 27Aug24 15:20:57 - (143323) SSH2_MSG_USERAUTH_SUCCESS: successful login
[02] Tue 27Aug24 15:20:58 - (143523) Connected to 1.2.3.4
[30] Tue 27Aug24 15:20:58 - (143523) SSH2_MSG_USERAUTH_REQUEST: user: alice
[02] Tue 27Aug24 15:20:58 - (143523) User \"alice\" logged in
[31] Tue 27Aug24 15:20:58 - (143523) SSH2_MSG_USERAUTH_SUCCESS: successful login"
| rex "^(\S+\s+){2}(?<_time>\S+\s+\S+) - \((?<sessionID>\d+)"
| eval _time = strptime(_time, "%d%b%y %T")
| reverse
``` the above emulates
index=honeypot sourcetype=honeypotLogs
```

Play with the emulation and compare with real data.

gcusello
SplunkTrust
SplunkTrust

Hi @st1 ,

don't use transaction command because it's very slow, please try something like this, adapting my solution to your use case (e.g. the thresholds in the last row):

index=honeypot sourcetype=honeypotLogs ("SSH2_MSG_USERAUTH_FAILURE" OR "SSH2_MSG_USERAUTH_SUCCESS")
| eval kind=if(searchmatch("SSH2_MSG_USERAUTH_FAILURE", "success","failure")
| stats 
     dc(kind) AS kind_count)
     count(eval(kind="success)) As success_count
     count(eval(kind="failure)) As failure_count
     BY sessionID
| where kind_count=2 AND success_count>0 AND failure_count>10

 Ciao.

Giuseppe

Get Updates on the Splunk Community!

Index This | What did the zero say to the eight?

June 2025 Edition Hayyy Splunk Education Enthusiasts and the Eternally Curious!  We’re back with this month’s ...

Splunk Observability Cloud's AI Assistant in Action Series: Onboarding New Hires & ...

This is the fifth post in the Splunk Observability Cloud’s AI Assistant in Action series that digs into how to ...

Now Playing: Splunk Education Summer Learning Premieres

It’s premiere season, and Splunk Education is rolling out new releases you won’t want to miss. Whether you’re ...