问答
发起
提问
文章
攻防
活动
Toggle navigation
首页
(current)
问答
商城
实战攻防技术
漏洞分析与复现
NEW
活动
摸鱼办
搜索
登录
注册
实战 | 记某次逆向小程序解密及签名破解
渗透测试
这是之前做的一个项目,想着从小程序入手,当我打开burp抓到流量看到加密的数据包,以及sign签名参数的时候,我就知道接下来是一场硬仗要打了,看我如何一步步解密并破解签名,且听我娓娓道来。
### 前言 这是之前做的一个项目,想着从小程序入手,当我打开burp抓到流量看到加密的数据包,以及sign签名参数的时候,我就知道接下来是一场硬仗要打了,看我如何一步步解密并破解签名,且听我娓娓道来。 ### 解密数据包 首先打开小程序并抓取数据流,发现数据包不管是请求包还是响应包都存在加密如下:  同时发现有验签,无法重放数据包,再次发包提示重复提交如下:  首次先解决加密问题,反编译小程序,这里使用的反编译工具为wxapkg。比较好用,地址为: ```php https://github.com/wux1an/wxapkg ``` 这个工具可以直接扫描本地缓存的小程序:  上下键选择小程序,直接回车即可在工具当前路径下保存此小程序源码:  小程序源码有了,现在定位加密代码:  进入t的Encrypt方法,发现bizContent参数的加密方式为AES,加密模式为CBC,填充为pkcs7,key和iv 为HqNRc2XXXXXXXXXXX0wsiw==  编写如下脚本进行测试: ```python from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.backends import default_backend import base64 key_base64 = "HqNRXXXXXXXXXXXXwsiw==" # 替换为你的Base64编码的密钥 iv_base64 = "HqNRXXXXXXXXXXXXXwsiw==" # 替换为你的Base64编码的初始向量 def encrypt(text): key = base64.b64decode(key_base64) iv = base64.b64decode(iv_base64) cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend()) encryptor = cipher.encryptor() padded_data = text.encode('utf-8') + b"\0" * (16 - len(text) % 16) # PKCS7 padding ciphertext = encryptor.update(padded_data) + encryptor.finalize() return base64.b64encode(ciphertext).decode('utf-8') def decrypt(encrypted_text): key = base64.b64decode(key_base64) #print(base64.b16encode(key)) iv = base64.b64decode(iv_base64) cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend()) decryptor = cipher.decryptor() encrypted_data = base64.b64decode(encrypted_text) decrypted_data = decryptor.update(encrypted_data) + decryptor.finalize() return decrypted_data.rstrip(b"\0").decode('utf-8') # Remove PKCS7 padding # 测试 while 1: enc_data = input("输入密文:") print("-----------------------------------------------------------------------------------------------------------") print("\n\n\n\n\n明文是:"+decrypt(enc_data)) print("-----------------------------------------------------------------------------------------------------------\n\n\n\n\n") ``` 运行脚本,输入密文,发现解密成功:  ### 破解签名 上文解密了数据包,接下来需要破解签名,解决数据包无法重放的问题,定位到加签代码位置,查看加签逻辑,**发现加签逻辑为appid=&bizContent=&nonstr=&timestamp=&key=拼接值之后的md5值并转换为大写。** 其中appid和key为固定值如下: ```php appid: 4d75a8047XXXXXf481018315bab24851 key: 5cdf4b8d27XXXXXX88b5d2a4d7ff985b ``` bizContent为AES加密后的实际请求内容 nonstr为随机数,在签名中可不变动 timestamp为时间戳,重放加签的时候需要像后修改不同时间戳  现在了解了加签逻辑,为方便测试,再写一个加密脚本,获取bizContent的AES加密后的值,脚本代码逻辑和上面差不多,这里为避免占用篇幅就不贴了,加密如下:  加密内容有了,appid、key为固定值,nonstr为随机数,所以破解验签脚本如下: ```python import hashlib def sign(): appid = '4d75a8047XXXXXX8315bab24851' bizContent = input("输入bizContent:") nonstr = '8888888888' timestamp = input("输入timestamp:") key = '5cdf4b8d27XXXXXX5d2a4d7ff985b' all_data = "appid="+appid+"&bizContent="+bizContent+"&nonstr="+nonstr+"&timestamp="+timestamp+"&key="+key print(all_data) md=hashlib.md5(all_data.encode()) # 创建md5对象 md5pwd=md.hexdigest() # md5加密 print("签名是:\n"+md5pwd.upper()) print("-----------------------------------------------------------------------------------------------------------\n\n\n\n\n") while 1: sign() ``` 生成新的验签如下:  使用新的签名进行数据包的重放,发现重放数据包成功,签名破解成功。  解密返回的数据包:  ### 小结 上文重点讲解了小程序数据包解密以及签名破解过程,如有错误,请斧正。
发表于 2024-03-11 09:33:05
阅读 ( 6413 )
分类:
渗透测试
3 推荐
收藏
4 条评论
333333333333333333心心深爱的
2024-03-11 13:42
<p>pcz8iqb7</p>
请先
登录
后评论
郑辣鸡
2024-03-11 17:39
最后挖到了啥漏洞呀,这个也可以写写
小艾
回复
郑辣鸡
后续有时间再补充。
请先
登录
后评论
N4v1
2025-01-17 15:52
小艾?
请先
登录
后评论
请先
登录
后评论
小艾
4 篇文章
×
发送私信
请先
登录
后发送私信
×
举报此文章
垃圾广告信息:
广告、推广、测试等内容
违规内容:
色情、暴力、血腥、敏感信息等内容
不友善内容:
人身攻击、挑衅辱骂、恶意行为
其他原因:
请补充说明
举报原因:
×
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!