void send_channel_event(EVT_HANDLE evt, os_channel *channel) { DWORD buffer_length = 0; PEVT_VARIANT properties_values = NULL; DWORD count = 0; EVT_HANDLE context = NULL; os_event event = {0}; char final_msg[OS_MAXSTR]; int result = 0; if ((context = EvtCreateRenderContext(count, NULL, EvtRenderContextSystem)) == NULL) { log2file( "%s: ERROR: Could not EvtCreateRenderContext() for (%s) which returned (%lu)", ARGV0, channel->evt_log, GetLastError()); goto cleanup; } /* Make initial call to determine buffer size necessary */ result = EvtRender(context, evt, EvtRenderEventValues, 0, NULL, &buffer_length, &count); if (result != FALSE || GetLastError() != ERROR_INSUFFICIENT_BUFFER) { log2file( "%s: ERROR: Could not EvtRender() to determine buffer size for (%s) which returned (%lu)", ARGV0, channel->evt_log, GetLastError()); goto cleanup; } if ((properties_values = malloc(buffer_length)) == NULL) { log2file( "%s: ERROR: Could not malloc() memory to process event (%s) which returned [(%d)-(%s)]", ARGV0, channel->evt_log, errno, strerror(errno)); goto cleanup; } if (!EvtRender(context, evt, EvtRenderEventValues, buffer_length, properties_values, &buffer_length, &count)) { log2file( "%s: ERROR: Could not EvtRender() for (%s) which returned (%lu)", ARGV0, channel->evt_log, GetLastError()); goto cleanup; } event.name = get_property_value(&properties_values[EvtSystemChannel]); event.id = properties_values[EvtSystemEventID].UInt16Val; event.source = get_property_value(&properties_values[EvtSystemProviderName]); event.uid = properties_values[EvtSystemUserID].Type == EvtVarTypeNull ? NULL : properties_values[EvtSystemUserID].SidVal; event.computer = get_property_value(&properties_values[EvtSystemComputer]); event.time_created = properties_values[EvtSystemTimeCreated].FileTimeVal; event.keywords = properties_values[EvtSystemKeywords].Type == EvtVarTypeNull ? 0 : properties_values[EvtSystemKeywords].UInt64Val; event.level = properties_values[EvtSystemLevel].Type == EvtVarTypeNull ? -1 : properties_values[EvtSystemLevel].ByteVal; switch (event.level) { case WINEVENT_CRITICAL: event.category = "CRITICAL"; break; case WINEVENT_ERROR: event.category = "ERROR"; break; case WINEVENT_WARNING: event.category = "WARNING"; break; case WINEVENT_INFORMATION: event.category = "INFORMATION"; break; case WINEVENT_VERBOSE: event.category = "DEBUG"; break; case WINEVENT_AUDIT: if (event.keywords & WINEVENT_AUDIT_FAILURE) { event.category = "AUDIT_FAILURE"; break; } else if (event.keywords & WINEVENT_AUDIT_SUCCESS) { event.category = "AUDIT_SUCCESS"; break; } default: event.category = "Unknown"; break; } if ((event.timestamp = WinEvtTimeToString(event.time_created)) == NULL) { log2file( "%s: ERROR: Could not convert timestamp for (%s)", ARGV0, channel->evt_log); goto cleanup; } /* Determine user and domain */ get_username_and_domain(&event); /* Get event log message */ if ((event.message = get_message(evt, properties_values[EvtSystemProviderName].StringVal, EvtFormatMessageEvent)) == NULL) { log2file( "%s: ERROR: Could not get message for (%s)", ARGV0, channel->evt_log); } else { /* Format message */ win_format_event_string(event.message); } snprintf( final_msg, sizeof(final_msg), "%s WinEvtLog: %s: %s(%d): %s: %s: %s: %s: %s", event.timestamp, event.name, event.category, event.id, event.source && strlen(event.source) ? event.source : "no source", event.user && strlen(event.user) ? event.user : "******", event.domain && strlen(event.domain) ? event.domain : "no domain", event.computer && strlen(event.computer) ? event.computer : "no computer", event.message && strlen(event.message) ? event.message : "(no message)" ); if (SendMSG(logr_queue, final_msg, "WinEvtLog", LOCALFILE_MQ) < 0) { merror(QUEUE_SEND, ARGV0); } if (channel->bookmark_enabled) { update_bookmark(evt, channel); } cleanup: free(properties_values); free_event(&event); if (context != NULL) { EvtClose(context); } return; }
/* Reads the event log */ void readel(os_el *el, int printit) { DWORD _evtid = 65535; DWORD nstr; DWORD user_size; DWORD domain_size; DWORD read, needed; int size_left; int str_size; int id; char mbuffer[BUFFER_SIZE + 1]; LPSTR sstr = NULL; char *tmp_str = NULL; char *category; char *source; char *computer_name; char *descriptive_msg; char el_user[OS_FLSIZE + 1]; char el_domain[OS_FLSIZE + 1]; char el_string[OS_MAXSTR + 1]; char final_msg[OS_MAXSTR + 1]; LPSTR el_sstring[OS_FLSIZE + 1]; /* er must point to the mbuffer */ el->er = (EVENTLOGRECORD *) &mbuffer; /* Zero the values */ el_string[OS_MAXSTR] = '\0'; el_user[OS_FLSIZE] = '\0'; el_domain[OS_FLSIZE] = '\0'; final_msg[OS_MAXSTR] = '\0'; el_sstring[0] = NULL; el_sstring[OS_FLSIZE] = NULL; /* Event log is not open */ if (!el->h) { return; } /* Read the event log */ while (ReadEventLog(el->h, EVENTLOG_FORWARDS_READ | EVENTLOG_SEQUENTIAL_READ, 0, el->er, BUFFER_SIZE - 1, &read, &needed)) { if (!printit) { /* Set er to the beginning of the buffer */ el->er = (EVENTLOGRECORD *)&mbuffer; continue; } while (read > 0) { /* We need to initialize every variable before the loop */ category = el_getCategory(el->er->EventType); source = (LPSTR) ((LPBYTE) el->er + sizeof(EVENTLOGRECORD)); computer_name = source + strlen(source) + 1; descriptive_msg = NULL; /* Get event id */ id = (int)el->er->EventID & _evtid; /* Initialize domain/user size */ user_size = 255; domain_size = 255; el_domain[0] = '\0'; el_user[0] = '\0'; /* We must have some description */ if (el->er->NumStrings) { size_left = OS_MAXSTR - OS_SIZE_1024; sstr = (LPSTR)((LPBYTE)el->er + el->er->StringOffset); el_string[0] = '\0'; for (nstr = 0; nstr < el->er->NumStrings; nstr++) { str_size = strlen(sstr); if (size_left > 1) { strncat(el_string, sstr, size_left); } tmp_str = strchr(el_string, '\0'); if (tmp_str) { *tmp_str = ' '; tmp_str++; *tmp_str = '\0'; } else { merror("%s: Invalid application string (size+)", ARGV0); } size_left -= str_size + 2; if (nstr <= 92) { el_sstring[nstr] = (LPSTR)sstr; el_sstring[nstr + 1] = NULL; } sstr = strchr( (LPSTR)sstr, '\0'); if (sstr) { sstr++; } else { break; } } /* Get a more descriptive message (if available) */ if (isVista && strcmp(el->name, "Security") == 0) { descriptive_msg = el_vista_getMessage(id, el_sstring); } else { descriptive_msg = el_getMessage(el->er, el->name, source, el_sstring); } if (descriptive_msg != NULL) { /* format message */ win_format_event_string(descriptive_msg); } } else { strncpy(el_string, "(no message)", 128); } /* Get username */ if (el->er->UserSidLength) { SID_NAME_USE account_type; if (!LookupAccountSid(NULL, (SID *)((LPSTR)el->er + el->er->UserSidOffset), el_user, &user_size, el_domain, &domain_size, &account_type)) { strncpy(el_user, "(no user)", 255); strncpy(el_domain, "no domain", 255); } } else if (isVista && strcmp(el->name, "Security") == 0) { int uid_array_id = -1; switch (id) { case 4624: uid_array_id = 5; break; case 4634: uid_array_id = 1; break; case 4647: uid_array_id = 1; break; case 4769: uid_array_id = 0; break; } if ((uid_array_id >= 0) && el_sstring[uid_array_id] && el_sstring[uid_array_id + 1]) { strncpy(el_user, el_sstring[uid_array_id], OS_FLSIZE); strncpy(el_domain, el_sstring[uid_array_id + 1], OS_FLSIZE); } else { strncpy(el_user, "(no user)", 255); strncpy(el_domain, "no domain", 255); } } else { strncpy(el_user, "(no user)", 255); strncpy(el_domain, "no domain", 255); } if (printit) { DWORD _evtid = 65535; int id = (int)el->er->EventID & _evtid; final_msg[OS_MAXSTR - OS_LOG_HEADER] = '\0'; final_msg[OS_MAXSTR - OS_LOG_HEADER - 1] = '\0'; snprintf(final_msg, OS_MAXSTR - OS_LOG_HEADER - 1, "%s WinEvtLog: %s: %s(%d): %s: %s: %s: %s: %s", epoch_to_human((int)el->er->TimeGenerated), el->name, category, id, source, el_user, el_domain, computer_name, descriptive_msg != NULL ? descriptive_msg : el_string); if (SendMSG(logr_queue, final_msg, "WinEvtLog", LOCALFILE_MQ) < 0) { merror(QUEUE_SEND, ARGV0); } } if (descriptive_msg != NULL) { LocalFree(descriptive_msg); } /* Change the point to the er */ read -= el->er->Length; el->er = (EVENTLOGRECORD *)((LPBYTE) el->er + el->er->Length); } /* Set er to the beginning of the buffer */ el->er = (EVENTLOGRECORD *)&mbuffer; } id = GetLastError(); if (id == ERROR_HANDLE_EOF) { return; } /* Event log was cleared */ else if (id == ERROR_EVENTLOG_FILE_CHANGED) { char msg_alert[512 + 1]; msg_alert[512] = '\0'; merror("%s: WARN: Event log cleared: '%s'", ARGV0, el->name); /* Send message about cleared */ snprintf(msg_alert, 512, "ossec: Event log cleared: '%s'", el->name); SendMSG(logr_queue, msg_alert, "WinEvtLog", LOCALFILE_MQ); /* Close the event log and reopen */ CloseEventLog(el->h); el->h = NULL; /* Reopen */ if (startEL(el->name, el) < 0) { merror("%s: ERROR: Unable to reopen event log '%s'", ARGV0, el->name); } } else { debug1("%s: WARN: Error reading event log: %d", ARGV0, id); } }