一、前言最近玩王者榮耀,下載了一個(gè)輔助樣本,結(jié)果被鎖機(jī)了,當(dāng)然破解它很簡(jiǎn)單,這個(gè)后面會(huì)詳細(xì)分析這個(gè)樣本,但是因?yàn)檫@個(gè)樣本引發(fā)出的欲望就是解析Android中鎖屏密碼算法,然后用一種高效的方式制作鎖機(jī)惡意樣本。現(xiàn)在的鎖機(jī)樣本原理強(qiáng)制性太過(guò)于復(fù)雜,沒(méi)意義。所以本文就先來(lái)介紹一下Android中的鎖屏密碼算法原理。
二、鎖屏密碼方式我們知道Android中現(xiàn)結(jié)單支持的鎖屏密碼主要有兩種:一種是手勢(shì)密碼,也就是我們常見(jiàn)的九宮格密碼圖一種是輸入密碼,這個(gè)也分為PIN密碼和復(fù)雜字符密碼,而PIN密碼就是四位的數(shù)字密碼比較簡(jiǎn)單。當(dāng)然現(xiàn)在也有一個(gè)高級(jí)的指紋密碼,這個(gè)不是本文研究的范圍了。我們只看手勢(shì)密碼和輸入密碼算法解析。
三、密碼算法分析我們?nèi)绾握业酵黄瓶冢鋵?shí)很簡(jiǎn)單,在設(shè)置鎖屏密碼界面,用工具分析獲取當(dāng)前的View類(lèi),然后一步一步跟入,最終回到了一個(gè)鎖屏密碼工具類(lèi):LockPatternUtils.java,因?yàn)槊總(gè)版本可能實(shí)現(xiàn)邏輯不一樣,這里我用5.1的源碼進(jìn)行分析了,找到這個(gè)類(lèi)之后,直接分析即可。第一、輸入密碼算法分析首先我們來(lái)分析一下輸入密碼算法分析:

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

查看getSalt方法,他首先會(huì)根據(jù)字段key為:lockscreen.password_salt,進(jìn)行從一個(gè)地方獲取salt值,如果發(fā)現(xiàn)這個(gè)值為0,就隨機(jī)生成一個(gè),然后將其保存到那個(gè)地方去,最后會(huì)將salt轉(zhuǎn)化成hex值即可。現(xiàn)在需要找到這個(gè)地方,繼續(xù)跟蹤代碼:

這里猜想應(yīng)該是保存到一個(gè)數(shù)據(jù)庫(kù)中了,繼續(xù)跟蹤代碼:

這里是通過(guò)SM中獲取一個(gè)服務(wù)來(lái)進(jìn)行操作了,之前我們已經(jīng)把SM都玩爛了,像這種獲取服務(wù),最終實(shí)現(xiàn)邏輯都是在XXXService類(lèi)中,所以這里應(yīng)該是LockSettingsService.java類(lèi)中,找到這個(gè)類(lèi),查看他的getLong方法:

其實(shí)到這里就非常肯定是數(shù)據(jù)庫(kù)保存的了,繼續(xù)跟蹤代碼:

這里果然是保存到一個(gè)數(shù)據(jù)庫(kù)中,我們繼續(xù)查看LockSettingStorage.java類(lèi):

這里看到了,數(shù)據(jù)庫(kù)名字叫做:locksettings.db,那么他保存在哪里呢?繼續(xù)看這個(gè)類(lèi):

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

這里可能會(huì)提示找不到find命令,這時(shí)候需要安裝busybox工具了,才能使用這個(gè)命令了。找到這個(gè)數(shù)據(jù)庫(kù)文件就好辦了,直接取出來(lái),然后用SQLite工具進(jìn)行查看即可,當(dāng)然也可以直接在手機(jī)中查看。我為了方便還是弄出來(lái)看:

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

下面我就用就簡(jiǎn)單的Java代碼手動(dòng)的實(shí)現(xiàn)這個(gè)算法,看看分析是否正確,加密算法都不用自己寫(xiě),直接從上面的源碼中拷貝出來(lái)就可以了:

然后這里的salt值是我們從數(shù)據(jù)庫(kù)中拿到的,不過(guò)要記得進(jìn)行hex轉(zhuǎn)化一下:

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

運(yùn)行直接看結(jié)果:

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

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

這個(gè)是數(shù)據(jù)庫(kù)中的long類(lèi)型值轉(zhuǎn)化成hex之后的值。
第二、手勢(shì)密碼算法分析下面繼續(xù)來(lái)分析手勢(shì)密碼,代碼依然在LockPatternUtils.java中:

這個(gè)算法比較簡(jiǎn)單,就是九宮格圖案轉(zhuǎn)化成字節(jié)數(shù)組,然后在SHA1加密即可,關(guān)于九宮格不再多說(shuō)了,從0開(kāi)始順時(shí)針計(jì)數(shù)到8,類(lèi)似如下:

這里看代碼,有行和列之分,所以比如L形狀的手勢(shì)密碼應(yīng)該是:00 03 06 07 08,這樣組成的五個(gè)長(zhǎng)度的字節(jié)。這里為了驗(yàn)證手勢(shì)密碼是否正確,我們?cè)O(shè)置一個(gè)簡(jiǎn)單的手勢(shì)密碼:

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

為了最大化的還原算法,我們依然把源碼代碼拷貝出來(lái),然后定義一個(gè)手勢(shì)九宮格類(lèi),構(gòu)造出這個(gè)手勢(shì)的點(diǎn)數(shù)據(jù):

這個(gè)是源碼的加密算法,下面在構(gòu)造出手勢(shì)點(diǎn)數(shù)據(jù):

手勢(shì)點(diǎn)應(yīng)該是:00 01 02 05 08,打印看看結(jié)果:

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