您當前的位置:首頁 > 舞蹈

安卓APP逆向入門分析——破解某APP登陸請求引數

作者:由 Jerry 發表于 舞蹈時間:2020-02-16

前言:

前段時間做爬蟲遇到一個app,裡面的資料需要登入之後才能拿到,而且登入不能用密碼,只能透過驗證碼登入。這不是明擺著欺負人麼,按趙四哥那句話來說就是:

生死看淡,不服就幹!

所以接下來手把手帶大家就某個app登陸請求的加密引數進行分析破解,從而實現從網路抓包的密文到明文的轉換。

環境配置:

PyhtonJavadex2jar

(將apk反編譯成java原始碼)

jd_gui

(原始碼檢視)

jadx已root的手機或者安卓模擬器fiddler

PS:公眾號後臺回覆 "反編譯" 即可獲取反編譯工具包

分析:

首先我們用fiddler抓包工具對app的登陸進行抓包,這個app抓包需要開啟全域性代理,不然會抓不到資料。

如果還不會使用全域性代理抓包的朋友,可以看下前面一篇文章,裡面有詳細的抓包教程。

抓包的資料如下:

安卓APP逆向入門分析——破解某APP登陸請求引數

我們可以看到有個

token

的引數,有經驗的朋友知道,這是伺服器後臺生成的,而且在傳送登陸驗證碼請求之前並沒有其它的資料交換!

安卓APP逆向入門分析——破解某APP登陸請求引數

這時候我們就要去看app原始碼找到這個引數的加密方式,然後用轉換成

Python

程式碼生成。

接下來就帶大家就一步一步來破解這個引數。

破解過程:

我們要獲取app原始碼,就要對app進行反編譯,反編譯方式很簡單,直接用工具搞定。有兩種反編譯方式可供選擇,反編譯過程如下:

1。將安卓app的字尾更改為可解密的包,並解壓

安卓APP逆向入門分析——破解某APP登陸請求引數

2。將解壓後生成的字尾為

。dex

複製到

dex2jar

安裝目錄中

安卓APP逆向入門分析——破解某APP登陸請求引數

3。DOS命令列進入此資料夾,然後執行命令:

dex2jar。bat classes。dex

。這個app有兩個

。dex

檔案,所以兩個

。dex

檔案都需要執行

執行完之後會生成兩個對應的

。jar

檔案,效果如下:

安卓APP逆向入門分析——破解某APP登陸請求引數

生成。jar檔案就是apk的原始碼了,我們使用

jd_gui

來檢視原始碼

安卓APP逆向入門分析——破解某APP登陸請求引數

幸運的是這個app並沒有加固,有app進行了加固,像

騰訊樂固

360加固

等等

安卓APP逆向入門分析——破解某APP登陸請求引數

安卓APP逆向入門分析——破解某APP登陸請求引數

對於這種我們不能直接反編譯,首先需要脫殼,然後再反編譯

5。第二種反編譯的方法是直接使用工具

jadx

開啟

。apk

檔案剩下的事就是仔細閱讀程式碼,分析其中的邏輯了。

6。根據請求或響應的引數去原始碼中搜索加密方式

需要注意的是,反編譯的程式碼非常混亂,錯誤很多,並且apk經過混淆,變數名都消失了,這時一定要有有耐心,仔細研究程式碼。根據前面請求、響應引數去搜索,或者請求的 url 地址去搜索,而且經驗很重要。

安卓APP逆向入門分析——破解某APP登陸請求引數

我們就要根據這些搜尋到的結果慢慢去找了。我們主要找到傳送請求的時候定義引數的程式碼,然後往上追溯在查詢的過程中要儘可能的多嘗試,大膽猜測

最後根據

keycode

找到了登入響應引數的生成函式

安卓APP逆向入門分析——破解某APP登陸請求引數

其中有下劃線的地方,我們可以直接點進去

安卓APP逆向入門分析——破解某APP登陸請求引數

這部分程式碼就是加密的方法!

驗證

