0x01前言
上篇可以使用frida进行hook解密,但是还是不方便,环境配置也麻烦,本篇文章为师傅们找了一个好方法,App抓包利器,并可以自动解密数据包参数,由于mumu抽风,本文使用雷电模拟器。
注:本文涉及的工具均以打包网盘,网盘下载即可。
0x02环境配置
雷电模拟器安装
直接安装雷电模拟器,新建模拟器
点击设置
System.vmdk可写入,root权限
保存后,启动模拟器。
Reqable安装
地址:
https://reqable.com/en-US/download
此工具需要下载手机端与pc端,可以将app的流量转发到pc端中,看起来直观一些。
将apk拖入模拟器,安装完之后,选择协同模式
填自己的出口网卡IP,pc端也是这样填
可以看到,已成功连接,这时候需要安装根证书
侧边栏-->证书管理-->
点击下载,保存文件,然后使用mt管理器,复制进system分区
长按证书,点击复制,点击确定
完成之后,证书管理处会显示证书已安装,
点击这个飞机,启动,pc端右上角点击启动
效果如下:
此方法可以抓绝大多数双向证书的app包,不需要frida等繁琐配置,如果流量多的话,还可以点击左下角的+号,指定程序流量抓取
0x03 自动化解密
黄鸟不能实时解密,需要导出为API合集,然后调用脚本,
右键点击脚本,可以配置环境
因为调用的本地的python环境,所以需要将依赖库都安装好
点击一条请求包,添加到API合集中
演示案例为第三弹的App,设置脚本,点击发送
效果如下:
脚本:
# API Docs: https://reqable.com/docs/capture/addons
from reqable import *
import base64
import hashlib
from urllib.parse import quote
from Crypto.Cipher import DES
from Crypto.Util.Padding import pad, unpad
class DuDu:
def __init__(self, key, iv):
if key is None:
raise ValueError("Parameter is null!")
self.init_cipher(key.encode(), iv.encode())
def init_cipher(self, sec_key, sec_iv):
md5 = hashlib.md5()
md5.update(sec_key)
des_key = md5.digest()[:8] # DES uses an 8-byte key
self.iv = sec_iv[:8] # DES uses an 8-byte IV
self.en_cipher = DES.new(des_key, DES.MODE_CBC, self.iv)
self.de_cipher = DES.new(des_key, DES.MODE_CBC, self.iv)
def encrypt64(self, data):
padded_data = pad(data, DES.block_size)
encrypted_bytes = self.en_cipher.encrypt(padded_data)
return base64.b64encode(encrypted_bytes).decode()
def decrypt64(self, data):
encrypted_data = base64.b64decode(data)
decrypted_data = self.de_cipher.decrypt(encrypted_data)
return unpad(decrypted_data, DES.block_size).decode()
def sign(self, data):
append = "sdlkjsdljf0j2fsjk"
# 将 JSON 字符串转换为字典
param_map = dict(item.split(":") for item in data.replace("{", "").replace("}", "").split(","))
# 对字典中的键进行排序
sorted_keys = sorted(param_map.keys())
# 拼接参数字符串
param_str = "&".join([f"{key}={quote(param_map[key].strip().replace('\"', ''))}" for key in sorted_keys if key != "sign"])
param_str += f"&key={quote(append)}"
print("sign明文:", param_str)
# 对拼接后的参数字符串进行 MD5 加密
md5 = hashlib.md5()
md5.update(param_str.encode())
return md5.hexdigest().upper()
def onRequest(context, request):
data = request.body.payload
start_index = data.find('"Encrypt":"') + len('"Encrypt":"')
end_index = data.find('"', start_index)
encrypted_str = data[start_index:end_index]
cleaned_str = encrypted_str.replace(' ', '').replace('\\n', '')
# print(cleaned_str)
du = DuDu("65102933", "32028092")
decrypted_string = du.decrypt64(cleaned_str)
print("body明文:", decrypted_string)
print("sign密文:", du.sign(decrypted_string))
return request
def onResponse(context, response):
return response
0x04 文末
工具地址:
扫描下方二维码即可下载
实习/校招/社招
安全服务工程师、安全攻防工程师、安全研发工程师、前后端开发工程师、测试工程师等等,所有岗位均可内推 |
推荐阅读
渗透实战|记一次简单的Docker逃逸+反编译jar接管云主机