Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CVE-2020-8443: analysisd: OS_CleanMSG off-by-one heap overflow cleaning syslog msgs. #1816

Closed
cpu opened this issue Jan 15, 2020 · 1 comment · Fixed by #1824
Closed

CVE-2020-8443: analysisd: OS_CleanMSG off-by-one heap overflow cleaning syslog msgs. #1816

cpu opened this issue Jan 15, 2020 · 1 comment · Fixed by #1824

Comments

@cpu
Copy link
Contributor

cpu commented Jan 15, 2020

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.

/* 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:

/* 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:

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),.

@cpu cpu changed the title analysisd: OS_CleanMSG off-by-one heap overflow cleaning syslog msgs. CVE-2020-8443: analysisd: OS_CleanMSG off-by-one heap overflow cleaning syslog msgs. Jan 30, 2020
@cpu
Copy link
Contributor Author

cpu commented Jan 30, 2020

This was assigned CVE-2020-8443

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant