IAM身份驗(yàn)證方法之SAML協(xié)議
一、SAML協(xié)議介紹
SAML(Security Assertion Markup Language)是一種基于XML的開放式標(biāo)準(zhǔn),用于在不同的安全域之間交換認(rèn)證和授權(quán)數(shù)據(jù)。
1.SAML發(fā)展歷史
SAML協(xié)議由結(jié)構(gòu)化信息標(biāo)準(zhǔn)促進(jìn)組織(OASIS)安全服務(wù)技術(shù)委員會(huì)在2002年提出,已經(jīng)經(jīng)歷了1.0、1.1、2.0三個(gè)版本。目前國(guó)內(nèi)外的主流云服務(wù)平臺(tái)、SaaS應(yīng)用以及一些常見軟件系統(tǒng),例如阿里云、AWS、Saleforce、Jira、Confluence、Sonarqube等,都支持通過SAML協(xié)議實(shí)現(xiàn)單點(diǎn)登錄。

2.SAML相關(guān)概念
Asserting Party,即斷言簽發(fā)方,是簽發(fā)斷言的業(yè)務(wù)系統(tǒng)。
Relying Party,即斷言依賴方,是消費(fèi)斷言的業(yè)務(wù)系統(tǒng)。
Principal,即認(rèn)證主體,一般通過Web瀏覽器與兩個(gè)業(yè)務(wù)系統(tǒng)進(jìn)行交互。
AuthnRequest,AuthnRequest由斷言依賴方向認(rèn)證主體簽發(fā),主要包含了斷言依賴方的需要的一些信息。
Response,Response由斷言簽發(fā)方向認(rèn)證主體簽發(fā),包含了最為重要的斷言(Assertion)信息。
Assertion,Assertion包含了認(rèn)證主體的名稱、id、所屬組等重要認(rèn)證信息。
3.SAML Web SSO
在SAML Web SSO場(chǎng)景中,認(rèn)證有以下幾個(gè)流程:
用戶通過Web瀏覽器訪問受保護(hù)資源
資源提供方(SP)向用戶發(fā)出SAML斷言請(qǐng)求,該請(qǐng)求包含了需要用戶進(jìn)行身份驗(yàn)證的相關(guān)信息
用戶的身份提供方(IdP)接收到請(qǐng)求,并請(qǐng)求用戶提供身份驗(yàn)證信息
用戶提供身份驗(yàn)證信息給身份提供方
身份提供方向用戶頒發(fā)SAML斷言,該斷言包含有關(guān)用戶身份的信息
用戶將SAML斷言發(fā)送回資源提供方
資源提供方驗(yàn)證SAML斷言的有效性,如果斷言有效,則向用戶授權(quán)訪問所請(qǐng)求的資源
用戶被授權(quán)訪問資源

二、SAML協(xié)議攻擊面
SAML是一個(gè)基于XML的認(rèn)證協(xié)議,由于XML數(shù)據(jù)格式靈活、處理復(fù)雜,導(dǎo)致實(shí)現(xiàn)過程非常容易造成邏輯漏洞,并且XML本身也存在XXE、XSLT等安全風(fēng)險(xiǎn),這一攻擊面也由SAML所繼承。

1.XXE攻擊
XXE(XML External Entity Injection)攻擊是OWASP TOP10中的???,其本身是XML的攻擊面,但由于SAML基于XML,也就繼承了這一攻擊面。
XXE漏洞的主要原因是XML解析器在沒有禁用外部實(shí)體( External Entity)的情況下,攻擊者可以向被處理的XML文檔中并且實(shí)體定義中可以包含一些控制服務(wù)器行為的指令。
XXE的常規(guī)攻擊方式有以下兩種:
本地文件包含(LFI)Payload
<!--?xml version="1.0" encoding="UTF-8"?-->
]>
&xxe;
服務(wù)端請(qǐng)求偽造(SSRF)Payload
<!--?xml version="1.0" encoding="UTF-8"?-->
]>
2.XSLT攻擊
XSLT攻擊指的是一種利用XSLT(Extensible Stylesheet Language Transformations)漏洞的攻擊方式。XSLT是一種用于將XML文檔轉(zhuǎn)換為其他格式的語言,例如HTML或PDF。攻擊者可以利用XSLT漏洞來執(zhí)行惡意代碼或獲取敏感信息。
在SAML中造成XSLT的原因是SAML簽名前使用了多個(gè)transform對(duì)簽名內(nèi)容進(jìn)行一系列處理,每一個(gè)transform定義了數(shù)據(jù)處理算法,如
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>規(guī)定的是規(guī)范化算法<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>表示的是數(shù)字簽名算法
在w3c組織定義的transform算法中
<ds:Transform Algorithm="http://www.w3.org/TR/1999/REC-xslt-19991116">可以用來實(shí)現(xiàn)XSLT轉(zhuǎn)換,如果服務(wù)端沒有任何校驗(yàn)就對(duì)SAML簽名進(jìn)行驗(yàn)證就會(huì)產(chǎn)生XSLT漏洞。


