文章出處

 

在這里分享一些之前對某網站會員/用戶系統(一般域名都是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、不苛求用戶有很強的安全意識,作為網站的開發要主動保護用戶的密碼等敏感信息,提示用戶經常修改密碼,并為網站建立安全分析體系,對用戶的操作進行安全評級,如有必要對用戶的登錄請求進行駁回。

 


文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()