逆向APP - XX房產

需求分析

  • 拿到每套房子房價
  • 拿到所有戶型介紹

抓關鍵包

  • 房價請求包
  • 工具 Charles

抓包如下

原始數據

看這樣子內容是加密後在app內不進行解密完成的, 那麼我們要獲取到通過api請求到的真實數據就需要拆解app!獲取其加解密方法才行。

殼檢測

  • 可以用工具查看是否有殼
  • 或者查看特徵
  • 檢測混淆

百度加固特徵明顯所以判斷爲百度加固
[外鏈圖片轉存失敗(img-jYM2EbCz-1563893153505)(https://www.zhangkunzhi.com/images/20190720/查看到百度加固.png)]

脫殼

  • 此處省略 500 字(發這些會被舉報)
  • 利用反編譯工具 jadx 對 apk 進行反編譯

跟蹤代碼

[外鏈圖片轉存失敗(img-K1a0rCFr-1563893153506)(https://www.zhangkunzhi.com/images/20190720/房價查詢目錄.png)]

  1. 查看到 cmdDHP 就是我們請求的 url

  2. 查看調用 cmdDHP 到位置

    public static void getHousePrice(String houseId, String bId, String unitId, RequestResultI requestResultI) {
        RequestParams params = new RequestParams();
        StringBuffer sb = new StringBuffer();
        String sp = "$$@$$";
        for (int i = 0; i < 30; i++) {
            if (i == 3) {
                sb.append(houseId);
            } else if (i == 4) {
                sb.append(bId);
            } else if (i == 9) {
                sb.append(unitId);
            } else {
                sb.append(new Random().nextInt(100) + "");
            }
            sb.append(sp);
        }
        String str = "";
        params.put("key", Utils.encodeKey(sb.toString()));
        SendRequest.getInstance().get(112, params, cmdDHP, requestResultI);
    }
    

檢查參數

方法參數 房屋id bID? unitId 開放商id? 然後對其拼接發送的 get 請求

跟蹤解密方法

搜索 response

查找找到基類

ResponseBaseModel 或 ResponseBaseDomain

private static final String key_Code = "Code";
private static final String key_Data = "Data";
private static final String key_Remark = "Remark";
private static final String key_Total = "Total";	
    
// 找到json關鍵字樣 
 public ResponseBaseModel(JSONObject response) throws Exception {
    if (response.has(key_Code)) {
        this.Code = response.getString(key_Code);
    }
    if (response.has(key_Remark)) {
        this.Remark = response.getString(key_Remark);
    }
    if (response.has(key_Data)) {
        this.Data = response.getString(key_Data);
    }
    if (response.has(key_Total)) {
        this.Total = response.getInt(key_Total);
    }
}

跟蹤到解密模塊

// 解密工作模塊
    
public static String decodeB(String encryptText) {
    try {
        checkKeyAndIv();
        Key deskey = SecretKeyFactory.getInstance("desede").generateSecret(new DESedeKeySpec(secretKey.getBytes())); // key 處理
        Cipher cipher = Cipher.getInstance("desede/CBC/PKCS5Padding");
        cipher.init(2, deskey, new IvParameterSpec(iv.getBytes()));
        return new String(cipher.doFinal(Base64.decodeBase64(encryptText)), "UTF-8");
    } catch (Exception e) {
        e.printStackTrace();
        return "";
    }
}
    
public static String decodeA(String en) {
    String content = "";
    try {
        checkKeyAndIv();
        String den = decodeB(en);
        String content2 = den.substring(0, den.length() - 6);
        String[] hIndex = decodeBase64(den.substring(den.length() - 6, den.length()).replace("==", ""), "UTF-8").split("_");
        String content3 = content2.substring(Integer.valueOf(hIndex[0]).intValue(), content2.length());
        return decodeBase64(new StringBuffer(content3.substring(0, content3.length() - Integer.valueOf(hIndex[1]).intValue())).reverse().toString(), "UTF-8").replace("##", "").replace("{@mk7}", "");
    } catch (Exception e) {
        e.printStackTrace();
        return content;
    }
}

檢查 key 與 Iv

發現每次解密都會調用 checkKeyAndIv()

// 每次加解密都會調用check 函數來看是否有key
private static void checkKeyAndIv() {
    if (stringIsNull(secretKey) || stringIsNull(iv)) {
        secretKey = FuniSecret.getSecretKey();
        iv = FuniSecret.getSecretIv();
    }
}

跟蹤獲取 Key 與 Iv 處

// 再次跟蹤到 getSecretIv
package com.funi.cloudcode.util;
    
public class FuniSecret {
    public static native String getSecretIv();
    
    public static native String getSecretKey();
    
    static {
        System.loadLibrary("FuniSecret");
    }
}

SO 層跟蹤

在上面看到了 native, 與 System.loadLibrary("FuniSecret")
發現 他們是將 key 與 Iv 在 SO 層(C/C++)處理好, 交給 java 處理的

靜態調試 SO 層

他們用的是 DES 加密
最終找到 KeyIv

原始數據

再利用 python 實現 DES 解密過程即可

此處省略

感謝

lilac , 小周

以上兩位的支持與幫忙

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章