1. 程式人生 > 其它 >超星學習通逆向介面引數加密分析 - 課程頁面切換tab介面

超星學習通逆向介面引數加密分析 - 課程頁面切換tab介面

超星的介面分析了很久,分析到這個介面的時候才想到寫篇部落格,之前的一些介面和分析就沒寫下來

先開倆坑在這裡,等以後再填

1.如何抓安卓APP上HTTPS的包(需ROOT)
2.如何逆向安卓APP


本次分析的介面是這個
http://data.xxt.aichaoxing.com/analysis/course/tab
引數 u=224217004&sign=task&description=%E4%BB%BB%E5%8A%A1&enc=E783557848978DAFBC36732F63E554E9&personid=243104286&classid=49650050&courseid=220816469

介面大致分析

這個介面在課程頁面點選tab切換時會被呼叫一次

先看引數

引數名
u 224217004
sign task
description 任務
enc E783557848978DAFBC36732F63E554E9
personid 243104286
classid 49650050
courseid 220816469

根據之前抓包的內容可以得到除了enc以外的內容,再看enc長度是32位,可以猜一手MD5

反編譯

反編譯看下程式碼

反編譯用了MT管理器
脫殼用了Arm Pro
都是要付費的,怎麼操作就省略,相信你們都會

用MT管理器搜尋介面關鍵字analysis/course/tab

,只搜尋到一個結果,好的開頭是成功的一半

點進去看下,反編譯成,java程式碼很明顯程式碼被混淆了,
包名都變成了單個的英文字母,先不管,試試繼續分析下去
看到方法上的註解,返回引數還用了泛型,很明顯是Retrofit2框架了,enc引數在這裡

手機上截圖有點小,把程式碼粘出來

@f(value="analysis/course/tab")
public b<String> a(
    @t(value="u") String var1,
    @t(value="sign") String var2,
    @t(value="description") String var3,
    @t(value="enc") String var4,
    @t(value="personid") String var5,
    @t(value="classid") String var6,
    @t(value="courseid") String var7
);

已經找到源頭,那看看哪裡會呼叫這個介面就行了
搜尋呼叫這個類的程式碼,看這個類的包名和類名方法名分別是e.g.u.h2.b、d和a

有好幾個同名的過載方法,先不管,搜尋smali呼叫的程式碼e/g/u/h2/b;->a
找到了20多個結果,不好辦
看一下這個方法有7個String型別的引數,超過4個引數smali裡面就會使用invoke-interface/range來呼叫
用正則來搜尋一下程式碼invoke-interface/range.*?e/g/u/h2/b/d;->a
結果沒減少多少,還是有21個

不過我們知道引數有7個,看哪裡有呼叫7個引數的方法好了,range後面大括號裡的就是引數,v1-v6就是6個引數,快速找一下
還是沒法找出來,不過還有別的方法,搜一下字串任務 完全匹配,就是抓包抓到的引數
搜尋到2個結果,lucky,看了下第一個沒看出啥,看第二個,很明顯對應的是課程介面的tab,裡面還有介面的域名

public void run() throws Throwable {
  String string;
  String string2;
  if (Objects.equals("任務", this.a)) {
      string2 = "task";
      string = "任務";
  } else if (Objects.equals("章節", this.a)) {
      string2 = "chapters";
      string = "章節";
  } else if (Objects.equals("更多", this.a)) {
      string2 = "more";
      string = "更多";
  } else {
      string2 = "";
      string = "";
  }
  if (g.b((CharSequence)string)) {
      return;
  }
  String string3 = URLEncoder.encode(string, "utf-8");
  string3 = b.a((b)this.f, (String)this.b, (String)string2, (String)string3, (String)this.c, (String)this.d, (String)this.e);
  ((d)s.a((String)"http://data.xxt.aichaoxing.com/").a(d.class)).a(this.b, string2, string, string3, this.c, this.d, this.e).a((o.d)new a(this));
}

前面的程式碼就是介面引數裡的sign和description
先看這兩行

String string3 = URLEncoder.encode(string, "utf-8");
  string3 = b.a(
    (b)this.f,
    (String)this.b,
    (String)string2,
    (String)string3,
    (String)this.c,
    (String)this.d,
    (String)this.e
  );

看前面程式碼可以知道這裡string是tab的名字,就是任務、章節、更多這三個其中一個
隨後對string進行了一次url編碼
最後呼叫了b.a方法,傳入了7個引數,上下文並不存在名稱為b的物件,因此可以斷定b是一個類名
檢視import,定位到了e.g.k.e.b這個類
點進去檢視一下

public static String a(b b2, String string, String string2, String string3, String string4, String string5, String string6) {
    return b2.a(string, string2, string3, string4, string5, string6);
}

private String a(String string, String string2, String string3, String string4, String string5, String string6) {
    StringBuilder stringBuilder = new StringBuilder();
    stringBuilder.append(string5);
    stringBuilder.append(string6);
    stringBuilder.append(string3);
    stringBuilder.append(string4);
    stringBuilder.append(string2);
    stringBuilder.append(string);
    stringBuilder.append("qK`b3XjC");
    return m.a((String)stringBuilder.toString()).toUpperCase();
}

呼叫了b2.a方法,b2的型別是b,其實就是自身了,傳遞了6個引數,也就是呼叫了下面的a方法
可以看到就是按 5 6 3 4 2 1的順序將引數進行拼接,最後拼上一個鹽,最後呼叫一個m.a方法
m.a其實就是一個md5的方法

根據引數順序,最後可以分析出 string3 = md5(this.e + this.d + string3 + this.c + string2 + this.b + salt),其中salt是一個字串qK`b3XjC
檢視程式碼發現下面呼叫了介面

((d)s.a((String)"http://data.xxt.aichaoxing.com/").a(d.class)).a(this.b, string2, string, string3, this.c, this.d, this.e).a((o.d)new a(this));

根據介面定義的引數順序就可以得到這樣一個引數對應表

變數名 介面引數名
this.b u
string2 sign
string description
string3 enc
this.c personid
this.d classid
this.e courseid

那麼可以得到虛擬碼enc= md5(classid + courseid + URLEncoder.encode(description) + personid + sign + u + salt).toUpperCase()

最後根據以上的分析,編寫出對應的程式碼,驗證分析結果

和抓包時得到的引數一致。

完美收場。