-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
In src/analysisd/cleanevent.c the OS_CleanMSG function performs pattern matching and if applicable, tries to decode syslog messages to populate some lf structure fields according to the syslog data.
ossec-hids/src/analysisd/cleanevent.c
Lines 88 to 169 in abb36d4
| /* Check for the syslog date format | |
| * ( ex: Dec 29 10:00:01 | |
| * or 2015-04-16 21:51:02,805 for proftpd 1.3.5 | |
| * or 2007-06-14T15:48:55-04:00 for syslog-ng isodate | |
| * or 2007-06-14T15:48:55.3352-04:00 for syslog-ng isodate with up to 6 optional fraction of a second | |
| * or 2009-05-22T09:36:46.214994-07:00 for rsyslog | |
| * or 2015 Dec 29 10:00:01 ) | |
| */ | |
| if ( | |
| ( /* ex: Dec 29 10:00:01 */ | |
| (loglen > 17) && | |
| (pieces[3] == ' ') && | |
| (pieces[6] == ' ') && | |
| (pieces[9] == ':') && | |
| (pieces[12] == ':') && | |
| (pieces[15] == ' ') && (lf->log += 16) | |
| ) | |
| || | |
| ( /* ex: 2015-04-16 21:51:02,805 */ | |
| (loglen > 24) && | |
| (pieces[4] == '-') && | |
| (pieces[7] == '-') && | |
| (pieces[10] == ' ') && | |
| (pieces[13] == ':') && | |
| (pieces[16] == ':') && | |
| (pieces[19] == ',') && | |
| (lf->log += 23) | |
| ) | |
| || | |
| ( | |
| (loglen > 33) && | |
| (pieces[4] == '-') && | |
| (pieces[7] == '-') && | |
| (pieces[10] == 'T') && | |
| (pieces[13] == ':') && | |
| (pieces[16] == ':') && | |
| ( /* ex: 2007-06-14T15:48:55-04:00 */ | |
| ( | |
| (pieces[22] == ':') && | |
| (pieces[25] == ' ') && (lf->log += 26) | |
| ) | |
| || | |
| /* ex: 2007-06-14T15:48:55.3-04:00 or 2009-05-22T09:36:46,214994-07:00 */ | |
| ( | |
| ( | |
| (pieces[19] == '.') || (pieces[19] == ',') | |
| ) | |
| && | |
| ( | |
| ( (pieces[24] == ':') && (lf->log += 27) ) || | |
| ( (pieces[25] == ':') && (lf->log += 28) ) || | |
| ( (pieces[26] == ':') && (lf->log += 29) ) || | |
| ( (pieces[27] == ':') && (lf->log += 30) ) || | |
| ( (pieces[28] == ':') && (lf->log += 31) ) || | |
| ( (pieces[29] == ':') && (lf->log += 32) ) | |
| ) | |
| ) | |
| ) | |
| ) | |
| || | |
| ( /* ex: 2015 Dec 29 10:00:01 */ | |
| (loglen > 21) && | |
| (isdigit(pieces[0])) && | |
| (pieces[4] == ' ') && | |
| (pieces[8] == ' ') && | |
| (pieces[11] == ' ') && | |
| (pieces[14] == ':') && | |
| (pieces[17] == ':') && | |
| (pieces[20] == ' ') && (lf->log += 21) | |
| ) | |
| || | |
| ( | |
| /* ex: 2019:11:06-00:08:03 */ | |
| (loglen > 20) && | |
| (isdigit(pieces[0])) && | |
| (pieces[4] == ':') && | |
| (pieces[7] == ':') && | |
| (pieces[10] == '-') && | |
| (pieces[13] == ':') && | |
| (pieces[16] == ':') && (lf->log += 20) | |
| ) | |
| ) { |
When a message contains leading text matching the patterns expected for syslog, and contains a substring like "[ID xx facility.severity]" in the correct location OS_CleanMSG will attempt to remove it by advancing the lf->log pointer beyond the end of the substring:
ossec-hids/src/analysisd/cleanevent.c
Lines 327 to 345 in abb36d4
| /* Remove [ID xx facility.severity] */ | |
| if (pieces) { | |
| /* Set log after program name */ | |
| lf->log = pieces; | |
| if ((pieces[0] == '[') && | |
| (pieces[1] == 'I') && | |
| (pieces[2] == 'D') && | |
| (pieces[3] == ' ')) { | |
| pieces += 4; | |
| /* Going after the ] */ | |
| pieces = strchr(pieces, ']'); | |
| if (pieces) { | |
| pieces += 2; | |
| lf->log = pieces; | |
| } | |
| } | |
| } |
The code is careful about checking the result from strstr when advancing to the expected closing ], however it makes an assumption that there must be a non-null character following the ] when it subsequently advances the pieces pointer by 2:
ossec-hids/src/analysisd/cleanevent.c
Line 341 in abb36d4
| pieces += 2; |
If a message like "Oct 31 00:00:00 0 sshd: [ID 0 auth.notice]" is processed OS_CleanMSG will advance beyond the terminating null byte of lf->log, resulting in a heap overflow when operating on the lf->log pointer subsequently during decoding.
This code was introduced in 8672fa0 on Nov 18, 2006. I believe it affects OSSEC 2.7+.
This is triggerable via an authenticated client through the ossec-remoted. The client needs only write a message to the remote server of any queue type that will match the expected syslog format and authority substring, but end immediately after the ].
I think the best fix is to change the pieces pointer to be incremented by 1 instead of 2, or to update the strstr check for "[ " instead of just "[" (edit: implemented in #1824),.