我們把原始碼複製出來,分析加密引數

private String c(String paramString)

{

Date localDate = new Date();

Locale localLocale1 = Locale。CHINA;

String str1 = new SimpleDateFormat(“yyyyMMdd”, localLocale1)。format(localDate);

Locale localLocale2 = Locale。CHINA;

String str2 = new SimpleDateFormat(“MMdd”, localLocale2)。format(localDate);

StringBuilder localStringBuilder1 = new StringBuilder();

String str3 = paramString。substring(7);

StringBuilder localStringBuilder2 = localStringBuilder1。append(str3);

StringBuilder localStringBuilder3 = localStringBuilder1。append(str2);

String str4 = localStringBuilder1。toString();

StringBuilder localStringBuilder4 = new StringBuilder();

StringBuilder localStringBuilder5 = localStringBuilder4。append(paramString);

StringBuilder localStringBuilder6 = localStringBuilder4。append(“|”);

StringBuilder localStringBuilder7 = localStringBuilder4。append(str1);

String str5 = localStringBuilder4。toString();

try

{

str5 = zxw。data。c。b。a(str5, str4);

}

catch (Exception localException)

{

localException。printStackTrace();

str5 = null;

}

return c。a(str5);

}

其中生成了兩個引數

str5

str4

傳到加密函式。下面是

str5

的生成程式碼

String str1 = new SimpleDateFormat(“yyyyMMdd”, localLocale1)。format(localDate);

StringBuilder localStringBuilder4 = new StringBuilder();

StringBuilder localStringBuilder5 = localStringBuilder4。append(paramString);

StringBuilder localStringBuilder6 = localStringBuilder4。append(“|”);

StringBuilder localStringBuilder7 = localStringBuilder4。append(str1);

String str5 = localStringBuilder4。toString();

str1 = 20190319

,也就是今天的日期

str5 = 傳過來的引數 + '|' + '20190319'

那麼

str4

String str2 = new SimpleDateFormat(“MMdd”, localLocale2)。format(localDate);

StringBuilder localStringBuilder1 = new StringBuilder();

String str3 = paramString。substring(7);

StringBuilder localStringBuilder2 = localStringBuilder1。append(str3);

StringBuilder localStringBuilder3 = localStringBuilder1。append(str2);

String str4 = localStringBuilder1。toString();

java的

substring()

方法類似 python中的字串切片,只是

substring()

方法返回字串的子字串。也可以推測,

paramString

是一個長度大於7的字串。這裡大膽的猜測是我們提交的那個手機號碼,因為我們請求的時候只提交了這個引數。

所以

str4 = '手機號碼後四位' + 0319

如果不知道生成的方式,就用 java執行一波,將這兩個引數打印出來,是最方便快捷的方法~~

既然知道加密引數了,接下來就是驗證了原始碼加密的方法如下:

安卓APP逆向入門分析——破解某APP登陸請求引數

用 python 程式碼改造的加密

安卓APP逆向入門分析——破解某APP登陸請求引數

執行之後的結果為 False,仔細看兩者字母,數字基本都是一樣的,感覺應該是對了,但還是有點差異!再返回去看看原始碼,原始碼中最後將生成的加密資料再傳給了某個函式再返回

return c。a(str5);

下面是這個

c。a

的函式:

public class c

{

public static String a(String paramString)

{

return paramString。replaceAll(“\\+”, “!”);

}

}

原來是將 “+” 替換成了 “!”所以我們將之前執行出來的結果中的 “+” 替換成 “!” 就是完全正確了!so, 我們就將這個

token

引數給破解了!

總結

1。對於app加密的要有耐心,尤其是在根據引數在原始碼中尋找加密方式的時候,更加需要耐心。2。善於利用搜索引擎,碰到看不懂的方法,就去網上多搜尋。3。如果認識大佬,當然是要抱緊大佬的大腿啊,多問問大佬,會讓你事半功倍!

當你解決的問題那一刻,你就會發現之前受的苦都是值得的!

Python程式設計與實戰