3.XSW攻擊
XSW是一種基于XML文件格式變換的攻擊手法,因?yàn)閄ML簽名的驗(yàn)證和斷言使用通常是在兩個(gè)不同的函數(shù)進(jìn)行處理,如果兩個(gè)模塊對(duì)同一個(gè)數(shù)據(jù)有不同的處理方式,那么就可以利用這種攻擊來對(duì)Response進(jìn)行偽造。

4.SAML重放
SAML重放攻擊主要是由于實(shí)現(xiàn)中沒有防止重放的安全機(jī)制如隨機(jī)參數(shù)、過期時(shí)間等,攻擊者在截獲SP簽發(fā)的斷言后,可以利用截獲的斷言向SP進(jìn)行驗(yàn)證,獲取訪問權(quán)限。

5.Golden SAML
Golden SAML是一種偽造SAML斷言的權(quán)限維持攻擊手法,攻擊者首先通過攻陷Idp服務(wù)竊取Idp簽名密鑰,在得到簽名密鑰后即可對(duì)信任該Idp的服務(wù)簽署任意用戶的斷言獲取其訪問權(quán)限。這種攻擊手法與黃金票據(jù)較為類似。

三、SAML漏洞案例
1.XXE
在一些漏洞眾測(cè)write-up中經(jīng)??梢钥吹絏XE漏洞案例,在下圖中作者通過某云服務(wù)平臺(tái)SAML配置后臺(tái),通過配置Idp元數(shù)據(jù)功能插入XXE payload造成本地文件泄露。


2.CVE-2022-47966
CVE-2022-47966影響Zoho ManageEngine系列多個(gè)產(chǎn)品,CVSS評(píng)分高達(dá)9.8,主要原因是這些產(chǎn)品都使用了xmlsec 1.4.1去驗(yàn)證SAML簽名,而這一版本的xmlsec組件包含有多個(gè)漏洞。下面是SAML簽名的示例。

SP在接收到用戶傳入的Response后首先會(huì)對(duì)斷言的的簽名進(jìn)行驗(yàn)證,通常有以下幾個(gè)步驟:
1)檢查斷言完整性,對(duì)斷言進(jìn)行格式轉(zhuǎn)換(規(guī)范化、數(shù)字簽名格式),計(jì)算hash摘要與DigestValue內(nèi)容進(jìn)行對(duì)比,如果結(jié)果不同說明簽名被篡改。
2)利用Idp公鑰解密SignatureValue,與DigestValue進(jìn)行對(duì)比,如果結(jié)果不同說明斷言不是由信任的Idp簽發(fā)。
3)以上兩個(gè)步驟同事滿足時(shí)說明簽名是合法的。
以上3個(gè)步驟中1和2的處理順序是可以互換的,但是在步驟1中對(duì)斷言進(jìn)行轉(zhuǎn)換會(huì)產(chǎn)生XSLT注入漏洞,如果按照這個(gè)順序處理會(huì)造成未授權(quán)命令執(zhí)行漏洞。
下圖中xmlsec1.4.1對(duì)簽名進(jìn)行檢查的邏輯,在[1]處首先檢查了簽名內(nèi)容的完整性,也就是上述步驟1的內(nèi)容,在[2]中根據(jù)簽名算法驗(yàn)證了簽名的合法性,這也就是漏洞在未授權(quán)情況下利用的核心原因。

