声明:该文章涉及的所有案例均为个人学习记录使用,严禁用于商业用途和非法用途,否则
由此产生的一切后果均与作者无关!如有侵权,请私信联系本人删帖!
目录
一、verifyParam加密流程分析。
全局定位搜索verifyParam发现其值等于a,往上跟栈可以知道a = e[Jt("0x3a")],其中Jt("0x3a")等于send,也就是接收上一步返回过来的值。
我们接着分析可以知道case0中next等于3,也就是说a最后是case0中返回过来的,也就是i[Jt("0x34")](Xt["a"], c);返回的值。
我们接着分析i[Jt("0x34")](Xt["a"], c); 可以比较容易的知道就是执行了Xt["a"],c是这个函数的参数,c也就是我们的明文参数。因为是异步执行了,我们需要跟进去看看异步内部的逻辑,直接跟进Xt["a"]函数。(v[r("0x0")](this, arguments)简化下就是v.apply(this,arguments),就是执行了v函数,v函数就在下面,需要第一次刷新页面的时候才会进入到下面的v,也就是完成初始化的过程,后面再次滑动在v函数里面是断不住的)
不管是第一次刷新还是后续的滑动,最终都会进入到核心的加密位置,也就是下面的switch语句中完成最后的加密过程。
我们接着分析明文的加密过程,
function h(e) {
var n = {};
n[r("0x26")] = function (e, n) {
return e < n
}
;
for (var t = e[r("0x27")], c = new Uint8Array(t), a = 0; n[r("0x26")](a, t); a++)
c[a] = e[r("0x28")](a);
return c
}
// 关键加密伪代码
return regeneratorRuntime[r("0x30")]((function (t) {
while (1)
switch (t[r("0x31")] = t[r("0x1a")]) {
case 0:
return i = a.a[r("0x32")](c), // 对明文c就行序列化,即执行JSON.stringfy操作
o = h(i), // 将序列化的c进行Uint8Array 操作
t[r("0x1a")] = 4, // 下一轮进入case4
n[r("0x29")](x, o); // 执行x(o),并返回给case4中的u u
case 4:
return u = t[r("0x33")], // 接收case0最后返回过来的值
t[r("0x34")](n[r("0x2a")], e[r("0x35")](u)[r("0x36")](r("0x37"))); // 最终返回的值,对接收的u进行Uint8Array操作后转base64编码
case 6:
case n[r("0x2c")]:
return t[r("0x38")]()
}
}
case0中的n[r("0x29")](x, o);是比较关键的加密过程,跟进去x可以看到其为异步操作,通过补环境导出Jose即可。
进一步分析可以知道Jose在088e中,一个典型的字典类型的webpack,没啥难点,一个字 “扣”
总结下大致的加密过程,1.明文参数进行序列化。2.转Uint8Array。3.经过Jose进一步加密。4.在转Uint8Array。5.最后进行base64编码。
二、明文参数分析
{
"captchaSn": "Cgp6dC5jYXB0Y2hhEu4CX8zQ7Opapg7Ej91Ar7N8c5Jc5KJvzG9jT0dLyY2wFjRx4S3L8HEr3Ijx1QaPQ26dpqHYsZ8EsIXMkosfiSGuqg1WKFhy9-A7EGO0l62mlUeZfHLVTugLiQpkc6MjCml3mq0OqIjCkVAslgxzIH4p4BWWDUQnQFqMC9Oicp0NqX7xdzsDdx8UYkBQ0_pHP6tnM4OnjeLycHDvHWEJ6VbWNYpQ7DtCng7SdCKpmpCTUFQUobYbQnEgaLb9dMWtJsM1vSieL0fTQ9R2qbCOwjIRtWNgf7arHChFSKPELv8lzMcRjs1ffHS0UpNBP0Pb--JjGXomqSBDkEXRe6l7BwoD1bULNnYwRt-FzPlDs4OTshpLskqF9Kx18BbHQNiwWXwAt6_U_x1eNqlCnr-QJtUCt_lXxksXdtgfoTrQOwrJTa44e4lOw-YAJlWYWlaJ6e57RWCj0CeXXs8rwwRqKqLz_G5oMzsv4EJg-uvTfJJAGhIMBkxCONRI4rqzJJkPiSSCZoMoBTAC",
"bgDisWidth": 316,
"bgDisHeight": 184,
"cutDisWidth": 56,
"cutDisHeight": 56,
"relativeX": 147,
"relativeY": 67,
"trajectory": "0|24|0,21|24|12,36|24|20,43|24|28,61|24|36,94|24|40,137|23|48,192|22|56,246|20|64,304|19|76,355|17|84,405|15|92,449|12|100,492|11|108,521|10|116",
"gpuInfo": "{\"glRenderer\":\"WebKit WebGL\",\"glVendor\":\"WebKit\",\"unmaskRenderer\":\"ANGLE (NVIDIA, NVIDIA GeForce RTX 4060 Laptop GPU (0x000028E0) Direct3D11 vs_5_0 ps_5_0, D3D11)\",\"unmaskVendor\":\"Google Inc. (NVIDIA)\"}",
"captchaExtraParam": "{\"ua\":\"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36 Edg/129.0.0.0\",\"userAgent\":\"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36 Edg/129.0.0.0\",\"timeZone\":\"UTC+8\",\"language\":\"zh-CN\",\"cpuCoreCnt\":\"16\",\"platform\":\"Win32\",\"riskBrowser\":\"false\",\"webDriver\":\"false\",\"exactRiskBrowser\":\"false\",\"webDriverDeep\":\"false\",\"exactRiskBrowser2\":\"false\",\"webDriverDeep2\":\"false\",\"battery\":\"1\",\"plugins\":\"1a68ba429dd293b14e41a28b6535aa590\",\"resolution\":\"2048x1152\",\"pixelDepth\":\"24\",\"colorDepth\":\"24\",\"canvasGraphFingerPrint\":\"104448240937f45b2ccc629cd5715ee6e\",\"canvasGraph\":\"104448240937f45b2ccc629cd5715ee6e\",\"canvasTextFingerPrintEn\":\"1f4e7253d49f58f5f0cc44483e386e1ac\",\"canvasTextEn\":\"1f4e7253d49f58f5f0cc44483e386e1ac\",\"canvasTextFingerPrintZh\":\"1217ee88e0a133c462ed93349c723313f\",\"canvasTextZh\":\"1217ee88e0a133c462ed93349c723313f\",\"webglGraphFingerPrint\":\"18bb529a12fbb538d8e222a77c7c5498c\",\"webglGraph\":\"18bb529a12fbb538d8e222a77c7c5498c\",\"webglGPUFingerPrint\":\"1b044dae07989c58fdcc978c600d33711\",\"webglGpu\":\"1b044dae07989c58fdcc978c600d33711\",\"cssFontFingerPrintEn\":\"10a344f5534d5b367655c7f90f04de717\",\"fontListEn\":\"10a344f5534d5b367655c7f90f04de717\",\"cssFontFingerPrintZh\":\"16c1334aeae228bca19e18632c8472a52\",\"fontListZh\":\"16c1334aeae228bca19e18632c8472a52\",\"voiceFingerPrint\":\"1dd96cac4e826abdbbe261dc4f3a08292\",\"audioTriangle\":\"1dd96cac4e826abdbbe261dc4f3a08292\",\"nativeFunc\":\"1973dcbb27a04c3a2ee240d9d2549e105\",\"key1\":\"web_f8f6a11a02509dd0e231b3733bc1a307\",\"key2\":1728202167871,\"key3\":\"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36 Edg/129.0.0.0\",\"key4\":\"20030107\",\"key5\":\"zh-CN\",\"key6\":\"Gecko\",\"key7\":2048,\"key8\":1152,\"key9\":2048,\"key10\":1104,\"key11\":360,\"key12\":360,\"key13\":1102,\"key14\":2046,\"key15\":\"00000111\",\"key16\":1,\"key17\":1,\"key18\":[],\"key19\":{},\"key20\":[],\"key21\":{},\"key22\":[],\"key23\":{},\"key24\":[],\"key25\":{},\"key26\":{\"key27\":[\"0,1,32,2,266,prepare1\",\"1,1,40,6,266,prepare1\",\"2,1,48,12,266,prepare1\",\"3,1,56,15,266,prepare1\",\"4,1,64,22,267,prepare1\",\"5,1,77,29,267,prepare1\",\"6,1,82,30,267,prepare1\",\"7,1,176,30,272,prepare1\",\"8,1,185,28,275,prepare1\",\"9,1,192,28,282,prepare1\",\"10,3,560,27,297\",\"11,1,568,27,296,prepare2\",\"12,1,577,28,296,prepare2\",\"13,1,584,34,296,prepare2\",\"14,1,592,37,296,prepare2\",\"15,1,600,41,296,prepare2\",\"16,1,608,47,298,prepare2\",\"17,1,616,59,298,prepare2\",\"18,1,624,74,300,prepare2\",\"19,1,632,88,301,prepare2\",\"20,1,640,103,301,prepare2\",\"21,4,696,114,301\",\"22,2,748,114,301,prepare3\",\"23,1,749,114,301,prepare3\"],\"key28\":[],\"key29\":[],\"key30\":[],\"key31\":{\"prepare1\":\"9,1,192,28,282\",\"prepare2\":\"20,1,640,103,301\",\"prepare3\":\"23,1,749,114,301\"},\"key32\":{},\"key33\":{},\"key34\":{}},\"key35\":\"cd84b9229fa7c7a2e31bbc574fd37c42\",\"key36\":\"f22a94013fc94e90e2af2798023a1985\",\"key37\":1.25,\"key38\":\"not support\",\"key39\":16}"
}
- captchaSn为图片接口返回。
- bgDisWidth为固定值
- bgDisHeight为固定值
- cutDisWidth为固定值
- cutDisHeight为固定值
- relativeX滑动距离
- relativeY为图片接口返回的disY*0.46
- trajectory滑动轨迹,重点,直接影响滑块的成功率
- gpuInfo显卡信息,可固定
- captchaExtraParam浏览器指纹,可模拟
经过我不断的尝试,浏览器指纹可以动态变得有以下几个值:
- ua
- userAgent
- canvasGraphFingerPrint
- canvasGraph
- key1
- key2
- key7-key14 屏幕宽度相关的
其实浏览器指纹直接写死应该问题也不大,但是注册did高并发下可能会影响实际的成功率,因为长时间使用同一指纹请求,会导致指纹短时间内被封,即使是做了本地的指纹库,也会导致指纹短时间用不了,所以上述的几个值还是需要动态变化的,其中canvas指纹一定要动态变化下,关于如何变化,下文会讲,反正比较玄学的。
三、canvas指纹动态模拟。
全局搜索captchaExtraParam,有三位置,找到下图的位置,分析过程和verifyParam差不多,都是异步中加密的。
进度Ga,在进入下面的Ea
Ea中的switch就是关键的加密位置
其中的e[pa("0x65")](ua);就是加密位置,也是异步操作,跟进去ua看看里面是怎么执行的。跟进ua后在跟进oa,由此定位到具体的加密位置
下面分析下oa
function oa() {
return ac(this, void 0, void 0, (function () {
var e;
return ic(this, (function (n) {
switch (n.label) {
case 0:
return [4, ra()]; // ra()生成了所有的加密值
case 1:
return e = n.sent(),
[2, e.reduce((function (e, n) {
var t = n.name
, c = n.hash; // 循环赋值
return e[t] = c,
e
}
), {})]
}
}
))
}
))
}
进入ra,发现是hash中进行了进一步的加密,是个循环,依次对值就行了加密
进入ca,进一步在ta中进行了加密,再次分析就一目了然了。
也就是浏览器画了个图,将图片的base64进行了加密,
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHoAAABuCAYAAADoHgdpAAAAAXNSR0IArs4c6QAAFGZJREFUeF7tXQ2UXVV1/s57M5lMkgnKjySByDDIACqu0gm2tNYMlIJKEEUTGYffCAlo6ZKUGvyjVCuWqrRSWZBBiYokkFoUCUVsMEEWpG1mCDZQkmmZDGsgKSVpIJMfXmbeO33ffe++d+999+ec++599yaZvRYrCe/87HO+u/fZe599zhFIkGS7nIEMugCcDqATQDuAWQCOAtAGYFKZvQMARgHsBLANwDCAQQCbUMAAlj432SiXLXRD4gTj70J2G39Ko02S+Sf/zvolEuW/FzCMjHjS+H/5wrC47sx17VLOyKA+/grAwLAQ/5PgNJeH2UAO5LvlJORwASTOA3A2gFNCdV84AIwRcwC5bcAxAE4EcHK5xWyoVjEGYC2ApwD8K4ChtknAzDZgVhswbVLpz3C0hU0L4FctwKP/KQQ/3IaSaERvskNeAKAHwCcBtGj3aQJbyFUB9mqkCcB7AbxP/TMiuI8AeAyALwJW4DupdEJRrsjhT4vcrRwS4tFQLYSoFBvQhvS+hc8BWKw+5Y4R5EeBAzuDwfUaOCX9TAC/T7VuL0TpvY+zTckNMXGIBnRK+rLJwJ1xS3ksQMsOeVNxTf1zAEdrz6EpvVTJUdFUAB8A8MFSg3cD+D6AXVG1b4LeNQvGB6BPO4o2yXeGhPgb/apqNSIFWp4kL4fELeUVU40DsxQBJrjm2qtXW6n0Q0cCd5wDjJyhVDxcIap0/hduPd9aBOSWl4T4cbjOvWtFArTskCdD4NuQ+Kg2g1TP+4cBAh0T0cS+FcATZvunAfhw2baPqU9DsinhIdZyAfxCAjcOCfFfUbFXN9DyRHkNBP5B28gisG8NA+P0muKjB4tNU8XUfEY02uaV1/D4ui+p8nmnhFHpOQlcv1WIe6Jgry6gZYfkckdjS53iWIM9ev9K2djyZe79AC5SZz9USYLdeTTQNTNM9WVDQlwbpqK1Tiig5QlyJrK4v+wLq/OQ215ah2Om1wF8vuwLK3XVAWBBOUSjVCFkofCAr80DvS8LsT1kz9AGWp4k3wtp+IHqwY4GqWlOAsNl9Om0XSa6YvT0jw07lRr1aKjNbddV51sE8MmXhHheo6dKUS2g5bvk7yKPRyCMMKUa0djay+mPn14AcA2A18J2NR3AZeUgbNg2VOuFkG4JbMsCF/63EM+qdmOWUwbakOQCHtcCuUGq2pTkK+sB2ZwRgs2GGiHZ7JOWucbaTbAzwPm6kq0EdHlNZqRQTV03UFVzrrgmfzqMuvYSC6rxzzRgzTb717fMt+SBs3XWbDWgO+SvlQ0vgrxvS6x+sROfXh3DS1Xn0UAj2I0ifbDXDglxjip7gUBruVANXI/NASq5UKqz4SzXCNfL2qc+2Mquly/Q5WBIn9I8JQAygyFfUmKujkIfa0BQxQm2hs9dXLMXqQRVPIE2wprc2FfZVkwAZIY1GcWML3Bann1G0P4s5nCp8zvUs8i57Xl6ULjUG+iT5MNKsesEQOa8LLLGrusQWKWqjI1fqlQyukIEm762wuYIY+MvCeEb33MFurwL9aNArhMC+SEAfxHIXMQFmDIR566XG7t6YF/ht+vlDnSHZGCJyTneROt6DzV742kugFca3e2R5R32RverbqBtHRKCvoIr1QBdThr4ZiDIDdh5cuOBuyjfavRkm/2dX01eaCgL6mB/0St5wQZ0Of3n1cDMkH2DsW8vuk0k03/OijIzRBctZqosrU1L0m0mVHmC3cNkWV/aMRk4zi0tyQ50h7wBwO2+TTUwrOnk414A3wgaaty/fwTAH8bdiUf7TGLotmYtu5ZbMiTE3zl/cQK92TfMmZDxZTL9J1GGOcNixfAo90CTonmdQZb4liEhTvUEupySu9qT/wSNL/LEQPvVSU2us9/LlaP+0XOstl7Pc6YSVyRadsifAGDY2J0SWpdNZpYUvZuHo5+2cC3+DoD54apGUou+NSXbm+4fEsLm+RtAl42w3Z5RMGZmMoEvIaIRxnz82KNgquNjtOzmhIwyk0eu1d6Jh7nJwHSrUVYC+iT5cUgwDuFOuwdUpyCWco8D+GwsLdfRKHXfu+uoX2/VACtcABe/JMTPzG5KQHfIuwC4J6BRkmPMtVYZ71eLJ/BWqBRsZJlG72y5jc3fCr97SIjrnEC7W9sJW9kmk6mwtp0TnbT1TX78Q6Q261uUj666ZxcmbIBxLMwe4dGpVBIPHoU+YBnRiHwMswIw0zyyKzzdqoQNMHMaUuVWObFJ0s2y8uLtW1fcLALN77I2tp0CaeZYEo1tBwldUrFvJ1/eUl2JfRNoRhavstVNydpMnhhaZhJ5Kol3NVycEs7cpXr5kBALySGBrk38S4k0k8FYEv+iwqbRCYR+fLtLdSWBkEDbLe6EQ53OsaTS4jaZTIPl7b9WVyxvAk3DtnpgPQV+s5X3OUluSwZJPrctY89ODGLC8nutX71jSAh+jobqfssW+kw4CuYcFtO1UhP6dDLHUOhfaQARd9HaaFmumIhg3NhEoAvGJUyklLhU1vl4l3GDVEqJs/bXKePNbpTJISEytUCnTG2TQS2gM3uBzDCQ3Q4UtgKSR3R3AoU3ivb7fqAwBmQEUMgCmSlA5m2AodlmAJgNyNnAOM8Pvl0NvTQCbTfKbEBXVXfK1DZn2191jwOZ54DmzUDTbwHBuHwBGMsDBU09wA+gOQu0ZIFCO5A/Axg7DRjnXVbU0S6UNtVNFu3q26a6S8ZYCtU2+XY1xjK/BZr/DWj5TWkFJ6gEODeuJol+payAs1yhGcifDYydBYy/x14zbcaYyV1VfduMsZJ7lUK1Tb6r7tU40PI00PxoST2blC8Ae7ljHTE5ATdAbwfGLgByTBprKt1YmGRakdeQq+rb5l6VAibM0Y7xZqCwMBgBk5Y1QMs/1jpauXw0UuzFnBvYBuBvA8YWAMed29gTl6qTWFXftoBJKQSawvUZTeuxdPKD+GnG5d6TfWPAOB2GBhDX7laXdfqjs4CLeoFBXk+YMiqpb1sI9CaM7fxmkqlCNVOU2QG0PgBkf+O+qdFIkE3m3MDmuSCma2z7IPDkJcCo/kWJsX0epVQj26bGBdg/vDrpLJLKgJueAqYsq4RJarYp41bXfjPf0lSyyk3iPZO8o5g02gwMfh4YSIl0l9ZpyzYl78zet2l7KtbnlvuAFt6zWyVb4kFchpeqWHHNJtCUbhLvejYCjBYauBAY4I03CVPbJBR6Tq8mHpAdeVq/NFI5EqNdwNQ+IOuehFixvPeUXanE+EQp4MK7u7lz9S8ejIy+H1jJezEUAy8xjIfsrVk8p5LOLeRdG7rxiFiLf4+hN5UmM9uB1tuB7MuepY3kwCRVtpMzSvRnmoCv+wxwtB1YfQMwGuq2QJWZ8y3Dy3u+XpBn8yUBFhSyb+BKvCCXG/cANpoyI8C0vw28NMpI993Ng/0pIUr1fZNgvCPgR6PvAFYvBUZnN5xxpvWeZwN62cBfIi9vwdcARBBYUh4RJXnKN4DM/wZWGcvl8b7ceHp2sehp/bwJ+D2FNx0MsL/cUMnmjeH/UTyQ2Axxi1jcZeyvCXl3//LiAyJXgvGI5wLnPKICXJNv9VXXto72HMCSgkzXkZyFAuhRvISdanzlFxu2ZvOOC+NIrMQPxbVzjDQxIfv610KiG7z0P/LrwD2+i6m3eRperjV259J5yG5eMzDL2AUMJsNAuzG4XAQlKl6fwDqxaI7hAFaB5r/+vpxIHUFnnk24uFC+3XEnan9pTUlFWpE1vt3VBHQpqG9zgIMfA9bRTIqPbM6ADehl/Vsrb0I9DeCf42MCRjCEd7hrEEEm2ABSdxCe0kyp1qF1NwCDvLchHvoyACPts0TDYvEc4y4aIa1Acz5vK175szcGJhjWnMatHs3EIEu4M3VXW4QBmhG01d+NJVxKr329YYQFAc3fucVLfyZqmvo9I3atTY4gSaIJ/c6E/TYNg8w6cMbGV/+p9lQEVTBD75ZyNomuTcX4TvG2vP8Lalbj96b1wJSaazXUGnDxn1Nz/VRYoDlyBlO2RafC6akbkREHiXJ0jKq7FuiNER+PoMp222pUgdoF6FRdKEeDbCBEAKJtBtDTrzIDSmUEUHOhHF3nqntlXaOtTfKiixeV+vAv1PxLoJVmVEjyiG+n4opIU6IH8uHA7r4B6OQ7cPWR2xWRZnzEKtFVq9vaH9/4vKPeaNk4MO2zQIZZmCHJY+85FZe+Wo2xMGC3HQH0MEqlabnbp7Lm0tdKEMzT6nZisYGhvpAAsVrzE0Ar95brIJ8kg8Svce7MAt2WzJMwYHd/Aejk9cHhyHmNswVkNmgxxszImFc/vAoo7M7WtC/YE/nCjMUSMHGrnujF7ASZYFtJF+y22UAPnaJQZLuY3QEyj2V4RMa8+vpBiJvcmgeBVsJQJzGVl+u0D8Vy4lLlpCRj3VynnaQL9rxlwCy+vKxFtqcWakBmU7ZYt7mp4dcHXxUk2DrJCa3fB5p/pcW5Z+GAHLHEHk9Z5PMUtg7YnR8CuhmhVibb4ymuINcAzW1KSD7f6E98TOqHAHgbWSDRCLsCyESUbx2gvskOX9Zq6HNIKnFuVbCN9FzuKgUbZc7nkDxBNjCyblMywyQjmIMXTMy65evaQWA3vwC0RnjMUEF9k/mGPnDmJ83WmVQFe973gFl8wMObnA+c+YNMnMVVYlEXxRNC3rWxHZk8XSw1omTzGXU/Nd66Emiu3GWm1m5QKQWpNiU79icLVaRZF+yu+UCXb/TQ9mRhIMjsv5A9UVx3hnGsRR9o1uKavcrHQIvC2nYCT6nmWq1weC72R0hVpVkHbH/r2/YIqRLITqD570ryQZBUOX93db12AdP1XhpW7lZRqs32lFwv3RsAdZINnAMLUuOLGHt25g/D34XymTwzKmZIdF1AszKDKrz82Qz3RuVWeQ1AMxs00ofCdVW22xj8wLa7WTUPhStLsgFqNY2oCrSOQebGPMOlj5Vj4/XGtlXEWxNsLlK3Wp9P4qFrPpp1lEpn5TJh9p69mvcCu+t6oGsppe8XxejBjda3rLRANpCtGmIWoDUNMq8BUPM884O3sOdx496M2CjkeeiHjgTuOAcY0X3WKEqQzUlxAXtG14W517ruWuR81kgbZMf6XAHakHSvXSxdtM5a/CKe3nUa6P/v0q2sWV5Vsnlg/QPVF26YvKDMXhTqOkCymRnC1wWuPfrkN8Qn1tmOd4QCmQJtOaVhBzoo5q2Kwad6hnBEvgOMldDnpium/Ty7amcAeB6LeWVu1jjtGp55462xjpB0IHsMbc5tUs/y1GDZLMooa89AHpcNjJdCJVNnjolL+ys5xGFBdq7PdqDrXadN7i9ZsAvTHYeOGI7h2Tmu45opY0rzZ1Xl3EzitSO8sl/ttWsjlbjCHgHmRoVOdqcSk6VCRJHmwYXWd5pNNT6tLS96NxvbYaFBdlmfHUBHtE73LDiANmM8tUQx4qw+VT6JGJWkUzQotXMkMKMAvF4Atmkekm8TGOvMYm1XNjb2/qgMrmugk2APCik+PZypC2QXtW0D2viKolDfixYwNSnwXWrjK2Bk4/mi/mKYl7E5vkPIEzpc25mJaobKOTNcZ7l6vaO4wB5fflCREkvprXE9GdSRwHYCzt0vWfo3/zN3m/jnNFH6t4f0xsmeqyA8m5fY8E8/Mk7OhCWHW2U2Y3/3Kgr1rQN02MEcuvUk+lapCYnXHDjcKg+gI1Dffqr70AUoqpHl0LfKZ+8zuBunte0KdN1GABtwM8aC+ZsowRnYjV14YFX40/MeartmjTaA1t3NckL04d4RzB5r/IHgQ+FTeTM7hAdXej4NHDhEy26Vs6z7+9H1GGXnL9yIE/boxp4Cx3BYFNj09hexfhkDtPrkI82uEl2Sao1kBCdLp3xlI+YOTgCtDxXw7DufQv+36YXpk+V2A7fKnhZeaFer/btrcN7T5+pzOlEDD//xAF5bzJc69MiS7elV0RvosFLd+uQmXHZn4IvWeiM5TEqvunoN3jhPX0gCpNlTdZvTGkqqMztHcPV1E8ZYmG+zj4cdNI1uBWkOBjqsBT5heevDPNI8gsfu1xcQBWkOBNowzFTyvp3D6ry5H92bedX2BKnOwMCJazFwm3nhpFqtAEvb2khguC2UXz3l18/j0rsZhZ4g1Rn4ybXPY985WnPmFQXTsrqthY1L56RcrsozxNjLuKaXD1XUFc5T7u/gL5hD34oWzycdXJGzpwoFTUGgRIc2zM5csh5nvBLdkf6gkRzMv288fj023K4+V4oGmJbqrgBdMsy4m9yuNKcTbpbSNBmF7vvcJuyfq+qSVo7Cqnegum9cblE7YjZhfQdjoWttK1rZzo6VVXdFslUP5bHCMfduwMd/mZKbyoPnPJESP/vQBry+UHGOqofmdHnVB5oqPJtfblwrGUQ0yj7VO70mhyyo3uHz+w70rThayQgLsS6HWqNtVrjOen3ssgFc9IR+/PZwAFs9th1qXa4baDZQ9q9VjLNhfKS3BcePJXNDeVo/mDezI3hwpUokbBgFeZV5wXrY4WirbhfJDj5yO3X1ZvT++NSwTB6S9e6/fDP2zguek5DGV93GmLMBZUv83GueQcebf3BIgqY7qKEjnsGae4LnIiKQyV5dEl2xxFUiZ+KVV3HJkmM8c751J+vgLZ/DPbfvgDz+ON8hRAhyZECX1myFrJSjVjyDT/w8+Es+eEEM5nzFJVuw52L/MyQRgxwp0MoG2uG8s7Xu1H4Mfs1vVy8Sw8vta4tEdWu6XsM4f+Guwy6B8OVpG/H4vX65dLGBHLlEV9bsID87s2ME868fM05dHg5kpPHe2QEc6TXauv3koGmMXKLtYBeu8LzDLLP1VSy4qQnT5bFBTB7Uv+8Wr+GBbx0LvNNjGOHDmjrzEhvQVcANI4172bW7XtnBbZj/1ewhCzZBfujmV3DgPW6RwVhVdeR+tMpXVYqieUg3JXv+l3KHnBo31PVtHa6SXGfcWmXOnWX+H0bjc9iR/SIlAAAAAElFTkSuQmCC
进一步进入ta,发现不像是标准的MD5加密,具体是啥加密我也不知道,不管三七二十一,我们扣下加密函数不就行了。
加密方法也不多,几十行就可以解决了。
比较玄学的问题来了,实际上,我在实际动态模拟的过程中发现,使用任何值进行加密,生成的canvas指纹也能用,而且不用上述的加密方法,直接用标准的md5加密也可以使用。
四、遇到的坑点记录
坑点一:
快手滑块主要用于did注册,用于后续的数据采集,did注册用到了几个接口,评论接口、视频列表接口,其中评论接口过了滑块后还会出文字点选或者旋转的验证码,视频列表接口过一次就好了,但是要注意一个坑点,一般出现滑块会有两种响应包,
响应包体一
{
"errors": [
{
"message": "Need captcha",
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"visionConfig"
],
"extensions": {
"code": "GRAPHQL_VALIDATION_FAILED"
}
}
],
"data": {
"visionConfig": null,
"captcha": {
"jsSdkUrl": "//static.yximgs.com/udata/pkg/fe/indentity-verification.umd.f6645615.js",
"url": "https://captcha.zt.kuaishou.com/iframe/index.html?captchaSession=Cgp6dC5jYXB0Y2hhEqYCZJVYpHaI7bzG_s0N4WflPRnJbPOF7x3hMhJQuuMwXPDNYD6caALGzGegytSX_YBiVHnLNIHrRP_DtOhSCMTM7oKux_IcWiq7jwiaZ9i3neVbajc7cSZmn7iWr9PqxhZKXGgiSazo9H6uiQiaiBLDhybMSrr67cSM5XFl2T3V0lrUes_GMRxJnXihIld3fIiAEzp8MQqmdc84437iUmDX8ssggnP95mgbd7NXQ4uB6nrwBJcLWeD9JOTl5fUSyk1wBQOC7CCfagb1VZ4rX4gKdZWjYz1gjYk5ESTfanrjJZABy9GCZMH16AOScw2h4uvR26QgnTV9lU3sEhXwimWLDoRIvkvR6dgWRpiaDP6M-Z_ltfZY0iP9aRFO2OG8Z7dxmaU88gzmGhJxat9v18_vGhz0w0fGzFHTlSooBTAC&type=1&configUrl=https%3A%2F%2Fcaptcha.zt.kuaishou.com%2Frest%2Fzt%2Fcaptcha%2Fsliding%2Fconfig&bizName=ANTICRAWL_COMMON"
}
}
}
响应包体二
{
"data": {
"result": 400002,
"jsSdkUrl": "//static.yximgs.com/udata/pkg/fe/indentity-verification.umd.f6645615.js",
"url": "https://captcha.zt.kuaishou.com/iframe/index.html?captchaSession=Cgp6dC5jYXB0Y2hhEogCL8jHHY-VWZmt8n19baxMNrqgVTpsLwZImMvAtGOERLrA4W0XgZFA4fLl1vh3nkUqZB4qpaj2q7MILVsTOZGavmT0xd0FdxacFndkQwjUDXORDGGPUw0VrVrV-JyzBqnRNSIOqYE6gtZ2dUDuCSoltqjyp3wM9BEbu_hwSOGUkuBOuzJPiBP-ZaG2zAuBTN_xRMWCAqiBXSNn3eG9H2WCyEKESh4cHRzzBErexQiI0p75bb-3pYRuX3L4t6tm1EtWhxaiazc4M-0-r4dpHCE3nO4oDyBbj_vDaoX-RnCMR0tyqDjuZpDiX0AQWX1jWbaYOYVsXs1VtadmWVSKwZtSKBRXrmMh3lgDGhIi_VYjwd6wf-ZmHqT8QvBDmRsoBTAC&type=1&configUrl=https%3A%2F%2Fcaptcha.zt.kuaishou.com%2Frest%2Fzt%2Fcaptcha%2Fsliding%2Fconfig&bizName=ANTICRAWL_DEFAULT"
}
}
上述两种响应包体,只有第一种生成的captchaToken才可以直接使用,第二种即便生成了captchaToken也是需要再次过一遍滑块的。我这边生成did和生成captchaSession的时候,用了sesson请求保持两个请求之间的会话,同时使用了快代理,这样每次请求返回的captchaSession响应体都是第一种情况了,避免了二次过滑块的情况。目前过了滑块后需要用captchaToken去激活did,其中激活之前,需要模拟一下log日志发包,一定要模拟,一定要模拟,一定要模拟,重要的事情说三遍,不模拟did激活不了,用一次后面就无法使用了,这个问题坑死我了。
log日志包接口:https://gdfp.gifshow.com/p/z/s
坑点二:
一直返回350014,除了轨迹的问题之外,就是浏览器指纹被黑了,还是需要动态模拟下canvas指纹的。
五、深度学习
由于最开始的时候使用评论接口注册did,过了滑块之后一直出文字点选和旋转验证码,一气之下,就将文字点选和旋转也都搞定了,识别打码这块也都是自己训练的模型,模型训练这块总体来说难度也不是很大,毕竟都是使用的开源框架进行训练的,没有什么很大的技术含量,这里简单的记录一下吧。
5.1 滑动验证码
直接使用yolov5划分训练集和测试集,大概10:1的一个比例吧,我这边训练集标注了500张左右的图,测试集标注了50多张,总体训练下来识别准确率接近100%了。
5.2 文字点选验证码
文字点选稍微复杂些,主要体现在数据集的准备上,我光准备数据集就花了将近两个星期,因为要上班,都是业余时间准备的,算是比较的费时费力,本来是想着自己慢慢标注的,但是文字这块实在太多,最后还是妥协用了超能力准备了将近2万多个文字单图,简单说下文字点选的处理思路,第一步需要使用yolov5切割下来背景图上的文字,然后将文字与目标文字进行相似度匹配,匹配出点击顺序,所以文字点选这块训练了两个模型,一个yolov5做目标检测,一个孪生神经网络模型做相似度匹配。
yolov5训练集
孪生神经网络模型训练集
使用到的开源模型地址:
- yolov5:GitHub - ultralytics/yolov5: YOLOv5 🚀 in PyTorch > ONNX > CoreML > TFLite
- 孪生神经网路:GitHub - bubbliiiing/Siamese-pytorch: 这是一个孪生神经网络(Siamese network)的库,可进行图片的相似性比较。
5.3 旋转验证码
基本原理就是使用cnn神经网络做角度的预测,快手的原图大概32个,基本思路就是对这32个原图依次进行360度旋转然后丢进框架里面训练,32个原图准备下来的训练集大概11520张。
旋转原图
训练图
使用到的开源模型地址:
GitHub - 8yteDance/RotateCaptcha: 基于CNN的旋转验证码通用解决方案,附带标注系统,适用于小红书、百度、抖音等,速度快误差小,效果非常的棒棒!
六、结语
快手整体的难度不大,我完成verifyParam参数加密不到1天弄完,但是到生产环境中具体应用,前后经历了将近一个月,里面的坑还是比较多的,总体来说收益还是比较大的,模型训练这块也是基本能够略懂一二,包括将训练出的.pt模型转.onnx本地部署使用,过程可以说也是比较艰难,到处百度查资料,真就应验了那句话,“我不是代码的生产者,我只是百度上的搬运工”,那么最后看下我的成果展示吧。
多线程批量注册did
24小时注册使用,根本不成问题,一个did可以使用10来次,生成环境够够的。最近在整ast,有没有志同道合的朋友可以一起交流学习啊,此文发表的时候,刚入行一年半吧(本人科班毕业),很多东西还是不太会,还得继续学,共勉。