[Android][筆記] 開發 Android App 時的安全概觀 (AKDG#11)

2015.3.15
Android 高雄開發者社群 #11 - 開發 Android App 時的安全概觀
講者: Sean

 

/*Maple 2015.3.16*/

[2015.3.15] Android 高雄開發者社群 #11 - 開發 Android App 時的安全概觀 

講者: Sean

PART I :  開發 Android app 時的安全概觀

投影片: http://www.slideshare.net/erinus/android-security-development

PART II : 如何客制化 AOSP 進行 APP 動態追蹤分析

投影片: http://www.slideshare.net/erinus/android-security-development-45870056

Android 高雄開發者社群 FB:  https://www.facebook.com/groups/AKDGroup/

活動報名頁: http://akdg.kktix.cc/events/akdg-meetup11

 

---------------------------------- 以下是筆記 ----------------------------------

PART I :  開發 Android app 時的安全概觀
 
防範: USB 連線 / 截圖功能 / 剪貼簿 / 權限 / DB / 網路 / API控管
 
[USB 防範] 上架時參數調整為以下值
/* 與 ADB 有關,開 true 可讓 APP 的所有資料傳到電腦*/
android:allowBackup="false"  
 
/* 預設完全無此設定,預設會依照使用者的手機環境設定
    若為 true ,當忘記關閉 log.e 等訊息,連上 usb 後將可看到 log 輸出的資訊
    eclipse 預設會將此設定視為錯誤 (但其實 Android 官方是允許此設定),
    因為 eclipse 建議開發者依照行動裝置環境的設定,而不要關閉,
    在錯誤訊息上面按右鍵>Quick fix>Disable Check>就可以正常編譯了
*/
android:debuggable="false" 
 
[截圖功能關閉] 通常會搭配浮水印
在 onCreate 時 Activity 增加屬性
getWindow().setFlags(LayoutParams.FLAG_SECURE,LayoutParams.FLAG_SECURE)
且此設定還可阻擋目前執行中 APP 列表 (多工列) 的預覽顯示,會呈現黑色
當然此時拿另一支手機拍攝就阻止不了,但因為螢幕截圖的圖檔資訊很乾淨,容易把浮水印修掉,但若利用另一支手機拍照,相片裡的圖檔會有雜訊,因此不好修圖,也容易反查出有修圖
 
[剪貼簿關閉] 利用 life cycle 離開時對剪貼簿增加空白內容
若使用者有 root ,就擋不了(也不用防什麼資安了....),
有 root 權限才能存取全部的剪貼簿內容,
在未 root 的行動裝置,只能拿到最新一筆的剪貼簿內容,
因此在剪貼簿內加入最新的"空白"內容,
使用者複製原先複製的內容會變成第二筆,就會撈不到第二筆
通常都是控制 只進不出 (進:onResume / 出: onPause)
注意: Activity 切換時也會觸發 onPause ,但最後還是會進到另一個 Activity 的 onResume 
因此利用延遲判斷最後 APP 的 Activity 狀態是 onPause 就對剪貼簿做動作
 
[權限控制] 不需要的權限不要開
EX: GCM 官方文件指出
在 android 4.0.3 以下需要 GET_ACCOUNTS 的權限
但 android 4.0.4 以上不需要
而 GET-ACCOUNT 的權限還涵蓋可以拿取其他 APP 的帳號資料 (如 dropbox,yahoo,gmail 等)
若安裝到惡意的 APP 有此權限,可能因為抓到帳號資料交叉比對後偽裝成原本的 APP 登入
 
[DB 加密]
套件: SQLCipher (for ios/android) <-推薦
         SQLite Encryption Extension (for android)<-SQLite官方
 
[網路]
使用 SSL
除了檢查 IP 還要檢查 HOST NAME
檢查出去的憑證 (EX: 期貨 / 股票等 APP 會要求使用者另外下載憑證安裝,就需要檢查)
方法:清除原本憑證管理器內所有的列表內容,防止有不明憑證混入,然後只重新加入自己的憑證,這樣就能確保連線的憑證只能用自己的
也要檢查資料回傳回來的憑證 (可能透過中間人又被轉向)
SHA256 與 SHA1 兩種加密方式都做檢驗,可以提高破解的難度
 
中間人攻擊的硬體 keyword:鳳梨派
 
為了防止傳輸資料被解開( SSL 也不一定安全),儲存的資料與傳出的資料都可以做加解密
Android SDK: 語言 java <-反解譯易懂
Android NDK: 語言 C / C++ <-反解譯較不容易懂 (也不在memory中)
NDK 可考慮用 OpenSSL 或 PolarSSL (推薦,小眾,程式碼乾淨,可拆換也可單獨載入部分)
 
密碼: RANDOM KEY (最好每次換 key) + HARDWARE KEY (機碼) + USER KEY(使用者自訂,最好只放在 memory 不要存 DB )
由於科技進步,中間人可能只需要 100 萬次連線統計就能計算出加密方式,以及解開 SSL
因此利用 密文+擾亂 (如 Base64 )  增加破解難度
 
[API 控管] Access Token 就像 cookie 
需要 refresh,每次都亂數產生,不要用 time 或 GUID (也是依據 time 去產生的)
所有的API連線必須要使用token
 
利用 Access Token ->抓到 userid ->抓到 hardware key -> 加解密 -> 才連到DB撈資料 
(可降低 DB 被 ddos 附載及 sql 攻擊)
 
-----
PART II : 如何客制化 AOSP 進行 APP 動態追蹤分析
 
投影片的指令都是經測試(百般組合與失敗後中)可以正常跑的
ps.檔案超大 下載超久 (6hr / 12hr / 24hr....)
注意:指令最後一行的 JDK 版本,用錯版本就跑不了(不明原因)
repo sync -j1  (最後的 1 是執行序數量,但下載時提高到 8 可能下載一半就被 google 鎖...鎖一天)
行動裝置切換到 (其中一種的) 工程模式: power & 音量-  按住約五秒
 
改寫 android system 底層開始~
 
先找 code
code 有好幾 G  所以需要 View Source code 工具
Java 中的關鍵字 native 就是呼叫JNI -> c++ 的程式
所以 java 的 source code 看到 function 這樣定義就代表要開始跳到 c++ 找
 
調整 log 紀錄
- 把底層 java 的 system.log 改寫,增加傳入參數 tag
- 調整相關程式的 tag 參數
- 新增新 funciton (例如名稱: appsendbox),指定 log 的 tag (例如名稱: appsendbox)
- 要追蹤 log 改呼叫 appsendbox
- 在 ADB 輸出 log 訊息時指令改用
> adb logcat -v long appsendbox:V *:S > 輸出 LOG 的檔名
其中 appsendbox 是 tag 的意思
 
調整每次 LOG 使用的 tag 易懂性
- 自動抓取 PID 取代常用的 package name 
(有經驗的人就知道印 package name 跳來跳去不好判斷)
- 利用 application 在 onCreate 時印出 package Name 就不會亂跳其他的 package name,就可以與 PID 比對
 
監視 (Hook) read/write 字串
(惡意軟體都會將字串加密,利用此方式可以得到明文)
- 基本上改寫 Input Stream / Output Stream 即可,因為是其他 Stream 的底層
 
監視 (Hook) 網址呼叫
(惡意軟體會將網址分開成數個 function 最後串接成完整網址,利用此方式就可得到最後串好的網址)
- 直接監視 URI 與 URL 即可,不需要改寫 HTTP 或 HTTPS ,因為 URI 跟 URL 也是最底層
 
最後: 目前並未對 JNI 做 hook ,要修改可查 keyword: BIONIC (歡迎加入專案)