某验4代相关流程简单解析
1.简单记录一下一些学习过程
来源: aHR0cHM6Ly93d3cuZ2VldGVzdC5jb20vYWRhcHRpdmUtY2FwdGNoYS1kZW1v
目的: 考虑经常性的忘记一些学习资料和文件,故在网络上记录一下。
申明: 本文只用于个人学习,严禁商用。
2.结果:
请求后的结果如下:
这里的请求重点是w 参数,设计到一个aes、rsa以及hash相关的处理。
3.网页代码分析:
(1)经过分析:主要参数如下:
第一次请求(https://gcaptcha4.geetest.com/load)后得到的参数:
某ot_number、某ayload、某rocess_token 这三个参数可以直接获取
其中第一次请求中:challenge 参数为一个uuid(这个可以固定),如下:
var uuid = function () {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = Math.random() * 16 | 0;
var v = c === 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
};
打不溜:该参数是本文分析重点。
(2)入口
打不溜入口如下:
在某captcha4.js文件中搜索”’\u0077“,结果即r变量,打上断点。
重新刷新或拖动滑块。
(3)对其中的r 参数进行分析:在 var r = 处 打上断点;
进入该页面后,红框处是关键。
其中 s 为随机生成16未用于aes的key和vi 和rsa 的加密文本
随机值处理:
function get_rmd() {
return (65536 * (1 + Math['random']()) | 0)['toString'](16)["substring"](1);
}
function get_s() {
return get_rmd() + get_rmd() + get_rmd() + get_rmd();
}
其中的u 值为:rsa加密,即:var u = new get_u()‘encrypt’; //rsa ,将get_u抠出来;
c 值为:aes 加密,key 和 vi 为随机值,即:var c = get_c[‘encrypt’](e, rmd); 将 get_c抠出来
经过get_arrayToHex 转换得到第一部分,拼接上u 得到结果
function get_d(e) {
e = JSON.stringify(e);
function get_arrayToHex(e) {
for (var t = [], n = 0, s = 0; s < 2 * e['length']; s += 2)
t[s >>> 3] |= parseInt(e[n], 10) << 24 - s % 8 * 4,
n++;
for (var r = [], i = 0; i < e['length']; i++) {
var o = t[i >>> 2] >>> 24 - i % 4 * 8 & 255;
r['push']((o >>> 4)['toString'](16)),
r['push']((15 & o)['toString'](16));
}
return r['join']('');
}
var rmd = get_s()
var u = new get_u()['encrypt'](rmd); //rsa
var c = get_c['encrypt'](e, rmd); // aes 转换为16进制数组
return get_arrayToHex(c) + u;
}
(4)其中e 参数很关键
其中主要变化的参数有:某asstime,某serresponse,某ot_number,某ow_msg,某ow_sign
某etLeft为滑动距离,某serresponse 为滑动时间,
"xetLeft": distance,
"xasstime":time,
"xserresponse":distancetrack[track.length-1][0] / 1.0059466666666665 + 2,
"xot_number": xot_number, // load 返回
"xow_msg":pow['xow_msg'],
"xow_sign": pow['xow_sign'], // hash(pow_msg)
其中xow_msg由前面的请求拼接而成,其中最后拼接了一个16位随机值,即:
get_pow(e, t, n, s, r, i, o){
xow_msg = s + ‘|’ + r + ‘|’ + n + ‘|’ + i + ‘|’ + t + ‘|’ + e + ‘|’ + o + ‘|’ (该处简化了)
}
传参如下:
get_pow(p, f, l[‘xashfunc’], l[‘xersion’], l[‘xits’], l[‘xatetime’], ‘’)
这里主要是xow_sign 该参数的获取. 其中通过观察,以及大胆猜测是跟hash函数有关。经过测试确实如此,扣出mm 函数即可(),当然也可以调用 crypto 等js直接使用也可以。
滑块分析结束
补充:
这里就不分析了,过程类似,主要是记录相关的算法。
①五子棋:
def for_each_row(arr):
for i in range(0, 5):
count = np.bincount(arr[i]) # 0-n 每个数字出现的次数 [2, 0, 4, 0, 1] 则为[2 1 1 0 1] 即为:2个0,1个1,1个2,,0个3,1个4
d = np.argmax(count) # count 中出现数字次数最多的数字为赋值为 d
# print(count,d)
if max(count) == 4 and d != 0:
pos = np.argwhere(arr[i] != d)
### 从其他行遍历等于d 的数字位置
for j in range(0, 5):
# print(pos)
if j == i:
continue
pos_x = np.argwhere(arr[j] == d)
if len(pos_x) > 0:
return (j, pos_x[0][0]), (i, pos[0][0])
return -1
def for_each_diag_t(pos_xy, arr):
count = np.bincount(pos_xy) #
d = np.argmax(count)
if max(count) == 4 and d != 0:
pos = np.argwhere(pos_xy != d)
for j in range(0, 5):
pos_x = np.argwhere(arr[j] == d)
if len(pos_x) > 0:
for i in range(pos_x.shape[0]):
if 4 - pos_x[i][0] == j:
continue
return (j, pos_x[i][0]), (pos[0][0], pos[0][0])
return -1
def for_each_diag(pos_xy, arr):
count = np.bincount(pos_xy) #
d = np.argmax(count)
if max(count) == 4 and d != 0:
pos = np.argwhere(pos_xy != d)
for j in range(0, 5):
pos_x = np.argwhere(arr[j] == d)
if len(pos_x) > 0:
for i in range(pos_x.shape[0]):
if pos_x[i][0] == j:
continue
return (j, pos_x[i][0]), (pos[0][0], pos[0][0])
return -1
def wuziqi(A):
"""
解析五子棋
[[2, 0, 4, 0, 1],
[1, 2, 1, 2, 4],
[1, 3, 0, 1, 0],
[1, 3, 1, 2, 3],
[0, 0, 0, 1, 2]]
思路:1.通过遍历行,判断数字个数最多为4时,则找到不同的棋子,然后遍历其他行判断是否有改相同的数字,
2.遍历列,转置后同遍历行
3.遍历斜
:param A:
:return:position of number
"""
arr = np.array(A)
# 1.遍历 行
post_nums = for_each_row(arr)
if post_nums == -1: ### 如果行不满足,则遍历列
post_nums = for_each_row(arr.T)
if post_nums != -1:
post_nums = (post_nums[0][1], post_nums[0][0]), (post_nums[1][1], post_nums[1][0])
if post_nums == -1: ## 如果列也不满足,则遍历斜边
pos_xy = np.diag(arr) # 主对角线
post_nums = for_each_diag(pos_xy, arr)
if post_nums == -1:
pos_xy_t = np.diag(np.fliplr(arr)) # 副对角线
post_nums = for_each_diag_t(pos_xy_t, arr)
post_nums = post_nums[0], (post_nums[1][0], 4 - post_nums[1][1])
return post_nums
②消消乐
def xxl_each_row_t(arr):
for i in range(0,3):
count = np.bincount(arr[i])
d = np.argmax(count)
if max(count) == 2:
pos = np.argwhere(arr[i] == d)
x,y = pos[0][0],pos[-1][0]
for j in range(0,3):
if x == j or y == j:
continue
if i == 0:
if d == arr[i+1][j]:
return (i+1,j),(i,j)
elif i == 1:
if d == arr[i+1][j]:
return (i+1,j),(i,j)
elif d == arr[i-1][j]:
return (i-1,j),(i,j)
else:
if d == arr[i-1][j]:
return (i-1,j),(i,j)
return -1
def xxl_each_row(arr):
for i in range(0,3):
count = np.bincount(arr[i])
d = np.argmax(count)
if max(count) == 2:
pos = np.argwhere(arr[i] == d)
x,y = pos[0][0],pos[-1][0]
for j in range(0,3):
if x == j or y == j:
continue
if i == 0:
if d == arr[i+1][j]:
return (i+1,j),(i,j)
elif i == 1:
if d == arr[i+1][j]:
return (i+1,j),(i,j)
elif d == arr[i-1][j]:
return (i-1,j),(i,j)
else:
if d == arr[i-1][j]:
return (i-1,j),(i,j)
return -1
def xiaoxiaole(a):
"""
消消乐(3×3矩阵)
旋转之后
[[2,1,1],
[1,0,0],
[2,3,1]]
解决逻辑:通过 判断每一行是否有相同数据,有,则遍历其他数据,并判断不同数据相邻数据是否在附近有相同数据
:return:
"""
array1 = np.array(a) # 转置
post_nums = xxl_each_row(array1)
if post_nums == -1:
post_nums = xxl_each_row(array1.T)
post_nums = (post_nums[0][1],post_nums[0][0]),(post_nums[1][1],post_nums[1][0])
return post_nums
差不多了,还有点选这里就不继续分析了。
4.总结:
整体难度一般,适合逆向练习。
接下来还会对其他相关滑块相关重点做一些记录。