繞過DKIM驗證,偽造釣魚郵件
概要
DKIM和DMARC以及SPF一樣,都是用來防止在郵件中進行網路釣魚攻擊的主要方法。DMIM的主要思路就是數字簽名應用在郵件中,然後收件方收到郵件後進行簽名驗證。這種方法的作用是為了驗證這個郵件確實是從發送者的郵件伺服器發送到收件人的信箱當中的。
本文將展示一下如何在實際攻擊中如何繞過DKIM這一驗證方法,在特定情況下,我們儘管改變了郵件內容,但是並不會使DKIM簽名無效,從而證明這一方法的安全性的確不好。文章最後展示了如何使用DKIM使用戶信任大部分郵件。
什麼是DKIM
這裡會給出DKIM一些介紹,他的作用是防止郵件釣魚,以及他是如何進行工作的。如果你已經了解過了DKIM,你可以跳過這一部分。
郵件釣魚經常用來騷擾以及攻擊向量
攻擊方如果很容易發送釣魚郵件,在接收方方面不僅是一種騷擾而且還是一種潛在的危險。當人們收到釣魚郵件時,通常情況下都會認為郵件是從發件郵箱地址欄填寫的地址放鬆過來的。但是如果發送者的郵件是你熟悉的人,或者他看起來是非常可靠的郵箱地址,那麼受到攻擊的概率會大大增加。這些釣魚郵件攻擊在亞馬遜,蘋果,DHL,以及一些銀行等公司內經常發生,一旦感染,病毒就會嘗試盜取用戶數據,以及感染其他用戶電腦。
使用DKIM,DMARC,SPF防禦釣魚郵件
因為防禦釣魚攻擊很重要,在過去幾年中已經開發出了幾種防禦方法。目前主要使用的防禦方法是SPF,DKIM以及DMARC。SPF的原理是判斷來源IP是否在合理範圍之內,DKIM原理是由發送域的郵件伺服器在郵件中添加數字簽名,收件方通過數字簽名判斷郵件是否被修改。DMARC將確認收件欄中的郵箱是否和SPF以及DKIM中的郵件域是否相匹配。DMARC還增加了如何處理與預期不符的郵件的策略,並向原始域發送有關此類問題的報告。這三種方法都是基於DNS來提供策略的,即域的所有者需要將域中所需要的策略添加到DNS設置的特殊的SPF當中。
對DKIM的一個簡單介紹
DKIM的基本思想是發件人域中的郵件伺服器在郵件中添加數字簽名,收件人通過簽名驗證郵件是否由郵件伺服器發送,簽名大概格式如下:
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=dhl.com; l=1850; s=20140901; t=1452769712; h=date:from:to:message-id:subject:mime-version; bh=yCbsFBJJ9k2VYBxKGgyNILalBP3Yzn1N8cMPQr92+zw=; b=bnuXrH/dSnyDR/kciZauK4HTgbcDbSFzmHR78gq+8Cdm20G56Ix169SA...
在郵件簽名中,最重要的部分是:
1. d是這一個域的簽名。這一部分是在DMARC檢查簽名中的域是否和發送者的域相匹配中用到。2. h是應該包含在簽名中的郵件頭的欄位列表3. bh是郵件正文的hash4. l是hash在郵件正文中所佔的位元組數。這一選項是可選的。5. b是簽名本身,包括"h 給出的欄位,以及DKIM-Signature頭本身。由於頭部保保存的是整個正文的hash,所以b這一參數也可以作為電子簽名。
除此之外,簽名中還包含了使用的加密演算法』a』,以及用於在DNS中尋找RSA密鑰的參數』s』,規範性的方法』c』,以及時間戳』t』.
郵件頭部哪些內容應該進行簽名
如上所述,簽名應該包括正文以及相應的頭部欄位,並且包含的欄位內容在』h』中已經給出。這裡需要理解的是簽名每次都會匹配』h』欄位中給出的第一個頭信息。因此,如果標題中包含了兩個』to』欄位,並且兩者都應該寫被保護,那麼就應該在簽名的』h』選項中包含』to』兩次。
簽名唯一的硬性要求就是必須包括』from』,除此之外,標準都是比較模糊的。在RFC 6376標準中5.4章中寫道:
在選擇哪些標題欄位進行簽名時給出的內容是不明顯的,消息存在的簽名欄位如:Date, Subject, Reply-To, Sender, and all MIME這些頭部。
有趣的是在5.4.1這一部分給出的例子中部分與聲明相矛盾,因為一些新的內容被添加,那麼另外一些規則就會被忽略。然而, opendkim正將5.4.1列表中的欄位規定為推薦欄位,不過這裡面並不包含郵件內容類型以及內容傳輸編碼等重要的欄位。更奇怪的是,作為當前DKIM標準的RFC 6376的前身RFC 48771在5.5節中可以看到列表裡面的內容比前者更多。
除了標註頭欄位表達不清楚之外,當前標準對於如何防止額外添加欄位的描述更加模糊。在標準中明確表示額外添加欄位會產生很嚴重的攻擊。
破解DKIM的目的
DKIM標準的模糊性,缺乏安全默認值,以及MIME標準的實現的複雜性,靈活性都可以產生改變郵件的主要信息,比如主題,甚至改變整個郵件的內容。包括添加新的惡意附件。
欺騙郵件頭部:Subject,Content-Type等等
我的研究表明頭部簽名是不夠充分安全的,並且在許多情況下可能會存在DKIM繞過,達成釣魚。雖然在郵件中我已經分析出在簽名中97%是包括了郵件內容。3%是防止惡意增加主題標題。但是GMail和AOL網路郵件在有多個主題的情況下只會顯示第一個主題行的內容,而DKIM簽名僅涵蓋最後一個主題行。這樣一來攻擊者就可以輕易的改變顯示的主題,而不影響簽名的有效性。
而且,當繼續繞過Content-Type頭部驗證時,這也是可能實現的。
通過下面簡單的一個郵件舉個例子:
使用安裝DKIM插件的郵件客戶端Thunderbird查看郵件時顯示如下:
但是通過添加額外的Subject以及Content-Type頭部,它顯示的結果會發生不同:
Subject: Urgent Update at http://foo Content-type: multipart/mixed; boundary=bar DKIM-Signature: v=1; h=from:to:cc:subject:content-type; ... From: To: knurrt.hase@gmail.com Subject: 20170920:1755 - good Content-type: multipart/mixed; boundary=foo Date: Wed, 20 Sep 2017 17:55:18 +0200 --foo Content-type: text/plain some text --foo--
我們可以觀察到subject是不同的,並且郵件正文已經沒有了,但是DKIM驗證結果還是正確的。
欺騙郵件正文:攻擊者完全控制正文內容
在特定的情況下,攻擊者不僅可以控制Content-Type之類的頭部,而且還可以控制郵件的正文,包括改變正文內容,或者添加附件。當然在添加的同時保證了DKIM的驗證結果仍然有效。
如果郵件發送方在簽名中使用了』l』選項,那麼這種攻擊就可以被實現。通常』l』屬性是用於保護簽名的有效性,即使郵件伺服器或者防火牆在郵件正文末尾添加了它們各自的簽名。比如「這一郵件已經通過xyz殺毒軟體的掃描」類似的欄位。
通常情況下,伺服器設置的』l』值是覆蓋的正文全部內容的。因此,可以推斷出我們不能改變正文的內容,但是可以在正文最後添加一些東西。不過我在德國的一家大型企業中發現,不管他們發送的郵件長度為多少,他們的DKIM只是覆蓋了郵件的前10個字元。這種錯誤的配置使得攻擊變得更為簡單。
作為一個例子,在2016年年初我們通過DHL.com發送了一個實際的郵件。因為沒有添加DKIM簽名到期時間,所以在2017年9月這一簽名還是有效的。並且DHL也沒有更改RSA加密的密鑰。原始郵件在Gmail的web界面看起來如下圖:
通過查看這一郵件的源代碼,發現一些選項是被簽名保護的,但是簽名並沒有防止添加另外欄位。並且在簽名中,一些重要的選項並沒有包含其中。正文hash值僅僅涵蓋了郵件的特定部分,所以在原始郵件正文中添加任何東西都不會使簽名驗證失效。
具體來說的話,我們可以在郵件中繼續添加另外一個Date、To、Message-Id等等其他選項,並且可以更改當前的Content-Type、在正文中添加任意數據。這樣都不會使簽名無效。更改的內容為紅色,原始郵件為黑色和藍色:
這裡能夠替換正文的原因是因為重新定義了具有不同MIME邊界的Content-Type。在MIME邊界之前的任何內容都被視為MIME的前導碼,並且在任何兼容mime的郵件客戶端中忽略。這就意味著在客戶端顯示的郵件內容是攻擊者修改之後的內容,而不是原始的郵件內容。
在」signed-by」欄位中可以看到簽名仍然有效。而且如果我們查看郵件的來源,Gmail會提供一個很好的摘要,其中包括攻擊者設置的Date以及Messahe-Id.由於DKIM簽名與顯示的發件人DMARC的域相匹配,所以即使郵件未通過DHL的郵件伺服器發送,也會成功:
這個問題的確很嚴重,我在過去的日子裡發現,不僅是dhl.com在DKIM簽名中使用了』l』選項,而且我在cisco.com,deutschepost.de或者dpdhl.com發送的郵件中都存在這一問題。有趣的是,DKIM標準的製作者已經發現了』l』屬性的問題,在8.2章節:
使用』l』標籤可能會在郵件中顯示欺詐內容,並且用戶可能不會察覺到……這種攻擊的一個例子包括改變MIME結構。……
為了避免這種攻擊,進行簽名的過程應該非常警惕使用這一標籤。
打破DKIM
在之前我們已經展示了如何使用現有郵件創造欺詐郵件,並且DKIM不會失效。這就使得DKIM並不是那麼可信賴的,即使DKIM簽名有效,那也不能確定郵件是不是被修改過。
另外還有一個問題,由於SMTP協議的特殊性,即使郵件沒有被改變,DKIM簽名同樣會失效。這就意味著儘管現在郵件已經被修改了,但是收件方同樣可能會認為這一郵件沒有問題。
傳統的郵件只限於ASCII進行編碼,行長度為1000個字元。MIME標準定義了Content-Transfer-Encoding的base64以及quotable-printable不限於傳統郵件規定。但是這些編碼效率不是很高,如果客戶端可以忽略歷史性限制,使用完整8位傳輸郵件,這樣會好一點。
這裡可以使用8BITMIME拓展進行郵件傳輸。如果郵件伺服器支持此類拓展,那麼客戶端就會忽略只識別ASCII字元的規則。但是郵件的傳遞過程並不是點到點傳遞的,而是逐跳進行傳遞的。傳遞路徑上的第一個伺服器支持8BITMIME並且接受這樣的郵件,但是路徑上另一個郵件伺服器不支持8BITMIME。在這種情況下郵件需要轉換成僅ASCII格式。不過這樣會破壞現有的DKIM簽名:
這一問題在DKIM標準中也已經提到,並且說了如何解決這一問題:
在某些郵件中使用了8BITMIME,在傳輸過程中,會轉換為7位格式,進而破壞DKIM簽名。為了將破壞損失達到最小化,簽名者應該在簽名之前將郵件內容轉換為合適的MIME內容傳輸編碼。這種轉換超過了DKIM的範圍,在DKIM呈現之前,實際的消息被MUA或者MSA轉換為7位MIME。
然而,幾個主要的郵件服務商並沒有注意到這一問題,因此在實際發送郵件的過程中會受到這一轉換問題的影響。比如Paypal和Booking.com的郵件就受到了這一郵件的影響,儘管大部分郵件看起來很正常,但是由於主要的郵件服務商不支持8BITMEME,所以會受到這一問題的影響。
如何修復這一問題呢?
雖然DKIM標準試圖將大部分驗證工作都交給接收方,但是實際上作用並不大。相反,發送方和接收方都應該作出最大努力:發件人應該確保郵件無法在不破壞簽名的情況下進行修改,收件人應該檢查簽名是否完好。這樣郵件就不會被惡意修改。
在發送方,這意味著首先要確保郵件符合歷史性限制,即全ASCII碼,行長度最多為1000個字元。如果郵件不存在,則需要在進行DKIM簽名前進行轉換。
為了防止攻擊者添加額外的標題,簽名本身需要包含可能會影響郵件顯示的所有郵件頭。需要進行簽名的標題很顯然是從展示給用戶的內容選出,比如:Subject,來自,發送到,日期,以及發送者。另外,應該包括影響消息顯示的任何標題,即內容類型,內容傳輸編碼,內容處理和MIME版本。而且還有一些標題會影響未來的消息流,或者是如何在其他人的上下文中顯示這個消息,例如「回復」,「應答到」和「引用」。只要所有可能影響消息顯示的頭部都包含在簽名中,那麼將身體的長度添加到「l」屬性也可能是有用的。
在接受方,應該檢查每個相關的標題是否包含在簽名中。不包括在簽名中的任何標題都應該非常小心處理,並且在顯示消息時不要過分信賴簽名。鑒於這在許多情況下是不可能的,至少應該向用戶傳達DKIM簽名不包括關鍵頭部,即使簽名看起來是有效的,因此可能會欺騙該消息。另外,如果設置了』l』屬性,那麼只有被限制的主體哈希所覆蓋的部分才能顯示給最終用戶,否則散列外的部分應該被明確地顯示為不可信。
當然,最好的是,如果所有發件人都使用S/MIME或PGP簽名他們的消息,並且所有客戶端都將檢查此端到端簽名。但這可能是未來幾年的夢想,因此我們需要使SPF,DKIM和DMARC等當前的解決方案更加可靠。
總結
DKIM嘗試通過發送MTA簽署郵件來處理髮件人欺騙。雖然這個想法在理論上是合理的,但標準過於靈活。它只提出模糊的建議,然後依靠具體的實施和配置來提供必要的安全性和可靠性。鑒於缺乏明確的要求,所以實際使用的DKIM在許多情況下都不能提供預期的效果。
※Mac固件安全研究
※Powershell 安全最佳實踐
※域滲透——利用DCOM在遠程系統執行程序
※內存取證分析的實戰演練
※黑客開發虛假WordPress安全插件植入後門感染用戶
TAG:嘶吼RoarTalk |