Openfind Mail2000 认证前 RCE 漏洞分析
一、前言 Mail2000 是一套由台湾厂商 Openfind 所开发,简单易用的电子邮件系统,被广泛使用于台湾的公家机关、教育机构,如台北市教育局、中科院,以及台湾科技大学都有使用 Mail2000 作为主要的邮件服务器。本文以研究学习为目的对 Mail2000 的一个漏洞的成因和利用进行详细分析。 该漏洞是Mail2000的Web服务在处理多个文件的http数据包时未对全局结构体中的数组进行边界检查,导致越界写堆地址。针对原作者使用堆喷+爆破的利用手法,本文将介绍一种仅爆破地址即可利用的更加稳定的手法。 二、服务器架构 邮件系统的攻击面一般是邮件服务(imap、pop3、smtp)和Web服务。 Mail2000的Web服务器采用的是Apache httpd和CGI (Common Gateway Interface)的架构,实现如图: 当客户端向Web服务器(httpd)发送一个http请求时,httpd对数据包作简单的路由鉴权等处理,之后fork一个子进程。子进程中调用execve运行对应的CGI程序,CGI程序处理完请求后通过httpd发送响应给客户端。CGI程序会使用一些动态库,其中libm2k.so和libm2kc.so是由Openfind开发实现的两个核心库。本文分析的漏洞就存在libm2kc中。 三、漏洞成因 首先了解http发送多个文件的格式。在http格式中如果要发送多个文件首先需要Content-Type指定是multipart以及指定boundary,http正文中每两个boundary之间表示一个文件内容。文件内容是http头加上http正文的格式。 Content-Type: multipart/form-data; boundary="--AaBbCcDd" --AaBbCcDd Content-Disposition: form-data; name="files"; filename="file1.txt" Content-Type: text/plain aaaabbbbcccc --AaBbCcDd Content-Disposition: form-data; name="files"; filename="file2.txt" Content-Type: text/plain ddddeeeeffff --AaBbCcDd 在处理多个文件的请求时,libm2kc使用stCGIEnv结构体来存储相关文件信息。这里重点关注multipart_file_arr变量,该变量是MultipartFileVar结构体数组,个数固定为200。MultipartFileVar中的name和filaname对应文件内容中的Content-Disposition中的name和filename。 00000000 stCGIEnv struc ; (sizeof=0xD308, align=0x8, mappedto_126) 00000000 cgi_var_content dq ? 00000008 cgi_var_str_len_from_content_length_or_strlen dq ? 00000010 cgi_var_arr dq 6144 dup(?) 0000C010 multipart_file_arr MultipartFileVar 200 dup(?) 0000D2D0 file_arr dq ? 0000D2D8 file_max_count dd ?...