/
githubmirror
/
audit-userspace
Обзор
Документация
Войти
/
githubmirror
/
audit-userspace
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
audisp/plugins/ids/model_bad_event.c
185 строк
5 KB
Steve Grubb
Update license and copyrights
20 июл 2026, 22:56
20 июл 2026, 22:56
aad6ac2
Код
Авторство
О чём код?
/* model_bad_event.c -- * Copyright 2021,2026 Steve Grubb. * All Rights Reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; see the file COPYING. If not, write to the * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor * Boston, MA 02110-1335, USA. * * Authors: * Steve Grubb <sgrubb@redhat.com> * */ #include "config.h" #include <libaudit.h> #include <string.h> #include <stdlib.h> #include "ids.h" #include "session.h" #include "origin.h" #include "model_bad_event.h" #include "reactions.h" /* Local Data */ static void terminate_sessions(void) { if (get_num_sessions() == 0) return; if (debug) my_printf("terminating all sessions"); // Might want to do more than this like update persistent scores destroy_sessions(); } // Look at the acct, is it a daemon acct and forbidden // Is the acct root and forbidden // is it a bad login // is it a new session static void start_session(auparse_state_t *au, struct ids_conf *config) { ids_address_t address; const char *addr = auparse_find_field(au, "addr"); int have_address = ids_address_parse(addr, &address); int service_acct = 0; char *acct = NULL; const char *atype = auparse_normalize_subject_kind(au); if (atype && strncmp(atype, "service", 7) == 0) service_acct = 1; if (auparse_normalize_subject_primary(au) == 1) { const char *field = auparse_interpret_field(au); if (field) acct = strdup(field); } // Have we seen this endpoint before? origin_data_t *o = find_origin(&address); if (have_address && o == NULL) { new_origin(&address); o = find_origin(&address); } // Is this login a service account? if (service_acct && !config->option_service_login_allowed) { my_printf("bad_service_login_origin: %s", acct ? acct : "?"); bad_service_login_origin(o, config, acct); } // Is this a root login else if (!config->option_root_login_allowed && acct && strcmp(acct, "root") == 0) { my_printf("watched_login_origin: %s", acct); watched_login_origin(o, config, acct); } // Check if it's a failed login if (auparse_normalize_get_results(au) == 1) { // Handle a bad login const char *res = auparse_interpret_field(au); if (res && strcmp(res, "failed") == 0) { // Since the login failed, we don't need to // start a new session bad_login_origin(o, config); free((void *)acct); return; } } // Look for new login sessions if (auparse_normalize_session(au) == 1) { unsigned int s = auparse_get_field_int(au); if (s != UNSET) { // new_session copies acct before storing it. new_session(s, &address, acct); // otherwise we have a strange daemon login } else if (debug) my_printf("start_session: can't find session in serial %s", auparse_get_type_name(au)); } free(acct); } static void end_session(auparse_state_t *au) { if (auparse_normalize_session(au) == 1) { const char *ses = auparse_get_field_str(au); if (ses && strcmp(ses, DAEMON_SESSION)) { unsigned int s = auparse_get_field_int(au); del_session(s); } } } /* This function receives a single complete event from the auparse library. */ void process_bad_event_model(auparse_state_t *au, struct ids_conf *config) { unsigned int answer = 0; auparse_first_record(au); int type = auparse_get_type(au); /* Now we can branch based on what the first record type we find. */ switch (type) { case AUDIT_SYSTEM_BOOT: case AUDIT_SYSTEM_SHUTDOWN: // Reset everything terminate_sessions(); break; // FIXME: update this list as events are added case AUDIT_ANOM_LOGIN_SERVICE: case AUDIT_ANOM_LOGIN_ACCT: // Do not process our own events break; case AUDIT_ANOM_LOGIN_FAILURES: { // Do not process our own events const char *exe = auparse_normalize_how(au); if (exe && strcmp(exe, "/usr/sbin/audisp-ids") == 0) break; } // fallthrough if pam related case AUDIT_ANOM_LOGIN_TIME: case AUDIT_ANOM_LOGIN_SESSIONS: case AUDIT_ANOM_LOGIN_LOCATION: // watch for pam discovered problems break; case AUDIT_USER_LOGIN: start_session(au, config); break; // case AUDIT_USER_END: user_end can be for su case AUDIT_USER_LOGOUT: end_session(au); break; default: break; } // We only mess with origins because it could be a bad login origin_data_t *o = current_origin(); if (o) { if (o->karma >= config->option_origin_failed_logins_threshold && !o->blocked) { //AUDIT_ANOM_ORIGIN_FAILURES answer |= config->option_origin_failed_logins_reaction; do_reaction(answer, "login_failures", NULL); } } }