Pidgin是一款跨平台的实时通信客户端,它支持多个常用的实时通信协议,用户可用同一个软件登录不同的实时通信服务。 Pidgin和其他一些即时消息客户端所使用的Libpurple库中存在内存破坏漏洞,远程攻击者可以通过向聊天客户端发送特制的MSNSLP报文触发这个漏洞,导致执行任意代码。 攻击需要发送两个连续的MSNSLP消息,第一个用于对slpmsg存储会话id,第二个用于触发漏洞,最终目标是到达msn_slplink_process_msg()中的memcpy()调用。需要创建偏移为非0的MSNSLP消息,因为这个值是memcpy()的目标。 因为偏移非0,所以在调用msn_slplink_message_find()返回NULL时会出现第一个问题: /----------- if (offset == 0) { .. construct a new slpmsg .. } else { slpmsg = msn_slplink_message_find(slplink, msg->msnslp_header.session_id, msg->msnslp_header.id); } if (slpmsg == NULL) { /* Probably the transfer was canceled */ purple_debug_error("msn", "Couldn't find slpmsg\n"); return; } - -----------/ 因此,slpmsg必须为非空,这就是为什么需要发送两次消息才能进行攻击。发送的第一个MSNSLP消息偏移为0,用于创建slpmsg对象,Libpurple会存储这个对象;第二个MSNSLP消息的偏移非0,但由于Libpurple已经存储了第一个MSNSLP消息,因此调用msn_slplink_message_find()会有效的返回之前的对象而不是NULL: /----------- if (slpmsg->fp) { /* fseek(slpmsg->fp, offset, SEEK_SET); */ len = fwrite(data, 1, len, slpmsg->fp); } else if (slpmsg->size) { if (G_MAXSIZE - len < offset ||...
Pidgin是一款跨平台的实时通信客户端,它支持多个常用的实时通信协议,用户可用同一个软件登录不同的实时通信服务。 Pidgin和其他一些即时消息客户端所使用的Libpurple库中存在内存破坏漏洞,远程攻击者可以通过向聊天客户端发送特制的MSNSLP报文触发这个漏洞,导致执行任意代码。 攻击需要发送两个连续的MSNSLP消息,第一个用于对slpmsg存储会话id,第二个用于触发漏洞,最终目标是到达msn_slplink_process_msg()中的memcpy()调用。需要创建偏移为非0的MSNSLP消息,因为这个值是memcpy()的目标。 因为偏移非0,所以在调用msn_slplink_message_find()返回NULL时会出现第一个问题: /----------- if (offset == 0) { .. construct a new slpmsg .. } else { slpmsg = msn_slplink_message_find(slplink, msg->msnslp_header.session_id, msg->msnslp_header.id); } if (slpmsg == NULL) { /* Probably the transfer was canceled */ purple_debug_error("msn", "Couldn't find slpmsg\n"); return; } - -----------/ 因此,slpmsg必须为非空,这就是为什么需要发送两次消息才能进行攻击。发送的第一个MSNSLP消息偏移为0,用于创建slpmsg对象,Libpurple会存储这个对象;第二个MSNSLP消息的偏移非0,但由于Libpurple已经存储了第一个MSNSLP消息,因此调用msn_slplink_message_find()会有效的返回之前的对象而不是NULL: /----------- if (slpmsg->fp) { /* fseek(slpmsg->fp, offset, SEEK_SET); */ len = fwrite(data, 1, len, slpmsg->fp); } else if (slpmsg->size) { if (G_MAXSIZE - len < offset || (offset='' + len='') > slpmsg->size) { purple_debug_error("msn", "Oversized slpmsg - msgsize=%lld offset=%" G_GSIZE_FORMAT " len=%" G_GSIZE_FORMAT "\n", slpmsg->size, offset, len); g_return_if_reached(); } else memcpy(slpmsg->buffer + offset, data, len); } - -----------/ 例如,如果创建的第一个MSNSLP消息大小为0x01ffffff,第二个消息的偏移为小于0x01ffffff - len的任意值,就满足了任意写入的条件。 最后,以小于0x01ffffff - len的任意偏移值到达了memcpy(),缓冲区指向0。这意味着可以向低于0x01ffffff - len的任意位置写入数据内容。