小白入门,无壳app登录算法还原并实现发包(重发)

查看 18|回复 0
作者:xaf   
如题本文主要讲某app登录算法还原并实现发包的全过程,此app非常适合小白入门时拿来练手,是一个无壳无混淆的app,软件链接我放在文章最下面,建议先看一下文章后,再去下载上手。


1.jpg (52.42 KB, 下载次数: 0)
下载附件
2023-7-1 18:23 上传

从jadx分析得到上图代码,是手机号加密码的发包位置,其中可见手机号和密码都被传入了login,跟踪进去后,可见的相关代码如下图。


2.jpg (48.24 KB, 下载次数: 0)
下载附件
2023-7-1 18:23 上传

这里login又调用的私有方法doLogin,将手机号和密码传给了UserService里面,我们进行追踪,得到如下图代码。


3.jpg (74.75 KB, 下载次数: 0)
下载附件
2023-7-1 18:23 上传

看到了密码登录参数,手机号和密码被传入了这里,密码被传进了getMD5后,加密后存入了params又传入了getRSAParams,然后传入request,先继续追踪getMD5,


4.jpg (26.05 KB, 下载次数: 0)
下载附件
2023-7-1 18:23 上传

是一个普通的MD5,用python进行一下复现,代码如下。


6.jpg (25.41 KB, 下载次数: 0)
下载附件
2023-7-1 18:23 上传

然后追进getRSAParams里面得到下图代码,写的还挺多,又一层base64加密,还有RSA加密


7.jpg (35.77 KB, 下载次数: 0)
下载附件
2023-7-1 18:23 上传

