趙 梁,李 磊,李向麗
(鄭州大學 信息工程學院,鄭州 450000)
在Web應用的安全保障措施中,通常使用各類權限框架來保證整個系統的安全性以及數據的完整性。雖然權限框架能夠實現客戶端請求的合法性校驗,但是攻擊者仍可以通過攔截合法的請求報文來獲取交互過程中的請求信息,從而對Web應用程序執行重放攻擊,入侵系統獲取用戶的數據信息。
針對重放攻擊防御的問題,現有基于權限認證框架的方案多為每一次請求設置一個新鮮性標識來確定此次請求是否為新請求,從而過濾重放攻擊。設置消息新鮮性標識的方法可以使用基于時間戳[1-2]、序列號[3]、版本號[4]和計數器[5]等。然而服務端權限框架針對每次請求的新鮮性檢測能力較弱,使得服務端應用程序在重放攻擊方面的防御能力有限。
文獻[1]提出一種利用傳遞消息時系統的時間戳進行消息新鮮性標識的方法,當攻擊者執行重放攻擊時,通過將報文的時間戳與已緩存時間戳進行比較判斷消息的新鮮性,從而過濾重放攻擊報文。該方法能有效地防御重放攻擊,但存放時間戳信息會耗費大量的存儲空間,從而影響服務端程序運行效率。文獻[2]提出一種基于時間戳比較的請求過濾方案,即當消息時間戳超出服務端預定的范圍時即拒絕消息請求。該方案在一定的請求時延內可有效防御重放攻擊,但是如果服務端的時鐘與客戶端的時鐘不同步,就會導致服務端拒絕客戶端的請求。文獻[3]提出一種通過設置無重復請求序列號進行消息新鮮性標識的方法,將每個到達服務端的請求信息序列號與已存儲的序列號進行比較,如果不存在,存儲該序列號,否則就認為是重放攻擊。該方法解決了使用時間戳比較時的時鐘同步問題,但是由于服務端需要存儲每次請求的序列號,因此會造成服務端存儲開銷較大,影響運行效率。文獻[4]提出一種基于版本號的消息新鮮性標識方案,通過在雙端定義請求版本號來維持新鮮性標識。該方案解決了依賴于服務端存儲的重放攻擊防御問題,同時保證了雙端的請求的可靠性,但是當攻擊者在抓取大量的請求信息后,可以猜解出請求版本號的更新模式,從而偽造請求執行新的重放攻擊。
為解決基于時間戳方案的時鐘同步問題以及基于請求版本號方案服務器存儲空間開銷較大的問題,文獻[5]提出一種基于計數器與動態交驗子的請求校驗方案。該方案可以在一定網絡延時內抵御重放攻擊,同時又能夠解決雙端的時鐘同步問題,但是由于其中的動態校驗子是基于服務器端的時間戳生成的,當網絡延遲過大時會造成校驗失敗,因此對于大部分Web應用的權限框架攻擊防御方案不適用。
基于時間戳的重放攻擊防御方案對于服務器的時效性要求較高,Web應用系統經常會因訪問量過大而導致延遲,基于時間戳的方法在此種情況下會失效;而基于版本號的方案除了服務器本身的存儲開銷以外還需要對每一次請求進行版本號存儲,服務器的存儲開銷過大。為此,本文通過引入雙序列函數,提出不依賴于時間戳與存儲版本的的請求校驗方案對請求進行合法校驗,并使其能夠適用于多數Web權限框架進行重放攻擊的防御。
在本文方案中,請求過程分為身份校驗過程和會話保持過程。身份校驗過程是指在登錄過程中通過比較序列函數值對兩端身份進行雙向認證。會話保持過程是指在客戶端與服務端相互認證之后在保持會話的過程中通過雙端周期函數值比對進行會話的合法性校驗。在會話保持過程中使用周期校驗因子對周期函數的周期進行變換,周期校驗因子是指周期函數中影響函數周期變化的參數,周期值則是變化后的結果。例如,f(x)=cos(x/n),則n就是f(x)的周期校驗因子,x/n為周期函數的周期值。請求過程中所用到的符號及其定義如表1所示。

