天天看點

某網站漏洞排查經驗先驗證後操作沒有綁定在一起整體對待安全相關的接口定義的太通用導緻可以暴力破解廢棄的API導緻的漏洞總結

在這裡分享一些之前對某網站會員/使用者系統(一般域名都是passport.xx.com)進行漏洞檢查查出的一些問題,這些問題大多都是邏輯類漏洞,利用漏洞進行攻擊并不需要什麼高深的技術能力,是以危害尤其大,把相關經驗分享給大家希望大家可以自查。

這裡要說明,下面很多漏洞的例子是基于已經獲得有效的賬号密碼(行話說就是密正的賬号)的前提的,大家可能會問:

1、怎麼可能拿到别人的賬号和密碼?其實有很多網站都洩露過帶明文密碼的賬号庫(也有一些賬号庫是不帶密碼的,或者是MD5哈希後的密碼,不帶密碼的可以用一些常見簡單密碼嘗試,MD5後的密碼可以用雲MD5密碼庫來“解密”),很多人會用一些工具拿手頭拿到的幾百萬個賬号密碼針對某網站進行逐一的登入測試(這個過程叫做掃号),遇到有驗證碼的網站使用程式自動識别密碼,更進階一點可以使用雲打碼平台來識别驗證碼,隻要能登入那麼這個賬号密碼就是針對這個網站的密正賬号,就可以以一定的價格賣給收号的人了(比如5元一個賬号),掃号的人幹的是純技術活,至于收号的人拿到賬号去幹啥這就根據網站不同各不相同了(對于遊戲網站的賬号拿去後基本是洗号之類的)。

2、既然已經拿到了賬号和密碼什麼都可以幹了,還談什麼漏洞?很多網站雖然有賬号密碼可以登入,但是一些關鍵性操作往往有雙重驗證的(比如通過郵箱驗證,通過手機驗證),更何況有一些網站有賬戶安全政策,如果檢測到賬戶不安全的話(比如是異地登入)可能會需要通過手機驗證碼驗證後才能登入。是以一般情況下即使有别人的賬号你也隻能登入到他的背景看看,幾乎不可能做什麼敏感操作(比如提取賬戶餘額、修改密碼之類的),隻有進一步把一些綁定換綁之後才可能有進一步的行為。

先驗證後操作沒有綁定在一起整體對待

假設自己的賬号是A并且已經綁定過郵箱,手頭密正的賬号是B。

1、使用A賬号登陸網站,在浏覽器中開兩個頁簽。

2、進入更換郵箱的功能,頁面會提示需要擷取驗證碼,點選擷取後進入了“更換郵箱”界面,在這個界面中網站會要求你輸入驗證碼以及希望更換的新郵箱。

3、剛才不是打開了兩個标簽頁面嗎,到第二個标簽頁面點選登出,使用B的賬号登陸進入網站後同樣進入更換郵箱的功能,點選擷取驗證碼按鈕。

4、 在第一個頁簽更換郵箱的第二步輸入一個新的要更換的郵箱xx,然後輸入正确的驗證碼(到A賬号綁定的郵箱檢視驗證碼)完成更換郵箱的流程(其實目前登陸的賬戶已是B)。

5、在第二個頁簽重新整理一下頁面,可以看到B的郵箱已經更換為xx。

也就是說更換郵箱這個操作的第二步直接讀取了B的登陸資訊進行了更換,而沒有驗證B已經不是當初提出更換郵箱申請的A了,沒有把操作作為整體驗證導緻漏洞的發生。如果網站有這個邏輯漏洞,那麼很可能更換手機功能也可以這麼破。

安全相關的接口定義的太通用導緻可以暴力破解

如果玩遊戲可能知道有一種叫做密保卡的東西,比如是一個X*Y(比如10*10)的二維表格,每一格都是一個數字,玩家在做敏感操作的時候需要輸入密保卡上指定位子的三個數字,全部輸入正确後才可以進行操作。比如會要求你輸入(A10,C2,F8)三個坐标的數字,你需要檢視密保卡找到這三個數字依次輸入,如果你沒有密保卡,密保卡的數字範圍是0-99那麼每一個數字猜中的機率就已經是1%了,三個數字全部猜中的機率是百萬分之一(左右),是以是一種簡單且基本有效的安全驗證方式。

現在AJAX技術用的很多,如果對于密保卡驗證的操作也采用了一個類似checkmibao/?locations=A10,C2,F8&code=11,22,33這樣的AJAX請求固然可以達到功能需求,但是有沒有想過,這種API(如果沒有請求頻度限制)非常容易快速爆破,完全可以模拟這樣的請求checkmibao/?locations=A1,A1,A1&code={0},{0},{0},參數{0}來一個循環從0到99(最壞的情況是嘗試100次,這裡要說明的是既然是爆破這裡提供的三個坐标肯定是相同的坐标位置),如果傳回的結果是正确的則A1的密保已經得出了,否則繼續查詢,對于表格的其它坐标A2-J10也同樣進行同樣的操作很快就可以把整個密保卡“計算”出來(如果不是那麼貪婪的話可以拿到坐标後直接計算3個坐标,會快一點)。應該怎麼改?API完全不應該設locations參數,因為使用者在驗證密保卡的時候系統是知道驗證的三個坐标的,僅僅是checkmibao/?code=11,22,33這樣就可以了。

