本文主要是介绍某音签名jsvmp还原__ac_signature,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
前言
此文章仅供学习交流!!!禁止用于违法途径!!!技术交流!!!
还原后运行结果
__ac_signature:47位长度和147位长度,具体长度校验没有进行过测试,生成147位的签名,传入cookie里的tt_scid即可;直播发言貌似验证了该签名
加密位置
以往访问主页不携带cookie会返回一个名为__ac_nonce的cookie值和一段JS代码,签名由返回的这段代码进行加密得到的,目前此方法貌似已经失效了。。。
打开抓包工具,打开某用户主页并登录某音,此时应该会在抓包中看到这段返回的JS代码(忘记前两天怎么做的了,貌似是要登录后会返回,具体自行测试)
代码最底部加密即为__ac_signature的加密位置
加密流程分析
__ac_signature(以空格进行分割,共七部分):
_02B4Z6wo00d01 3gpRIwAAIDD-Cu- z rENegN4CUAAALry cg2O WSWKjqmEuvAZtarLJpsVutUwlQwXMxqHzosGv8mZxaGjf-XCIXlR6kLaMOPCVXv-mXzhZulem3xmk.Ny8j6Bx366M8obof 30
第一部分:_02B4Z6wo00d01;14位字符,该部分应该可以固定,调试中遇见后三位会变动d01、f01、101;
第二部分:3gpRIwAAIDD-Cu-;15位字符,该部分由时间戳、url、canvas进行加密处理;
第三部分:z;1位字符,此部分也由时间戳、url、canvas进行加密处理;
第四部分:rENegN4CUAAALry;15位字符;此部分由时间戳、url、canvas、__ac_nonce、userAgent进加密处理;
第五部分:cg2O;4位字符,此部分在日志中没有找到生成逻辑,可自行下条件断点跟进测试;
第六部分:WSWKjqmEuvAZtarLJpsVutUwlQwXMxqHzosGv8mZxaGjf-XCIXlR6kLaMOPCVXv-mXzhZulem3xmk.Ny8j6Bx366M8obof,96位字符;此部分由上一步的cg2O以及cookie中的tt_scid加密处理(TEA);
第七部分:30;2位字符,此部分由以上六部分生成的__ac_signature拼接处理转16进制处理;
插桩位置
两个插桩位置点,在函数 function G(b, e, f, a, c, l, m, I) 下方的判断处插桩
插桩好进行运行脚本,执行代码window.byted_acrawler.sign("","12344111"),"12344111"自定义输入,执行后开始输出日志,日志输出完成后将日志保存在本地进行分析;
算法分析
分析工作较为复杂,此处简写,可以自行手动打份日志逐个分析
第二部分分析
"3gpRI" 、"wAAID" 、"D-Cu-"
搜索日志中首次出现以上三组字符的位置
3gpRI 、wAAID 、D-Cu-运算逻辑如下(使用||分割):
-142437304 >> 24 & 63 || (35394255737123 << 28 | 515) >> 24 & 63 || (-1073741824 | ((canvas_num ^ num) >>> 6)) >> 24 & 63
-142437304 >> 18 & 63 || (35394255737123 << 28 | 515) >> 18 & 63 || (-1073741824 | ((canvas_num ^ num) >>> 6)) >> 18 & 63
-142437304 >> 12 & 63 || (35394255737123 << 28 | 515) >> 12 & 63 || (-1073741824 | ((canvas_num ^ num) >>> 6)) >> 12 & 63
-142437304 >> 6 & 63 || (35394255737123 << 28 | 515) >> 6 & 63 || (-1073741824 | ((canvas_num ^ num) >>> 6)) >> 6 & 63
-142437304 >> 0 & 63 || (35394255737123 << 28 | 515) >> 0 & 63 || (-1073741824 | ((canvas_num ^ num) >>> 6)) >> 0 & 63
注意!!!此处不是最终得到的字符 只是运算逻辑,此处会对计算的数值大小进行判断,以便进行下步操作;
-142437304、35394255737123是由时间戳、url计算得转二进制一系列计算到的,canvas_num由canvas计算得到,固定为639296988;
第二部分15位字符生成函数如下:
function calculate(number) {//应该还存在缺陷if (number < 26) {return String.fromCharCode(number + 65)} else if (number < 52) {return String.fromCharCode(number + 71)} else if (number < 62) {return (number - 52).toString()} else if (number >= 62 && number <= 63) {return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-.".charAt(number)} else {return String.fromCharCode(number)}
}
function calculate1(number, str) {str = str.toString()let n;for (let i = 0; i < str.length; i++) {if (i === 0) {n = ((number ^ str.charCodeAt(i)) * 65599) >>> 0} else {n = ((n ^ str.charCodeAt(i)) * 65599) >>> 0}}return n
}t = "1693276913"
n = calculate1(calculate1(0, t), url)
u = n % 65521
binary = "10000000110000" + ((Number(t) ^ ((n % 65521) * 65521)) >>> 0).toString(2).padStart(32, '0')
n = (num = (parseInt(binary, 2))) >> 2
a = b = c = ""
canvas_num = 639296988
for (let i = 24; i > -1; i -= 6) {a += calculate(n >> i & 63)b += calculate((num << 28 | 515) >> i & 63)c += calculate((-1073741824 | ((canvas_num ^ num) >>> 6)) >> i & 63)
}
console.log(a,b,c)
第三部分分析
"z"
由上部分的数值运算得到 "z" => calculate((canvas_num ^ num) & 63)
第四部分分析
"rENeg" 、"N4CUA" 、"AALry"
依旧搜索日志中首次出现以上三组字符的位置
此处追加userAgent、__ac_nonce进行计算
第四部分15位字符生成函数如下:
c = calculate1(0, num)
n = (((calculate1(c, userAgent) % 65521) << 16) ^ (calculate1(c, __ac_nonce) % 65521))
a = b = c = ""
for (let i = 24; i > -1; i -= 6) {a += calculate(n >> 2 >> i & 63)b += calculate(((n << 28) ^ ((524576 ^ num) >>> 4)) >> i & 63)c += calculate(u >> i & 63)
}
第五部分分析
"cg2O"
此部分日志中没有找到生成规律,自行下条件断点进行调试
第六部分分析
"WSWKjqmEuvAZtarLJpsVutUwlQwXMxqHzosGv8mZxaGjf-XCIXlR6kLaMOPCVXv-mXzhZulem3xmk.Ny8j6Bx366M8obof"
此部分是对tt_scid进行加密处理,里面对tt_scid计算转数组,数组再进行七、八层运算加密(应该是个TEA算法,手抠也可以抠下来),加密后转为乱码,乱码再依次取值进行计算,得到最终的96位字符;
此部分代码较为敏感,也是手抠分析最难的部分,需要此部分联系"QQ"=>934615599或自行分析
第七部分分析
"30"
此处对上方生成的签名进行加密,转十六进制取6:8;
如果是生成47位的__ac_signature,分析完第四部分传入参数即可;
function calculate3(str) {str = str.toString()let n;for (let i = 0; i < str.length - 1; i++) {if (i === 0) {n = (str.charCodeAt(i) * 65599 + str.charCodeAt(i + 1)) >>> 0} else {n = (n * 65599 + str.charCodeAt(i + 1)) >>> 0}}return n.toString(16).substring(6, 8)
}
代码部分
function calculate(number) {// 取值可能还存在问题if (number < 26) {return String.fromCharCode(number + 65)} else if (number < 52) {return String.fromCharCode(number + 71)} else if (number < 62) {return (number - 52).toString()} else if (number >= 62 && number <= 63) {return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-.".charAt(number)} else {return String.fromCharCode(number)}
}function calculate1(number, str) {str = str.toString()let n;for (let i = 0; i < str.length; i++) {if (i === 0) {n = ((number ^ str.charCodeAt(i)) * 65599) >>> 0} else {n = ((n ^ str.charCodeAt(i)) * 65599) >>> 0}}return n
}function calculate3(str) {str = str.toString()let n;for (let i = 0; i < str.length - 1; i++) {if (i === 0) {n = (str.charCodeAt(i) * 65599 + str.charCodeAt(i + 1)) >>> 0} else {n = (n * 65599 + str.charCodeAt(i + 1)) >>> 0}}return n.toString(16).substring(6, 8)
}function func1(url, userAgent, __ac_nonce) {let __ac_signature = "_02B4Z6wo00d01"; //有问题, d01、f01、101 暂时固定let t, binary, n, u, num, a, b, c, canvas_num;t = Date.now().toString().substring(0, 10)n = calculate1(calculate1(0, t), url)u = n % 65521binary = "10000000110000" + ((Number(t) ^ ((n % 65521) * 65521)) >>> 0).toString(2).padStart(32, '0')n = (num = (parseInt(binary, 2))) >> 2a = b = c = ""canvas_num = 536919696for (let i = 24; i > -1; i -= 6) {a += calculate(n >> i & 63)b += calculate((num << 28 | 515) >> i & 63)c += calculate((-1073741824 | ((canvas_num ^ num) >>> 6)) >> i & 63)}__ac_signature += a + b + c + calculate((canvas_num ^ num) & 63)c = calculate1(0, num)n = (((calculate1(c, userAgent) % 65521) << 16) ^ (calculate1(c, __ac_nonce) % 65521))a = b = c = ""for (let i = 24; i > -1; i -= 6) {a += calculate(n >> 2 >> i & 63)b += calculate(((n << 28) ^ ((524576 ^ num) >>> 4)) >> i & 63)c += calculate(u >> i & 63)}__ac_signature += a + b + c__ac_signature += calculate3(__ac_signature)return __ac_signature
}ua = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36'__ac_signature = func1("www.douyin.com/discover", ua, "12344111")
console.log(__ac_signature, '\n', __ac_signature.length)
后言
此文章仅供学习交流!!!禁止用于违法途径!!!技术交流!!!
还原此算法并不困难,只是分析过程有些枯燥,还是需要耐心一点一点分析
需要完整147位算法联系"QQ"=>934615599;"V裙"=>Y52115F
这篇关于某音签名jsvmp还原__ac_signature的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!