一、前言最近玩王者榮耀,下載了一個輔助樣本,結果被鎖機了,當然破解它很簡單,這個后面會詳細分析這個樣本,但是因為這個樣本引發出的欲望就是解析Android中鎖屏密碼算法,然后用一種高效的方式制作鎖機惡意樣本。現在的鎖機樣本原理強制性太過于復雜,沒意義。所以本文就先來介紹一下Android中的鎖屏密碼算法原理。
二、鎖屏密碼方式我們知道Android中現結單支持的鎖屏密碼主要有兩種:一種是手勢密碼,也就是我們常見的九宮格密碼圖一種是輸入密碼,這個也分為PIN密碼和復雜字符密碼,而PIN密碼就是四位的數字密碼比較簡單。當然現在也有一個高級的指紋密碼,這個不是本文研究的范圍了。我們只看手勢密碼和輸入密碼算法解析。
三、密碼算法分析我們如何找到突破口,其實很簡單,在設置鎖屏密碼界面,用工具分析獲取當前的View類,然后一步一步跟入,最終回到了一個鎖屏密碼工具類:LockPatternUtils.java,因為每個版本可能實現邏輯不一樣,這里我用5.1的源碼進行分析了,找到這個類之后,直接分析即可。第一、輸入密碼算法分析首先我們來分析一下輸入密碼算法分析:

這里看到有一個方法:passwordToHash方法,參數為用戶輸入的密碼和當前用戶對應的id,一般設備不會有多個用戶,所以這里一般userId默認值就是0,下面就是最為核心的加密算法了:原文密碼+設備的salt值,然后分別MD5和SHA-1操作,轉化成hex值再次拼接就是最終保存到本地的加密密碼了。而這里現在最重要的是如何獲取設備對應的salt值了,這個可以一步一步跟蹤代碼:

查看getSalt方法,他首先會根據字段key為:lockscreen.password_salt,進行從一個地方獲取salt值,如果發現這個值為0,就隨機生成一個,然后將其保存到那個地方去,最后會將salt轉化成hex值即可。現在需要找到這個地方,繼續跟蹤代碼:

這里猜想應該是保存到一個數據庫中了,繼續跟蹤代碼:

這里是通過SM中獲取一個服務來進行操作了,之前我們已經把SM都玩爛了,像這種獲取服務,最終實現邏輯都是在XXXService類中,所以這里應該是LockSettingsService.java類中,找到這個類,查看他的getLong方法:

其實到這里就非常肯定是數據庫保存的了,繼續跟蹤代碼:

這里果然是保存到一個數據庫中,我們繼續查看LockSettingStorage.java類:

這里看到了,數據庫名字叫做:locksettings.db,那么他保存在哪里呢?繼續看這個類:

這里看到有兩個key文件,那么這個就是用來保存加密之后的手勢密碼和輸入密碼的信息到本地,下次開機解鎖就需要讀取這個文件內容進行密碼比對了。這里看到一個目錄是system了,所以數據庫和這兩個key文件很可能保存到該目錄下了:/data/system/,不過為了確保,我們直接用find命令去根目錄下搜索這個數據庫文件也是可以的。最終確定是該目錄:

這里可能會提示找不到find命令,這時候需要安裝busybox工具了,才能使用這個命令了。找到這個數據庫文件就好辦了,直接取出來,然后用SQLite工具進行查看即可,當然也可以直接在手機中查看。我為了方便還是弄出來看:

這里看到了這個表格字段,并且獲取到這個值了,那么下面就要用這個值來驗證我們的分析是否正確,我們首先給設備設置一個簡單的輸入密碼,這里直接輸入簡單的"1234"了,然后會在/data/system目錄下生成一個密碼加密key文件:/data/system/password.key,這時候我們將改文件導出來:

下面我就用就簡單的Java代碼手動的實現這個算法,看看分析是否正確,加密算法都不用自己寫,直接從上面的源碼中拷貝出來就可以了:

然后這里的salt值是我們從數據庫中拿到的,不過要記得進行hex轉化一下:

然后我們用"1234"密碼去生成加密之后的信息:

運行直接看結果:

這里發現內容和上面的password.key內容完全一致了,也就驗證了,我們的分析完全符合,到這里我們就分析完了輸入密碼的加密算法,總結一點就是:MD5(輸入明文密碼+設備的salt).Hex+SHA1(輸入明文密碼+設備的salt).Hex;就是最終的加密內容了。而這里最重要的是如何獲取設備的salt值,這個其實也簡單,我們可以用反射機制進行獲取,新建一個簡單的Android工程:

這樣我們就不用去查看數據庫獲取salt值了,這樣方便快捷:

這個是數據庫中的long類型值轉化成hex之后的值。
第二、手勢密碼算法分析下面繼續來分析手勢密碼,代碼依然在LockPatternUtils.java中:

