Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Auditbeat] normalized event.type/category/outcome fields for auditd module #11432

Merged
merged 1 commit into from
Apr 5, 2019

Conversation

adriansr
Copy link
Contributor

@adriansr adriansr commented Mar 25, 2019

The auditd module is updated to set normalized values for event.category
and event.type. It also sets event.outcome from auditd.result.

Currently it supports the following values:

event.category event.outcome event.type
authentication success authentication_success
authentication failure authentication_failure

Closes #11428

@elasticmachine
Copy link
Collaborator

Pinging @elastic/secops

CHANGELOG.next.asciidoc Outdated Show resolved Hide resolved
@@ -473,6 +473,7 @@ func buildMetricbeatEvent(msgs []*auparse.AuditMessage, config Config) mb.Event
"event": common.MapStr{
"category": auditEvent.Category.String(),
"action": auditEvent.Summary.Action,
"outcome": auditEvent.Result,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this need normalized too? We want to use failure or success.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Replaced fail with failure.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For consistency I think it would make sense to substitute failure for fail all of the time. WDYT? It makes the breaking change a little bit bigger but I think it's a win for users.

action common.MapStr
}{
{
fields: common.MapStr{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would these maps be continuously allocated for each event it processes?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I improved it, thanks

@adriansr
Copy link
Contributor Author

jenkins, test this

Copy link
Contributor

@webmat webmat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@adriansr adriansr force-pushed the feature_ab_auditd_event_fields branch from 4d71035 to 6f3add3 Compare March 26, 2019 13:44
@adriansr
Copy link
Contributor Author

adriansr commented Mar 26, 2019

I've realised the audit messages I was using, USER_LOGIN, are not generated in all cases (su or sudo). Also it an USER_LOGIN failure seems to be generated when the ssh-client offers an ssh-key and then falls-back to password.

I'm testing if USER_AUTH works in all cases.

@adriansr
Copy link
Contributor Author

After a quick investigation this is what I observe:

Action USER_LOGIN USER_AUTH Event(s)
local login failed Y Y "type=USER_AUTH msg=audit(1553622768.697:628): pid=6261 uid=0 auid=1002 ses=40 msg='op=PAM:authentication acct="root" exe="/bin/login" hostname=? addr=? terminal=/dev/pts/1 res=failed'"

"type=USER_LOGIN msg=audit(1553622768.697:629): pid=6261 uid=0 auid=1002 ses=40 msg='op=login acct="root" exe="/bin/login" hostname=? addr=? terminal=/dev/pts/1 res=failed'"
local login succeeded Y Y "type=USER_AUTH msg=audit(1553622784.557:630): pid=6261 uid=0 auid=1002 ses=40 msg='op=PAM:authentication acct="adrian" exe="/bin/login" hostname=? addr=? terminal=/dev/pts/1 res=success'"

"type=USER_LOGIN msg=audit(1553622784.973:634): pid=6261 uid=0 auid=1002 ses=40 msg='op=login acct="adrian" exe="/bin/login" hostname=? addr=? terminal=/dev/pts/1 res=success'"
SSH from remote with key Y - "type=USER_LOGIN msg=audit(1553621402.493:548): pid=5858 uid=0 auid=1000 ses=37 msg='op=login id=1000 exe="/usr/sbin/sshd" hostname=10.0.2.2 addr=10.0.2.2 terminal=/dev/pts/1 res=success'"
SSH from local, failure Y Y "type=USER_AUTH msg=audit(1553621419.693:549): pid=5936 uid=0 auid=4294967295 ses=4294967295 msg='op=PAM:authentication acct="root" exe="/usr/sbin/sshd" hostname=127.0.0.1 addr=127.0.0.1 terminal=ssh res=failed'"

"type=USER_LOGIN msg=audit(1553621419.693:550): pid=5936 uid=0 auid=4294967295 ses=4294967295 msg='op=login acct="root" exe="/usr/sbin/sshd" hostname=? addr=127.0.0.1 terminal=sshd res=failed'"
SSH from local, success Y Y "type=USER_AUTH msg=audit(1553621439.149:551): pid=5941 uid=0 auid=4294967295 ses=4294967295 msg='op=PAM:authentication acct="adrian" exe="/usr/sbin/sshd" hostname=127.0.0.1 addr=127.0.0.1 terminal=ssh res=success'"

"type=USER_LOGIN msg=audit(1553621439.633:561): pid=5941 uid=0 auid=1002 ses=38 msg='op=login id=1002 exe="/usr/sbin/sshd" hostname=127.0.0.1 addr=127.0.0.1 terminal=/dev/pts/2 res=success'"
SSH from remote, key failed Y - "type=USER_LOGIN msg=audit(1553621480.001:567): pid=6036 uid=0 auid=4294967295 ses=4294967295 msg='op=login acct="adrian" exe="/usr/sbin/sshd" hostname=? addr=10.0.2.2 terminal=sshd res=failed'"
... then fail password Y Y "type=USER_AUTH msg=audit(1553621498.857:568): pid=6036 uid=0 auid=4294967295 ses=4294967295 msg='op=PAM:authentication acct="adrian" exe="/usr/sbin/sshd" hostname=10.0.2.2 addr=10.0.2.2 terminal=ssh res=failed'"

"type=USER_LOGIN msg=audit(1553621498.857:569): pid=6036 uid=0 auid=4294967295 ses=4294967295 msg='op=login acct="adrian" exe="/usr/sbin/sshd" hostname=? addr=10.0.2.2 terminal=sshd res=failed'"
... then right password Y Y "type=USER_AUTH msg=audit(1553621512.245:570): pid=6036 uid=0 auid=4294967295 ses=4294967295 msg='op=PAM:authentication acct="adrian" exe="/usr/sbin/sshd" hostname=10.0.2.2 addr=10.0.2.2 terminal=ssh res=success'"

"type=USER_LOGIN msg=audit(1553621512.681:580): pid=6036 uid=0 auid=1002 ses=40 msg='op=login id=1002 exe="/usr/sbin/sshd" hostname=10.0.2.2 addr=10.0.2.2 terminal=/dev/pts/1 res=success'"
su - failure - Y "type=USER_AUTH msg=audit(1553621536.361:581): pid=6129 uid=1002 auid=1002 ses=40 msg='op=PAM:authentication acct="root" exe="/bin/su" hostname=? addr=? terminal=/dev/pts/1 res=failed'"
sudo failure - Y "type=USER_AUTH msg=audit(1553621549.941:583): pid=6130 uid=1002 auid=1002 ses=40 msg='op=PAM:authentication acct="adrian" exe="/usr/bin/sudo" hostname=? addr=? terminal=/dev/pts/1 res=failed'"

"type=USER_AUTH msg=audit(1553621555.529:584): pid=6130 uid=1002 auid=1002 ses=40 msg='op=PAM:authentication acct="adrian" exe="/usr/bin/sudo" hostname=? addr=? terminal=/dev/pts/1 res=failed'"
su - Y "type=USER_AUTH msg=audit(1553621598.789:587): pid=6138 uid=1002 auid=1002 ses=40 msg='op=PAM:authentication acct="vagrant" exe="/bin/su" hostname=? addr=? terminal=/dev/pts/1 res=success'"
sudo ls -l success - - (nothing)
sudo su - Y "type=USER_AUTH msg=audit(1553621630.597:599): pid=6154 uid=0 auid=1002 ses=40 msg='op=PAM:authentication acct="root" exe="/bin/su" hostname=? addr=? terminal=/dev/pts/1 res=success'"
sudo su - - Y "type=USER_AUTH msg=audit(1553621645.241:611): pid=6167 uid=0 auid=1002 ses=40 msg='op=PAM:authentication acct="root" exe="/bin/su" hostname=? addr=? terminal=/dev/pts/1 res=success'"

So the issue here is, if we also want to catch elevations from the console using su/sudo then it's necessary to also set "event.type": "authentication" for USER_AUTH messages. Do we mind the duplication?

@adriansr adriansr requested review from webmat and andrewkroh March 26, 2019 17:56
Copy link
Member

@andrewkroh andrewkroh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment is from yesterday. Just realized I had not submitted it yet. Still need to review the user_auth / user_login table.

@@ -473,6 +473,7 @@ func buildMetricbeatEvent(msgs []*auparse.AuditMessage, config Config) mb.Event
"event": common.MapStr{
"category": auditEvent.Category.String(),
"action": auditEvent.Summary.Action,
"outcome": auditEvent.Result,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For consistency I think it would make sense to substitute failure for fail all of the time. WDYT? It makes the breaking change a little bit bigger but I think it's a win for users.

@andrewkroh
Copy link
Member

@adriansr That table is really helpful. Thank you for doing the research. I don't see an alternative, so I think we have to categorize both user_auth and user_login.

@FrankHassanabad WDYT? I guess this could cause some of the authentication counts to be less accurate.

Copy link
Member

@andrewkroh andrewkroh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Let's wait to hear from @FrankHassanabad regarding the earlier ^ question.

if !ok1 || !ok2 || !ok3 {
return
}
if category == "user-login" &&
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I love the simplicity.

@FrankHassanabad
Copy link

Duplicates without knowing why they're duplicates would be really bad. Users of the system would def. ask questions and trust the system less if they started noticing all their users logging in were showing up twice as success. Alerts could be fired twice on a failure as well.

I would imagine as a user they would want to query/show login attempts separate from account escalations so it would also be weird/bad if we had a system locked down to where root is absolutely not allowed to login but then we start to see what looks like root logging in from the outside when in fact it's that security trick where you have to login as your regular user account first and then do a sudo or su to gain privilege.

We can use event.action: executed to track sudo at the moment if they configure auditd that way so I'm thinking to side on not having duplicates to start with.

I would imagine threat hunters would first be looking for password attempts from outside -> in, and then the second would be legitimate creds are already on the system but are trying to gain escalation or account changes. If I were writing rules, I would know that bad password attempts are going to be a constant noisy thing (such as morning when users are all trying to login) and not setup an alert for that. But for more than say 2 privilege escalation failures within a day I would setup an alert on that as that should be something rare occurring.

So keeping the two separate is a good thing and just doing logins as authenticated is a good starting point IMHO.

@adriansr
Copy link
Contributor Author

Thanks for your response @FrankHassanabad , it makes complete sense.

I've updated the PR to stop mapping USER_AUTH to authentication category, pending a further discussion on how to track privilege gains.

The auditd module is updated to set normalized values for event.category
and event.type. It also sets event.outcome from auditd.result.

Currently it sets the following values for audit messages of
USER_LOGIN and USER_AUTH type:

| event.category | event.outcome |        event.type      |
|----------------|---------------|------------------------|
| authentication | success       | authentication_success |
| authentication | failure       | authentication_failure |

Closes elastic#11428
@adriansr adriansr force-pushed the feature_ab_auditd_event_fields branch from 923728a to 65f1f57 Compare April 4, 2019 12:55
@adriansr adriansr merged commit 0df354a into elastic:master Apr 5, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants