Cyrus IMAP Server是一款免费开放源代码Interactive Mail Access Protocol (IMAP)协议实现,可使用在Unix和Linux操作系统下。 Cyrus-imapd的pop3d中存在远程溢出漏洞。如果在imapd.conf中Cyrus-imapd将popsubfolders设置为1的话,则攻击者就可以通过向远程pop3d发送超长的USER命令参数触发栈溢出。 在cyrus-imapd-2.3.2/imap/pop3d.c中,每次向pop3 server提供USER命令时都会调用pop3d_canon_user,ulen=0。在char userbuf[MAX_MAILBOX_NAME+1], *p; ... if (!ulen) ulen = strlen(user); ... memcpy(userbuf, user, ulen); userbuf[ulen] = \'\'\0\'\'; 这个例程中没有执行长度检查,如果user大于MAX_MAILBOX_NAME+1的话,memcpy就会溢出userbuf缓冲区。 --- snip ---static int popd_canon_user(sasl_conn_t *conn, void *context, const char *user, unsigned ulen, unsigned flags, const char *user_realm, char *out, unsigned out_max, unsigned *out_ulen) { char userbuf[MAX_MAILBOX_NAME+1], *p; size_t n; int r; if (!ulen) ulen = strlen(user); if (config_getswitch(IMAPOPT_POPSUBFOLDERS)) { /* make a working copy of the auth[z]id */ memcpy(userbuf, user, ulen); userbuf[ulen] = \'\'\0\'\'; user = userbuf; /* See if we\'\'re trying to access a subfolder */ if ((p =...
Cyrus IMAP Server是一款免费开放源代码Interactive Mail Access Protocol (IMAP)协议实现,可使用在Unix和Linux操作系统下。 Cyrus-imapd的pop3d中存在远程溢出漏洞。如果在imapd.conf中Cyrus-imapd将popsubfolders设置为1的话,则攻击者就可以通过向远程pop3d发送超长的USER命令参数触发栈溢出。 在cyrus-imapd-2.3.2/imap/pop3d.c中,每次向pop3 server提供USER命令时都会调用pop3d_canon_user,ulen=0。在char userbuf[MAX_MAILBOX_NAME+1], *p; ... if (!ulen) ulen = strlen(user); ... memcpy(userbuf, user, ulen); userbuf[ulen] = \'\'\0\'\'; 这个例程中没有执行长度检查,如果user大于MAX_MAILBOX_NAME+1的话,memcpy就会溢出userbuf缓冲区。 --- snip ---static int popd_canon_user(sasl_conn_t *conn, void *context, const char *user, unsigned ulen, unsigned flags, const char *user_realm, char *out, unsigned out_max, unsigned *out_ulen) { char userbuf[MAX_MAILBOX_NAME+1], *p; size_t n; int r; if (!ulen) ulen = strlen(user); if (config_getswitch(IMAPOPT_POPSUBFOLDERS)) { /* make a working copy of the auth[z]id */ memcpy(userbuf, user, ulen); userbuf[ulen] = \'\'\0\'\'; user = userbuf; /* See if we\'\'re trying to access a subfolder */ if ((p = strchr(userbuf, \'\'+\'\'))) { n = config_virtdomains ? strcspn(p, \"@\") : strlen(p); if (flags & SASL_CU_AUTHZID) { /* make a copy of the subfolder */ if (popd_subfolder) free(popd_subfolder); popd_subfolder = xstrndup(p, n); } /* strip the subfolder from the auth[z]id */ memmove(p, p+n, strlen(p+n)+1); ulen -= n; } } r = mysasl_canon_user(conn, context, user, ulen, flags, user_realm, out, out_max, out_ulen); if (!r & & popd_subfolder & & flags == SASL_CU_AUTHZID) { /* If we\'\'re only doing the authzid, put back the subfolder in case its used in the challenge/response calculation */ n = strlen(popd_subfolder); if (*out_ulen + n > out_max) { sasl_seterror(conn, 0, \"buffer overflow while canonicalizing\"); r = SASL_BUFOVER; } else { p = (config_virtdomains & & (p = strchr(out, \'\'@\'\'))) ? p : out + *out_ulen; memmove(p+n, p, strlen(p)+1); memcpy(p, popd_subfolder, n); *out_ulen += n; } } return r; } --- snip ---