作者:
阿里移動安全
·
2016/05/16 15:17
作者:[email protected]
0x00 簡介
在阿里聚安全的漏洞掃描器中和人工APP安全審計中,經常發現有開發者將金鑰硬編碼在Java程式碼、檔案中,這樣做會引起很大風險。資訊保安的基礎在於密碼學,而常用的密碼學演算法都是公開的,加密內容的保密依靠的是金鑰的保密,金鑰如果洩露,對於對稱密碼演算法,根據用到的金鑰演算法和加密後的密文,很容易得到加密前的明文;對於非對稱密碼演算法或者簽名演算法,根據金鑰和要加密的明文,很容易獲得計算出簽名值,從而偽造簽名。
0x01 風險案例
金鑰硬編碼在程式碼中,而根據金鑰的用途不同,這導致了不同的安全風險,有的導致加密資料被破解,資料不再保密,有的導致和伺服器通訊的加簽被破解,引發各種血案,以下借用烏雲上已公佈的幾個APP漏洞來講講。
1.1 某網際網路金融APP加密演算法被破解導致敏感資訊洩露
某P2P應用客戶端,用來加密資料的DES演算法的金鑰硬編碼在Java程式碼中,而DES演算法是對稱密碼演算法,既加密金鑰和解密金鑰相同。
反編譯APP,發現DES演算法:
發現DES演算法的金鑰,硬編碼為“yrdAppKe”,用來加密手勢密碼:
將手勢密碼用DES加密後存放在本地LocusPassWordView.xml檔案中:
知道了密文和加密演算法以及金鑰,透過解密操作,可以從檔案中恢復出原始的手勢密碼。或者使用新的生成新的手勢密碼
而與伺服器通訊時介面中的Jason欄位也用了DES演算法和金鑰硬編碼為“yRdappKY”:
和伺服器通訊採用http傳輸,沒有使用https來加密通訊,如果採用中間人攻擊或者路由器映象,獲得流量資料,可以破解出使用者的通訊內容。
1.2 某租車APP加密演算法被破解導致一些列風險
某租車APP與伺服器通訊的介面採用http傳輸資料,並且有對傳輸的部分引數進行了加密,加密演算法採用AES,但是金鑰硬編碼在java程式碼中為“shenzhoucar123123”,可被逆向分析出來,導致偽造請求,結合伺服器端的漏洞,引起越權訪問的風險,如越權檢視其它使用者的訂單等。
和伺服器通訊時的資料為:
q欄位是加密後的內容。逆向APP,從登入Activity入手:
分析登入流程:v1是使用者名稱,v2是密碼,v3是PushId,在使用者名稱和密碼不為空並且長度不小於11情況下,執行LoginOperate相關操作,追蹤LoginOperate的實現,發現繼承自BaseOperate,繼續追蹤BaseOperate的實現:
在BaseOperate的initUrl()方法中,找到了APP是怎麼生成請求資料的:
繼續追蹤上圖中的initJsonUrl()方法,發現其呼叫了AES加密:
繼續追蹤aes.onEncrypt()函式:
在onEncrypt()函式中呼叫了encrypt()函式用來加密資料,追蹤encrypt()函式的實現,發現其使用AES演算法,並且金鑰硬編碼在java程式碼中為“shenzhoucar123123”
到現在請求中的資料加密如何實現的就清晰了,另外由於伺服器許可權控制不嚴,就可以構造訂單id的請求,達到越權訪問到其他使用者的訂單。
構造{“id”:”11468061”}的請求:
其中uid設定為你自己的uid即可,可以成功看到其他人的訂單:
攻擊者完全可以做到使用其他指令碼重新實現相同的加密功能並拼接出各個介面請求,批次的刷取訂單資訊和使用者其他資訊。
1.3 某酒店APP加簽演算法被破解導致一系列風險
某酒店APP和伺服器通訊時介面採用http通訊,資料進行了加密,並且對傳輸引數進行簽名,在伺服器端校驗簽名,以檢查傳輸的資料是否被篡改,但是加簽演算法和金鑰被逆向分析,可導致加簽機制失效,攻擊者可任意偽造請求包,若結合伺服器端的許可權控制有漏洞,則可引發越權風險等。
APP和伺服器通訊的原始包如下圖,可以看到有加簽欄位sign:
逆向APP定位到加密演算法的邏輯程式碼,com.htinns.biz.HttpUtils.class,其實現邏輯為:
原始資料是unSignData,使用RC4演算法加密,金鑰為KEY變數所代表的值,加密後的資料為signData,傳輸的資料時的data欄位為signData。
加簽欄位signd的生成方法是用unsignData拼接時間戳time和resultkey,然後做md5,再進行base64編碼。時間戳保證了每次請求包都不一樣。
sendSign()演算法是用c或c++寫的,放入了so庫,其他重要演算法都是用java寫的。
可以使用IDA逆向分析so庫,找到sendSign()方法
而烏雲漏洞提交者採用的是分析sign和getSign(sign)的資料,做一個演算法破解字典。其實還有種方法直接呼叫此so庫,來生成字典。
簽名破解以後,就可以構造傳送給伺服器的資料包進行其他方面的安全測試,比如越權、重置密碼等。
0x02 阿里聚安全開發建議
透過以上案例,並總結下自己平時發現金鑰硬編碼的主要形式有:
1、金鑰直接明文存在sharedprefs檔案中,這是最不安全的。
2、金鑰直接硬編碼在Java程式碼中,這很不安全,dex檔案很容易被逆向成java程式碼。
3、將金鑰分成不同的幾段,有的儲存在檔案中、有的儲存在程式碼中,最後將他們拼接起來,可以將整個操作寫的很複雜,這因為還是在java層,逆向者只要花點時間,也很容易被逆向。
4、用ndk開發,將金鑰放在so檔案,加密解密操作都在so檔案裡,這從一定程度上提高了的安全性,擋住了一些逆向者,但是有經驗的逆向者還是會使用IDA破解的。
5、在so檔案中不儲存金鑰,so檔案中對金鑰進行加解密操作,將金鑰加密後的金鑰命名為其他普通檔案,存放在assets目錄下或者其他目錄下,接著在so檔案裡面新增無關程式碼(花指令),雖然可以增加靜態分析難度,但是可以使用動態調式的方法,追蹤加密解密函式,也可以查詢到金鑰內容。
保證金鑰的安全確是件難事,涉及到金鑰分發,儲存,失效回收,APP防反編譯和防除錯,還有風險評估。可以說在裝置上安全儲存金鑰這個基本無解,只能選擇增大攻擊者的逆向成本,讓攻擊者知難而退。而要是普通開發者的話,做妥善保護金鑰這些事情這需要耗費很大的心血。
產品設計者或者開發者要明白自己的金鑰是做什麼用的,重要程度怎麼樣,金鑰被逆向出來會造成什麼風險,透過評估APP應用的重要程度來選擇相應的技術方案。
參考
- p2p宜人貸app幾種安全問題
- 神州租車APP客戶端設計缺陷導致的一系列安全問題(演算法破解/許可權遍歷等)
- 講解一步步逆向破解華住酒店集團官網APP的http包加密演算法以及一系列漏洞打包
- http://jaq.alibaba.com/safety?spm=a313e.7837752.1000001.1.zwCPfa
- https://www.zhihu.com/question/35136485/answer/84491440
本文章來源於烏雲知識庫,此映象為了方便大家學習研究,文章版權歸烏雲知識庫!