我们如何在银行的邮件服务器中发现漏洞以及它如何受到威胁

我们经常对银行和其他金融机构进行渗透测试。我们还经常发现不同严重性级别的漏洞。这篇文章是关于这种情况之一。



最近,在检查银行Web资源的安全性时,我们在Exim 4.89邮件服务器中发现了一个漏洞,该漏洞可能导致远程执行代码。该漏洞称为CVE-2018-6789。使用PoC漏洞,我们在远程计算机上安装了反向外壳,然后访问银行的网站。







自然,我们想知道为什么可以利用这种漏洞。



CVE-2018-6789来自哪里?



简而言之,该漏洞是由于在Exim使用的base64.c:b64decode函数中计算缓冲区长度时出错。您可以在此处阅读更多信息(英文)。



如果输入特殊长度的字符串,则可以覆盖一个字节的信息,并使用简单的操作即可更改服务器命令,从而执行任意代码(RCE)。



Exim分配3 *(len / 4)+1字节的缓冲区来保存解码数据。但是,如果将错误的base64字符串送入函数输入,例如4n + 3,则Exim将为缓冲区分配3n + 1个字节。但与此同时,它将把3n + 2字节的数据写入缓冲区。这将导致堆中的一个字节被覆盖。



Exim提供store_malloc_3和store_free_3,它们是Glibc的malloc和free函数的包装。 Glibc分配大量数据,然后将其元数据存储在前0x10字节中,并返回指向内存的指针,用户可以在其中写入其数据。外观如下:





元数据包括上一个块的大小(上面的内存中的大小),当前块的大小和一些标志。大小的前三位用于存储标志。在该示例中,大小为0x81表示当前块为0x80字节,而先前的块已在使用中。



一旦被Exim使用,已释放的块将放置在双向链表中。 Glibc根据标志对其进行维护,并将释放的连续块合并为更大的块,以避免碎片。对于每个内存分配请求,Glibc均按FIFO顺序检查这些块并重新使用它们。





为了提高性能,Exim使用了自己的内存管理插件。它基于storeblock结构。 storeblock的主要特点是每个大小至少为0x2000字节,这成为利用的限制。请注意,storeblock也是块数据。这就是内存中的样子:





邮件服务器支持的用于在堆上组织数据的命令:



  • EHLO hostname. EHLO hostname sender_host_name. , store_free store_malloc .
  • . , , Exim .
  • AUTH. Exim base64 . , store_get (). store_get().
  • Reset EHLO/HELO, MAIL, RCPT. , Exim smtp_reset. store_reset , « ». , storeblock- store_get .




为了使用一个字节的堆溢出,我们必须能够释放base64解码字符串下的数据块。 Sender_host_name适合于此。



堆的形成方式应使数据块在包含sender_host_name的块上方被释放。





为此,您需要:



1.将一个大块放入未分类的垃圾箱中。首先,我们发送带有超大主机名的EHLO消息,以便它分配长度为0x6060的块并将其释放到未排序的bin中。



2.选择第一个存储块。然后,我们发送一个无法识别的命令来调用store_get(),并在释放的块中分配storeblock。



3.选择第二个块并释放第一个。我们发送EHLO来接收第二个块。由于EHLO完成后调用了smtp_reset,因此顺序释放了第一个块。



准备好堆之后,我们可以使用它来覆盖原始块大小。我们将0x2021修改为0x20f1,这会稍微扩展块。







4.发送base64数据,并在堆上溢出1个字节。运行AUTH命令发送base64数据。



5.创建并发送适当大小的字符串。由于我们扩展了数据块,因此下一个块的开始现在将位于内部某处。现在,我们需要对其进行修复,以便通过Glibc完整性检查。我们在这里发送另一个base64字符串。



6.释放扩展块。要控制扩展块的内容,我们需要首先释放该块,因为我们无法直接对其进行编辑。也就是说,我们必须发送新的EHLO消息来释放旧的主机名。但是,成功执行后,处理EHLO命令将调用smtp_reset。这可能导致程序中断或异常终止。为了避免这种情况,我们发送了无效的主机名,例如+。



7.覆盖重叠存储块的下一个指针。





释放块后,我们可以使用AUTH来获取它并覆盖部分重叠的存储块。在这里,我们使用一种称为“部分记录”的技术。这使我们能够在不破坏ASLR的情况下更改指针。我们已将以下指针部分更改为包含ACL行的块。 ACL行由一组全局变量指定,例如uschar * acl_smtp_helo;。



这些指针在Exim处理开始时进行初始化,并根据配置进行设置。例如,如果配置包含acl_smtp_mail = acl_check_mail行,则acl_smtp_mail指针指向acl_check_mail行。



每次服务器收到MAIL FROM命令时,Exim都会执行ACL检查,该检查首先扩展acl_check_mail。扩展时,如果Exim遇到行$ {run {cmd}},它将尝试执行cmd命令,因此远程攻击者可以获取要执行的代码。



8.重置存储块并获取包含ACL的存储块。 ACL区块现在位于区块链上。 smtp_reset()完成后,它将被释放,然后我们可以通过分配一些块来再次检索它。



9.覆盖ACL行并运行ACL检查。最后,我们重写包含ACL行的整个块。现在,我们发送诸如EHLO,MAIL,RCPT之类的命令来运行ACL检查。



顺便说一句,由于我们未知的原因,被禁用的ASLR促进了漏洞的利用。



客户有什么问题?



首先是缺乏更新管理。由于使用了旧版本的Exim,因此有可能组织该系统的一个折衷方案。为避免这种情况,建议您在信息基础结构的组件上定期组织检查和安装安全更新。



我们建议至少每月检查一次新的安全性和重要更新。要检查更新,最好使用设备制造商的站点/邮件列表或存储库中的信息。



该银行还缺乏漏洞管理流程,这就是为什么未能及时发现漏洞的原因。使用专门的漏洞扫描程序,例如OpenVAS,Nessus,xSpider等,将有助于纠正这种情况;定期进行渗透测试和监视漏洞消除的时间也将有所帮助。



最后但并非最不重要。银行缺乏变更管理流程。所有更改均由管理员在生产环境中进行。因此,没有人控制或监视这一点。这导致在服务器上禁用了ASLR。



输出量



几起看似无关的漏洞导致该银行的网站遭到破坏。例如,攻击者可以使用它来将银行详细信息更改为自己的信息。



故事结局很好。妥协后,我们立即将情况通知了客户。银行紧急将Exim服务器更新为当前版本,与此漏洞不再相关。但是,如果不是在渗透测试期间发现漏洞,而是由真正的攻击者发现,则结果可能会有所不同。



All Articles