3.CVE-2022-41912
CVE-2022-41912是crewjam/saml由go語言實(shí)現(xiàn)的saml庫中存在的一個(gè)認(rèn)證繞過的漏洞,這個(gè)漏洞是由于使用了兩種不同方式處理Response導(dǎo)致的簽名驗(yàn)證繞過。解析SAML響應(yīng)的代碼如下,首先在A代碼部分利用golang原生的xml反序列化函數(shù)將SAML響應(yīng)反序列化到Response結(jié)構(gòu)中,在B代碼又利用etree來將Response反序列化為Document對(duì)象。然后在C代碼塊將這兩對(duì)象傳入validateXMLResponse函數(shù)中。

跟進(jìn)這個(gè)函數(shù),在紅框部分將responseEL變量傳入validateSigend進(jìn)行簽名驗(yàn)證,通過后返回resp.Assertion,注意這里的responseEL和resp分別是上一步驟通過etree和go反序列化得到的結(jié)果。這里驗(yàn)證的是responseEL返回的卻是resp的邏輯是這個(gè)漏洞的關(guān)鍵。

根據(jù)validateSigned函數(shù),這里的處理邏輯是利用findChild函數(shù)從responseEL中找到Assertion,再從Assertion中找到Signature元素,兩個(gè)元素不為空且Assertion合法性驗(yàn)證通過的話就通過驗(yàn)證。

回頭再看一下最開始反序列化的地方利用go原生反序列化得到的Response結(jié)構(gòu)定義如下,在這個(gè)結(jié)構(gòu)中只有一個(gè)Assertion對(duì)象,如果處理的Response含有多個(gè)Assertion元素時(shí),按照golang的處理,這里會(huì)取到最后一個(gè)Assertion。

再看一下findChild的實(shí)現(xiàn),這里的邏輯是遍歷所有子元素,如果命名空間和標(biāo)簽名匹配上就馬上返回這個(gè)元素,所以在含有多個(gè)Assertion的情況下在validateSigned中得到的第一個(gè)Assertion。

作者給出的payload如下,SAML響應(yīng)中包含兩個(gè)Assertion其中第一個(gè)合法,第二個(gè)是偽造的Assertion。

最后處理的邏輯就是驗(yàn)證第一個(gè)Assertion,由于是合法的,可以通過驗(yàn)證,但是返回的是第二個(gè)也就是偽造的Assertion,如果通過驗(yàn)證的是一個(gè)低權(quán)限用戶,那么就可以偽造一個(gè)高權(quán)限的用戶Assertion來實(shí)現(xiàn)認(rèn)證繞過和權(quán)限提升。
4.vcenter_saml_login
vcenter_saml_login是一個(gè)vCenter后利用工具,主要場(chǎng)景是拿到vCenter服務(wù)器root權(quán)限之后需要登錄vCenter web控制臺(tái)進(jìn)行下一步攻擊。
這個(gè)工具中也利用了SAML簽名,我們可以結(jié)合SAML協(xié)議流程來分析一下這個(gè)工具的利用過程。首先看參數(shù),target指定vCenter服務(wù)器的ip,path參數(shù)指定的是data.mdb文件,data.mdb是vCenter中用于存儲(chǔ)ldap數(shù)據(jù)的文件,而vCenter用于SAML簽名的私鑰就存儲(chǔ)在ldap數(shù)據(jù)庫中。

重點(diǎn)有以下幾個(gè)步驟:
首先是使用get_idp_cert獲取ipd簽名密鑰,這里利用了data.mdb文件的特征字符定位到idp私鑰的偏移,通過私鑰的固定數(shù)據(jù)結(jié)構(gòu)獲取長(zhǎng)度,再利用其讀取取到私鑰內(nèi)容。

然后是偽造管理用戶Assertion,這個(gè)工具通過編寫一個(gè)SAML響應(yīng)模板,并且響應(yīng)中的Assertion部分填寫的都是管理員的屬性,在ID、簽發(fā)時(shí)間、域名等動(dòng)態(tài)參數(shù)做了標(biāo)記,然后進(jìn)行填充,就得到了一個(gè)偽造的SAML響應(yīng)。

最后最關(guān)鍵的部分就是對(duì)偽造的SAML響應(yīng)進(jìn)行簽名,這里利用的是第三方庫,通過之前獲取的Idp私鑰對(duì)偽造的SAML響應(yīng)簽名,參數(shù)中的cert1和cert2是可選項(xiàng)。

最后生成的SAML響應(yīng)就可以發(fā)送到斷言消費(fèi)接口(ACS)進(jìn)行認(rèn)證。
