吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 8987|回复: 38
收起左侧

[Android 原创] CC某V app加密分析及视频提取

  [复制链接]
spcspcspcspcspc 发表于 2021-1-6 16:08
本帖最后由 spcspcspcspcspc 于 2021-3-9 14:12 编辑

还是先感谢热心网友分享的APP,这几天有空就又出了一篇帖子,和上篇的思路基本相同。

程序中所有地址及数据均经过修改,不作为真实数据!仅提供分析方法!。




        程序分析第一步 抓包。

       请求内容类似{"data":"nrDugWses删除一大段BdbYTixA5MQ==","handshake":"v20200610"}


       返回的内容为乱码,经仔细辨认十六进制中包含1F8B0800,这是gzip格式压缩。

       直接解压出来类似{"code":200,"message":"操作成功","data":"ObzEZUE4删除一大段sJUQo0RI","handshake":"v20200610"}

       可以看到来回的信息里面data都经过加密了,一看就是很火的AES加密!假如你看不出来是什么加密方式,一步步来分析他。

       JADX打开app,搜索"data",发现出来200多条信息,我们换个关键词"handshake",结果只有一条。

[Java] 纯文本查看 复制代码
 public static final String f26955g = "handshake";

       继续以f26955g为关键字搜索,出来2条。我们进另外一条看看
[Java] 纯文本查看 复制代码
     if (sVar.mo33077c() != 0) {            String a = JSONUtil.m36637a(new JSONObject(hashMap2));
            LogUtils.m14031b("===ParamsString: " + a);
            hashMap.put("data", AESUtils.m40156b(a));
        }
        hashMap.put(AbstractC4663a.f26955g, "v20200610");
        String a2 = JSONUtil.m36637a(hashMap);
        LogUtils.m14031b("===realParamsJson: " + a2);
        return b0Var.mo32465f().mo32478a(b0Var.mo32467h()).mo32473a(f26933d, RequestBody.m46225a(this.f26934a, String.valueOf(a2))).mo32479a();
    }

       上面果然出现了"data",后面的AESUtils.m40156b就是加密函数了,CTRL再单击m40156b,跟进去看看:           
[Java] 纯文本查看 复制代码
 public static String m40156b(String str) {        if (f28855c.equals("AES/ECB/NoPadding")) {
            while (str.getBytes().length % 16 != 0) {
                str = str + ' ';
            }
        }
        byte[] k = EncryptUtils.m15560k(str.getBytes(), f28856d.getBytes(), f28855c, null);
        return k != null ? new String(k) : "";
    }
}

       看到"AES/ECB/NoPadding"是不是很激动,但这不是加密方式,f28855c才是真正的加密方式,CTRL再单击f28855c
[Java] 纯文本查看 复制代码
  private static String f28855c = "AES/ECB/PKCS7Padding";

       所以真正的加密方式是"AES/ECB/PKCS7Padding",返回再跟进EncryptUtils.m15560k看看:
[Java] 纯文本查看 复制代码
   public static byte[] m15560k(byte[] bArr, byte[] bArr2, String str, byte[] bArr3) {   
return m15513b(m15556j(bArr, bArr2, str, bArr3));
   }

       CTRL再单击m15556j
[Java] 纯文本查看 复制代码
  public static byte[] m15556j(byte[] bArr, byte[] bArr2, String str, byte[] bArr3) {  
return m15504a(bArr, bArr2, "AES", str, bArr3, true);
    }

       CTRL再单击m15504a
   