其實說白了這個漏洞出現的原因是沒有遵循“用戶端的一切是不可信”的原則,隻能相信服務端的資料,用戶端送出的資料始終要帶着懷疑的态度來處理,任何資料隻能作為參考或呈現不能作為參數直接使用。除了這個問題之外,AJAX也可能會帶來一些安全隐患,這種隐患和AJAX并無關系,而是很多開發人員在做AJAX接口的時候會錯誤的以API的心态去開發而忘記了接口是網站的一部分,比如:

1、 有的時候為了屏蔽一些資料的呈現(比如IP位址顯示為192.168.*.*),隻是在前端進行資料格式化,AJAX接口還是提供了原始資料192.168.0.1那麼完全達不到安全的目的。

2、 AJAX接口往往輕量,刷起來也快,而且容易遺漏對通路頻度的控制,更容易爆破。

3、 無重新整理意味頁面的初始加載和後續操作的驗證會分段,分段就容易産生漏洞。

廢棄的API導緻的漏洞

現在很多網站都會制作APP版本,在測試此網站的APP後發現和服務端的互動參數都進行了簽名+BASE64,我們知道安卓的應用程式是可以反編譯的,經過反編譯可以檢視到:

1、公鑰私鑰都寫在了Java代碼裡,使用公鑰來加密要發送給服務端的資料,使用私鑰來解密從服務端傳回的資料,這樣就可以通過翻譯服務端傳回的資料來熟悉API也可以繞過用戶端直接發送請求給服務端。

2、了解了所有API後發現代碼裡有一個隐藏API沒有用到,經過測試這是一個“内部使用”的API,可以通過這個API把某個用戶端換綁到賬戶并且無需進行其它驗證。至此整個網站的賬号安全都因為這個點失守了。

這個過程看上去很簡單,但要發現這個漏洞是經過了大量的嘗試的,要先熟悉整個操作流程,逐個嘗試是否有邏輯漏洞和其它突破點,每一個漏洞都是不同的不是每一個APP都會有隐藏的内部API,每一次可能的突破往往都是基于非正常思維。

那麼改進方法也很簡單,把KEY值以打散方式存儲于SO檔案中,最好協定的加密解密全采用C編寫,在Java層對于協定都是透明的。

總結

可别小看這幾個漏洞,出現這樣的漏洞意味着黑客可以随便修改使用者的郵箱、手機、密碼、進而繞過各種二次驗證,把賬号完全掌握在自己手裡。如果掃号的人手頭有1000萬個賬号庫,掃到密正賬号50萬個,想想也吓人。從這幾點我覺得可以總結一下,對于網站的安全始終要記住幾點:

1、木桶理論,整個網站99%的地方都很安全是不夠的,如果網站的賬戶體系是打通的,那麼隻要有1%的地方有問題,其它99%的安全都是白搭,找漏洞的人往往也最喜歡找(由初級程式員開發的)邊緣子產品下手。

2、不要信任用戶端的任何資料,對于每一項由用戶端送出的資料我們都應該當做是使用者的輸入(哪怕這個資料本來就是從服務端讀取的),進行嚴格的驗證。

3、對于已經實作的邏輯要思考一下是不是有非正常的路徑,是否有可以繞過的邏輯。

4、做好請求的頻度監控以及控制,如果發現某些請求通路量徒增可能就會是一個漏洞點在被别人爆破。

5、重要的功能盡量不要去走AJAX,不是說AJAX有什麼問題,而是AJAX容易讓人放松警惕。如果可以的話讓(AJAX)請求或API調用變得完全沒有意義,比如使用統一的通用的AJAX API提供接口,比如

http://passport.xxx.com/ajax?token=xxx

,token是在服務端事先生成的對應了某個操作邏輯,使用後則失效,即使是相同的API token也是動态的(而不是為每一個業務配置設定一個具體的URL,這樣隻根據token根本就不知道是哪個業務,如果别人不能熟悉你的流程當然也很難去破解邏輯漏洞)

6、不苛求使用者有很強的安全意識,作為網站的開發要主動保護使用者的密碼等敏感資訊,提示使用者經常修改密碼,并為網站建立安全分析體系,對使用者的操作進行安全評級,如有必要對使用者的登入請求進行駁回。

作者:

lovecindywang

本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。

繼續閱讀