Loading

超星学习通逆向接口参数加密分析 - 课程页面切换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
image

接口大致分析

这个接口在课程页面点击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,只搜索到一个结果,好的开头是成功的一半
image
点进去看下,反编译成,java代码很明显代码被混淆了,
包名都变成了单个的英文字母,先不管,试试继续分析下去
看到方法上的注解,返回参数还用了泛型,很明显是Retrofit2框架了,enc参数在这里
image
手机上截图有点小,把代码粘出来

@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
image
有好几个同名的重载方法,先不管,搜索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个
image

不过我们知道参数有7个,看哪里有调用7个参数的方法好了,range后面大括号里的就是参数,v1-v6就是6个参数,快速找一下
还是没法找出来,不过还有别的方法,搜一下字符串任务 完全匹配,这个是抓包抓到的参数
运气不错只搜索到2个结果,看了下第一个没看出啥,看第二个,很明显对应的是课程界面的tab,里面还有接口的域名
image

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,string2就对应参数里的sign了,string对应参数里的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()

最后根据以上的分析,编写出对应的代码,验证分析结果
image

和抓包时得到的参数一致。

posted @ 2022-04-02 20:18  马卡龙MK  阅读(2313)  评论(8编辑  收藏  举报