IAM單點登錄之CAS協(xié)議分析
一、CAS協(xié)議介紹
集中式認(rèn)證服務(wù)(Central Authentication Service,簡稱CAS)是一種針對web應(yīng)用的單點登錄協(xié)議,旨在為 Web 應(yīng)用系統(tǒng)提供一種可靠的單點登錄方法,它允許一個用戶訪問多個應(yīng)用程序,而只需向認(rèn)證服務(wù)器提供一次憑證(如用戶名和密碼)。這樣用戶不僅不需在登陸web應(yīng)用程序時重復(fù)認(rèn)證,而且這些應(yīng)用程序也無法獲得密碼等敏感信息?!癈AS”也指實現(xiàn)了該協(xié)議的軟件包。
發(fā)展歷史
CAS最初由耶魯大學(xué)的Shawn Bayern開發(fā)實現(xiàn),后來由耶魯大學(xué)的Drew Mazurek維護。CAS1.0實現(xiàn)了單點登錄。 CAS2.0引入了多級代理認(rèn)證(Multi-tier proxy authentication)。CAS其他幾個版本已經(jīng)有了新的功能。
2004年12月,CAS成為Jasig的一個項目,2008年該組織負(fù)責(zé)CAS的維護和發(fā)展。CAS原名“耶魯大學(xué)CAS”,現(xiàn)在則被稱為“Jasig CAS”。
2005年5月,CAS協(xié)議版本2發(fā)布,引入代理和服務(wù)驗證。2006年12月,安德魯·W·梅隆基金會授予耶魯大學(xué)第一屆梅隆技術(shù)協(xié)作獎,頒發(fā)50000美元的獎金對耶魯大學(xué)開發(fā)CAS進行獎勵。頒獎之時,CAS在“成百上千的大學(xué)校園”中使用。
2012年12月,JASIG與Sakai基金合并,CAS改名為Apereo CAS。2016年11月,基于Spring Boot的CAS軟件版本5發(fā)布。
CAS協(xié)議角色介紹
1.CAS Clients
客戶端,也可以叫做服務(wù),通常是我們?yōu)g覽器訪問的web應(yīng)用。
2.CAS Server
認(rèn)證服務(wù)器,它的主要用途是頒發(fā)票據(jù)和對用戶進行身份驗證。
CAS協(xié)議常見概念以及數(shù)據(jù)的基本介紹
局部會話:瀏覽器-客戶端之間的會話。
全局會話:瀏覽器-認(rèn)證服務(wù)器之間的會話。
TGT(Ticket Granting Ticke):建立全局會話的憑證,包含用戶信息、票據(jù)生命周期等信息。
TGC(Ticket Granting Cookie):認(rèn)證服務(wù)器認(rèn)證成功后返回給瀏覽器的cookie,與存儲在認(rèn)證服務(wù)器上的TGT相對應(yīng),TGC和TGT類似于cookie和session的關(guān)系。
ST(Service Ticket):服務(wù)憑證,用于客戶端驗證用戶身份。

上面這圖是CAS協(xié)議的經(jīng)典架構(gòu),從圖中我們可以看到,用戶訪問不同語言、不同架構(gòu)的服務(wù),服務(wù)又通過CAS、SAML、Oauth等協(xié)議與認(rèn)證服務(wù)器進行交互,基于spring mvc框架的認(rèn)證服務(wù)器從LDAP、數(shù)據(jù)庫、或AD獲取數(shù)據(jù)對用戶進行身份驗證,然后向用戶頒發(fā)憑據(jù)。
當(dāng)前版本的CAS集成的身份驗證機制有AD、Generic、LDAP、JDBC等等,由于發(fā)展的需要,現(xiàn)在的CAS已經(jīng)支持其他的一些身份協(xié)議,例如OIDC、Oauth 2.0等等。
CAS協(xié)議認(rèn)證流程
以下為CAS官方規(guī)范協(xié)議流程:

我們可以將這個流程分為兩個部分,第一個部分為未登陸時瀏覽器向第一個網(wǎng)站app1請求資源的過程,可以分為以下幾步:
1. 瀏覽器訪問網(wǎng)站app1
2. 網(wǎng)站app1對瀏覽器的請求進行解析,過濾器檢測用戶是否需要進行身份驗證(AuthenticationFilter和TicketValidationFilter)
3. 網(wǎng)站app1將瀏覽器重定向到認(rèn)證服務(wù)器
4. 用戶輸入賬號密碼進行登錄
5. 認(rèn)證服務(wù)器向瀏覽器返回TGC,并將瀏覽器重定向回之前訪問的URL,并在URL中添加參數(shù)ticket,也就是ST
6. 網(wǎng)站app1攜帶ST去認(rèn)證服務(wù)器進行認(rèn)證(這個過程對于用戶來講是不可見的)
7. 認(rèn)證成功網(wǎng)站app1為瀏覽器生成cookie,并返回用戶請求的資源。



下面是第二部分:
我們已經(jīng)經(jīng)過了身份驗證,這個時候用戶再訪問網(wǎng)站app2。
1. 網(wǎng)站app2驗證瀏覽器的cookie,但是因為網(wǎng)站app2沒有登錄過,所以沒有網(wǎng)站app2的cookie。
2.網(wǎng)站app2將瀏覽器重定向到認(rèn)證服務(wù)器,瀏覽器訪問認(rèn)證服務(wù)器時會帶上cookie。
3.認(rèn)證服務(wù)器發(fā)現(xiàn)cookie中有TGC,驗證TGC與TGT的對應(yīng)關(guān)系,TGC有效。
4.認(rèn)證服務(wù)器將瀏覽器重定向到網(wǎng)站app2,并返回一個ST。
5.瀏覽器使用ST請求網(wǎng)站app2。
6.網(wǎng)站app2使用這個ST去認(rèn)證服務(wù)器進行認(rèn)證。
7.如果認(rèn)證成功,網(wǎng)站app2為瀏覽器生成cookie,并返回用戶請求的資源。


以下為CAS認(rèn)證流程中用到的兩個過濾器,用于AuthenticationFilter用于檢測用戶是否登錄,TicketValidationFilter用于驗證票據(jù)是否存在,注意這個過濾器只是檢測票據(jù)參數(shù)是否存在,并不對票據(jù)做正確性驗證。這么做的目的減少跟認(rèn)證服務(wù)器之間的不必要交互,減少通信,減輕網(wǎng)絡(luò)負(fù)載,這些規(guī)則都是可以自定義的。CAS中的過濾器是可以配置的,所以具體效果與當(dāng)前部署有關(guān)。


CAS注銷流程
CAS的注銷流程大概可以分為以下四步:
瀏覽器向網(wǎng)站app1發(fā)起注銷請求
瀏覽器跳轉(zhuǎn)到認(rèn)證服務(wù)器發(fā)起注銷請求
認(rèn)證服務(wù)器校驗瀏覽器請求里的TGC
認(rèn)證服務(wù)器注銷TGT,同時通知已經(jīng)登錄的系統(tǒng)注銷已經(jīng)頒發(fā)的ST

CAS 2.0代理模式認(rèn)證流程
CAS V2引入了代理模式,代理模式的出現(xiàn)解決了不同網(wǎng)站之間的資源相互引用的問題。

