elastic / detection-rules

https://www.elastic.co/guide/en/security/current/detection-engine-overview.html
Other
1.91k stars 487 forks source link

[New Rule] Multiple failed Okta logins followed by a successful login from an IP #1154

Closed aarju closed 3 years ago

aarju commented 3 years ago

Description

Detect successful Brute Force attempts against Okta from a single IP with an EQL rule that uses data from the Okta filebeat module to detect when there are multiple failed authentication events from a source.ip followed by a successful authentication event.

Required Info

Target indexes

filebeat-*

Additional requirements

Filebeat Okta module

Target Operating Systems

N/A

Platforms

Okta

Tested ECS Version

1.8.0

Optional Info

Query

New fields required in ECS/data sources for this rule?

Related issues or PRs

References

Example Data

threat-punter commented 3 years ago

Thanks for opening this issue @aarju. What do you think is an appropriate number of authentication failure events to match before alerting after the final successful authentication event?

aarju commented 3 years ago

We regularly see users fail an authentication 3 or 4 times and then successfully authenticate so I think setting it to 5-10 failed attempts from an IP before triggering would be a good alert without too many false alarms.

I think a common false alarm we may have with this alert are when multiple users are authenticated to the same VPN so they are all coming from the same source.ip. Orgs that have lots of hosts hitting Okta from the same source IP will want to filter out those IPs.

aarju commented 3 years ago

It may be worth splitting this into two separate detections. One that looks for multiple failed auths followed by a successful to a single user.full_name or okta.actor.alternate_id to detect brute force attacks against a single account, and another rule to look for activity on multiple accounts to looks for password spray events.

threat-punter commented 3 years ago

Thanks @aarju. I'll look into that.

Just checking - Are you already aware of the rules below to complement the use cases that you're describing?

Attempts to Brute Force an Okta User Account - Identifies when an Okta user account is locked out 3 times within a 3 hour window, which is consistent with brute force attempts

Okta Brute Force or Password Spraying Attack - Identifies a high number of failed Okta user authentication attempts from a single IP address, which could be indicative of a brute force or password spraying attack.

aarju commented 3 years ago

Those rules go off on our Okta environment fairly regularly as we get scanned from the internet. When they go off one of the questions we have is 'were they successful at guessing a password?' To investigate we will usually look for any successful logins from that IP or against that specific account shortly following the brute force.

threat-punter commented 3 years ago

That's good to know. I'll look at those use cases and report back!

austinsonger commented 3 years ago

I know for splunk this logic seems similar to the following splunk search query

Okta login unsuccessful attempts due to bad credentials for more than one user, originating from the same ip address.

