SAML協議漏洞分析,攻擊者利用該漏洞以其他用戶身份登錄
背景
SAML(Security Assertion Markup Language)即安全聲明標記語言,它是一個基於XML的標準,用於在不同的安全域(security domain)之間交換認證和授權數據。SAML是用於單點登錄系統的標準。
認證原理
服務提供商(SP)處理SAML響應的過程如下:
用戶認證IdP,IdP會生成帶簽名的SAML響應。用戶瀏覽器轉發該響應到SP;
SP驗證SAML響應簽名的有效性;
如果簽名有效,SAML響應中的字元串id(比如nameid)就會識別出認證那個用戶。
下面是一個簡化的SAML響應示例:
https://idp.com/
user@user.com
some base64 data that represents the signature of the assertion
上面示例的SAML響應消息中比較重要的元素有Assertion和Signature。
如果攻擊者在不改變簽名的有效性的情況下修改NameID,那麼就可以發起攻擊。
XML Canononononicalizizization
另外一個跟XML簽名相關的方面是XML canonicalization,XML canonicalization允許兩種邏輯等價的XML文檔有同樣的位元組表示,比如:
some text
和
some text
兩個文檔有不同的位元組表示,但是表達了同樣的信息。
Canonicalization是在簽名之前就應用到XML元素中的。這就預防了XML文檔中毫無意義的變化引起的數字簽名不同的問題。這是非常重要的一點,也就是說「多個不同但是相似的XML文檔可以用完全相同的簽名」。而XML文檔中不同的部分是在canonicalization演算法中說明的。
在上面的SAML響應中,CanonicalizationMethod規定了在對文檔簽名之前使用哪個canonicalization方法。在XML簽名說明中有很多的簽名演算法,最常用的演算法是http://www.w3.org/2001/10/xml-exc-c14n#(下文中簡寫為exc-14n)。
http://www.w3.org/2001/10/xml-exc-c14n#WithComments是exc-14n的一個變種。該變種不會省去注釋,所以上面的不同的XML文檔就會有不同的canonical表示。
XML APIs
引起該漏洞的一個重要原因是Python的 lxml和Ruby的REXML這樣的XML庫的一個特別的行為。請看下面的XML元素NameID:
kludwig
如果想要從該元素中提取用戶識別符,Python代碼應該是這樣的:
from defusedxml.lxml import fromstring
payload = "kludwig"
data = fromstring(payload)
return data.text # should return "kludwig"
.text方法會提取NameID元素的內容。
如果我們給元素中加入注釋會怎麼樣呢?
from defusedxml.lxml import fromstring
doc = "kludwig"
data = fromstring(payload)
return data.text # should return 『kludwig』?
你以為返回的結果與沒有加入注釋是一樣的嗎?NO,.text API返回的是 klud。可是為什麼呢?
如果把XML看做是樹形的,那麼XML文檔應該是這樣的:
element: NameID
|_ text: klud
|_ comment: a comment?
|_ text: wig
Lxml在第一個節點結束後就不讀取內容了。沒有注釋的節點的表述是這樣的:
element: NameID
|_ text: kludwig
另一個有同樣行為的XML庫是Ruby的REXML。
[get_text]返回第一個子Text節點,該方法返回的是真實的Text節點而不是字元串的內容。如果所有的API或庫都在第一個子節點之後停止文本提取,也沒有問題,但是有些XML庫處理文本提取的方式是不同的:
import xml.etree.ElementTree as et
doc = "kludwig"
data = et.fromstring(payload)
return data.text # returns "kludwig"
在這種方法中,只會提取節點的第一個孩子的內部文本(inner text)。
漏洞分析
根據上面的描述,一共有三種方法引發該漏洞:
SAML響應含有能夠識別要認證的用戶的字元串;
XML canonicalization在簽名驗證時移除注釋的情況,也就是說在SAML中增加註釋不會影響簽名的有效性;
當響應中含有注釋時,XML文本提取只返回XML元素中文本的子字元串時。
https://idp.com/
user@user.com.evil.com
some base64 data that represents the signature of the assertion
對依賴SAML的服務的影響
SAML IdPs和SP通常是可配置的,所以關於該漏洞造成的影響有很大的變化空間。比如,使用郵箱地址並用白名單來驗證域名的SAML SP被利用的可能性就比用任意字元作為用戶id的SAML SP被利用的可能性低很多。
在IdP端,允許用戶開放註冊賬戶也會增加問題帶來的影響。而手動的用戶驗證過程可以讓利用變難。
修復
修復該漏洞的關鍵在於系統和服務於SAML之間的關係
如果在運行或維護IdP或IP,那麼最佳的方式就是確保SAML處理庫不受該漏洞的影響。下面是研究人員發現的一些含有該漏洞的SAML庫,研究人員認為還有一些受該漏洞影響的庫還沒有被發現。研究人員發現該漏洞影響的產品有:
OneLogin - python-saml - CVE-2017-11427
OneLogin - ruby-saml - CVE-2017-11428
Clever - saml2-js - CVE-2017-11429
OmniAuth-SAML - CVE-2017-11430
Shibboleth - CVE-2018-0489
Duo Network Gateway - CVE-2018-7340
另一種修復的方法就是選擇一種默認的canonicalization演算法。當攻擊者加入注釋時,canonicalization演算法會讓簽名發生變化。但是這種修復方法需要IdP和SP的支持,所以通用性不強。
如果SAML SP使用了雙因子認證,那麼該漏洞的影響就更小了,因為該漏洞只允許繞過用戶的第一個因子。如果IdP負責第一個因子和第二個因子的認證,那麼該漏洞就可以繞過雙因子認證。
如果是維護SAML處理庫
那麼要確保有注釋時,SAML庫提取了給定XML元素中的全部文本。許多SAML庫都有單元測試,那麼很容易可以修改測試用例來測試在簽過名的文檔中加入注釋後提出特徵的情況。如果測試不通過,那麼可能就受到該漏洞的影響。
另外一個修復方法是修改XML標準。研究人員沒有發現有正確交互行為的標準,因此,這些相關的標準是如何交互的就非常重要。
※攻擊Windows PXE 啟動鏡像
※醫療影像領域安全狀況令人擔憂
TAG:嘶吼RoarTalk |