From a18d6866a82bb1fd0222d2d4d59725d36a789091 Mon Sep 17 00:00:00 2001 From: Stephen Fox Jr Date: Wed, 28 Jun 2023 15:32:08 -0400 Subject: [PATCH] sshd: Use '.*' for regex. Add accept pw test. The processAcceptedPasswordEntry function was untested. I also added some additional characters to the "exp" test constants. --- processors/sshd/openssh_regex.go | 30 +++++++++++++++--------------- processors/sshd/user_type_test.go | 29 ++++++++++++++++++++++++++--- 2 files changed, 41 insertions(+), 18 deletions(-) diff --git a/processors/sshd/openssh_regex.go b/processors/sshd/openssh_regex.go index 31bff7a4..06cbe7ba 100644 --- a/processors/sshd/openssh_regex.go +++ b/processors/sshd/openssh_regex.go @@ -68,7 +68,7 @@ var ( // extra != NULL ? extra : ""); // //nolint:lll // This is a long regex... pretty hard to cut it without making it less readable. - loginRE = regexp.MustCompile(`Accepted publickey for (?P\S+) from (?P\S+) port (?P\d+) ssh[[:alnum:]]+: (?P[\w -]+):(?P\S+)`) + loginRE = regexp.MustCompile(`Accepted publickey for (?P.*) from (?P.*) port (?P.*) ssh[[:alnum:]]+: (?P[\w -]+):(?P\S+)`) // passwordLoginRE matches the sshd password login log message, // allowing us to extract information about the login attempt, @@ -79,7 +79,7 @@ var ( // Accepted password for auditomalditotesting from 127.0.0.1 port 45082 ssh2 // //nolint:lll // This is a long regex... pretty hard to cut it without making it less readable. - passwordLoginRE = regexp.MustCompile(`Accepted password for (?P\S+) from (?P\S+) port (?P\d+) ssh[[:alnum:]]+`) + passwordLoginRE = regexp.MustCompile(`Accepted password for (?P.*) from (?P.*) port (?P\d+) ssh[[:alnum:]]+`) // failedPasswordAuthRE matches an OpenSSH log message that occurs // when the user fails to authenticate with a password. This log @@ -108,7 +108,7 @@ var ( // cafp == NULL ? "(null)" : cafp, // methinfo == NULL ? "" : ", ", // methinfo == NULL ? "" : methinfo); - certIDRE = regexp.MustCompile(`ID (?P\S+)\s+\(serial (?P\d+)\)\s+(?P.+)`) + certIDRE = regexp.MustCompile(`ID (?P.*) \(serial (?P\d+)\)\s+(?P.+)`) // invalidUserRE matches the sshd invalid user log message, // allowing us to extract information about the user. @@ -128,7 +128,7 @@ var ( // "not listed in AllowUsers", pw->pw_name, hostname); // //nolint:lll // This is a long regex... pretty hard to cut it without making it less readable. - notInAllowUsersRE = regexp.MustCompile(`^User (?P.*) from (?P\S+) not allowed because not listed in AllowUsers$`) + notInAllowUsersRE = regexp.MustCompile(`^User (?P.*) from (?P.*) not allowed because not listed in AllowUsers$`) // userNonExistentShellRE matches an OpenSSH log message that // occurs when the user's shell does not exist. @@ -139,7 +139,7 @@ var ( // "does not exist", pw->pw_name, shell); // //nolint:lll // This is a long regex - userNonExistentShellRE = regexp.MustCompile(`^User (?P.*) not allowed because shell (?P\S+) does not exist$`) + userNonExistentShellRE = regexp.MustCompile(`^User (?P.*) not allowed because shell (?P.*) does not exist$`) // userNonExecutableShellRE matches an OpenSSH log message that // occurs when the user's shell is not executable. @@ -150,7 +150,7 @@ var ( // "is not executable", pw->pw_name, shell); // //nolint:lll // This is a long regex - userNonExecutableShellRE = regexp.MustCompile(`^User (?P.*) not allowed because shell (?P\S+) is not executable$`) + userNonExecutableShellRE = regexp.MustCompile(`^User (?P.*) not allowed because shell (?P.*) is not executable$`) // userInDenyUsersRE matches an OpenSSH log message that occurs // when the user is listed in DenyUsers. @@ -164,7 +164,7 @@ var ( // pw->pw_name, hostname); // //nolint:lll // This is a long regex - userInDenyUsersRE = regexp.MustCompile(`^User (?P.*) from (?P\S+) not allowed because listed in DenyUsers$`) + userInDenyUsersRE = regexp.MustCompile(`^User (?P.*) from (?P.*) not allowed because listed in DenyUsers$`) // userNotInAnyGroupRE matches an OpenSSH log message that // occurs when the user is not in any group. @@ -175,7 +175,7 @@ var ( // "not in any group", pw->pw_name, hostname); // //nolint:lll // This is a long regex - userNotInAnyGroupRE = regexp.MustCompile(`^User (?P.*) from (?P\S+) not allowed because not in any group$`) + userNotInAnyGroupRE = regexp.MustCompile(`^User (?P.*) from (?P.*) not allowed because not in any group$`) // userGroupInDenyGroupsRE matches an OpenSSH log message that // occurs when the user's group is listed in DenyUsers. @@ -189,7 +189,7 @@ var ( // pw->pw_name, hostname); // //nolint:lll // This is a long regex - userGroupInDenyGroupsRE = regexp.MustCompile(`^User (?P.*) from (?P\S+) not allowed because a group is listed in DenyGroups$`) + userGroupInDenyGroupsRE = regexp.MustCompile(`^User (?P.*) from (?P.*) not allowed because a group is listed in DenyGroups$`) // userGroupNotListedInAllowGroupsRE matches an OpenSSH log // message that occurs when none of the user's groups appear @@ -204,7 +204,7 @@ var ( // "in AllowGroups", pw->pw_name, hostname); // //nolint:lll // This is a long regex - userGroupNotListedInAllowGroupsRE = regexp.MustCompile(`^User (?P.*) from (?P\S+) not allowed because none of user's groups are listed in AllowGroups$`) + userGroupNotListedInAllowGroupsRE = regexp.MustCompile(`^User (?P.*) from (?P.*) not allowed because none of user's groups are listed in AllowGroups$`) // rootLoginRefusedRE matches an OpenSSH log message that occurs // when a root user login attempt fails. @@ -213,7 +213,7 @@ var ( // // logit("ROOT LOGIN REFUSED FROM %.200s port %d", // ssh_remote_ipaddr(ssh), ssh_remote_port(ssh)); - rootLoginRefusedRE = regexp.MustCompile(`^ROOT LOGIN REFUSED FROM (?P\S+) port (?P\d+)$`) + rootLoginRefusedRE = regexp.MustCompile(`^ROOT LOGIN REFUSED FROM (?P.*) port (?P.*)$`) // badOwnerOrModesForHostFileRE matches an OpenSSH log message // that occurs when a user's authorized_keys file has incorrect @@ -237,7 +237,7 @@ var ( // // logit("Nasty PTR record \"%s\" is set up for %s, ignoring", // name, ntop); - nastyPTRRecordRE = regexp.MustCompile(`^Nasty PTR record "(?P\S+)" is set up for (?P\S+), ignoring$`) + nastyPTRRecordRE = regexp.MustCompile(`^Nasty PTR record "(?P.*)" is set up for (?P.*), ignoring$`) // reverseMappingCheckFailedRE matches an OpenSSH log message // that occurs when the reverse DNS lookup fails. @@ -250,7 +250,7 @@ var ( // "[%s] failed.", name, ntop); // //nolint:lll // This is a long regex - reverseMappingCheckFailedRE = regexp.MustCompile(`^reverse mapping checking getaddrinfo for (?P\S+) \[(?P\S+)\] failed.$`) + reverseMappingCheckFailedRE = regexp.MustCompile(`^reverse mapping checking getaddrinfo for (?P.*) \[(?P.*)\] failed.$`) // doesNotMapBackToAddrRE matches an OpenSSH log message that // occurs when the reverse DNS lookup yields a record that does @@ -264,7 +264,7 @@ var ( // "map back to the address.", ntop, name); // //nolint:lll // This is a long regex - doesNotMapBackToAddrRE = regexp.MustCompile(`^Address (?P\S+) maps to (?P\S+), but this does not map back to the address.$`) + doesNotMapBackToAddrRE = regexp.MustCompile(`^Address (?P.*) maps to (?P.*), but this does not map back to the address.$`) // maxAuthAttemptsExceededRE matches an OpenSSH log message that // occurs when the maximum authentication attempt limit is exceeded @@ -280,7 +280,7 @@ var ( // ssh_remote_port(ssh)); // //nolint:lll // This is a long regex - maxAuthAttemptsExceededRE = regexp.MustCompile(`^maximum authentication attempts exceeded for (?P.*) from (?P.*) port (?P\d+) ssh[[:alnum:]]+$`) + maxAuthAttemptsExceededRE = regexp.MustCompile(`^maximum authentication attempts exceeded for (?P.*) from (?P.*) port (?P.*) ssh[[:alnum:]]+$`) // revokedPublicKeyByFileRE matches an OpenSSH log message that // occurs when the client's public key appears in the file named diff --git a/processors/sshd/user_type_test.go b/processors/sshd/user_type_test.go index 6caea133..9ea20761 100644 --- a/processors/sshd/user_type_test.go +++ b/processors/sshd/user_type_test.go @@ -15,8 +15,8 @@ import ( // The linter made me do this, sorry. const ( - expUsername = "foo foo" - expSource = "bar" + expUsername = "abc ABC !@#$%^&*() ,. <>? 123" + expSource = "192.168.1.2:666 abc ABC !@#$%^&*() <>? 123.com" ) func TestUserTypeLogAuditFn(t *testing.T) { @@ -42,6 +42,27 @@ func TestUserTypeLogAuditFn(t *testing.T) { } } +func TestProcessAcceptedPasswordEntry(t *testing.T) { + t.Parallel() + + p, events := newUserLogSSHDProcessor(t, + fmt.Sprintf("Accepted password for %s from %s port %s ssh2", + expUsername, expSource, expPort)) + + err := processAcceptedPasswordEntry(p) + + require.NoError(t, err) + + select { + case event := <-events: + require.Equal(t, expSource, event.Source.Value) + require.Equal(t, expUsername, event.Subjects["loggedAs"]) + require.Equal(t, expPort, event.Source.Extra["port"]) + default: + t.Fatal("expected a channel write - got none") + } +} + func TestProcessNotInAllowUsersEntry(t *testing.T) { t.Parallel() @@ -192,11 +213,13 @@ func newUserLogSSHDProcessor(t *testing.T, logEntry string) (x *SshdProcessorer, events := make(chan *auditevent.AuditEvent, 1) p := &SshdProcessorer{ + ctx: context.Background(), + logins: make(chan common.RemoteUserLogin, 1), logEntry: logEntry, nodeName: "a", machineID: "b", when: time.Now(), - pid: "c", + pid: "1", eventW: auditevent.NewAuditEventWriter(&testtools.TestAuditEncoder{ Ctx: context.Background(), Events: events,