先用frida来对这个对象动刀子,得结果如下
  • getRSAParams is called, params: {password=d8578edf8458ce06fbc5bb76a58c5ca4, os=android, mobile=15536263522, version=2.2.3}
  • getRSAParams ret value is {data=eyJwYXNzd29yZCI6ImQ4NTc4ZWRmODQ1OGNlMDZmYmM1YmI3NmE1OGM1Y2E0Iiwib3MiOiJhbmRyb2lkIiwibW9iaWxlIjoiMTU1MzYyNjM1MjIiLCJ2ZXJzaW9uIjoiMi4yLjMifQ==,
  • sign=DmxjCCvf8aJnZNve4BQkcy6turIGzkE13DkIu9JSnJF7yUDp3ZUxANRnSn6+BCN2nEogZsHFOm0fzzTU/NMnEqijA8lklHoxZspzVOe6Hkp8jYRrzvf0PQIh25lEL2GGWSslgzEK710opNDoQUVHA95ArOv9FQN95HxZuj7ywio=, timestamp=1687264102}

    传入之前的密码,和python复现的MD5结果相同,传入getRSAParams后成了后面的三项,data   sign   和   timestamp,然后这些数据和charles抓包得到的login数据相同。
    先解决data,进行追踪得到下图代码。Base64加密与解密,


    8.jpg (53.37 KB, 下载次数: 0)
    下载附件
    2023-7-1 18:23 上传

    对其进行python复现得到下图代码,运行结果与frida打印信息相同,


    9.jpg (47.71 KB, 下载次数: 0)
    下载附件
    2023-7-1 18:23 上传

    接着追踪sign的相关代码,得到下图代码


    10.jpg (39.55 KB, 下载次数: 0)
    下载附件
    2023-7-1 18:23 上传

    这里用frida进行hook,得到信息如下,可见这里是data与timestamp的拼接被传入了sign,被privateKey进行了加密,然后得到的sign
  • sign is called, content: data=eyJwYXNzd29yZCI6ImQ4NTc4ZWRmODQ1OGNlMDZmYmM1YmI3NmE1OGM1Y2E0Iiwib3MiOiJhbmRyb2lkIiwibW9iaWxlIjoiMTU1MzYyNjM1MjIiLCJ2ZXJzaW9uIjoiMi4yLjMifQ==×tamp=1687276955,
  • privateKey: MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMNGABIfN+iron2hbwB7mLK1Dm05V1qLZBILTDj7dypr+GJzQ9fk0V7gIIchpFG7pDQEXMbb2nj8VkNAIIDBaw7UY1h9n+sCBT+Xzz6BB2UxLBBMQVwOwv55tJkZ2YBcHFQDGz51HjxAonKJdHwGpjIp7bwdx375gybn2ic4qNuFAgMBAAECgYEAmcha7eqgASCKCx5DaMHtc2+bOPFblfcIjB1Rnd6L7mCxb/cOisutB2bCtykLW0LHAiAdYI5r87Ply3iJIF0yjU35I8aieDVmeaQXXQfpisimXLOmz6p4VlBzAkz493oXPEH81cHqbwnFkiFE3VVtHbCNoZqXlFWthIdae2kpjlECQQDyCMl09eyDBNGuzg1r4tAQ4CeZe7aCkEFwK2at76Raqz9NKrynBiZHsKLU3JedRm2eZ7JimUhsuKbbkS/mcxBrAkEAzop7/PyddSXGDFDECyuXtuEKyzzUvdGiyNmOexhSwTmTZ7QdQqe5p382yCQcY8RXxZ6W9CLjuukfa9I6Tcz/zwJAQbjpG318D8fLOHBzbIxWe36iwia51JJfcpoWc7zTIFvIAKhOOfyNgIISdULBWM+7DHyUD/oXlI4/oPe3zhgIqQJAQd3gFJnrDQTy19KZ8oYAaA30h0PrBG3qX+shiRgErCJUY+oIus0KY+Qp8EGz3A0tgJRGx6you17E6nmspksN+QJBAKhaBGeHqs0+Z5wtFcunuqc6hV7WlhBYCe5YSxBNSiaohXDr6nQwjiOY22Q3m8aInp9KS+lDwW0o4C58VARKyo8=
  • sign ret value is Z5dDahgsBp06lh76v1fos8GSqX4HdcB+vJBJgw4qWN6wJ52T2LkX9e/WqtLrb+biSg10J23/f0KIQW57GFLIWEgLwQRWgKaacvJJVMtoeETAXhgMvYU9LWmjFzrtd1EuRLyHLVkWik7IbJM5mySllm+bG/nfcPvohXp6ATRqy7k=



    11.jpg (95.13 KB, 下载次数: 0)
    下载附件
    2023-7-1 18:23 上传

    sign的python还原,生成的结果与frida的hook结果相同,sign完成,然后就是将已经实现的python代码进行拼接,并完成发包。
    首先实现手机号与密码的输入,传入parems,实现相同的login。


    12.jpg (74.75 KB, 下载次数: 0)
    下载附件
    2023-7-1 18:23 上传

    python实现代码如下


    13.jpg (56.84 KB, 下载次数: 0)
    下载附件
    2023-7-1 18:24 上传

    接着实现下图代码:


    14.jpg (35.77 KB, 下载次数: 0)
    下载附件
    2023-7-1 18:24 上传

    python实现代码如下:


    15.jpg (71.03 KB, 下载次数: 0)
    下载附件
    2023-7-1 18:24 上传

    最终实现发包:


    16.jpg (35.44 KB, 下载次数: 0)
    下载附件
    2023-7-1 18:24 上传

    最终发包代码:
    [Python] 纯文本查看 复制代码import requests
    import json
    import time
    import hashlib
    from Crypto.Hash import SHA
    from Crypto.Signature import pkcs1_15
    from Crypto.PublicKey import RSA
    import base64
    pey = 'MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMNGABIfN+iron2hbwB7mLK1Dm05V1qLZBILTDj7dypr+GJzQ9fk0V7gIIchpFG7pDQEXMbb2nj8VkNAIIDBaw7UY1h9n+sCBT+Xzz6BB2UxLBBMQVwOwv55tJkZ2YBcHFQDGz51HjxAonKJdHwGpjIp7bwdx375gybn2ic4qNuFAgMBAAECgYEAmcha7eqgASCKCx5DaMHtc2+bOPFblfcIjB1Rnd6L7mCxb/cOisutB2bCtykLW0LHAiAdYI5r87Ply3iJIF0yjU35I8aieDVmeaQXXQfpisimXLOmz6p4VlBzAkz493oXPEH81cHqbwnFkiFE3VVtHbCNoZqXlFWthIdae2kpjlECQQDyCMl09eyDBNGuzg1r4tAQ4CeZe7aCkEFwK2at76Raqz9NKrynBiZHsKLU3JedRm2eZ7JimUhsuKbbkS/mcxBrAkEAzop7/PyddSXGDFDECyuXtuEKyzzUvdGiyNmOexhSwTmTZ7QdQqe5p382yCQcY8RXxZ6W9CLjuukfa9I6Tcz/zwJAQbjpG318D8fLOHBzbIxWe36iwia51JJfcpoWc7zTIFvIAKhOOfyNgIISdULBWM+7DHyUD/oXlI4/oPe3zhgIqQJAQd3gFJnrDQTy19KZ8oYAaA30h0PrBG3qX+shiRgErCJUY+oIus0KY+Qp8EGz3A0tgJRGx6you17E6nmspksN+QJBAKhaBGeHqs0+Z5wtFcunuqc6hV7WlhBYCe5YSxBNSiaohXDr6nQwjiOY22Q3m8aInp9KS+lDwW0o4C58VARKyo8='
    url = 'https://api.langshiyu.com/user/v2/account/login'
    def md5(pwd_str):
        md5_obj = hashlib.md5()
        md5_obj.update(pwd_str.encode('utf-8'))
        return md5_obj.hexdigest()
    def times():
        return str(int(time.time()))
    def sign(content, private_key):
        private_key_value = base64.b64decode(private_key)
        key = RSA.import_key(private_key_value)
        # 计算 SHA-1 哈希值
        hash_value = SHA.new(content.encode('utf-8'))
        # RSA 的密钥长度为 1024 位
        k = 1024
        # 计算最大签名长度,根据 Java 的实现方式计算
        em_len = k // 4
        h_len = 20
        t_len = 3
        s_len = em_len - h_len - t_len - 1
        # 进行签名
        signature_value = pkcs1_15.new(key).sign(hash_value)[:s_len]
        # 返回 Base64 编码的结果
        return base64.b64encode(signature_value).decode()
    def login(mobile, param):
        params = {
            "password": md5(param),
            "os": "android",
            "mobile": mobile,
            "version": "2.2.3",
        }
        return params
    def jiaparams(params):
        # 将参数转换为 JSON 字符串,并进行 Base64 编码
        params_json = json.dumps(params,separators=(',', ':'))
        print("json转成功:",params_json)
        data = base64.b64encode(params_json.encode('utf-8')).decode('utf-8')
        print("data成功:",data)
        # 对加密后的参数进行签名
        signstr = f"data={data}×tamp={times()}"
        print("时间戳:",times())
        print("拼接成功",signstr)
        signss = sign(signstr, pey)#sign加密的地方
        print("sign成功",signss)
        # 创建一个空字典用于存储加密后的参数
        result = {}
        result['data'] = data
        result['sign'] = signss
        result['timestamp'] = times()
        return result
    mobile = input("请输入16位手机号:")
    parem = input("请输入密码:")
    params = login(mobile,parem)
    paramss = jiaparams(params)
    print("发包内容:",paramss)
    fb= requests.post(url, paramss)
    print("结果:",fb.text)bjsdm
    #结果:{"code":0,"message":"该账户不存在","reqdata":{"data":0},"reqtime":"0.015238"}
    app放在有道云文章里面,想尝试一下的小白可以进去拿一下。
    算法还原过程有道云文章链接:https://note.youdao.com/s/Yf9jGzqk
    [color=]如有违规,请管理及时删帖

    下载次数, 下载附件

  • 您需要登录后才可以回帖 登录 | 立即注册

    返回顶部