入口analysis_rucan,仅做学习用 转载需声明出处
import re,base64,random
from pyDes import des, ECB
import time
# 表示小红书
organization = 'eR46sBuqF0fdw7KWFLYa'
# 处理数组2
# end_index = _0x1d4270/_0x598a9e 处理数组的最后长度除以2
# 以下就是按规律让数组按中数左右交换
# _0x225836 = arg[循环的下标]
# arg[循环的下标] = arg[(_0x1d4270固定值=1256-循环的下标)-固定值_0x4c0588=1]
# arg[_0x1d4270固定值=1256-循环的下标-固定值_0x4c0588=1] = _0x225836
def change_array(array_orign,array_rucan):
n = 1256
v = array_orign
for i in range(n // 2):
v[i], v[n - 1 - i] = v[n - 1 - i], v[i]
return array_orign
# 以下是直接翻译js
# end_index = array_orign[array_rucan.index('_0x1d4270')]
# stable_jianshu = array_orign[array_rucan.index('_0x4c0588')]
# stable_chushu = array_orign[array_rucan.index('_0x598a9e')]
#
#
# for_index = int(end_index/stable_chushu)
#
# for i in range(for_index):
# _0x225836 = array_orign[i]
# array_orign[i] = array_orign[end_index-i-stable_jianshu]
# array_orign[end_index - i - stable_jianshu] = _0x225836
# return array_orign
# 对数组进行移位 处理1
# 前后颠倒
def offset(array_orign,index):
array_result = array_orign[index:] + array_orign[:index]
return array_result
# 按逗号分割,因为字符串里难保有逗号的,所以不能用split函数
def split_args(s):
"""
分割js参数
"""
r = []
a = ''
i = 0
while i < len(s):
c = s[i]
if c == ',' and (a[0] != '\'' or len(a) >= 2 and a[-1] == '\''):
r.append(a)
a = ''
elif c:
a += c
i += 1
r.append(a)
return r
# 加密
def get_encrypt_content(message, key, flag):
"""
接口参数的加密、解密
"""
des_obj = des(key.encode(), mode=ECB)
if flag:
content = pad(str(message).replace(' ', '').encode())
return base64.b64encode(des_obj.encrypt(content)).decode('utf-8')
else:
return des_obj.decrypt(base64.b64decode(message)).decode('utf-8')
# 加密之前填充位
def pad(b):
"""
块填充
"""
block_size = 8
while len(b) % block_size:
b += b'\0'
return b
#解析js入参
#script:captcha-sdk.min.js的内容
def analysis_rucan(script):
# js尾巴上的执行传参
tail = script.split(';}(')
rucan = split_args(tail[-1][0:-4])
# js最开头的base64的大数组
# a是移位的起点位置
a = re.findall(r'}\((.*?)\)\);', script)[0].split(',')[1]
# 先根据;分割 再根据中括号分割
first_array = script.split(';')[0]
array_base64 = first_array[first_array.index('[') + 1:-1].split(',')
# 先移位
array_base64 = offset(array_base64, int(a, 16))
# js自执行函数的入参
paras = re.findall(r'function\((.*?)\)', script)
para = getRelPara(paras)
result_array = []
len_para = len(para)
for i, r in enumerate(rucan):
r_10 = None
# 如果包含 () 则 获取变量 16进制转换成下标
if r.__contains__('(') and r.__contains__(')'):
r_16 = r[r.index('(') + 2:r.index(')') - 1]
# print('test:{},{}'.format(r,r_16))
if re.match('^0[xX][A-Fa-f0-9]+$', r_16):
r_10 = int(r_16, 16)
# 找到base 64 数组 ,解码 并赋值到para
if r_10:
first_decode = base64.b64decode(array_base64[r_10])
if not (str(first_decode).__contains__('+') or str(first_decode).__contains__('|')):
result_array.append((str(first_decode, 'utf8'))[::-1])
else:
result_array.append(first_decode)
else:
if i > len_para - 1:
break
if '' == r:
result_array.append(r)
elif re.match('^0[xX][A-Fa-f0-9]+$', r):
result_array.append(int(r, 16))
else:
result_array.append(r[::-1])
result_array = change_array(result_array, para)
return result_array