Microsoft Exchange Server是一款流行的邮件服务器。 Microsoft Exchange中负责解析iCal邮件附件的代码中漏洞,远程攻击者可能利用此漏洞导致Exchange进程崩溃。 iCal文件格式包含有一系列的记录,由BEGIN和END标签划分开,每个记录都可能包含有多个命名属性。Exchange的iCal解析器维护一个当前环境中有效属性的表格,遇到新的记录就会切换到合适的表格。X-MICROSOFT-CDO-MODPROPS属性是一个Microsoft扩展,允许iCal文件指定特定记录中应认为有效的属性列表,这时Exchange会乎略所有其他属性,如下所示:BEGIN:VEVENT X-MICROSOFT-CDO-MODPROPS:BEGIN,DTEND,DTSTART,END DTSTART:19970714T170000Z DTEND:19970715T035959Z SUMMARY:Bastille Day Party END:VEVENT 在这个例子中,Exchange不会处理SUMMARY属性。 当解析器遇到MODPROPS属性时,就会调用CICalSchema::AllocPropTables分配有效属性的新的表格,指向新表格的指针储存在this->field_F0,有效属性的列表被拷贝到这个表格中。如果存在第二个MODPROPS属性的话,就会再次调用该函数并重新使用之前分配的表格。如果第二个MODPROPS属性比第一个长的话,拷贝循环就会写过表格的末尾。 MS06-019通过在AllocPropTables函数的开始添加对CICalSchema::FreePropTables调用来修复这个漏洞,但FreePropTables还将this->field_28指针设置为空,之后在AllocPropTables的memcpy操作中使用了这个空指针,导致Exchange崩溃。 // Allocate a new property table int CICalSchema::AllocPropTables(arg_0, arg_4) { this->FreePropTables(); ... // Allocate space for the new table if (this->field_F0 == NULL)...
Microsoft Exchange Server是一款流行的邮件服务器。 Microsoft Exchange中负责解析iCal邮件附件的代码中漏洞,远程攻击者可能利用此漏洞导致Exchange进程崩溃。 iCal文件格式包含有一系列的记录,由BEGIN和END标签划分开,每个记录都可能包含有多个命名属性。Exchange的iCal解析器维护一个当前环境中有效属性的表格,遇到新的记录就会切换到合适的表格。X-MICROSOFT-CDO-MODPROPS属性是一个Microsoft扩展,允许iCal文件指定特定记录中应认为有效的属性列表,这时Exchange会乎略所有其他属性,如下所示:BEGIN:VEVENT X-MICROSOFT-CDO-MODPROPS:BEGIN,DTEND,DTSTART,END DTSTART:19970714T170000Z DTEND:19970715T035959Z SUMMARY:Bastille Day Party END:VEVENT 在这个例子中,Exchange不会处理SUMMARY属性。 当解析器遇到MODPROPS属性时,就会调用CICalSchema::AllocPropTables分配有效属性的新的表格,指向新表格的指针储存在this->field_F0,有效属性的列表被拷贝到这个表格中。如果存在第二个MODPROPS属性的话,就会再次调用该函数并重新使用之前分配的表格。如果第二个MODPROPS属性比第一个长的话,拷贝循环就会写过表格的末尾。 MS06-019通过在AllocPropTables函数的开始添加对CICalSchema::FreePropTables调用来修复这个漏洞,但FreePropTables还将this->field_28指针设置为空,之后在AllocPropTables的memcpy操作中使用了这个空指针,导致Exchange崩溃。 // Allocate a new property table int CICalSchema::AllocPropTables(arg_0, arg_4) { this->FreePropTables(); ... // Allocate space for the new table if (this->field_F0 == NULL) this->field_F0 = new(vector_size*16); ... // NULL pointer dereference of this->field_28 memcpy( &this->field_F4[offset_F4], &this->field_28[index*20], 20); } // Free the property table void CICalSchema::FreePropTables() { if (this->field_F0 != NULL) { ... ExFree(this->field_F0); this->field_F0 = NULL; } if (this->field_F4 != NULL) { if (this->field_28 == this->field_F4) { this->field_28 = NULL; // set this->field_28 to NULL this->field_1C = 0; } ExFree(this->field_F4); this->field_F4 = NULL; } ... }