#某小说站点签名算法破解
某小说站点在加载小说内容时会对url进行签名操纵,通过分析apk ipa 发现存在混淆加壳等乱七八糟的东西,为了快速解决问题输出结果,对目标进行简单收集发现了,web 站点。web站点也是同样的签名算法。
通过url 发现具有sign字符。
通过页面加载的js中字符串定位到 setParams 函数
key: "setParams",
value: function() {
var t = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {};
t.token = V.get("token") || "",
t.app = t.app ? t.app : "qutoutiao",
t.device = Object($.b)(),
t.dtu = "h5",
t.version = U.a.integer,
t.nonce = Math.ceil(1e4 * Math.random()),
t.time = Math.floor((new Date).getTime() / 1e3);
var e = z(P()(this.getMD5(t) + "&key=" + Q));
return t.sign = e,t
}
通过分析代码代码,完整模拟请求需要了解 this.getMD5()方法、常量Q、函数P()()、函数z(),
return t.sign
console.log(1,this.getMD5(t));console.log(2,Q);console.log(3,z);console.log(4,P());console.log(5,P()(this.getMD5(t) + "&key=" + Q));console.log(6,e);console.log(7,P()('admin'));return t.sign
sign 生产需要t和key,t最主要的是bookid找到key 并验证其方法可以获取每本书的详情,替换代码:
var e = z(P()(this.getMD5(t) + "&key=" + Q));
console.log(1, this.getMD5(t)); // 1 "app=qutoutiao&book_id=4095a188215e222eb82ad622a33da624&device=pageuser&dtu=h5&nonce=210&time=1550728569&token=&version=290"
console.log(2, Q); // 2 "T^xS0x31XL%wEowC"
console.log(3, z); // 3 f 放到下面
console.log(4, P()); // 4 ƒ 放到下面
console.log(5, P()(this.getMD5(t) + "&key=" + Q)); // 5 "b7b669fcc20b73e0f9fb56ef801e78d2"
console.log(6,e); // 6 "67326733333c63666637356732366035633c6367303360633d353460323d6137"
console.log(7,P()('admin')); // 7 "21232f297a57a5a743894a0e4a801fc3"
return t.sign = e,
// 函数 z
var z = function(t) {
for (var e = t.split("").map(function(t) {
return t.charCodeAt()
}), n = e.length, o = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"].map(function(t) {
return t.charCodeAt()
}), a = 0; a < n; a++)
e[a] = 5 ^ e[a];
for (var i = [], r = 0, s = 0, c = 0; ; ) {
var l = 255 & e[r];
if (c = s + 1,
i[s] = o[l >> 4],
s = c + 1,
i[c] = o[15 & l],
(r += 1) >= n)
break
}
return i.map(function(t) {
return String.fromCharCode(t)
}).join("")
}
// p()
function g(t, e, n) {
return e ? n ? m(e, t) : function(t, e) {
return h(m(t, e))
}(e, t) : n ? y(t) : function(t) {
return h(y(t))
}(t)
}
通过P()('admin') 输出的是21232f297a57a5a743894a0e4a801fc3,验证结果为md5算法。推论伪代码为
qingfengdeMacBook-Pro:Desktop$ cat xxxx.py
import hashlib
key ="T^xS0x31XL%wEowC"
src= "app=qutoutiao&book_id=4095a188215e222eb82ad622a33da624&device=pageuser&dtu=h5&nonce=210&time=1550728569&token=&version=290"+"&key="+key
m2 = hashlib.md5()
m2.update(src)
print(m2.hexdigest())
qingfengdeMacBook-Pro:Desktop$ python xxxx.py
b7b669fcc20b73e0f9fb56ef801e78d2
通过上面已得知 P()() 是完成一个md5()方法,而方法z() 是十六进制异或5
s=""
for i in md5:
s+="{:02x}".format(ord(i)^5)
print("sign:{}".format(s))
return s
qingfengdeMacBook-Pro:Desktop$ python xxxx.py
md5:b7b669fcc20b73e0f9fb56ef801e78d2
sign:67326733333c63666637356732366035633c6367303360633d353460323d6137
完整签名代码
def sign2(data):
# 签名算法:对所有字段进行排序并生成签名
src = "&".join(["{}={}".format(i, data[i]) for i in sorted(data.keys())])
key = "T^xS0x31XL%wEowC"
src = src+"&key="+key
m2 = hashlib.md5()
m2.update(src.encode('utf-8'))
md5 = m2.hexdigest()
s = ""
for i in md5:
s += "{:02x}".format(ord(i) ^ 5)
return s
流水账,搞定。
之后就是对每个接口API编写模拟代码