為了解決用戶訪問CAS單點登錄客戶端1的某資源,客戶端1代表用戶從客戶端2上獲取授權(quán)性資源的情況,CAS 2.0出現(xiàn)了代理模式
下面簡述一下CAS代理模式的認(rèn)證流程。
首先用戶去加載代理應(yīng)用程序“Proxy 網(wǎng)站app”。
proxy發(fā)現(xiàn)用戶沒有登錄,將瀏覽器重定向到認(rèn)證服務(wù)器。
用戶被重定向到認(rèn)證服務(wù)器之后,認(rèn)證服務(wù)器發(fā)現(xiàn)用戶沒有攜帶SSO Session。要求用戶輸入賬號密碼。
認(rèn)證服務(wù)器收到用戶名和密碼,如果驗證通過,會創(chuàng)建包含TGT的單點登錄(SSO)會話TGC cookie,TGT是用戶會話密鑰SSO session,給用戶設(shè)置cookie,簽發(fā)ST,同時會將頁面重定向到Proxy。
用戶使用ST請求proxy。
Proxy收到ST并向認(rèn)證服務(wù)器發(fā)起驗證,驗證成功后認(rèn)證服務(wù)器向Proxy返回PGT和PGTIOU。
Proxy收到PGT和PGTIOU之后,會將PGTIOU存儲為PGT的映射,并為用戶設(shè)置cookie。
用戶攜帶之前Proxy設(shè)置的cookie去訪問網(wǎng)站app。
用戶的請求到達Proxy,它會驗證cookie,如果驗證通過,Proxy會通過之前保存的PGT,去認(rèn)證服務(wù)器獲取PT。
認(rèn)證服務(wù)器返回PT給Proxy,Proxy再拿著PT去請求網(wǎng)站app。
網(wǎng)站app收到帶著PT的請求之后,會將PT發(fā)送到認(rèn)證服務(wù)器的proxyValidate接口去驗證。
認(rèn)證服務(wù)器驗證成功后響應(yīng)重定向URI。
網(wǎng)站app收到認(rèn)證服務(wù)器的響應(yīng)之后,會查看代理URI鏈并驗證該鏈?zhǔn)欠窨尚?,驗證通過,網(wǎng)站app會給proxy設(shè)置cookie。
Proxy有了cookie之后,會攜帶這個cookie去訪問網(wǎng)站app。
網(wǎng)站app驗證cookie并向proxy返回資源,代理再將收到的響應(yīng)轉(zhuǎn)發(fā)到瀏覽器。
PT(Proxy Ticket):如果用戶訪問的不是一個Web應(yīng)用,而是一個C/S架構(gòu)的應(yīng)用,因為C/S結(jié)構(gòu)的應(yīng)用得不到cookie,所以用戶不能自己去CAS獲取ST,而是通過訪問proxy service的接口,憑借proxy service的PGT去獲取一個PT,然后才能訪問到此應(yīng)用。
二、CAS攻擊面
CAS在安全方面都做了些什么?
強制認(rèn)證,很多CAS客戶端都支持強制認(rèn)證,用戶必須重新進行身份驗證才能訪問特定的資源,一般這種都是基于服務(wù)配置的。
加密傳輸,4.x之后的版本都默認(rèn)不允許http傳輸,但是CAS的安全問題也在于他只對https進行了強制要求。
設(shè)置標(biāo)頭,禁止瀏覽器緩存,避免憑據(jù)重放。

CAS Server為java實現(xiàn),不可避免的就是反序列化漏洞,最新版本的CAS Server使用Spring框架,也受到了去年的Spring framework RCE漏洞的影響,但是因為使用默認(rèn)CAS部署的web應(yīng)用并不是很多,影響倒不是很大。根據(jù)不同的實現(xiàn)和配置情況也會出現(xiàn)一些憑據(jù)泄漏未授權(quán)訪問等情況。

CAS攻擊面-XSS
通過POST請求CAS的REST API(默認(rèn)是不開啟的),輸入用戶名密碼。
如果身份驗證失敗會將用戶名輸出在頁面上,導(dǎo)致xss,由于這個信息也會寫入日志,且CAS 6.X一些版本使用了log4j組件,會有l(wèi)og4j2的漏洞。這個洞產(chǎn)生的原因是認(rèn)證失敗后拋出AuthenticationException異常,并輸出這部分信息。

