前言
此文章僅適用于興趣研究,不可作為損壞他人或其他機(jī)構(gòu)等利益之用,本文只是提出一個(gè)設(shè)想,并不保證具有普適性
開題
對于安全來說,app是毫無安全性可言的。
不管您是用了proGuard來混淆app,還是用了360加固寶,騰訊加固,等加固產(chǎn)品,最終都會(huì)被以各種方法破解。
例如使用IDA Pro,來進(jìn)行dump,很容易就可以進(jìn)行還原未加固的.dex文件,源代碼就會(huì)暴露出來
因?yàn)閍pp要運(yùn)行,總會(huì)把加固的東西還原進(jìn)內(nèi)存,總是會(huì)有一些工具可以做到脫殼。
所以與其想辦法在前端做加密,不如使用SSL和安全的服務(wù)器端
本講主要介紹如何利用手寫xposed模塊,hook(鉤)出我們想要的密碼的鹽值
注,此方法對于native method無解
需求
1.需求的出現(xiàn)
我學(xué)校有個(gè)查成績的app,抓包發(fā)現(xiàn)使用的是RESTful風(fēng)格的WebService,配合手機(jī)端的app

原理是
使用用戶名和加密的密碼登錄,返回一個(gè)由時(shí)間和用戶信息共同決定的token,以后的各種請求都由此token來確定請求者身份,可以很容易把此WebService搬到網(wǎng)頁上面來,而不用為了安裝一個(gè)一年只用2次的app而到處求包
于是決定搞清楚p字段(密碼)加密的原理
2.分析p字段
p字段的長相
c98f9b47a56d685001b94a9827feef36
他的特點(diǎn)有:32位,最大字母是f
由此可以初步判斷,他可能是使用了較為常見的MD5消息摘要算法進(jìn)行的加密
利用站長工具M(jìn)D5在線加密,對‘password’這個(gè)密碼進(jìn)行了測試,發(fā)現(xiàn)

與上文
c98f9b47a56d685001b94a9827feef36是不一樣的
3.對app進(jìn)行反編譯
由于第2步中的兩次測試結(jié)果不一致,猜測app內(nèi)部可能使用了鹽(Salt)
鹽(Salt),在密碼學(xué)中,是指在散列之前將散列內(nèi)容(例如:密碼)的任意固定位置插入特定的字符串。這個(gè)在散列中加入字符串的方式稱為“加鹽”。其作用是讓加鹽后的散列結(jié)果和沒有加鹽的結(jié)果不相同,在不同的應(yīng)用情景中,這個(gè)處理可以增加額外的安全性。
為了探尋加鹽方式和加密邏輯,要對app進(jìn)行反編譯
這里使用apktool
apktool的下載地址:https://ibotpeaches.github.io/Apktool/
將app的apk安裝包和apktool放在同一文件夾下
cd到該目錄 或 按住shift鍵在該目錄空白處右鍵,選擇在此處打開cmd/powershell窗口
執(zhí)行如下命令
java -jar .\apktool_【版本號(hào)】.jar d .\【apk名字】.apk
發(fā)現(xiàn)整個(gè)程序的入口被一個(gè)樁模塊(stub)取代,再看到qihoo,就知道是用了360加固


這下就很棘手了
4.面臨抉擇
app被加固,我有兩條路可以走
- 給app脫殼
- 想其他辦法
我也在網(wǎng)上搜了不少IDA pro的文章,看的也都似懂非懂,于是還是放棄了這個(gè)方法
正文
最后決定使用Xposed模塊hook相應(yīng)方法
hook的話我們需要知道m(xù)d5加密的方法的方法名,但是由于代碼是加固了的,我們無從得知
逆向思維
方法無非有這兩大類,一種是我們不知道名字的,一種是系統(tǒng)的類的方法,名字肯定是固定的
既然密碼有加鹽,那么定然會(huì)用到+來做字符串拼接:pass+salt
而字符串拼接會(huì)被編譯成StringBuilder的字節(jié)碼,所以只要hook了StringBuilder的toString方法,就會(huì)得到pass+salt的返回值
StringBuilder在現(xiàn)代化的IDE里面已經(jīng)不被推薦使用了,因?yàn)榫幾g器會(huì)把+連接的字符串編譯成StringBuilder的append方法,為了保持代碼的美觀和可讀性,IDE都會(huì)建議使用+號(hào)而不是sb
1.Xposed框架安裝
xposed分兩部分,一個(gè)是框架(framework),一個(gè)是模塊(module)
框架可以直接安裝,需要root的手機(jī)和兼容的系統(tǒng)
xposed官網(wǎng)下載地址 - XDA論壇
去百度上搜也可以,推薦使用酷安市場下載

