同盾BlackBox逆向分析
BlackBox逆向分析
TODO 这个分析只是同盾其中一份算法,它不止一份算法。
参数定位
请求头如下
因为网站更新,原BlackBox在payload中,现在在headers中,因此可以hook headers
var header_old = window.XMLHttpRequest.prototype.setRequestHeader;
window.XMLHttpRequest.prototype.setRequestHeader = function (key, value) {
if (key=='BlackBox'){
console.log(key, value)
debugger;
}
return header_old.apply(this, arguments);
}
效果如下
开始追栈
追栈过程,发现值是异步出来的,通过条件断点结合日志断点进行分析,最终找到,如下图
emm...发现直接搜索BlackBox关键词也能搜到......
接着进入n()函数
因为开始的时候BlackBox为空字符串,所以找到设置BlackBox的地方,然后往前追栈
接着仍是异步
结果是Nse()的回调,因此进入Nse()函数
追到这里,再往前追栈,就已经进入同盾代码,找到同盾入口了,如下图
分析同盾混淆代码,并进行AST
同盾代码链接如下Ose,是一个一万四千多行混淆的代码文件
const sg = Date.parse(new Date().toString())
, Ise = (new Date().getTime() / 36e5).toFixed(0)
, Ose = "https://static.tongdun.net/v3/fm.js?t=" + Ise;
具体如何解混淆请转到:http://1997.pro/archives/1706077758696
分析BlackBox如何生成
需求:无痕浏览器搜索航班失败,不是无痕搜索成功。
找到tokenId
文件AST后,替换网页代码,进行搜索航班失败,里面可能有检测代码格式化的东西。但是现在先不管,先看看这个值生成的逻辑。
进入
经过分析,后面代码是主要是对OooQQ0["tokens"]进行加密,最后出值,后面再分析。
现在主要要看OooQQ0["tokens"]是如何生成,进入栈底可以看到是一个接口返回,如下图:
值拿出来为:
{
"code": "000",
"result": {
"tokenId": "6WPS1706083189JxkyIKVl3",
"xxid": "79txRkL043JFie6h6i9WQiSycCyBaEC5efCbrMzA+3ANFQp5K6WMDPhpNiEjJv9oiuehIc+UpX44Dn+wP4F8lA==",
"xdid": "uR19HptGmGPvdCgHVH0TkPwxoyHPjFYSyH6wuuL83eM=",
"bxid": "96Zr9A0c62JO17M89cUUrOVIqyENX+Qvjb502t469cf1T6/ByXjN/ZUbcxeB+WX+JH5adB6Hk99O/3ZwgUArYw==",
"c": {
"factor": 0,
"op": 0,
"cm": 0,
"vt": 1296000
}
},
"desc": ""
}
这个值是由该链接返回
var url = https://fp.tongdun.net/web3_8/profile.json?partner=jxhk&app_name=jxhk_web&token_id=jxhk-1706083190276-deac951f3204e&i=5XR3hBur7l4i416wWQk~ecjEkCnkVuNeLfJF2iGkBd9F%2FRy1oqFWEzOOVwIu2VIlIonUFceQ7X1hu9xeI~HHz1EDwwUQi0kwDCdLgNt~aOXvuUDvQhjfQvCMA2jDMFV8jOuxEO53NYKlidICADXsTx2KwcL4xjSgh988QVl9DjwQVlQPIKJ99I3eweMTxVWF06BOYYwM%2FW3FuYnWaWjf5ekyZfdKCnK4ewpj8HgUr0YgGaHkIvq7p0M7clrSSflrsytJwxmbspGOz4hZ3yofharoYR431boqofRK6l1BULWKcWB16nxzBgoFYyDwSWs8&j=ikpahErC3P82kujMweHPl0n892k5V7SIPMVbHL4GtQ%2Fxuw9qpvGPDQTnWDoodS3T5s5qmLLc5tbkNGVurqeZnjYSqEIcFcqVMzH~eNVyn91fxM2eRntrlO5MmnMUPklJRrHT5p7b9NMfs4IutV~wTUg%2FqOu~%2FNNn0vcy~o6lW7O9N0J0P8vx~BKTvrZkohivoDjjjVZGF%2FgCcqsIqerbnK~~pDT%2FH3M5veEuRbZagRa%2FhZB2HPIlhuRZmKeVfAt~uA3UfjrJxXG2H2gA0nBnM2AkY0zIZxpRQhari1IuWjt6xePL4PGEaOXeufThIMAwmHu8PxIBd30%3D&k=zIakKQzTrQ62p2nX9bZFAQ6C6YlD~5~kRWbgeYNxGIpp9XtsSRJ7cU3J%2FHcg5r1xy05L8lBGuBiFdCxGi2NZKkkwbRGGQbKf8RojCQKUwxWP6jZfiidxTyum2v39ZUO05~v6dlhR6syCbMv4DqBT0Aj0XqVitBcNLfCAR9cWH6BSf3Laz5Q8H7BthEsE8WER%2FlyMCJ4EtoLhjQZKet7NQJnd8uXmI~ygTMI%2FepGEa9nCAgp6U7JVVyjSU%2F~JkZd3VVbwqfd1Asz8wacD8P3Ago1moWMJOqqIGllluxuIcAM~SAsnHH3YokthK5ZVW8XCBL%2FvicBPDwqTqNJFhOp29XOJAPe7M4796qmooYPEnovBTLjbjPGoP8z8TXSWgL6fsGStoHVbdz%2F9APreu6hwAAUi2JMKw8hZjr5KRaL%2FmV33TkaxbV1jADMOYduOCfhtbhRXYVrnnHTnv4EZXcbad~UycvihW00Xf7QSuTFjJGCSyN~gGS0KYOwRKDXfytV0F1WgodIFw%2F6UIM7mj3OXdj088cxd2SwG0nI6Myd2KHGvUdhkUsy1L5wC1LNwTJqf&l=YQ1%2F%2Ff4ewyYBsdiHbf6yo0g7Q1AbgnKQ4WxBsHvkZzuPtaqa1LW7K7CHxw0vqeZ6iZxTgWR~~OqMTc6GZa2uMat~mP3tj52r67Rw%2F8txZ70Tnz~P5H7LPNftKPdF5Fc6P%2FJl4OM3wiGFcu~KgB%2FUnwkjbRMQrSq1fvv%2FhRVEvP15NmwhEe8PEp5exphthu0eUKmNg88ilTqick~ysiP%2FLRMbODuiDMxCNUZ8GI5XebbGpzHt5SzcsdqbCki4FYnZGiN7y9aJ%2FWxW7o4XwcQ5WIrZ%2FMtXDEh5dGhjNC8503IZkx9Ob7gDQP8hAYFjtt2Ie%2FpLdr1Y8v~YBB9n%2FSeDZGKFWadvskYMOZByjXMGV23wzQWwcOis2q%3D%3D&o=J6gM1tC16Fl81eWAsMr8RYKx6skbZS%2FDItRjauS3EQLsCBWecQUlDus4b3wTMFnPOD3SBgJ%2F64Xg41dqM9nIwhQQS8Xp8Z7DxQoZa7M5U~hVr9XEEF5MmB5BFm8P0P1418x7~GLNNXLXd6im7fjcSc4hXRwi8hKZoqJM343DRVMgUA1K9PaOzezdo~o6gXQ5w8VK6TbT42zS~NRcaTYyXqD71jydiHuDv8vEV2XhApux5oYD5t70VqqDzxo7~jQRLVcBxJ96YHqwxfTjUFS6PbP0vfDHY%2FzLKgfS0f0pbY2RI8tuGJPo2EKA~CTUDZ9VQ~9VBVz~J85ZrWQBowHc4NWQcbaDv0qlAU8ujYuLk5cx0TC9P8qGVytSsyE2ZPA1fxaQrr~%2FJHQ8Bpz6N%2FQuZvJn81OT%2F79idulxTok7emHTnKbXHXBoMFOcvzz4jkm1nqoyADxpuaDsYR9acnVl3kFrAVQAsd7tnLE56G6XX%2FyJzrzQ3c8ID3whhtz0lAqyBTr03BeEI2kbmsHr%2FfAQsBEK2QtYCQiReBqFSBGpcUcYLTYREO5R5X8aTmHwcYxU&f=ZMZBkZ8pifGl68Dk0H72KEyOh9xaGQpx&e=79txRkL043JFie6h6i9WQiSycCyBaEC5efCbrMzA%2B3ANFQp5K6WMDPhpNiEjJv9oQiLttPqQLO4X6yvSe%2FRbqg%3D%3D&v=KTaw2r7Vhw6dhM9OPbaVzeQIeFzhTbyKtlXxliXAo168kfPdOSDJbQfIafAnScn9&idf=rd%2BY4HNkBAXBfeUmSvIavNhJxd7qxiKpdKGSExvFw7TBoQjSgb7DzgOKgO00JiNyNfJa6be%2Bkpf322EyO2%2FhhHdFH8GutRodUG%2FnuBHsyq5PwtuhCu4HNbZBBiw9buMO%2BnLrw%2F9bmbAFo9fuJN%2FVTQ0hw5jxdHbrDZYh6NLXekk%3D&w=ujy8xMMt9F1wgarNu1sQ4F2%2Fbqv6z0q77UopX46Mfr3nHxKBAkpHfSQoHTzhtd2DG4w1~SByZ~4~6jRF%2FAV3hbHt5rvjTOz3&ct=oChYH7pnpiy%3D&_callback=_1706083190878_7032&h=19f336176fd3a3186d34278a31837388
对该url进行了一个提取
url = "'https://fp.tongdun.net/web3_8/profile.json"
params = {
"partner": "jxhk",
"app_name": "jxhk_web",
"token_id": "jxhk-1706083190276-deac951f3204e",
"i": "5XR3hBur7l4i416wWQk~ecjEkCnkVuNeLfJF2iGkBd9F/Ry1oqFWEzOOVwIu2VIlIonUFceQ7X1hu9xeI~HHz1EDwwUQi0kwDCdLgNt~aOXvuUDvQhjfQvCMA2jDMFV8jOuxEO53NYKlidICADXsTx2KwcL4xjSgh988QVl9DjwQVlQPIKJ99I3eweMTxVWF06BOYYwM/W3FuYnWaWjf5ekyZfdKCnK4ewpj8HgUr0YgGaHkIvq7p0M7clrSSflrsytJwxmbspGOz4hZ3yofharoYR431boqofRK6l1BULWKcWB16nxzBgoFYyDwSWs8",
"j": "ikpahErC3P82kujMweHPl0n892k5V7SIPMVbHL4GtQ/xuw9qpvGPDQTnWDoodS3T5s5qmLLc5tbkNGVurqeZnjYSqEIcFcqVMzH~eNVyn91fxM2eRntrlO5MmnMUPklJRrHT5p7b9NMfs4IutV~wTUg/qOu~/NNn0vcy~o6lW7O9N0J0P8vx~BKTvrZkohivoDjjjVZGF/gCcqsIqerbnK~~pDT/H3M5veEuRbZagRa/hZB2HPIlhuRZmKeVfAt~uA3UfjrJxXG2H2gA0nBnM2AkY0zIZxpRQhari1IuWjt6xePL4PGEaOXeufThIMAwmHu8PxIBd30=",
"k": "zIakKQzTrQ62p2nX9bZFAQ6C6YlD~5~kRWbgeYNxGIpp9XtsSRJ7cU3J/Hcg5r1xy05L8lBGuBiFdCxGi2NZKkkwbRGGQbKf8RojCQKUwxWP6jZfiidxTyum2v39ZUO05~v6dlhR6syCbMv4DqBT0Aj0XqVitBcNLfCAR9cWH6BSf3Laz5Q8H7BthEsE8WER/lyMCJ4EtoLhjQZKet7NQJnd8uXmI~ygTMI/epGEa9nCAgp6U7JVVyjSU/~JkZd3VVbwqfd1Asz8wacD8P3Ago1moWMJOqqIGllluxuIcAM~SAsnHH3YokthK5ZVW8XCBL/vicBPDwqTqNJFhOp29XOJAPe7M4796qmooYPEnovBTLjbjPGoP8z8TXSWgL6fsGStoHVbdz/9APreu6hwAAUi2JMKw8hZjr5KRaL/mV33TkaxbV1jADMOYduOCfhtbhRXYVrnnHTnv4EZXcbad~UycvihW00Xf7QSuTFjJGCSyN~gGS0KYOwRKDXfytV0F1WgodIFw/6UIM7mj3OXdj088cxd2SwG0nI6Myd2KHGvUdhkUsy1L5wC1LNwTJqf",
"l": "YQ1//f4ewyYBsdiHbf6yo0g7Q1AbgnKQ4WxBsHvkZzuPtaqa1LW7K7CHxw0vqeZ6iZxTgWR~~OqMTc6GZa2uMat~mP3tj52r67Rw/8txZ70Tnz~P5H7LPNftKPdF5Fc6P/Jl4OM3wiGFcu~KgB/UnwkjbRMQrSq1fvv/hRVEvP15NmwhEe8PEp5exphthu0eUKmNg88ilTqick~ysiP/LRMbODuiDMxCNUZ8GI5XebbGpzHt5SzcsdqbCki4FYnZGiN7y9aJ/WxW7o4XwcQ5WIrZ/MtXDEh5dGhjNC8503IZkx9Ob7gDQP8hAYFjtt2Ie/pLdr1Y8v~YBB9n/SeDZGKFWadvskYMOZByjXMGV23wzQWwcOis2q==",
"o": "J6gM1tC16Fl81eWAsMr8RYKx6skbZS/DItRjauS3EQLsCBWecQUlDus4b3wTMFnPOD3SBgJ/64Xg41dqM9nIwhQQS8Xp8Z7DxQoZa7M5U~hVr9XEEF5MmB5BFm8P0P1418x7~GLNNXLXd6im7fjcSc4hXRwi8hKZoqJM343DRVMgUA1K9PaOzezdo~o6gXQ5w8VK6TbT42zS~NRcaTYyXqD71jydiHuDv8vEV2XhApux5oYD5t70VqqDzxo7~jQRLVcBxJ96YHqwxfTjUFS6PbP0vfDHY/zLKgfS0f0pbY2RI8tuGJPo2EKA~CTUDZ9VQ~9VBVz~J85ZrWQBowHc4NWQcbaDv0qlAU8ujYuLk5cx0TC9P8qGVytSsyE2ZPA1fxaQrr~/JHQ8Bpz6N/QuZvJn81OT/79idulxTok7emHTnKbXHXBoMFOcvzz4jkm1nqoyADxpuaDsYR9acnVl3kFrAVQAsd7tnLE56G6XX/yJzrzQ3c8ID3whhtz0lAqyBTr03BeEI2kbmsHr/fAQsBEK2QtYCQiReBqFSBGpcUcYLTYREO5R5X8aTmHwcYxU",
"f": "ZMZBkZ8pifGl68Dk0H72KEyOh9xaGQpx",
"e": "79txRkL043JFie6h6i9WQiSycCyBaEC5efCbrMzA+3ANFQp5K6WMDPhpNiEjJv9oQiLttPqQLO4X6yvSe/Rbqg==",
"v": "KTaw2r7Vhw6dhM9OPbaVzeQIeFzhTbyKtlXxliXAo168kfPdOSDJbQfIafAnScn9",
"idf": "rd+Y4HNkBAXBfeUmSvIavNhJxd7qxiKpdKGSExvFw7TBoQjSgb7DzgOKgO00JiNyNfJa6be+kpf322EyO2/hhHdFH8GutRodUG/nuBHsyq5PwtuhCu4HNbZBBiw9buMO+nLrw/9bmbAFo9fuJN/VTQ0hw5jxdHbrDZYh6NLXekk=",
"w": "ujy8xMMt9F1wgarNu1sQ4F2/bqv6z0q77UopX46Mfr3nHxKBAkpHfSQoHTzhtd2DG4w1~SByZ~4~6jRF/AV3hbHt5rvjTOz3",
"ct": "oChYH7pnpiy=",
"_callback": "_1706083190878_7032",
"h": "19f336176fd3a3186d34278a31837388'"
}
定位url出口
查看该请求是什么请求,如下图是get请求,没法进行xhr断点。
通过栈直接进来,看到src,找ooOOO
ooOOO 等于ooOOO + "?" + o0OOO["join"]("&")
因此,现在需要找到 o0OOO 是如何生成的
具体分析url params如何生成
分析这段代码
创建了一个RSA加密:OOo00
参数为:
{
default_key_size: 1024
default_public_exponent: "010001"
key: null
log: false
}
public_key = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCuR3+MuPOVYuAKOS6O+J/ds+JAesgyFforFupDiDBBMTItdXyMrG6gUPFxj/pT/9uQSq8Zxl7BrdiKdi0G2ppEn4Nym+VRLTv2+lNa3kvlrj25Lop7wDZkVRecK5oDvdaQHrm4KKiF7jZNbHEreWGsINLpGvzBMRNztRtOJ6+XEQIDAQAB'
这个时候OOO0o为:
{
"partner": "jxhk",
"app_name": "jxhk_web",
"token_id": "jxhk-1706085591174-b41912934476b",
"i": "otxQNROd9OoYWxMwu7w0kGcPM2N4Ey/xO8HGYaS~PoxJX/VgL/HED3AcZlfTdmiPNxj6cHOA8OP85PPYkyaft0qGha7gOxOLHwUBbDWi2iMPnnAXEAjgbRR~EWi2QK6ljdNUugWOF~R1bT3Ves3OANPSM3OLr7qbHf5VzPpUXDOzuALm0/cWmivk1WSLCNT~MzfC63FMa7ZKXu~3NMVNbm~CHjvYz4Ja~yJjb45phsMzLDYZHF1FwtqMlNOGFahZ5M/7zjvQD7PFJanvJnm~F3NxSm5Drc4QXBa3aYFKgwNGum/elQJYqiJqJcUho4ka",
"j": "ItjivkjBpQbcMuP~nysahU90G8iITXylehJcMShGSzp5LEokpSJrENZ3tI4WC~XXom~SFMMcQDGqW6ngONLwZrZkhJhFZFWavLjt9ewE3QaUbzucy6a5Rlz3/Pgw4UYXIxr4KjJQtcB3YfFWv8GlAXuSGyfEw~sp3boQy5ruy17VuMpqeoHI71uQMCmJPbZxDJAdvP3HFzyH/lf6wqBVSU0oRns4ynFAf2ktHpLayjqeJc9mHNtLOP3ID1nT3/gFJmUz9v5NtsTASAEKbdcUcQ~ftSXYXWRf88NY9xTWaAJPonqc3mYO02LaZ8s2YBhR/Btvn72arO0=",
"k": "2hcuO2X9lPJ3zxle1b4hhIZN1X8Pjx1dWPuG7DjaKurvAkP6JyMoPVJURh8Sv9mDEusqonVNe33FI2Ezzs7gx1FlNWLfoPTFQsbF9BqhSLSF/Iw1FCRaqAj7AuMhdUSy1/yoysfA90NwS27VRhvJo/cum2AUMoQmgK8P8yZA~Sl/YxdOYQVTskEEHa1KNAa2Uua1Q9sQWB/TT0DoBy0Y0Xi0bHtnfFzbT5Y8OPg0z4YkZC7QkY39lnxt9tSBIPOI/VyZWuV4mq6t4CPgqQGWVpv3EBs8XfIF1yC~f51pe2aTKq9SZSpT~EHgm56IwV7k/HlYiQkRqvAmyTcQ4J/aNO8b8Zs7DRZoHQcliSjWJCUycrC~Y5jthHRbNEk7Lnovq9qr8Os~s1lyjOdW/WAAYlN6Oxwgp03g3dQQtbNF/zGrGSxMUEr43i~mSGpTZcQlx5JyIwK8Qtnz0C0dNMlEM0s~vP9Iqw06VuVQgbImgp0QTYQ~ZJaYSb2rO~eYiKQVQJE9poOdZkQYVviZrBnq/7YEQa5splCrPza1PJjA6RQQBB0dk3YKMPOsHSuv5Y1p",
"l": "K5dmtUXQqXa/SZhk1LUOTSY4SBtNm8wmgwus4t7xk4Au/Urp9XyObuvUuT4y3vB9XKPRvJ/3fzZmJU0eIT5xglK94TIuMLKd28zSqPZFteG6MDKSqB5VccXhn5Xi3I1buXekavskXAhTTjnFdBNvIuTJ9IdK2JopL2BoMojGUzGhDiAletPF5FPAn01uWseoHjqEFIsNXaTN8gmcaZaCV0EFXenSGaJeJmajtEr9KW33MaqcndUpmPW4OEysO/PWBXaSKF2npjYLss~u4REvKHXwr8hre/lG2RzR4/6ZMp8JiOKJoY1CCQfH9JCIZOEKv6GUXN1RIVU3gvbnXFgQBFJIZMk6pizfEvhwr8L8Iz8XdnIDObZNeq==",
"o": "dJ12lBuxOX8dOk9lHtXXLXM~pv264slqJ1w1rVp4KPcwpeFyi/CY8OUTyns4Y2JTKD4ate~MbZa9gs/absejIUn~RFGilIrXKHKcxOLkviETwXie0enbPHtKPuN1j5ftXj0s~JoPiRhoOlzXICOJq6xXEWryZ~ilECYhh4H3qBuQRyepmbLjTyhB1b2N~wsYYmnFn8bwcOIz3g6mCZXGrNUSihCU8GOwMRyXIsJMmma72hl~6WXHfyN9~vqOik07CKdlp1A8OSLAZCKXHyY2pY3fwPRboF99CrkmKvWCN180Px/KLTNSPdpTNkApIyirFb0TIGpyWGfYYw7N2ELY~zIO13mFUPNXr5tZWUMlHLJZqhMlRo9v53PO9ObLBesh/JHBy2rh7WAv3DFLzoNNWi3ByxBRfV0BuffOvSur~vO9zjhaw3eN4wszubz3jnlbdKDdVj~51EHB/xx5lDyNYEvIClyefD8Mx3TkxcJv9eEiedcSVMUXwiDPUZQbOPmevt04IM4gppBXgWli6iJXg4fqmPevPM3Z4~ol1A7sC/lv2WaC1M518UKVzkosK3NP",
"f": "3ZK1tB4TDWtdXdK~TlSncXLOmadNkCEx",
"e": "79txRkL043JFie6h6i9WQiSycCyBaEC5efCbrMzA+3ANFQp5K6WMDPhpNiEjJv9os6DChRp6iI8+GJHfZJwkaw==",
"v": "KTaw2r7Vhw6dhM9OPbaVzeQIeFzhTbyKtlXxliXAo168kfPdOSDJbQfIafAnScn9",
"idf": "1706085591257-18432585651",
"w": "mbTt4FbZuBj0WUYCruZ8ypsvVghEmEGUYMfM3uT3ZiHVCXpT/e4fbCTDSgor/nOrue8EVSs/2cM5RWN74kCNEtRhA1kQM3mI",
"ct": "JH2u044VU6m="
}
TODO: 这里找到一个值
// OooQQ0["timestamp"] = '1706085591257-18432585651'
OOO0o["idf"] = OOo00["encrypt"](OooQQ0["timestamp"])
到这里,知道url_params 由 循环OOO0o生成(encodeURIComponent)
追OOO0o如何生成
TODO: 这里找到几个值
// OooQQ0["version"] = 'KTaw2r7Vhw6dhM9OPbaVzeQIeFzhTbyKtlXxliXAo168kfPdOSDJbQfIafAnScn9'
OOO0o["v"] = OooQQ0["version"]
// OooQQ0["timestamp"] = "1706090242986-15815285348"
OOO0o["idf"] = OooQQ0["timestamp"] // 后续OOO0o["idf"]被覆盖,由RSA加密出来
// oO0o0O(OooQQ0["version"]) = "TPb3KVewt0xGZ0kqwrPk6XrjgFDPsPBBXOl/tpccHq8MckCNjR~ukXFaGUTWj1fNdOrvT1kv2KjBsr6HggFi44wrbGGRlg7U"
OOO0o["w"] = oO0o0O(OooQQ0["version"])
// OooQQ0["jsDownloadedTime"] = 1706090242873
// new window["Date"]()["getTime"]() - OooQQ0["jsDownloadedTime"]
OOO0o["ct"] = oO0o0O(Oo0QO0(new window["Date"]()["getTime"](), OooQQ0["jsDownloadedTime"]))
到这里,以及找到 v、idf、w、ct 四个值
继续追OOO0o其他参数
通过追栈发现 OOO0o 为 O0Q0OQ["deviceInfo"]
搜索 O0Q0OQ["deviceInfo"] =,找到最开始初始化的地方
TODO: 找到几个值
// OooQQ0["partner"] = "jxhk"
OOoQo["partner"] = OooQQ0["partner"]
// OooQQ0["appName"] = "jxhk_web"
OOoQo["app_name"] = OooQQ0["appName"]
// "jxhk-1706096208512-befbebd0b9185"
OOoQo["token_id"] = OooQQ0["token"]
先不管 OooQQ0 如何生成,后续看
接着到这,如下图
对一个固定值OQOQO0进行forEach,循环到不同的值进入不同的函数,检测各种浏览器环境。
[
[
{
"n": "zPHda1EGjlPIiY7Ae4UDbpfj",
"m": "hyhbgqbaxi6",
"x": "q652mrpq0k",
"y": "h77umrlknir"
},
{
"n": "zVzDIoOcjzhiYOplNGUEJqfgz6Hlan",
"m": "f736mgcni9c",
"x": "prlt87lwxvm",
"y": "4enw49pim03"
},
{
"n": "zbHpIXEhRthLGZ7AoNUeb6xgh1zwIXEGjlhFG3",
"m": "hyhbgqbaxi6",
"x": "prlt87lwxvm",
"y": "q652mrpq0k"
},
{
"n": "zRzLINEGRVrRYy7FeyUoJg",
"m": "hyhbgqbaxi6",
"x": "h77umrlknir",
"y": "o8gm8qu97as"
},
{
"n": "zRzjaKw8Ru",
"m": "f736mgcni9c",
"x": "prlt87lwxvm",
"y": "o8gm8qu97as"
},
{
"n": "zSHLIDELjIhrHq7FMZUEbXgtzVzma1Eg",
"m": "hyhbgqbaxi6",
"x": "h77umrlknir",
"y": "q652mrpq0k"
},
{
"n": "zPHpanwXjOPF",
"m": "f736mgcni9c",
"x": "f736mgcni9c"
},
{
"n": "h0HLaXEFjCQHYK7blz",
"m": "h77umrlknir",
"x": "f736mgcni9c"
},
{
"n": "zxHLIXE7juh9iFplePUaldxaz6HLanwh",
"m": "h77umrlknir",
"x": "f736mgcni9c"
},
{
"n": "zczwaMwFRIhrGZqbM4C6bF4t",
"m": "h77umrlknir",
"x": "f736mgcni9c",
"w": true
},
{
"n": "zxHLIXE7juh9HF7AMaCcbKxizsOw",
"m": "h77umrlknir",
"x": "f736mgcni9c",
"w": true
},
{
"n": "zNHpaEELjIhwYOpAMNecJqfs",
"m": "h77umrlknir",
"x": "f736mgcni9c",
"w": true
},
{
"n": "h1zjawwrtOhqYy71MQefbjfjzV",
"m": "h77umrlknir",
"x": "f736mgcni9c"
}
],
// 下面还有几个数组,太长了不复制了
]
循环出来的结果(TODO 这个只是一次循环的结果,用来加密 i 值的,还有几次循环生成 j,k,l,o ):
// 下面canvas不是真实指纹,截取了部分
[
918, // document.body.clientHeight
"-", // navigator.appMinorVersion undefined
20, // navigator.hardwareConcurrency
1040, // window.outerHeight
"-", // navigator.oscpu
1, // window.devicePixelRatio
"6470a21d4c329f0ab99b6025dfxf39", // canvas
"4746e7f5fbc70ef2ccd36ss30c966a|b0f220ff3f0f7424ca4fc6db815df", // canvas和两个固定值相关
"Webkit-Chrome", // 检测window document navigator 里面的各种东西,然后判断,得到的结果做一个拼接
"-", // 判断QQQOo中东西,有就直接return了 TODO 异步任务
"-", // 判断QQQOo中东西,有就直接return了 TODO 异步任务
"-", // 判断QQQOo中东西,有就直接return了 TODO 异步任务
"0_Windows_Not_A Brand_8_Chromium_120_Google Chrome_120" // Qo0oOo["userAgentDataStr"] || ""
]
接着执行这个代码赋值:window[QQ0QOQ](O0Q0OQ["deviceInfo"], window["String"]["fromCharCode"](O0QOOo(105, oQoQQ0)), oO0o0O, OoO0OQ, OOQO0o)
// 方法内部
QooOQ0["body_str"] = "Cnioka|JCnlxZ[DhecHCHlxZ[a+Coa+B$CxfC$Dhec^C^CtChk"
接着进入一个很大的switch case中,每次循环进来的流程一致,并且在case 74的时候进行赋值。
对l进行赋值,如下图,其他值也是在这里赋值:
梳理 i 的生成流程,其他值同理
结合条件断点,日志断点调试,在oOQ0o == 'i'时端住,然后网上追栈,看Q00oo如何生成。
通过分析,i在case40的时候进行加密,生成如下:
var QQQOo = '919^^-^^20^^1040^^-^^1^^6470a21d4c329f0ab99b6025df4bff39^^4746e7f5fbc70ef2cc93f66a|b0f220f0f72f424ca4fc6db815df^^Webkit-Chrome^^-^^-^^-^^0_Windows_Not_A Brand_8_Chromium_120_Google Chrome_120^^1hkv9oco6'
OooQQ0["timestamp"] = "1706090242986-15815285348" // 上面已经分析过 TODO 没被覆盖前的值 时间差
// OooOoO 为加密函数
function oO0o0O(QQQOo) {
return OooOoO(O0QOOo(QQQOo, ""), OooQQ0["timestamp"]["substring"](0, 24));
}
进入OooOoO 函数,最终走到QoOooQ(QQQOo, QQoQ0),生成i值;
很明显可以看出这是一个TripleDES加密,注意它是一个魔改过的TripleDES加密,如下图:
接下来依次看每个键是对什么进行加密,如下图:
图片就不截了,下面对应上,里面有代码格式化检测(我也会截取部分),所以下面指纹无法使用,具体指纹如何生成,花时间慢慢找就能找到,无非就是检测浏览器环境,检测代码格式化,检测设备指纹之类的,有手就行。
// 下面指纹不是完整的指纹,随便截取了部分
data = {
"i": "919^^-^^20^^1040^^-^^1^^6470a21d4c329f0ab99b6025df4bff39^^4746e7f5fbc70ef2ccd365c366a|b0f2202fcf72f424ca4fc6db815df^^Webkit-Chrome^^-^^-^^-^^0_Windows_Not_A 8_Chro0_Google Chrome_120^^1hkvqq1g2",
"j": "-^^-^^zh-CN^^0^^^-^^919^^1^^1920^^Mozilla^^1080^^-^^Google Inc. (Intel)-&-ANGLE (Intel, Intel(R) UHD Graphics irect3D11 vs_5_0 ps_5_0, D3D11)^^functiongetoffsetHeight(){[nativecode]}^^-^^-^^-^^-^^12536^^-^^1hk",
"k": "63e9e0254e8ec24|0110010001111111101111011011110001111111111011111^^Netscape^^920^^1040^^Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/53ke Gecko) Chrom0.0.0 Safari/537.36^^0a386f39b15d2eac07d^^zh-CN,zh^^-^^48000_2_1_0_2_explicit_speakers^^-^^0^^functiongetParameter(){[nativecode]}^^-^^-^^UTF-8^^-^^1872_8_0_0^^qq1ir",
"l": "Win32^^6ef4aad14d663a1e981^^1920^^0^724534^^-^^480^^https%3A%2F%2Fwww.juneyaoae^^1706170320246^^1914^^M0FlrCpOOP1qUZnHF8ny0SwYqBdNcgdRQPlC4QI\sw4aIMPbfm8g352BUHRXIJuHP7lGPsrHOFUPJEgPiGaSnIP9lKFsGTi8wIetQgFt2DlUjC2^^[object Window]^^functioncreatlyser(){[nativecode]}^^-^^-^^-^^-^^-^^1hkvqq1jp",
"o": "functiontoStrnativecode]}^^33^^HyFpfpf0-1706170320513-f01a12b88ddb8941325680^^[objectPluginArray]^^8^^1unctionenumerateDevices(){[nativecode]}^^20^^functiontoDataURL(){[nativecode]}^^-^^functionRTCPion(){[nativecode]}^^Failed to construct 'WebSocket': The URL 'itsgonnafail' is invalid.^^-^^-^^-^^a04ec137d669da06e6a^^-^^1f2d82cb673277e484582d66e4^^-^^1hkvqq1k0",
}
追 f,e 参数
f参数是由 [1,0,0,0,0,0] 生成,同样也是经过了case40,进入魔改的TripleDES进行加密,不详写了
e参数:QQOoOO["get"](xxIdKey)生成
var xxIdKey = "1735D64331DF397E"
补充上面说的OooQQ0
// OooQQ0["partner"] = "jxhk"
OOoQo["partner"] = OooQQ0["partner"] // 固定 "jxhk"
// OooQQ0["appName"] = "jxhk_web"
OOoQo["app_name"] = OooQQ0["appName"] // 固定 "jxhk_web"
// "jxhk-1706096208512-befbebd0b9185"
OOoQo["token_id"] = OooQQ0["token"] // 固定 "jxhk-" + new window["Date"]()["getTime"]() + "-" + window["Math"]["random"]()["toString"](16)["substr"](2)
结束
至此,除了环境检测的东西需要进一步看,其他流程已经全部分析完毕。