好友
阅读权限 10
听众
最后登录 1970-1-1
xaf
发表于 2023-7-1 18:35
本帖最后由 xaf 于 2023-7-1 21:32 编辑
如题本文主要讲某app登录算法还原并实现发包的全过程,此app非常适合小白入门时拿来练手,是一个无壳无混淆的app,软件链接我放在文章最下面,建议先看一下文章后,再去下载上手。
从jadx分析得到上图代码,是手机号加密码的发包位置,其中可见手机号和密码都被传入了login,跟踪进去后,可见的相关代码如下图。
这里login又调用的私有方法doLogin,将手机号和密码传给了UserService里面,我们进行追踪,得到如下图代码。
看到了密码登录参数,手机号和密码被传入了这里,密码被传进了getMD5后,加密后存入了params又传入了getRSAParams,然后传入request,先继续追踪getMD5,
是一个普通的MD5,用python进行一下复现,代码如下。
然后追进getRSAParams里面得到下图代码,写的还挺多,又一层base64加密,还有RSA加密
先用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加密与解密,
对其进行python复现得到下图代码,运行结果与frida打印信息相同,
接着追踪sign的相关代码,得到下图代码
这里用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=
sign的python还原,生成的结果与frida的hook结果相同,sign完成,然后就是将已经实现的python代码进行拼接,并完成发包。
首先实现手机号与密码的输入,传入parems,实现相同的login。
python实现代码如下
接着实现下图代码:
python实现代码如下:
最终实现发包:
最终发包代码:
[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
如有违规,请管理及时删帖
免费评分
查看全部评分
发帖前要善用【论坛搜索 】 功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。