涉及程序: Cyrus Sieve/libSieve 描述: Cyrus Sieve/libSieve 缓冲溢出缺陷允许非法浏览其他用户邮件 详细: Cyrus 的 Sieve /libSieve 程序在实现时存在一个典型的缓冲溢出缺陷,这是由于 Sieve 对用户递交的代码缺乏正确边界检查引起的。 在对 Cyrus 的测试中发现,当递交的代码标题名超过100个字符,或IMAP标记超过100个字符,或其错误信息报文(error message)超过500个字符时,缓冲溢出就会被触发。 成功利用 Cyrus 的缓冲溢出缺陷,攻击者将能获得其他Cyrus用户的权限,非法读取所有用户的邮件。 受影响系统: libSieve 2.1.3 及之前版本 Cyrus IMAP 2.1.10 及之前版本 攻击方法: 当递交的代码标题名超过100个字符,或IMAP标记超过100个字符,或其错误信息报文(error message)超过500个字符时,缓冲溢出就会被触发。 解决方案: 第三方补丁(注意:用户在使用时还需要用他们生成 .c文件): diff -ru cyrus-imapd-2.1.10-old/sieve/addr.y cyrus-imapd-2.1.10/sieve/addr.y --- cyrus-imapd-2.1.10-old/sieve/addr.y 2002-10-28 18:30:18.000000000 +0200 +++ cyrus-imapd-2.1.10/sieve/addr.y 2002-12-02 04:52:58.000000000 +0200 @@ -82,8 +82,9 @@ /* copy address error message into buffer provided by sieve parser */ int yyerror(char *s) { -extern char addrerr<>; +extern char addrerr<512>; - strcpy(addrerr, s); + strncpy(addrerr, s, sizeof(addrerr)-1); + addrerr
= `\0`; return 0; } diff -ru cyrus-imapd-2.1.10-old/sieve/sieve.y cyrus-imapd-2.1.10/sieve/sieve.y --- cyrus-imapd-2.1.10-old/sieve/sieve.y 2002-05-14 19:51:50.000000000 +0300 +++ cyrus-imapd-2.1.10/sieve/sieve.y 2002-12-02 03:57:17.000000000 +0200 @@ -810,7 +810,7 @@ addrptr = s; addrerr<0> = \`\\0\`; /* paranoia */ if (addrparse()) { - sprintf(errbuf, \"address \`%s\`: %s\", s, addrerr); + snprintf(errbuf, sizeof(errbuf), \"address \`%s\`: %s\", s, addrerr); yyerror(errbuf); return 0; } @@ -835,7 +835,7 @@ ; controls, SP, and ; \":\". */ if (!((*h >= 33 && *h <= 57) || (*h >= 59 && *h <= 126))) { - sprintf(errbuf, \"header \`%s\`: not a valid header\", hdr); + snprintf(errbuf, sizeof(errbuf), \"header \`%s\`: not a valid header\", hdr); yyerror(errbuf); return 0; } @@ -853,14 +853,14 @@ if (strcmp(f, \"\\\\seen\") && strcmp(f, \"\\\\answered\") && strcmp(f, \"\\\\flagged\") && strcmp(f, \"\\\\draft\") && strcmp(f, \"\\\\deleted\")) { - sprintf(errbuf, \"flag \`%s\`: not a system flag\", f); + snprintf(errbuf, sizeof(errbuf), \"flag \`%s\`: not a system flag\", f); yyerror(errbuf); return 0; } return 1; } if (!imparse_isatom(f)) { - sprintf(errbuf, \"flag \`%s\`: not a valid keyword\", f); + snprintf(errbuf, sizeof(errbuf), \"flag \`%s\`: not a valid keyword\", f); yyerror(errbuf); return 0; }