某網站漏洞排查經驗

 

在這裏分享一些以前對某網站會員/用戶系統(通常域名都是passport.xx.com)進行漏洞檢查查出的一些問題,這些問題大多都是邏輯類漏洞,利用漏洞進行攻擊並不須要什麼高深的技術能力,因此危害尤爲大,把相關經驗分享給你們但願你們能夠自查。前端

這裏要說明,下面不少漏洞的例子是基於已經得到有效的帳號密碼(行話說就是密正的帳號)的前提的,你們可能會問:程序員

一、怎麼可能拿到別人的帳號和密碼?其實有不少網站都泄露過帶明文密碼的帳號庫(也有一些帳號庫是不帶密碼的,或者是MD5哈希後的密碼,不帶密碼的能夠用一些常見簡單密碼嘗試,MD5後的密碼能夠用雲MD5密碼庫來「解密」),不少人會用一些工具拿手頭拿到的幾百萬個帳號密碼針對某網站進行逐一的登陸測試(這個過程叫作掃號),遇到有驗證碼的網站使用程序自動識別密碼,更高級一點可使用雲打碼平臺來識別驗證碼,只要能登陸那麼這個帳號密碼就是針對這個網站的密正帳號,就能夠以必定的價格賣給收號的人了(好比5元一個帳號),掃號的人乾的是純技術活,至於收號的人拿到帳號去幹啥這就根據網站不一樣各不相同了(對於遊戲網站的帳號拿去後基本是洗號之類的)。ajax

二、既然已經拿到了帳號和密碼什麼均可以幹了,還談什麼漏洞?不少網站雖然有帳號密碼能夠登陸,可是一些關鍵性操做每每有雙重驗證的(好比經過郵箱驗證,經過手機驗證),更況且有一些網站有帳戶安全策略,若是檢測到帳戶不安全的話(好比是異地登陸)可能會須要經過手機驗證碼驗證後才能登陸。因此通常狀況下即便有別人的帳號你也只能登陸到他的後臺看看,幾乎不可能作什麼敏感操做(好比提取帳戶餘額、修改密碼之類的),只有進一步把一些綁定換綁以後纔可能有進一步的行爲。瀏覽器

 

先驗證後操做沒有綁定在一塊兒總體對待

假設本身的帳號是A而且已經綁定過郵箱,手頭密正的帳號是B。安全

一、使用A帳號登錄網站,在瀏覽器中開兩個頁籤。工具

二、進入更換郵箱的功能,頁面會提示須要獲取驗證碼,點擊獲取後進入了「更換郵箱」界面,在這個界面中網站會要求你輸入驗證碼以及但願更換的新郵箱。測試

三、剛纔不是打開了兩個標籤頁面嗎,到第二個標籤頁面點擊登出,使用B的帳號登錄進入網站後一樣進入更換郵箱的功能,點擊獲取驗證碼按鈕。網站

四、 在第一個頁籤更換郵箱的第二步輸入一個新的要更換的郵箱xx,而後輸入正確的驗證碼(到A帳號綁定的郵箱查看驗證碼)完成更換郵箱的流程(其實當前登錄的帳戶已經是B)。加密

五、在第二個頁籤刷新一下頁面,能夠看到B的郵箱已經更換爲xx。spa

也就是說更換郵箱這個操做的第二步直接讀取了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的心態去開發而忘記了接口是網站的一部分,好比:

一、 有的時候爲了屏蔽一些數據的呈現(好比IP地址顯示爲192.168.*.*),只是在前端進行數據格式化,AJAX接口仍是提供了原始數據192.168.0.1那麼徹底達不到安全的目的。

二、 AJAX接口每每輕量,刷起來也快,並且容易遺漏對訪問頻度的控制,更容易爆破。

三、 無刷新意味頁面的初始加載和後續操做的驗證會分段,分段就容易產生漏洞。

 

廢棄的API致使的漏洞

如今不少網站都會製做APP版本,在測試此網站的APP後發現和服務端的交互參數都進行了簽名+BASE64,咱們知道安卓的應用程序是能夠反編譯的,通過反編譯能夠查看到:

一、公鑰私鑰都寫在了Java代碼裏,使用公鑰來加密要發送給服務端的數據,使用私鑰來解密從服務端返回的數據,這樣就能夠經過翻譯服務端返回的數據來熟悉API也能夠繞過客戶端直接發送請求給服務端。

二、瞭解了全部API後發現代碼裏有一個隱藏API沒有用到,通過測試這是一個「內部使用」的API,能夠經過這個API把某個客戶端換綁到帳戶而且無需進行其它驗證。至此整個網站的帳號安全都由於這個點失守了。

這個過程看上去很簡單,但要發現這個漏洞是通過了大量的嘗試的,要先熟悉整個操做流程,逐個嘗試是否有邏輯漏洞和其它突破點,每個漏洞都是不一樣的不是每個APP都會有隱藏的內部API,每一次可能的突破每每都是基於很是規思惟。

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

 

總結

可別小看這幾個漏洞,出現這樣的漏洞意味着黑客能夠隨便修改用戶的郵箱、手機、密碼、從而繞過各類二次驗證,把帳號徹底掌握在本身手裏。若是掃號的人手頭有1000萬個帳號庫,掃到密正帳號50萬個,想一想也嚇人。從這幾點我以爲能夠總結一下,對於網站的安全始終要記住幾點:

一、木桶理論,整個網站99%的地方都很安全是不夠的,若是網站的帳戶體系是打通的,那麼只要有1%的地方有問題,其它99%的安全都是白搭,找漏洞的人每每也最喜歡找(由初級程序員開發的)邊緣模塊下手。

二、不要信任客戶端的任何數據,對於每一項由客戶端提交的數據咱們都應該當作是用戶的輸入(哪怕這個數據原本就是從服務端讀取的),進行嚴格的驗證。

三、對於已經實現的邏輯要思考一下是否是有很是規的路徑,是否有能夠繞過的邏輯。

四、作好請求的頻度監控以及控制,若是發現某些請求訪問量徒增可能就會是一個漏洞點在被別人爆破。

五、重要的功能儘可能不要去走AJAX,不是說AJAX有什麼問題,而是AJAX容易讓人放鬆警戒。若是能夠的話讓(AJAX)請求或API調用變得徹底沒有意義,好比使用統一的通用的AJAX API提供接口,好比http://passport.xxx.com/ajax?token=xxx,token是在服務端事先生成的對應了某個操做邏輯,使用後則失效,即便是相同的API token也是動態的(而不是爲每個業務分配一個具體的URL,這樣只根據token根本就不知道是哪一個業務,若是別人不能熟悉你的流程固然也很難去破解邏輯漏洞)

六、不苛求用戶有很強的安全意識,做爲網站的開發要主動保護用戶的密碼等敏感信息,提示用戶常常修改密碼,併爲網站創建安全分析體系,對用戶的操做進行安全評級,若有必要對用戶的登陸請求進行駁回。

相關文章
相關標籤/搜索