快猫视频app加密分析及收费视频观看

 程序分析第一步 抓包。请求内容类似为“api_token=&data=A11F0341C删除一大段&device=android&device_id=2273ce99efcb&device_type=MI999&device_version=99&version_code=9.9.9”,返回的全都是“589CF94EFBFAA858142064D……”这类的,一看就是很火的AES加密。假如你看不出来是什么加密方式,一步步来分析他。
        JADX打开app,打开AndroidManifest.xml,找到第一个<activity所在的位置:
        

[Java] 纯文本查看 复制代码
<activity android:theme="@style/AppTheme_Splash" android:name="com.省略.省略.main.activity.SplashActivity">

按住CTRL再单击“com.省略.省略.main.activity.SplashActivity”,就进入app初始化的第一个界面了。
        先整体浏览一遍,有中文的先看中文!其次再看双引号里面的内容。例如这一行:
        

[Java] 纯文本查看 复制代码
splashActivity.m14963h((SplashActivity) (DefaultWebClient.HTTP_SCHEME + ApiUtils.m15997e() + ":8099" + "/api/domain/index"));

        一看端口和地址就知道是请求某个网址,同样CTRL再单击m14963h,跟进去看看:
         

[Java] 纯文本查看 复制代码
1
2
3
4
5
6
private void m14963h(String str) {
      RequestCall a = ((PostFormBuilder) ((PostFormBuilder) OkHttpUtils.m13452e().mo30123b("data", new SimpleRequest().toString()).mo30122b().mo30118a(str)).mo30117a((Object) SplashActivity.class.getName())).mo30121a();
      a.mo30147b(3000);
      a.mo30149c(3000);
      a.mo30148b(new C3899c(str));
  }

其中的”data”应该就是抓包请求中的”data”,同样CTRL再单击mo30123b,跟进去看看:
   

[Java] 纯文本查看 复制代码
1
2
3
4
5
6
7
public PostFormBuilder mo30123b(String str, String str2) {
       if (this.f8573d == null) {
           this.f8573d = new TreeMap<>();
       }
       this.f8573d.put(str, AesEncryptionUtil.m11953b(str2, "x;j/6Sp})&{ZJD", "znbV%$JCpt<c"));
       return this;
   }

这两串乱码的字符是不是很特别?应该就是密码和偏移了,同样CTRL再单击m11953b,跟进去看看:
   

[Java] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
public static String m11953b(String str, String str2, String str3) {
       byte[] bArr;
       try {
           bArr = str.getBytes("UTF-8");
       } catch (Exception e) {
           e.printStackTrace();
           bArr = null;
       }
       return m11950a(m11955b(bArr, str2, str3));
   }

这一段是转化UTF-8格式的,String str2 和 String str3 原封不动给到了m11950a和m11955b函数,分别点进去看看:
   

[Java] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
public static byte[] m11955b(byte[] bArr, String str, String str2) {
       try {
           SecretKeySpec b = m11954b(str);
           Cipher instance = Cipher.getInstance("AES/CBC/PKCS5Padding");
           instance.init(1, b, m11951a(str2));
           return instance.doFinal(bArr);
       } catch (Exception e) {
           e.printStackTrace();
           return null;
       }
   }

不难发现果然就是AES/CBC/PKCS5Padding加密!这段其实是把请求的内容加密后给到data,然后发送请求。估计解密的密码也是一样吧。我们直接试试这套密码解密返回的数据。果然解密为明文信息。例如:
{“data”:{“video_fee_limit”:”1000~50000″,”video_hot_fee”:1000,”service_url”:”https:\/\/hhh.xxx.cn\/widget\/standalone.html?eid=e85ce5dcc79d5e1adcc&groupid=b786accb1554a12170″,”upload_notice”:”一天只能发布2次非原创付费视频,原创付费视频一天发布3次”,”upload_limit”:3,”discount_end_time”:11110640},”code”:200,”msg”:”查询成功”}
采用JSON格式数据。
请求中data的数据同样解密出来,我们分析两个关键的请求:

POST
/***/video/index 获取首页播放列表
api_token=&data=D8957D0A806CB388A565中间省略一大堆BB9A5D49C37DF5ED3AABD
{“page”:1,”perPage”:10,”signature”:”104AA9C95C8759999999F81B2B210660″,”type”:3} 第一页,每页10条,签名,视频类型