詳細(xì)的框架安裝教程這里不提供,網(wǎng)上可以搜到更為詳盡的教程
2.進(jìn)行模塊的開發(fā)
1)準(zhǔn)備Android Studio
2)新建一個(gè)項(xiàng)目
不需要添加Activity,建一個(gè)空空的項(xiàng)目就好
您可以選擇閱讀官方開發(fā)教程說明:https://github.com/rovo89/XposedBridge/wiki/Development-tutorial
也可以繼續(xù)看我的表演
3)添加如下依賴
我在這里使用kotlin語言來發(fā)開

//主要的依賴
provided 'de.robv.android.xposed:api:82'
//注解,可選
provided 'de.robv.android.xposed:api:82:sources'
4)在清單文件Application里面加入
<!-- 是否是xposed模塊,xposed根據(jù)這個(gè)來判斷是否是模塊 -->
<meta-data
android:name="xposedmodule"
android:value="true" />
<!-- 模塊描述,顯示在xposed模塊列表那里第二行 -->
<meta-data
android:name="xposeddescription"
android:value="測試Xposed模塊" />
<!-- 最低xposed版本號(hào)(lib文件名可知) -->
<meta-data
android:name="xposedminversion"
android:value="30" />
5)編寫一個(gè)普通的類
如Main
/**
* Created by harbo on 2018/1/16.
* Email: harbourzeng@gmail.com
*/
class Main : IXposedHookLoadPackage {
override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam?) {
if (lpparam!!.packageName != "【您要處理的app的包名】")
return
XposedHelpers.findAndHookMethod(StringBuilder::class.java,
"toString",
object : XC_MethodHook() {
override fun beforeHookedMethod(param: MethodHookParam?) {
Log.d("xposed抓到了", "before")
}
override fun afterHookedMethod(param: MethodHookParam?) {
Log.d("xposed抓到了", "after")
val result = param!!.resultOrThrowable
Log.d("xposed抓到了", result.toString())
}
})
}
}
6)代碼解釋

使用
XposedHelpers類的靜態(tài)方法findAndHookMethod:此方法有兩個(gè)重載,一個(gè)適用于系統(tǒng)類,一個(gè)適用于要hook的app自定義的類。
我們使用3個(gè)參數(shù)的那個(gè)方法:
- 第一個(gè)參數(shù):明確hook對象的類
- 第二個(gè)參數(shù):要hook的方法名
- 第三個(gè)參數(shù):一個(gè)hook方法的匿名內(nèi)部類實(shí)例
重寫 afterHookedMethod,將param的result打成日志即可
7)新建xposed_init文件

在項(xiàng)目上右鍵new -> Folder -> Assets Folder
新建文件
xposed_init,打開它,在里面寫上要執(zhí)行的xposed動(dòng)作類cn.tellyouwhat.mhook.Main即可
8)編譯的時(shí)候選擇不需要activity

9)激活模塊,硬重啟手機(jī)(虛擬機(jī)可以軟重啟)
在xposed installer中,點(diǎn)擊模塊選項(xiàng),勾中您開發(fā)的模塊,然后重啟手機(jī),就能啟用該模塊
打開您要hook的app,輸入用戶名和密碼進(jìn)行登錄
10)在LogCat中查找

就可能會(huì)發(fā)現(xiàn)加密字符串的鹽值
password后面那幾個(gè)字母就是鹽
還可能出現(xiàn)很多情況,比如加密
md5(md5(pass)+salt)
md5(md5(pass+salt))
md5(pass+salt)
等等情況,需要小心調(diào)試,慢慢發(fā)現(xiàn)
11)驗(yàn)證

此鹽值
c98f9b47a56d685001b94a9827feef36匹配
結(jié)束語
本次測試成功,純屬機(jī)緣巧合,如沒有解決您遇到的問題,還請見諒。本文只是提供一個(gè)思路,靠譜的還得是內(nèi)存DUMP。也奉勸各位app安全的從業(yè)人員,把重心轉(zhuǎn)移到傳輸層面上,app無絕對的安全可言。