1. 程式人生 > 其它 >WEB安全新玩法 [9] 重置密碼之驗證流程防繞過

WEB安全新玩法 [9] 重置密碼之驗證流程防繞過

「業務安全動態加固平臺 · 實踐系列」

一般來說,業務流程中出現多個操作環節時,是需要順序完成的。程式設計者往往按照正常使用者的操作順序實現功能,而忽略了攻擊者能夠繞過中途環節,直接在後續環節上進行非法操作。iFlow 業務安全加固平臺能夠在不修改網站程式的情況下,強制流程的順序執行。


某網站系統在使用者重置密碼時,需進行算術題人機識別驗證,再進入郵箱驗證碼驗證環節,通過後才能真正地重置密碼。由於程式設計不當,攻擊者可以輸入任意受害者賬號,並正常完成算術題驗證後,直接繞過郵箱驗證碼驗證過程,進入到重置受害者密碼的環節。我們接下來會看到如何利用 iFlow 來防範這類流程繞過。

一、原始網站

1.1 正常使用者訪問

使用者進入登入頁面,點選找回密碼

連結。

在第一步確認賬號頁面中輸入使用者名稱和算術題驗證碼。

正確提交答案後,網站向用戶的註冊郵箱傳送驗證碼。使用者進入第二步進行安全驗證的頁面,使用者將郵件中的驗證碼在頁面中輸入。

郵件驗證碼正確,則使用者可在第三步設定新密碼中重置密碼。

HTTP 互動流程如下:

sequenceDiagram participant 正常使用者 participant 瀏覽器 participant Web伺服器 participant 郵件系統 正常使用者->>瀏覽器: 點選找回密碼連結 瀏覽器->>Web伺服器: GET /one/getpassword.php Web伺服器->>正常使用者: 顯示:第一步頁面 正常使用者->>瀏覽器: 填寫使用者名稱和算術題驗證碼 瀏覽器->>Web伺服器: POST /one/getpassword.php<br/>action=step1,username=test01 Web伺服器->>郵件系統: 傳送驗證碼到郵箱 Web伺服器->>正常使用者: 顯示:第二步頁面 正常使用者->>郵件系統: 以test01收取驗證碼 正常使用者->>瀏覽器: 填寫郵箱驗證碼 瀏覽器->>Web伺服器: POST /one/getpassword.php<br/>action=step2,yzm=338238 Note over Web伺服器: 驗證郵箱驗證碼正確 Web伺服器->>正常使用者: 顯示:第三步頁面 正常使用者->>瀏覽器: 填寫新的密碼 瀏覽器->>Web伺服器: POST /one/getpassword.php<br/>action=step3,password=123456 Web伺服器->>正常使用者: 顯示:設定新密碼成功

1.2 攻擊者訪問

攻擊者使用 Burpsuite 工具作為瀏覽器和 Web 伺服器之間的代理,Burpsuite 可以攔截報文並修改其中內容後再發出。

攻擊者在第一步確認賬號頁面中填寫受害者的賬號和正確的算術題驗證碼並點選下一步。

然後,點選瀏覽器的回退按鈕回到上述頁面,開啟 Burpsuite 的攔截開關,重新填寫資訊,並點選下一步。攻擊者可以在 Burpsuite 看到發出的第一步請求報文。

攻擊者在 Burpsuite 中將請求體內容修改為第三步的報文,發往網站伺服器。

攻擊者在瀏覽器中可以看到密碼重置成功的提示。

至此,攻擊者在未訪問受害者郵箱的情況下,順利修改了受害者的密碼。

HTTP 互動流程如下:

sequenceDiagram participant 攻擊者 participant 瀏覽器 participant 攻擊工具 participant Web伺服器 participant 郵件系統 攻擊者->>瀏覽器: 點選找回密碼連結 瀏覽器->>Web伺服器: GET /one/getpassword.php Web伺服器->>攻擊者: 顯示:第一步頁面 攻擊者->>瀏覽器: 填寫使用者名稱和算術題驗證碼 瀏覽器->>Web伺服器: POST /one/getpassword.php<br/>action=step1,username=test01 Web伺服器->>郵件系統: 傳送驗證碼到郵箱 Web伺服器->>攻擊者: 顯示:第二步頁面 攻擊者->>瀏覽器: 點選回退按鈕 瀏覽器->>Web伺服器: GET /one/getpassword.php Web伺服器->>攻擊者: 顯示:第一步頁面 攻擊者->>瀏覽器: 填寫使用者名稱和算術題驗證碼 瀏覽器->>攻擊工具: POST /one/getpassword.php<br/>action=step1,username=test01 rect rgb(250, 128, 128) Note over 攻擊工具: 將請求修改成第三步報文 end 攻擊工具->>Web伺服器: POST /one/getpassword.php<br/>action=step3,password=123456 Web伺服器->>攻擊者: 顯示:設定使用者密碼成功

二、iFlow虛擬補丁後的網站

我們在 Web 伺服器前部署 iFlow 業務安全加固平臺,它有能力攔截、計算和修改雙向 HTTP 報文並具備儲存能力,成為 Web 應用的虛擬補丁。在本例中,iFlow 在進行第三步操作時,檢查了第二步操作中所作的記號,確保操作無法繞過第二步直接進入第三步。

2.1 正常使用者訪問

在第二步郵箱驗證碼返回正確資訊時,iFlow 給會話設定一個第二步完成標誌。在第三步提交新密碼時,iFlow 會檢查第二步完成標誌,如果這個標誌存在,則將請求發到後端 Web 伺服器進行正常處理。

正常使用者的 HTTP 互動流程如下:

sequenceDiagram participant 正常使用者 participant 瀏覽器 participant iFlow participant Web伺服器 participant 郵件系統 正常使用者->>瀏覽器: 點選找回密碼連結 瀏覽器->>Web伺服器: GET /one/getpassword.php Web伺服器->>正常使用者: 顯示:第一步頁面 正常使用者->>瀏覽器: 填寫使用者名稱和算術題驗證碼 瀏覽器->>Web伺服器: POST /one/getpassword.php<br/>action=step1,username=test01 Web伺服器->>郵件系統: 傳送驗證碼到郵箱 Web伺服器->>正常使用者: 顯示:第二步頁面 正常使用者->>郵件系統: 以test01收取驗證碼 正常使用者->>瀏覽器: 填寫郵箱驗證碼 瀏覽器->>Web伺服器: POST /one/getpassword.php<br/>action=step2,yzm=338238 Note over Web伺服器: 驗證郵箱驗證碼正確 Web伺服器->>iFlow: 返回:第二步頁面 rect rgb(160, 250, 160) Note over iFlow: 設定第二步完成標誌 end iFlow->>正常使用者: 顯示:第二步頁面 正常使用者->>瀏覽器: 填寫新的密碼 瀏覽器->>iFlow: POST /one/getpassword.php<br/>action=step3,password=123456 rect rgb(160, 250, 160) Note over iFlow: 檢查第二步完成標誌:存在 end iFlow->>Web伺服器: 原請求報文 Web伺服器->>正常使用者: 顯示:設定新密碼成功

2.2 攻擊者訪問

如前所示,如果攻擊者直接將第二步請求的報文修改為第三步請求的報文發出,iFlow 會攔截這個報文並檢查第二步完成標誌。由於攻擊者沒有實際完成第二步操作,因此也就沒有第二步完成標誌,iFlow 不會繼續向後端 Web 伺服器執行密碼重置操作。

攻擊者的 HTTP 協議互動過程如下:

sequenceDiagram participant 攻擊者 participant 瀏覽器 participant 攻擊工具 participant iFlow participant Web伺服器 攻擊者->>瀏覽器: 點選找回密碼連結 瀏覽器->>Web伺服器: GET /one/getpassword.php Web伺服器->>攻擊者: 顯示:第一步頁面 攻擊者->>瀏覽器: 填寫使用者名稱和算術題驗證碼 瀏覽器->>Web伺服器: POST /one/getpassword.php<br/>action=step1,username=test01 Web伺服器->>攻擊者: 顯示:第二步頁面 攻擊者->>瀏覽器: 點選回退按鈕 瀏覽器->>Web伺服器: GET /one/getpassword.php Web伺服器->>攻擊者: 顯示:第一步頁面 攻擊者->>瀏覽器: 填寫使用者名稱和算術題驗證碼 瀏覽器->>攻擊工具: POST /one/getpassword.php<br/>action=step1,username=test01 rect rgb(250, 128, 128) Note over 攻擊工具: 修改成第三步請求 end 攻擊工具->>iFlow: POST /one/getpassword.php<br/>action=step3,password=123456 rect rgb(160, 250, 160) Note over iFlow: 第二步完成標誌:不存在 end iFlow->>攻擊者: 顯示:訪問被拒絕

2.3 程式碼

iFlow 內建的 W2 語言是一種專門用於實現 Web 應用安全加固的類程式語言。它介於配置和通用語言之間,具備程式設計的基本要素和針對 HTTP 協議的特有擴充套件,能為業務系統編寫涉及複雜判斷和動態修改的邏輯。

考慮到安全產品的使用者通常為非程式設計師,他們習慣面對配置檔案而非一段程式碼。因此,W2 語言雖包含語言要素,仍以規則檔案方式呈現,並採用可以體現層次結構和方便詞法校驗的 JSON 格式。

用 W2 語言實現上述虛擬補丁的程式碼如下:

[
	{
		"if": [
			"REQUEST_FILENAME == '/ajax/yzm_check_ajax.php'",
			{
				"variable": "RESPONSE_BODY",
				"operator": "contain",
				"pattern": "window.document.userreg.yzm_mobile2.value='yes'"
			}
		],
        "then": "SESSION.step2_ok@300 = true"
    },
    {
        "if": [
			"REQUEST_METHOD == 'POST'",
			"REQUEST_FILENAME == '/one/getpassword.php'",
			"@ARGS.action == 'step3'"
		],
        "then": {
            "if": "SESSION.step2_ok",
            "then": "SESSION.step2_ok=null",
			"else": {
				"execution": "SESSION.step2_ok=null",
				"verdict": {
                    "action": "deny",
                    "log": "invalid access step3!"
                }
            }
        }
    }
]

示例程式碼中有兩條規則,分別作用如下:

第一條規則

當伺服器在第二步操作返回郵箱驗證碼成功時,iFlow 攔截此響應。並且,iFlow 將建立一個會話 (SESSION) 的儲存變數 step2_oktrue

第二條規則

當瀏覽器請求第三步操作即確認重置密碼時,iFlow 攔截此請求。iFlow 將檢查會話 (SESSION) 的儲存變數 step2_ok 是否存在:如果存在則放行,不存在則拒絕訪問。不管哪種情形,儲存變數 step2_ok 都會被清除,以防止第三步被重複單獨訪問。

注意:上述會話中的 step2_ok 是儲存在伺服器端的 iFlow 儲存中的,攻擊者在瀏覽器端是看不到資料更無法進行修改的。

三、總結

iFlow 使用兩條規則在不修改伺服器端程式碼的前提下,保證了順序操作中的關鍵環節不被繞過。

此外,我們注意到,關鍵環節的完成判斷是以響應內容作為依據而非以發起請求作為依據的,這樣可以避免攻擊者隨手發出一個不成功的操作來欺騙 iFlow。當然,這樣做的前提是 iFlow 具備強大的響應報文識別能力。(張戈 | 天存資訊)