POST
/***/video/info  获取视频信息
api_token=&data=55C73D6B1A9A7A78AAF0中间省略一大堆3DC886C865D6C4838118
{“signature”:”4268FBC4650C7EBE9999999B48F17CE1″,”video_id”:”9999″}  签名,视频ID


直接更改第二条中的“video_id”后的数据为888,然后加密,发送请求。测试发现返回 {“data”:null,”code”:401,”msg”:”签名无效”} 看来signature中的签名也是随参数改变而改变的,继续分析。
        JADX中点击-导航-搜索文本,输入signature发现太多条了,加引号后再搜,只有3条,后两条还在同一个地方,进去看看:
      

[Java] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
for (Map.Entry<String, Object> entry : getParams$app_officialRelease().entrySet()) {
               sb.append(HttpUtils.PARAMETERS_SEPARATOR);
               sb.append(entry.getKey());
               sb.append(HttpUtils.EQUAL_SIGN);
               sb.append(EncodeUtils.m11968a(entry.getValue().toString()));
           }
           String sb2 = sb.toString();
           C4842f.m16976a((Object) sb2, "sb.toString()");
           if (sb2 != null) {
               String substring = sb2.substring(1);
               C4842f.m16976a((Object) substring, "(this as java.lang.String).substring(startIndex)");
               String a = EncryptUtils.m11970a(substring + "ohI}-bD*z8)W7~REuYKQ=[C1&tevxBL/HS,Pqr0Z_{Xq5$z*");
               C4842f.m16976a((Object) a, "EncryptUtils.encryptMD5ToString + Api.URL_SIG_KEY)");
               if (a != null) {
                   String upperCase = a.toUpperCase();
                   C4842f.m16976a((Object) upperCase, "(this as java.lang.String).toUpperCase()");
                   add("signature", upperCase);

    其实“EncryptUtils.encryptMD5ToString这里已经暴露了是MD5加密,看前面PARAMETERS_SEPARATOR是“&”,EQUAL_SIGN是“=”,前面就是把JSON转换为URL格式,sb2.substring(1)就是去掉第一个字符“&”。
    举例:{“a”:1,”b”:2}转换后就是”a=1&b=2″。然后再加上一段乱码字符”ohI}-bD*z8)W7~REuYKQ=[C1&tevxBL/HS,Pqr0Z_{Xq5$z*”,之后采用MD5加密。
    MD5加密是没法解密的(一般情况下),不过我们已经知道了加密方法就无所谓了。加密一个试一下。
        例如“video_id=888”加上乱码字符“ohI}-bD*z8)W7~REuYKQ=[C1&tevxBL/HS,Pqr0Z_{Xq5$z*”,MD5加密后为“20C503275FE3222489F6E728BD41AB5A”,JSON数据就是{“signature”:”20C503275FE3222489F6E728BD41AB5A”,”video_id”:”888″},再经过AES加密后为“533B3BC中间省略一大堆95FECDCB1”,最后得到请求的数据为“data=533B3BC中间省略一大堆95FECDCB1”,其他参数可以不加的。然后就可以POST得到任意ID的视频信息了。

        关于收费(需要金币)视频,请求后返回“该视频收费”,并且不会返回视频的地址等信息。继续往下看。
        使用第一个请求,并修改perPage参数为50,就是获取首页列表50条(再多了会比较慢,也许是我电脑和网络卡的原因)。然后分析其中一条如下:
{“id”:999,”user_id”:888,”title”:”鍝ュ摜佹垜鍢?,”gold“:1000,”fee_num”:0,”praise_num”:165,”width”:320,”height”:568,”cover“:”https:\/\/www.52.com\/20201106\/1650802\/48822e9bd02bbce52c283.jpg”,”is_vip”:0,”is_original”:0,”type”:1,”nickname”:”楠眰鎻?,”is_certification”:0,”is_pay”:0,”base64_txt”:”https:\/\/www.52.com\/4882e52c283.txt”}
        cover中就是图片地址,其实仔细观察视频的图片地址,再对比获取的播放地址不难发现,中间部分是一样的。{:301_975:} !掐头去尾。。。移花接木。。。利用中间部分就可以拼接出视频地址,所有视频都可以看了。gold中是需要的金币,利用他可以筛选出付费视频,只看付费的,{:1_918:} 

给TA买糖
共{{data.count}}人
人已赞赏
技术教程

自由岛vip会员破解教程+去启动广告

2020-12-21 10:57:21

技术教程

苹果卡贴机 黑解

2020-12-25 11:18:08

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索