okta outcome.reason=INVALID_CREDENTIALS |  
rename client.geographicalContext.country as country,
client.geographicalContext.state as state, 
client.geographicalContext.city as city |  
stats min(_time) as firstTime max(_time) as lastTime dc(user) as distinct_users values(user) as users by src_ip, 
displayMessage, outcome.reason, country, state, city  | 
security_content_ctime(firstTime) |  
security_content_ctime(lastTime) |   
search distinct_users > 5| multiple_okta_users_with_invalid_credentials_from_the_same_ip_filter`

Something could probably be pulled from the logic above.

@threat-punter his reasoning behind this issue is like my reasoning behind #1126 and #1127

austinsonger commented 3 years ago

@threat-punter just messing around.

Version 1A

sequence by okta.client.ip,okta.request.ip_chain.ip   with maxspan=10m
[ authentication where event.dataset : "okta.system" and okta.event_type in ("user.session.start", 
    "user.authentication.auth_via_radius") and 
    okta.outcome.result : "failure" ] by okta.actor.alternate_id
[ authentication where event.dataset : "okta.system" and okta.event_type in ("user.session.start", 
    "user.authentication.auth_via_radius") and 
    okta.outcome.result : "failure" ] by okta.actor.alternate_id
[ authentication where event.dataset : "okta.system" and okta.event_type in ("user.session.start", 
    "user.authentication.auth_via_radius") and 
    okta.outcome.result : "failure" ] by okta.actor.alternate_id
[ authentication where event.dataset : "okta.system" and okta.event_type in ("user.session.start", 
    "user.authentication.auth_via_radius") and 
    okta.outcome.result : "success" ] by okta.actor.alternate_id

Version 1B

sequence by okta.client.ip,okta.request.ip_chain.ip   with maxspan=10m
[ authentication where event.dataset : "okta.system" and okta.event_type : (user.session.start or 
    user.authentication.auth*) and  okta.outcome.result : "failure" ] by okta.actor.alternate_id
[ authentication where event.dataset : "okta.system" and okta.event_type : (user.session.start or 
    user.authentication.auth*) and okta.outcome.result : "failure" ] by okta.actor.alternate_id
[ authentication where event.dataset : "okta.system" and okta.event_type : (user.session.start or 
    user.authentication.auth*) and okta.outcome.result : "failure" ] by okta.actor.alternate_id
[ authentication where event.dataset : "okta.system" and okta.event_type : (user.session.start or 
    user.authentication.auth*) and  okta.outcome.result : "success" ] by okta.actor.alternate_id

Version 2A

sequence by okta.client.ip,okta.request.ip_chain.ip   with maxspan=10m
[ authentication where event.dataset : "okta.system" and okta.event_type : "user.session.start" and 
    (okta.outcome.reason : "INVALID_CREDENTIALS" or okta.outcome.result : "failure" )] by okta.actor.alternate_id
[ authentication where event.dataset : "okta.system" and okta.event_type : "user.session.start" and 
    (okta.outcome.reason : "INVALID_CREDENTIALS" or okta.outcome.result : "failure" )] by okta.actor.alternate_id
[ authentication where event.dataset : "okta.system" and okta.event_type : "user.session.start" and 
    (okta.outcome.reason : "INVALID_CREDENTIALS" or okta.outcome.result : "failure" )] by okta.actor.alternate_id
[ authentication where event.dataset : "okta.system" and okta.event_type : "user.session.start" and  
    okta.outcome.result : "success" ] by okta.actor.alternate_id

Version 2B

sequence by okta.client.ip,okta.request.ip_chain.ip   with maxspan=10m
[ authentication where event.dataset : "okta.system" and okta.event_type : (user.session.start or 
    user.authentication.auth*) and (okta.outcome.reason : "INVALID_CREDENTIALS" or 
    okta.outcome.result : "failure" )] by okta.actor.alternate_id
[ authentication where event.dataset : "okta.system" and okta.event_type : (user.session.start or 
    user.authentication.auth*) and (okta.outcome.reason : "INVALID_CREDENTIALS" or 
        okta.outcome.result : "failure" )] by okta.actor.alternate_id
[ authentication where event.dataset : "okta.system" and okta.event_type : (user.session.start or 
    user.authentication.auth*) and (okta.outcome.reason : "INVALID_CREDENTIALS" or 
        okta.outcome.result : "failure" )] by okta.actor.alternate_id
[ authentication where event.dataset : "okta.system" and okta.event_type : (user.session.start or 
    user.authentication.auth*) and  okta.outcome.result : "success" ] by okta.actor.alternate_id
austinsonger commented 3 years ago

@threat-punter

And to prevent extra noise and we could also considered adding okta.authentication_context.external_session_id. This value is only populated on a successful login.

Success

okta.authentication_context.external_session_id != null

Failure

okta.authentication_context.external_session_id = null
threat-punter commented 3 years ago

With the current version of EQL in Elasticsearch, I don't think we can match on the following behavior. Note, this is just a pseudo query to help with my explanation.

sequence by source.ip with maxspan=10m
[authentication failure | count >= 5]
[authentication success]

We can match on a specific number of authentication failures before the successful authentication event occurs. Matching on a specific number of authentication failures in a rule before the successful authentication event would lead to false negatives.

@rw-access by any chance, do you know if the above use case is on the roadmap for EQL in Elasticsearch?

rw-access commented 3 years ago

We're having discussions and I'll be glad to point to the internal issues, but nothing committed to roadmap.

A threshold rule might work well here?

threat-punter commented 3 years ago

Thanks @rw-access. We do have a couple of threshold rules (see this comment). @aarju commented that when those rules fire, he has to investigate whether the user(s) logged in successfully after the failures occurred. Being able to match on greater than x failures followed by a success would reduce FPs and save analysts time during triage & investigation.

threat-punter commented 3 years ago

I'm going to close this issue as the use case can't be accomplished today using EQL.