Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/analysisd/cleanevent.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,10 @@ int OS_CleanMSG_ex(char *msg, Eventinfo *lf, time_t recv_time, int update_time_g

os_strdup(msg, lf->location);

/*CVE-2020-8445 fix*/
remove_control_characters(pieces);
/* CVE-2020-8445: strip C0/DEL from the log body. Syscheck locations keep
* '\n'/'\\t' so report_changes (and ACL) framing survives DecodeSyscheck
* (#2359). */
remove_control_characters_ex(pieces, OS_IsSyscheckLocation(lf->location));

/* Get the log length */
loglen = strlen(pieces) + 1;
Expand Down
8 changes: 8 additions & 0 deletions src/headers/file_op.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,5 +79,13 @@ int os_win_network_path(const char *path);

void remove_control_characters(char *str);

/* When preserve_nl is non-zero, '\\n' and '\\t' are kept (syscheck
* report_changes / ACL framing). Other C0 and DEL are still removed. */
void remove_control_characters_ex(char *str, int preserve_nl);

/* True for local "syscheck" / "syscheck-registry", or the module after the
* last "->" in an agent location ("(name) ip->syscheck"). */
int OS_IsSyscheckLocation(const char *location);

bool is_control_character(char c);
#endif /* __FILE_H */
61 changes: 53 additions & 8 deletions src/shared/file_op.c
Original file line number Diff line number Diff line change
Expand Up @@ -1807,23 +1807,68 @@ int w_ref_parent_folder(const char * path) {
}

bool is_control_character(char c) {
return (c >= 0 && c <= 31) || c == 127 || c == '\n';
unsigned char uc = (unsigned char)c;

/* C0 controls and DEL. '\n' is included (uc == 10). */
return (uc <= 31) || (uc == 127);
}

void remove_control_characters(char *str) {
int len = strlen(str);
int OS_IsSyscheckLocation(const char *location)
{
const char *mod;
const char *p;
const char *arrow = NULL;

if (!location || *location == '\0') {
return (0);
}

/* Agent locations are "(name) ip->module". Use the last "->" so a
* crafted name containing "->" cannot select the wrong component. */
for (p = location; (p = strstr(p, "->")) != NULL; p += 2) {
arrow = p;
}

mod = arrow ? arrow + 2 : location;
if (strcmp(mod, SYSCHECK) == 0 || strcmp(mod, SYSCHECK_REG) == 0) {
return (1);
}

return (0);
}

void remove_control_characters_ex(char *str, int preserve_nl) {
int len;
int i, j;

if (!str) {
return;
}

len = (int)strlen(str);

for (i = 0, j = 0; i < len; i++) {
if (!is_control_character(str[i])) {
str[j] = str[i];
j++;
char c = str[i];

/* Syscheck report_changes / Windows ACL text use '\n' as the
* path/diff separator (#2359). Keep tab too for diff bodies. */
if (preserve_nl && (c == '\n' || c == '\t')) {
str[j++] = c;
continue;
}

if (!is_control_character(c)) {
str[j++] = c;
} else {
DEBUG_MSG("%s:DEBUG: control character removed: %d",ARGV0, str[i]);
DEBUG_MSG("%s:DEBUG: control character removed: %d", ARGV0, (unsigned char)c);
}
}

str[j] = '\0'; // Null-terminate the string after removing control characters
str[j] = '\0';
}

void remove_control_characters(char *str) {
remove_control_characters_ex(str, 0);
}

#ifdef WIN32
Expand Down
9 changes: 8 additions & 1 deletion src/shared/tests/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ TOP = ../..
CFLAGS_COMMON = -g -Wall -I$(TOP)/headers -I$(TOP) -I$(TOP)/analysisd

# Headless tests run by `check`. Interactive helpers stay under `legacy_helpers`.
AUTO_TEST_BINS = thread_pool_test queue_op_test string_test fim_sum_test ar_expect_test fim_maint_test win_acl_test
AUTO_TEST_BINS = thread_pool_test queue_op_test string_test fim_sum_test ar_expect_test fim_maint_test win_acl_test report_changes_ctrl_test
LEGACY_HELPER_BINS = prime_test hash_test merge_test ip_test

.PHONY: maketest check clean legacy_helpers
Expand Down Expand Up @@ -45,6 +45,13 @@ fim_maint_test: fim_maint_test.c $(TOP)/shared.a
$(TOP)/os_xml.a $(TOP)/os_zlib.a $(TOP)/libcJSON.a -Wl,--end-group \
-lpcre2-8 -lm -lpthread -lz

# #2359: report_changes '\\n' must survive remove_control_characters().
report_changes_ctrl_test: report_changes_ctrl_test.c $(TOP)/shared.a
$(CC) $(CFLAGS_COMMON) -DARGV0=\"report_changes_ctrl_test\" -o $@ \
report_changes_ctrl_test.c \
-Wl,--start-group $(TOP)/shared.a $(TOP)/os_regex.a -Wl,--end-group \
-lpcre2-8 -lm -lpthread

# Interactive / argv-driven helpers (not part of automated check).
legacy_helpers:
$(CC) -g -I$(TOP)/headers -I$(TOP) -DARGV0=\"prime_test\" -o prime_test \
Expand Down
Loading