表1 符號定義Table 1 Symbol definition
本文方案采用雙序列函數對請求過程進行新鮮性驗證。客戶端與服務端具有相同的非周期函數,在身份校驗過程中,客戶端使用非周期函數生成身份校驗的隨機數,并根據身份校驗的隨機數生成加密校驗因子[6],服務端通過比較請求與自身通過運算(使用相同的隨機數在相同的周期函數下運算)所得的加密校驗因子是否一致來判斷服務端請求的新鮮性[7]。在每一次請求之后,兩個非周期函數都按同一步長[8]計算下一次的加密校驗因子。在身份校驗通過之后,生成隨機數作為下一次請求的周期函數參數,以保證每次校驗完成之后的周期函數新鮮性,并利用雙端的周期函數生成加密校驗因子,服務端通過同樣的方式生成加密校驗因子進行比對,在每次請求過后按統一步長向下運行,在運算一個周期后,利用周期校驗因子改變周期,利用同樣的步長重新開始運算,以保證每個周期的隨機數新鮮性[9]。
按照上述方案,客戶端與服務端均擁有相同的序列函數(即初值相同、序列函數的系數均相同且含有2個以上的系數[10])和周期校驗函數(初值相同且周期校驗因子相同),服務端與客戶端具有相同的運算參數P,在序列函數系數改變后使用P作為雙端序列函數運算的初值,而服務端擁有一個隨機數作為服務端的請求校驗參數Key的初值(初值的位數少于請求過程中md5運算加密值的位數)。為便于說明,此處假設客戶端與服務端發送失敗之后會執行重發操作以保證序列信息不發生位偏[11]現象。身份校驗過程如下:
步驟1首先客戶端生成隨機數X,并使用初始的序列函數執行F(X)函數運算得到運算結果Realmc,之后執行單向哈希算法md5(Realmc,A),得到加密參數Rc,然后向服務端發送Rc作為校驗參數、隨機數X,并將X作為服務端的序列函數初值[12]:X=Random(x),Realmc=F(X),Rc=md5(Realmc,A),C→S:REQUEST(Rc,X)。
步驟2服務端接收到X,首先判斷得到的請求參數Rc是否與Key相等。如果相等,則判斷請求為重放攻擊,拒絕會話;如果不相等,運算F(X)得到函數值Realms,再執行單向哈希算法md5(Realms,A)得到加密結果Rs,并將Rs與客戶端傳來的加密結果Rc進行比較。如果相同,則執行Key=Rc,否則拒絕通信。判斷完畢后,生成一個隨機數M,將原有的序列函數系數A的值替換為M,通過計算F(P)得到新的函數運算值[13]Realmres,執行單向哈希算法md5(Realmres,P)得到加密結果Ra,然后執行P=P+StepA,并將加密結果與新的F(X)系數A發送給客戶端。算法代碼如下:
If Rc==Key Then {Restart Protocol;}
Else Realms=F(X);
Rs=md5(Realm,A);
If Rs==Rc Then{M=Random(x);
A=M;
Realmres=F(P);
Ra=md5(Realmres,P);
P=P+StepA;
Key=Rc;
S→C:RESPONSE(Ra,M);}
Else Restart Protocol;
步驟3客戶端收到響應后,首先使用新的系數值M替換客戶端自身序列函數的系數A,計算F(P)得到Realmreq,執行單向哈希算法md5(Realmreq,P)得到加密結果Rac,然后將加密結果與服務器響應中的Ra做比較。如果相同,則承認此服務端合法并執行P=P+StepA,生成隨機數J,將周期函數的周期值改為J,否則拒絕通信。判斷完成后,計算新的F(P)得到函數值Realmcs,執行單向哈希算法md5(Realmcs,P)得到請求參數Rb,并將Rb和J作為請求參數發送到服務端。算法代碼如下:
A=M;
Realmreq=F(P);
Rac=md5(Realmreq,P);
If Rac==Ra Then{
P=P+StepA;
J=Random(x);
f(;J);
Realmcs=F(P);
Rb=md5(Realmcs,P);
C→S:REQUEST(Rb,J);}
Else Restart Protocol;
步驟4服務端接收到請求參數Rb之后,對Rb與Key做比較,如果相同則為重放攻擊拒絕會話,否則執行Key=Rb。再通過計算F(P)得到函數值Realmsc,執行md5(Realmsc,P)得到加密參數Rbs,判斷Rbs與Rb是否相等。如果相等,則承認客戶端合法并且運算P=P+StepA,將周期校驗函數的周期值置為J,否則拒絕客戶端會話。算法代碼如下:
If Rb==Key Then {Restart Protocol;}
Else Key=Rb;
Realmsc=F(P);
Rbs=md5(Realmsc,P);
If Rbs==Rb Then {
P=P+StepA;
f(;J);}
Else Restart Protocol;
客戶端與服務端相互認證身份后,客戶端與服務端進入會話保持過程。會話保持過程如下:
步驟1客戶端調用周期函數f(X),使用客戶端與服務端共享的初值X0運算得到周期函數初始值YGc,將X0/N結果作為加密參數Kxc,執行運算md5(Yc,Kxc)得到請求參數[14]Tc。然后執行X=X0+StepN更新X值作為下一次運算參數,并將請求參數Tc發送到服務端。算法代碼如下:
Yc=f(X0);
Kxc=X0/N;
Rc=md5(Yc,Kxc);
X=X0+StepN;
C→S:REQUEST(Tc);
步驟2服務端收到客戶端的請求參數Tc后,將Tc與Key做比較。如果相等,則判斷此次請求為重放攻擊,拒絕會話,否則執行key=Tc。再通過計算f(X0)得到函數值Ys,將X0/N作為加密參數[15]Kxs,執行md5(Ys,Kxs)得到加密值Tse。判斷Tse與Tc是否相等[16],如果相等,則此次會話是合法的,否則就終止會話。在確認此次會話合法之后,服務端計算X=X0+StepN并執行f(X)得到周期函數值Ysc,判斷Ysc是否大于等于U。如果Ysc≥U的話,則對周期函數執行周期校驗運算f(X;N),并將X置為初始值X0,重新運算f(X)得到新的周期函數值Ysc。然后運算X×N得到響應加密參數[17]Kxsc,執行md5(Ysc,Kxsc)得到響應參數Tsc,將響應參數Tsc響應給客戶端。算法代碼如下:
If Tc==Key ThenRestart Protocol;
Else Key=Tc;
Ys=f(X0);
Kxs=X0/N;
Tse=md5(Ys,Kxs);
If Tse==Tc Then X=X0+StepN;
Ysc=f(X);
If Ysc>=U Then{f(X)=f(X;N);
X=X0;
Ysc=f(X);}
Kxsc=X*N;
Tsc=md5(Ysc,Kxsc);
S→C:RESPONSE(Tsc);
Else Restart Protocol;
步驟3客戶端收到服務端的響應參數Tsc后,計算f(X)函數值Ycs,判斷Ycs是否大于等于U,如果Ycs≥U則周期函數執行周期校驗運算f(X;N),并將X置為初始值X0,重新運算f(X)得到新的函數值Ycs,計算X×N得到md5加密參數Kxcs,執行md5(Ycs,Kxcs)得到加密值Tcs,判斷Tcs與Tsc是否相等。如果相等,則判斷不是重放攻擊,允許會話,否則就終止會話。判斷完畢后,計算f(X)得到函數值Yc1,計算X/N得到加密參數[18]Kxc1,執行md5(Yc1,Kxc1)得到請求參數Tc1,在請求時發送Tc1作為服務端的加密校驗參數。每次請求都會執行以上步驟來保證消息的可靠性。算法代碼如下:
Ycs=f(X);
If Ycs>=U Then {f(X)=f(X;N);
X=X0;
Ycs=f(X);}
Kxcs=X*N;
Tcs=md5(Ycs,Kxcs);
If Tcs==Tsc Then {Yc1=f(X);
Kxc1=X/N;
Tc1=md5(Yc1,Kxc1);
C→S:REQUEST(Tc1);}
Else Restart Protocol;
為便于說明,本文假設攻擊者可以獲取所有的請求與響應信息,并利用請求信息對服務端執行重放攻擊。
如果在雙端認證階段步驟1執行重放攻擊,那么由于服務端會直接校驗Key值是否與加密校驗參數相等,相等的話就說明此次請求與上一次請求重復是重放攻擊,而Key值是由客戶端初次請求得到的Key,步驟2重復請求的話Key值必定會與加密校驗參數相等所以會拒絕此次請求。如果在步驟2執行重放攻擊,那么由于客戶端會比對響應中的加密校驗參數是否與自身生成的加密校驗參數相等,相等的話說明此次響應是服務端的響應并改變序列函數的運算值,由于該加密校驗參數的值是基于序列函數的值生成的,重放上一次請求會導致加密校驗參數比對失敗,因此會拒絕重放攻擊的請求。同理,在步驟3執行重放攻擊,由于序列函數值的變化以及Key值的變化,重放攻擊的請求無法通過Key值校驗。而在步驟4執行重放攻擊,由于客戶端序列函數值的變化,重放攻擊的響應無法通過加密校驗參數的校驗。
會話保持階段與身份校驗階段類似,服務端在每次收到請求時會校驗對應的Key值,由于周期函數值變化以及每次請求改變Key值,因此重放攻擊無法通過服務端的校驗。而客戶端每次收到響應都會與自身生成的加密校驗參數作比對,由于周期函數值的變化以及每經過一周期函數系數的變化,客戶端所運算出來的加密校驗參數也會改變,因此重放攻擊無法通過客戶端的校驗。
信息篡改攻擊指攻擊者攔截用戶請求報文,篡改其中的重要信息,并發送新的請求到服務端獲取用戶數據。假設攻擊者具有破解單向哈希加密算法的能力,并且可以獲取通信過程中的報文信息。由于每次請求的加密校驗參數的加密鹽值信息變化導致攻擊者無法破譯加密校驗參數,并且Key值與加密校驗參數每次請求生成的值都不同,因此信息篡改的請求無法通過服務端校驗。
密碼猜解攻擊是指攻擊者通過發送大量的請求到服務器窮舉出用戶密碼[19]。假設攻擊者可以發送大量的密碼嘗試報文。由于每次請求都需要經過雙重校驗,而校驗參數又隨請求次數不斷變化,所以攻擊者的猜解嘗試報文無法通過服務端的校驗。
線下密碼猜解攻擊是指利用線上抓取的報文信息在線下進行密碼的破解工作之后再構造報文請求。假設攻擊者可以線下破解單向哈希算法,由于每經過一個周期,函數的系數都會變化,而加密校驗參數又是基于系數生成的,因此每個周期的請求加密方式都不相同,無法破解。
中間人攻擊是指攻擊者大量竊聽雙端的通信,從中獲取雙端的通信規律,并用此偽造請求信息。假設攻擊者可以獲取雙端所有的通信報文信息,由于函數的初始系數都是隨機生成的,并且每個周期過后都會更新系數,因此每次請求的加密校驗參數生成策略是基于隨機數的、無規律的,攻擊者無法利用請求信息猜解出規律。
偽造服務端的攻擊是指攻擊者偽裝成服務端接收客戶端的請求信息并回送響應,從而獲取客戶端所發送到服務端的信息[20]。假設攻擊者可以偽造通信的服務端。由于客戶端每次收到響應都會校驗對應的加密校驗參數,因此如果偽造服務端,則在沒有服務端函數的情況下無法偽造響應到客戶端。
Session竊取攻擊是指攻擊者通過竊取合法用戶的Session,偽造合法用戶的會話請求來獲取用戶數據。假設攻擊者可以竊取合法用戶的Session信息。由于本文方案在Session校驗機制之外增加了新的校驗方案,即使攻擊者竊取了Session信息,在沒有序列函數與周期函數的情況下也無法生成加密校驗參數,因此無法通過服務端的校驗。
假設Web服務端網絡延遲較大。在身份驗證階段與會話階段均保證了兩種函數運算值的統一更新模式,即僅在此次請求正確之后才會更新函數運算值,請求報文丟失的情況下,在此次加密校驗參數未重發并收到回送請求之前,是不會更新函數的運算值的,由此可保證雙端的函數運算值不會出現位偏情況。基于以上分析可知,此方案可以抵御較高的網絡延遲。
上文從8個方面分析了本文方案的安全防御能力,為了便于說明,本節使用R1~R8分別表示這8種安全情況,并通過表2給出本文方案與文獻[1-5]方案在Web應用的權限框架中的安全性能比較。可以看出,本文方案在安全性表現上比單純基于時間戳的方案和單純基于序列號的方案的安全性更高。由于文獻[5]方案無法應對網絡延遲較大的情況,相對而言,本文方案在沒有接收到請求信息的時候不會更新序列函數值,即使網絡延遲較大也不會影響整個序列函數的運行。

表2 6種方案在Web應用中的安全性能Table 2 Security performance of six schemes in Web applications
表3給出了本文方案與文獻[1-5]中方案時間性能的比較,其中,Tt為時間戳運算時間,Ts為序列號運算時間,Ty是加密序列號運算時間,H為單向哈希運算時間,n為從數據庫取出之前請求的數據所需要的時間。由于不同運算之間具有一定的時間差距,從運算角度分析有如下運算時間差距:Tt 表3 8種方案客戶端與服務端的時間性能Table 3 Time performance of eight schemes inclient and server 針對Web應用層易受重放攻擊的問題,本文提出一種基于雙序列函數Web權限框架的重放攻擊防御方案。分析結果表明,該方案可以有效防御常見的Web應用層攻擊,并且適用于多數Web權限框架。下一步將從簡化運算和減少服務端運算量等方面改進本文方案,并使其能防御更多種類的Web應用層攻擊。此外,還將解決第三方授權機制中的重放攻擊防御問題。
4 結束語