邮件服务器漏洞攻击,Exim邮件服务中的严重漏洞分析
*本文中涉及到的相關(guān)漏洞已報(bào)送廠商并得到修復(fù),本文僅限技術(shù)研究與討論,嚴(yán)禁用于非法用途,否則產(chǎn)生的一切后果自行承擔(dān)。
一、摘要
在對(duì)Exim郵件服務(wù)器的最新更改進(jìn)行代碼審查期間(https://en.wikipedia.org/wiki/Exim),我們發(fā)現(xiàn)了一個(gè)RCE漏洞,版本4.87至4.91(含)。在這種特殊情況下,RCE表示遠(yuǎn)程*命令*執(zhí)行,而不是遠(yuǎn)程執(zhí)行代碼:攻擊者可以以root身份執(zhí)行execv()的任意命令;不需要考慮任何內(nèi)存損壞或涉及ROP(面向返回編程)問題。
此漏洞可由本地攻擊者立即利用(以及某些非默認(rèn)配置中的遠(yuǎn)程攻擊者)。遠(yuǎn)程在默認(rèn)配置中利用此漏洞,即攻擊者必須保持與易受攻擊的服務(wù)器的連接打開7天(通過每隔幾分鐘發(fā)送一個(gè)字節(jié))。但是,因?yàn)镋xim的代碼極其復(fù)雜,我們無法保證這一點(diǎn)開發(fā)方法獨(dú)特;可能存在更快的方法。
自4.87版(4月6日發(fā)布)以來,Exim在默認(rèn)情況下很容易受到攻擊,2016),當(dāng)#ifdef EXPERIMENTAL_EVENT成為#ifndef DISABLE_EVENT;和如果啟用了EXPERIMENTAL_EVENT,舊版本也可能容易受到攻擊手動(dòng)。令人驚訝的是,此漏洞在版本4.92中已得到修復(fù)(2019年2月10日發(fā)布):
但未被確定為安全漏洞,并且大部分都在運(yùn)行因此,系統(tǒng)受到影響。例如,我們利用最新的本通報(bào)中的Debian發(fā)行版(9.9)。
二、本地執(zhí)行測(cè)試
漏洞代碼位于deliver_message()函數(shù)中: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
因?yàn)閑xpand_string()識(shí)別“$ {run {}}”擴(kuò)展項(xiàng),而new-> address是郵件的收件人,本地攻擊者只需發(fā)送郵件即可“$ {run {...}} @ localhost”(其中“l(fā)ocalhost”是Exim的一個(gè)local_domains)并以root身份執(zhí)行任意命令(默認(rèn)情況下,deliver_drop_privilege為false)測(cè)試方法如下: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:
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)
在這個(gè)測(cè)試中:1.我們發(fā)送的次數(shù)超過received_headers_max(默認(rèn)為30)收到:“郵件服務(wù)器的頭文件,將process_recipients設(shè)置為RECIP_FAIL_LOOP,從而執(zhí)行易受攻擊的代碼;
2.我們使用反斜杠轉(zhuǎn)義收件人地址中的無效字符,這些字符由expand_string()(在expand_string_internal()和transport_set_up_command()中)方便地解釋。
二、遠(yuǎn)程代碼執(zhí)行測(cè)試
我們的本地開發(fā)方法不能遠(yuǎn)程工作,因?yàn)镋xim的默認(rèn)配置中的“verify = recipient”ACL(訪問控制列表)要求收件人地址的本地部分(@符號(hào)前面的部分)是本地用戶的名稱:john@debian:~$ nc 192.168.56.101 25
220 debian ESMTP Exim 4.89 Thu, 23 May 2019 10:06:37 -0400
HELO localhost
250 debian Hello localhost [192.168.56.101]
MAIL FROM:<>
250 OK
RCPT TO:
550 Unrouteable address
三、默認(rèn)配置解決問題
首先,我們利用“bounce”消息成功解決“verify = recipient”ACL問題:如果我們發(fā)送無法發(fā)送的郵件,Exim會(huì)自動(dòng)向嚴(yán)格的發(fā)件人發(fā)送一條遞送失敗消息(“退回”)。換句話說,我們?cè)监]件的發(fā)件人(我們的MAIL FROM)成為跳出的接收者(其RCPT TO),因此可以用“$ {run {...}}”執(zhí)行命令。實(shí)際上,Exim默認(rèn)配置中的“verify = sender”ACL只能檢查原始發(fā)件人地址的域部分,而不是本地部分(因?yàn)樗沁h(yuǎn)程地址)。
接下來,反彈必須到達(dá)易受攻擊的代碼并通過process_recipients!= RECIP_ACCEPT測(cè)試,但我們無法重用我們的received_headers_max技巧,因?yàn)槲覀儫o法控制反彈頭。我們對(duì)第二個(gè)問題的解決方案不是最優(yōu)的:如果是彈跳本身不能在7天后交付(默認(rèn)情況下timeout_frozen_after),然后Exim將process_recipients設(shè)置為RECIP_FAIL_TIMEOUT并執(zhí)行易受攻擊的代碼。
最后,我們必須解決一個(gè)看似棘手的問題:2天后(默認(rèn)ignore_bounce_errors_after)除非延遲退出(通過臨時(shí)傳遞失敗),并且4天后默認(rèn)重試規(guī)則(“F,2h,15m; G,16h,1h,1.5; F,4d,6h”),否則將丟棄跳出將延遲地址轉(zhuǎn)換為失敗的地址,因此在timeout_frozen_after的7天之前丟棄反彈。下面是我們對(duì)第三個(gè)問題的解決方案,以及一般的遠(yuǎn)程開發(fā)問題(但可能存在更簡(jiǎn)單,更快速的解決方案):(1)我們連接到易受攻擊的Exim服務(wù)器并發(fā)送不能的郵件交付(因?yàn)槲覀儼l(fā)送超過received_headers_max“收到:”頭)。我們郵件的收件人地址(RCPT TO)是“postmaster”,它的發(fā)件人地址(MAIL FROM)是“$ {run {...}} @ khazad.dum”(其中“khazad.dum”是我們控制的域名。
(2)因?yàn)槲覀兊泥]件無法發(fā)送,Exim連接到khazad.dumMX(我們監(jiān)聽并接受此連接的地方)并開始發(fā)送退回郵件至“$ {run {...}} @ khazad.dum”。
(3)我們保持此連接開放7天(默認(rèn)值timeout_frozen_after),每隔4分鐘向Exim發(fā)送一個(gè)字節(jié)。這個(gè)因?yàn)镋xim讀取對(duì)其SMTP命令的響應(yīng)(簡(jiǎn)單郵件)傳輸協(xié)議)用一個(gè)4096字節(jié)的緩沖區(qū)(DELIVER_BUFFER_SIZE)每次重置5分鐘超時(shí)(默認(rèn)的command_timeout)讀取一個(gè)字節(jié)。
(4)7天后,我們使用永久郵件完成冗長的SMTP響應(yīng)交付失敗(例如,“550 Unrouteable address”)凍結(jié)post_process_one()中的反彈。這個(gè)功能實(shí)際上應(yīng)該丟棄反彈而不是凍結(jié)它(這會(huì)阻止我們到達(dá)易受攻擊的代碼)因?yàn)樗^2天(默認(rèn)值ignore_bounce_errors_after):
四、非默認(rèn)配置下
我們最終設(shè)計(jì)了一個(gè)精心設(shè)計(jì)的方法來遠(yuǎn)程利用Exim的默認(rèn)配置,但是也很容易遠(yuǎn)程利用的各種非默認(rèn)配置:(1)如果管理員手動(dòng)刪除了“verify = recipient”ACL(可能是為了防止通過RCPT TO進(jìn)行用戶名枚舉),那么我們的本地開發(fā)方法也可以遠(yuǎn)程工作。
(2)如果Exim配置為識(shí)別收件人地址的本地部分中的標(biāo)簽(例如通過“l(fā)ocal_part_suffix = + *: - *”),那么遠(yuǎn)程攻擊者可以簡(jiǎn)單地重用我們的本地利用方法和RCPT TO“balrog + $ {run {...}} @ localhost“(其中”balrog“是本地用戶的名稱)。
(3)如果Exim配置為將郵件中繼到遠(yuǎn)程域,作為輔助MX(Mail eXchange),則遠(yuǎn)程攻擊者可以使用RCPT TO $ {run {...}} @ khazad簡(jiǎn)單地使用我們的本地利用方法。 dum“(其中”khazad.dum“是Exim的relay_to_domains之一)。實(shí)際上,”verify = recipient“ACL只能檢查遠(yuǎn)程地址的域部分(@符號(hào)后面的部分),而不是本地部分。
(4)7天后,我們使用永久郵件完成冗長的SMTP響應(yīng)交付失敗(例如,“550 Unrouteable address”)凍結(jié)post_process_one()中的反彈。 這個(gè)功能實(shí)際上應(yīng)該丟棄反彈而不是凍結(jié)它(這會(huì)阻止我們到達(dá)易受攻擊的代碼)因?yàn)樗^2天(默認(rèn)值ignore_bounce_errors_after):1613 /* If this is a delivery error, or a message for which no replies are
1614 wanted, and the message's age is greater than ignore_bounce_errors_after,
1615 force the af_ignore_error flag. This will cause the address to be discarded
1616 later (with a log entry). */
1617
1618 if (!*sender_address && message_age >= ignore_bounce_errors_after)
1619 setflag(addr, af_ignore_error);
然而,在這種特殊情況下,message_age不是反彈的真實(shí)時(shí)間(超過7天),但它是從Exim的線軸首次加載時(shí)的時(shí)間(當(dāng)它只有幾秒鐘或幾分鐘時(shí))。(5)最后,Exim的下一個(gè)隊(duì)列運(yùn)行(默認(rèn)情況下每30分鐘啟動(dòng)一次)Debian)從假脫機(jī)加載凍結(jié)彈跳,設(shè)置process_recipients
到RECIP_FAIL_TIMEOUT(這次,message_age是反彈的真實(shí)年齡,超過7天),并執(zhí)行易受攻擊的代碼和我們的命令(我們的
原始發(fā)件人地址“$ {run {...}} @ khazad.dum”是反彈的收件人地址,由expand_string()解釋。
注意:快速測(cè)試這種遠(yuǎn)程開發(fā)方法,日期Exim的默認(rèn)值為timeout_frozen_after,ignore_bounce_errors_after可以由小時(shí)替換,默認(rèn)重試規(guī)則由“F,4h,6m”替換。
*本文作者:freexploit,轉(zhuǎn)載請(qǐng)注明來自FreeBuf.COM
總結(jié)
以上是生活随笔為你收集整理的邮件服务器漏洞攻击,Exim邮件服务中的严重漏洞分析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 邮件服务器潜在漏洞的保护方法
- 下一篇: 邮件服务器 文件服务器,搭建邮件、终端和