這個算法比較簡單,就是九宮格圖案轉化成字節數組,然后在SHA1加密即可,關于九宮格不再多說了,從0開始順時針計數到8,類似如下:

這里看代碼,有行和列之分,所以比如L形狀的手勢密碼應該是:00 03 06 07 08,這樣組成的五個長度的字節。這里為了驗證手勢密碼是否正確,我們設置一個簡單的手勢密碼:

然后在/data/system目錄下生成一個密碼文件:/data/system/gesture.key,弄出來用二進制工具查看,不然可能會看到的是亂碼,這里用的是010Editor工具查看:

為了最大化的還原算法,我們依然把源碼代碼拷貝出來,然后定義一個手勢九宮格類,構造出這個手勢的點數據:

這個是源碼的加密算法,下面在構造出手勢點數據:

手勢點應該是:00 01 02 05 08,打印看看結果:

非常的激動發現,一模一樣,這樣就完美的分析完了,Android系統中鎖屏密碼加密算法了。這里再一次總結一下兩種方式鎖屏密碼算法:第一種:輸入密碼算法將輸入的明文密碼+設備的salt值,然后操作MD5和SHA1之后在轉化成hex值進行拼接即可,最終加密信息保存到本地目錄:/data/system/password.key中第二種:手勢密碼算法將九宮格手勢密碼中的點數據轉化成對應的字節數組,然后直接SHA1加密即可。最終加密信息保存到本地目錄中:/data/system/gesture.key中
四、鎖屏密碼破解上面分析完了Android鎖屏密碼加密算法原理,下面就來簡單分析一下,如何破解Android中鎖屏密碼。第一種:輸入密碼算法這個如果是針對于PIN類型密碼,只是簡單的四位數字密碼,那么所有的組合也就是10000個,這時候我們只需要將這10000個密碼通過加密算法進行加密生成一個密碼庫即可很容易破解。如果是復雜的輸入密碼那么就沒這么簡單了,這個或許就需要非常惡心的暴力破解了,隨著密碼長度增加,破解時間會很大。不過一般用戶密碼不會很長的。
第二種:手勢密碼算法這個其實網上已經有人給出了一個密碼庫了,因為九宮格的圖案可以全部算出,然后將其轉化成字節數據,在用加密算法加密就能生成一個手勢密碼庫了。具體信息可以自行網上搜索了。
到這里,有的同學會有一些壞的想法了,比如撿到一個手機或者是查看老婆手機密碼,是否可以直接破解它的密碼呢?大致思路應該很簡單,首先把設備root,因為我們看到上面分析會發現如果想讀key文件,必須有root權限的,當然root操作在對應的系統版本上還是有方法操作的。假如root成功了,那么這時候就獲取他的salt值,然后利用密碼庫開始暴力破解即可。當然這個是悄無聲息的不會被發現的破解,不過你root了其實已經被發現了哈哈,假如你是撿到一個手機,其實沒這么費勁了,直接刪除key文件,這時候你隨便輸入一個密碼都能解鎖了,這個因為系統在檢查密碼的時候發現key文件不存在,就認為這個設備沒有密碼鎖,所以你輸入什么都可以解鎖了。可惜到這里上面說的都是扯淡的,因為你在這一系列的操作前,你必須有一個認可,那就是設備連接允許框,我們在將手機首次連接到電腦的時候會彈出一個授權框,如果你不授權,那么什么都干不了。除非這時候利用偉大的漏洞過了這一關,不過一般是辦不到的。那么現在的問題是,你撿到了一個手機,當然高興的插入到電腦破解的時候會發現,先解鎖,然后才能看到授權框,所以就悲劇了。你什么都干不了。就老老實實的把手機還給人家,做一個偉大的良民才是正道。
注意:對于這個加密算法系統是不會在某個系統版本改變的,因為你想如果加密算法變了,加入4.4用戶升級到5.0,結果發現加密算法變了,手機解鎖失敗,用戶會瘋的,我頁查看了2.3的代碼,算法是一模一樣的。所以就把算法整理了一份Java工程放到github上,感興趣的同學可以下載查看或者直接使用操作即可。變的可能是設備的salt值,或者數據庫文件等發生變化。但是加密算法是不會改變的。
加密算法源碼:https://github.com/fourbrother/AndroidScreenOffPwd
五、總結我相信大家讀完這篇文章都是迫不及待的想手動嘗試一下,在操作之前一定要記住,先拿到你設備的salt值,這個方式有兩種,一種是查看/data/system/locksetting.db文件,一種是用反射獲取。然后就要注意的是源碼版本,本文介紹的是5.1版本以及5.1設備進行操作,所以你操作的時候一定要注意版本,不過版本不一樣,這樣的算法不會變的。
|