[Java] 纯文本查看 复制代码
 private static byte[] m15504a(byte[] bArr, byte[] bArr2, String str, String str2, byte[] bArr3, boolean z) {  
                        SecretKey secretKey;
                              if ("DES".equals(str)) {
                    secretKey = SecretKeyFactory.getInstance(str).generateSecret(new DESKeySpec(bArr2));
                } else {
                    secretKey = new SecretKeySpec(bArr2, str);
                }
                Cipher instance = Cipher.getInstance(str2);

       secretKey就是密码,这一步中str为上面的"AES",所以bArr2就是关键密码。
       一路反推回去其实就是EncryptUtils.m15560k(str.getBytes(), f28856d.getBytes(), f28855c, null);中的f28856d
       CTRL再单击f28856d
[Java] 纯文本查看 复制代码
 private static String f28856d;
    static {
        String str;
        if (TextUtils.equals("release", "debug")) {
            str = TestUtil.getSecret2();
        } else {
            str = TextUtils.equals("release", "staging") ? TestUtil.getSecretPre() : TestUtil.getSecret();
        }
        f28856d = str;
    }
这一步就是判断APP是测试版还是正式版使用不同密码,随便跟一个进去,例如CTRL再单击TestUtil.getSecretPre
[Java] 纯文本查看 复制代码
public class TestUtil {
    static {
        System.loadLibrary("security");
    }
    public static native String getSecret();
    public static native String getSecret2();
    public static native String getSecret3();
    public static native String getSecretPre();
    public static native String getSecretVP();
}
loadLibrary是调用的系统"security"的模块,并没法直接看到明文。
继续往下分析:直接用压缩软件把app解压,文件夹中搜索security,出现两个libsecurity.so,一个在\lib\arm64-v8a中,一个在lib\armeabi-v7a。
打开IDA软件,把libsecurity.so拖进去,左侧列表就出现了Java_com_niming_weipa_utils_TestUtil_getSecret等函数,点击进去看看,右侧窗口F5,转为JAVA代码
[Java] 纯文本查看 复制代码
__int64 __fastcall Java_com_niming_weipa_utils_TestUtil_getSecret(__int64 a1)[/font][/font]
{
  return (*(__int64 (__fastcall **)(__int64, const char *))(*(_QWORD *)a1 + 1336LL))(a1, "0MDQRQgYI4a9e3Zns");
}
以此类推,一共有"A7D90#83B1o6!d1F6","4rKFwocME2SIp4Anftc","E8yC1EncqQ3ZrfWQg","0MDQRQgYI4a9e3Zns"四种密码。
直接一个个试试吧。其中有一个就是密码。
把所有发送请求的数据解压成明文,还是采用JSON数据,
其中list/hot的链接返回内容直接包含视频地址,“is_free”标签有的是0有的是1,不知道是不是收费和免费的意思,如果是那收费的也就都可以看了。
api/user/info链接返回的数据应该是用户信息,其中"coins":0和"is_vip":"n"感觉可以伪造一下数据破解一下本地VIP。
留给感兴趣的同学去研究吧。

当我们再次去请求数据的时候显示认证失败!!!看来还是有坑。
仔细观察发现请求的头部参数里有个X-TOKEN: 6rb+/wSXpc删除一大段S1JJZNQ30g7RvMmNJQE
(下面关于X-TOKEN的分析有错误,正确方法见文章末尾
再仔细观察发现在auth/login/device链接中返回的数据中包含有TOKEN的参数,
所以可以先请求auth/login/device获取X-TOKEN的参数后,再加到协议头里,再请求list/hot链接就正常了。
至此app的加密分析就结束了。

因为没找到易语言"AES/ECB/PKCS7Padding"加密解密的模块或者算法,所以就没有深入研究,也没有成品。(即使有也不可能发布的!)  
如果有易语言"AES/ECB/PKCS7Padding"加密解密的模块或者算法的请分享交流,谢谢!  



X-TOKEN的参数密后数据为
{"device_no":"e509-a93d-3e02-b39-205b6","device_type":"A","token":"eyJ0eXAiOiJKV1删除一大段QiLre1visa1s","version":"1.0.0"}

所以可以先请求auth/login/device获取TOKEN的参数后,替换掉上面的“token”参数,
加密后数据给到X-TOKEN,
再加到协议头里,再请求list/hot链接就正常了。
邀请码得会员流程:
伪造device_no(8个随机数-3个随机数-12个随机数),替换下列行中的999999999,
[Asm] 纯文本查看 复制代码
{"channel":"","code":"","device_no":"999999999","device_type":"A","version":"1.0.1"}
加密后的数据替换下列行中的999999999,
[Asm] 纯文本查看 复制代码
{"data":"999999999","handshake":"v20200610"}
附加协议头后发送 ***/app/api/auth/login/device,返回数据提取data数据解密,
提取token数据,替换下列行中的999999999,device_no替换下列行中的88888888
[Asm] 纯文本查看 复制代码
{"device_no":"88888888","device_type":"A","token":"999999999","version":"1.0.1"}
加密后的数据替换下列行中的999999999,
[Asm] 纯文本查看 复制代码
Accept-Language: zh-CN,zh;q=0.8
User-Agent: Mozilla/5.0 (Linux; U; Android 2.1; en-us; Nexus One Build/ERD62) AppleDart/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17
Accept: application/json
X-TOKEN: 999999999
Content-Type: application/json; charset=utf-8
Connection: Keep-Alive
Accept-Encoding: gzip
上面作为协议头,邀请码替换下行的666666作为数据
[Asm] 纯文本查看 复制代码
{"code":"666666"}
发送**/app/api/user/bindcode
返回信息提取message为“操作成功”就是成功邀请了一个账户。
每邀请一个可以得3天VIP,可以累计叠加,永久会员不是梦


免费评分

参与人数 12吾爱币 +12 热心值 +11 收起 理由
涛行 + 1 + 1 我很赞同!
nnelqw + 1 + 1 热心回复!
luochunyan + 1 + 1 谢谢@Thanks!
jianljuan + 1 + 1 谢谢@Thanks!
枫叶零渡 + 1 + 1 用心讨论,共获提升!
yysyys + 1 + 1 我很赞同!
zjun777 + 1 + 1 用心讨论,共获提升!
_小白 + 1 + 1 我很赞同!
fuy56go + 1 我很赞同!
侑燈 + 1 谢谢@Thanks!
芽衣 + 2 + 1 用心讨论,共获提升!
杨辣子 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

逍遥一仙 发表于 2021-1-6 18:01
闷骚小贱男 发表于 2021-1-6 16:54
原来我一直用的M3U8下载器是大佬你的呀...上一次提醒我E2EE我没太注意.
这一次我去试了试.发现了一点问 ...

已帮你测试,易语言内部为gbk编码,如网站使用utf8编码,需要先转换下。套一个e2ee的文本编码转换即可。

文本编码转换 (“吾爱破解”, “GBK”, “UTF-8”)
 楼主| spcspcspcspcspc 发表于 2021-2-24 08:09
闷骚小贱男 发表于 2021-2-23 16:00
[md]
好像输出变量都用字节集  再到文本能输出123123

我之前也遇到同样的问题,正确方法如下
[Erlang] 纯文本查看 复制代码
e2ee.加密数据 (#算法_AES_128_CBC, “123123”, “ed0f0f7e7ae8d46f521076d61fffb555”, 结果, #填充方式_PKCS5, 到字节集 (“2f71a0c886360026”), #文本内容类型_Base64)
调试输出 (“加密:” + 结果)
e2ee.解密数据 (#算法_AES_128_CBC, Base64解码 (结果, ), “ed0f0f7e7ae8d46f521076d61fffb555”, 结果1, #填充方式_PKCS5, 到字节集 (“2f71a0c886360026”), #文本内容类型_原始内容)
调试输出 (“解密:” + 结果1)

加密后结果为Base64加密,必须先 Base64解码 (结果, ) ,最后的编码是 #文本内容类型_原始内容 ,这样才能解密原始信息。
感觉这个解密最后的参数 ‘文本输出方式’应该改为‘文本输入方式’才对,因该是个小BUG。
逍遥一仙 发表于 2021-1-6 16:27
易语言加解密建议使用E2EE->加解密对象。如有RSA需求,使用 RSA加解密 类
m_h 发表于 2021-1-6 16:27
https://www.cnblogs.com/midea0978/articles/1437257.html
关于PKCS5Padding与PKCS7Padding的区别  学习下填充字节区分方法。。
https://www.jianshu.com/p/a9add8119089
http://www.toocruel.net/aes-ecb/
不会java会点点C(百度)和pascal.
闷骚小贱男 发表于 2021-1-6 16:35
本帖最后由 闷骚小贱男 于 2021-1-7 10:06 编辑

分享个自用的在线AES解密网站https://www.keylala.cn/aes

M3U8大佬说的E2EE中的AES加解密挺实用的。


四、易语言AES-CBC加解密源码(JS):

    原理:脚本组件调用cryptoJS达到AES加解密,默认是CBC模式
    最近的几期:某哩某哩和某岛都可以用这个解密的
   


    源码下载地址:https://wwa.lanzouj.com/isazLjsiqfg 密码:52pj
 楼主| spcspcspcspcspc 发表于 2021-1-6 16:35
逍遥一仙 发表于 2021-1-6 16:27
易语言加解密建议使用E2EE->加解密对象。如有RSA需求,使用 RSA加解密 类

谢谢指点,,我去试一试
 楼主| spcspcspcspcspc 发表于 2021-1-6 16:38
m_h 发表于 2021-1-6 16:27
https://www.cnblogs.com/midea0978/articles/1437257.html
关于PKCS5Padding与PKCS7Padding的区别  学习 ...

多谢分享,回头仔细研究下
syrmb 发表于 2021-1-6 16:44
pkcs7和pkcs5是一样的
 楼主| spcspcspcspcspc 发表于 2021-1-6 16:46
闷骚小贱男 发表于 2021-1-6 16:35
分享个自用的在线AES解密网站https://www.keylala.cn/aes

感谢分享,,非常好用!
闷骚小贱男 发表于 2021-1-6 16:54
逍遥一仙 发表于 2021-1-6 16:27
易语言加解密建议使用E2EE->加解密对象。如有RSA需求,使用 RSA加解密 类

原来我一直用的M3U8下载器是大佬你的呀...上一次提醒我E2EE我没太注意.
这一次我去试了试.发现了一点问题

#算法_AES_128_CBC
#填充方式_PKCS7
要加密的字符:吾爱破解
密码:cf292aa85e3d4630
iv偏移:05fd62871f153398

用易语言的E2EE加密的结果是zOLbIqCT5IpjyJVwm7kVLA==
但是用在线加解密网站加密的结果是GJ0Gk/gSGeZxwsbvoxzn7A==
1111.png
没搞明白哪里有问题。
在线加解密的方法是用的cryptoJS,能成功解密APP的CBC加密
逍遥一仙 发表于 2021-1-6 17:18
闷骚小贱男 发表于 2021-1-6 16:54
原来我一直用的M3U8下载器是大佬你的呀...上一次提醒我E2EE我没太注意.
这一次我去试了试.发现了一点问 ...

目前在外面呢,晚上晚一点给你试试
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-26 10:19

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表