CAS攻擊面-統(tǒng)一注銷錯誤
如果服務(wù)注銷時只注銷局部會話,這種情況大部分是由于認(rèn)證服務(wù)器配置出錯導(dǎo)致的。由于配置不當(dāng)?shù)仍颍脩粼诰W(wǎng)站app1注銷,如果是局部會話注銷,這個時候瀏覽器與認(rèn)證服務(wù)器的cookie,也就是TGC依然是活躍的狀態(tài),這個時候訪問網(wǎng)站app2,網(wǎng)站app2與認(rèn)證服務(wù)器進行交互的時候發(fā)現(xiàn)我們的賬戶依然是登錄狀態(tài),所以就可以直接從網(wǎng)站app2獲取資源,其實這個時候,注銷是失敗的。
還有一種情況和這種情況是類似的,就是當(dāng)我們集群部署CAS的時候,由于負(fù)載均衡或者一些別的轉(zhuǎn)發(fā)配置的原因,從認(rèn)證服務(wù)器到客戶端的注銷請求可能會被轉(zhuǎn)發(fā)到不是瀏覽器提交注銷請求的客戶端,那這個時候客戶端驗證ST就會失敗,注銷操作也就失敗了。
CAS攻擊面-憑據(jù)泄漏
在CAS V1里最重要的憑據(jù)為TGC,而TGC又保存在瀏覽器的cookie里,如果TGC泄露,則我們可以構(gòu)造請求向認(rèn)證服務(wù)器請求服務(wù),而認(rèn)證服務(wù)器驗證TGC后,會向我們返回服務(wù)的ST,前面認(rèn)證流程然后我們說了,瀏覽器將ST放入?yún)?shù)請求服務(wù),服務(wù)驗證ST,那么這個時候我們就可以從服務(wù)獲取數(shù)據(jù)了。當(dāng)然這個憑據(jù)泄露僅僅指的是TGC。相信大家剛開始接觸web的時候都用過一些xss平臺,本質(zhì)上是一樣的,就是獲取cookie。


CAS攻擊面-憑據(jù)爆破
如果憑據(jù)在生成時不遵守隨機不可猜測的開發(fā)原則,那么用戶可以通過爆破來猜測憑據(jù)。比如ST生成有規(guī)律性,那么用戶可以通過猜測ticket來請求其他服務(wù),因為CAS授權(quán)是統(tǒng)一的,所以在經(jīng)過身份認(rèn)證后,只要知道服務(wù)的ST就可以向服務(wù)發(fā)起請求。
CAS攻擊面-其他問題
1.憑據(jù)重放,在一些早期版本的Safari瀏覽器可以通過回退按鈕,瀏覽器會被迫重放用戶憑據(jù)。CAS官方也意識到了這個問題并在登錄頁顯示了提示。

2.未授權(quán)訪問,用戶繞過授權(quán)流程,通過請求CAS Server接口獲得票據(jù)。再請求向服務(wù)發(fā)起請求獲取特定的受保護的資源,因為CAS架構(gòu)下的服務(wù)使用統(tǒng)一身份認(rèn)證,導(dǎo)致攻擊者可以訪問權(quán)限內(nèi)的所有服務(wù)。
三、CAS漏洞案例
漏洞案例-XSS
一些CAS版本提供了reset功能來創(chuàng)建或查詢憑據(jù),右邊是reset協(xié)議的處代碼。用戶輸入用戶密碼請求reset接口,如果認(rèn)證失敗就拋出AuthenticationException異常。

進入ResponseEntity,將用戶信息輸出。

漏洞案例-反序列化
在CAS的一些版本里面,數(shù)據(jù)傳輸加密的key硬編碼到了源碼,如果部署的時候不修改,就會導(dǎo)致用戶通過傳入精心構(gòu)造的序列化數(shù)據(jù)達到命令執(zhí)行的效果。
環(huán)境搭建:
Vulhub
/apereo/4.1-rce
影響版本:CAS 4.X
漏洞原因:數(shù)據(jù)傳輸加密的key硬編碼

漏洞利用:
使用工具生成反序列化payload

2.將payload傳入excution參數(shù)


CAS V1相對其他身份協(xié)議并沒有任何優(yōu)勢,甚至因為它的B/S架構(gòu),導(dǎo)致很多應(yīng)用場景無法接入。相比CAS,其實OIDC、OAuth和SAML優(yōu)勢更加明顯,但是經(jīng)過了這么多年的發(fā)展,CAS因為融入了越來越多其他的身份協(xié)議,已經(jīng)不再是一個簡單的身份協(xié)議了,它更像是一個協(xié)議架構(gòu)。現(xiàn)在的CAS Server可以接入多種身份協(xié)議,比如你可以用CAS認(rèn)證服務(wù)器,也可以使用SAML、OAuth等協(xié)議進行認(rèn)證,當(dāng)然,接入更多的場景也會伴隨著更多的漏洞,這需要我們更深入的研究。