算法暴露接口(xhs、dy、ks、wx、hnw)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

227 lines
8.0 KiB

import hashlib, time, random
from functools import reduce
def hash_sm3(data):
sm3 = hashlib.new("sm3")
if isinstance(data, str):
sm3.update(data.encode("utf-8"))
else:
sm3.update(data)
return sm3.hexdigest()
def get_array(timestamp):
array1 = [0] * 4
array1[0] = (timestamp >> 24) & 255
array1[1] = (timestamp >> 16) & 255
array1[2] = (timestamp >> 8) & 255
array1[3] = (timestamp >> 0) & 255
return array1
def deal(orginalString, target, step=20):
"""
计算最后一部 获得最终的数据
"""
result = ""
for i in range(0, len(orginalString), 3):
if i > step:
break
M0 = orginalString[i]
if i >= len(orginalString) - 1:
M1 = M2 = 0
else:
M1 = orginalString[i + 1]
M2 = orginalString[i + 2]
baseNum = (M0 << 16) | (M1 << 8) | M2
num1 = target[(16515072 & baseNum) >> 18]
num2 = target[(258048 & baseNum) >> 12]
if i >= len(orginalString) - 1:
num3 = num4 = target[-1]
else:
num3 = target[(4032 & baseNum) >> 6]
num4 = target[63 & baseNum]
tmpNum = num1 + num2 + num3 + num4
result += tmpNum
return result
def get_fn(code):
fn = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255]
j = 0
for i in range(len(fn)):
j = (j + fn[i] + ord(code[i % 3])) % 256
tmp = fn[i]
fn[i], fn[j] = fn[j], tmp # 替换
return fn
def deal1(orginalString, fn):
"""
计算数组
"""
tmp1 = 0
F_array = []
for i in range(len(orginalString)):
j = (tmp1 + fn[i + 1]) % 256
tmp2 = fn[j]
tmp1 = fn[i + 1]
fn[i + 1], fn[j] = tmp2, tmp1
# print(f"ua_code: {ua_code[i]} ^ {fn[(tmp1 + tmp2) % 256]}")
F_array.append(orginalString[i] ^ fn[(tmp1 + tmp2) % 256])
tmp1 = j
return F_array
def get_ua_code(o_string, ua, code):
"""
o_string: '\u0000\u0001\u000e'
"""
fn = get_fn(o_string) # 获得256变换后的数组
ua_code = [ord(i) for i in ua] # 需要配合计算的数组
F_array = deal1(ua_code, fn)
ua_base = deal(F_array, code, 117)
return ua_base
def get_head(shift_list):
"""
获取编码头
"""
random_code = int(random.random() * 10000)
tmp_num1 = random_code & 255
tmp_num2 = (random_code >> 8) & 255
tmp = shift_list[0] & 85
num1 = (tmp_num1 & 170) | tmp
tmp2 = shift_list[0] & 170
num2 = (tmp_num1 & 85) | tmp2
tmp3 = shift_list[1] & 85
num3 = (tmp_num2 & 170) | tmp3
tmp4 = shift_list[1] & 170
num4 = (tmp_num2 & 85) | tmp4
return [num1, num2, num3, num4]
def get_original(o_string, originalString, code):
fn = get_fn(o_string)
# print(f"fn => {len(fn)} {str(fn).replace(' ', '')}")
original_string1 = deal1(originalString, fn)
# print(f"original_string1 {len(original_string1)}=> {len(original_string1)} {str(original_string1).replace(' ', '')}")
original_string = []
# 这下面仨字符固定了 TODO: 可能是随机的 每次都不一样
a1 = get_head([3, 45]) # header1
a2 = get_head([1, 0]) # header2
a3 = get_head([1, 5]) # header3
original_string.extend(a1)
original_string.extend(a2)
original_string.extend(a3)
# print(f"original_string => {original_string}")
# code = "Dkdpgh2ZmsQB80/MfvV36XI1R45-WUAlEixNLwoqYTOPuzKFjJnry79HbGcaStCe="
#
original_string.extend(original_string1)
a_bogus = deal(original_string, code, 124)
return a_bogus
def get_h2(env="1440|150|1440|900|0|0|0|0|1440|900|1440|900|1440|150|24|24|MacIntel"):
"""
涉及环境变量 固定可
"""
return [ord(i) for i in env]
def exchange_array(array1, array2, array3, array4, array5, array6, array7):
h1 = [44, array1[0], array2[0], 0, 0, 0, array3[1], array4[21], array5[21], array2[1], array6[23], array1[1],
0, array2[2], array2[3], 1, 0, array3[0], array4[22], array5[22], array6[24], array1[2], 0, 0, array3[2],
0, array1[3], 0, 0, 14, array7[0], array7[1], array3[2], array7[2], array7[3], 3, 400, 1, 400, 1, 67,
0, 0, 0]
return h1
def main(params, ua, timestamp1, timestamp2, base_key):
P = lambda x: [int(x[i:i + 2], 16) for i in range(0, len(x), 2)]
tags = "cus"
pageId = 6241
aid = 6383
array1 = get_array(timestamp1) # 后面计算时候的时间戳
# print(f"array1 => {str(array1).replace(' ', '')}")
array2 = get_array(pageId) # pageId
# print(f"array2 => {str(array2).replace(' ', '')}")
array3 = get_array(aid)[::-1] # aid
# print(f"array3 => {str(array3).replace(' ', '')}")
array4 = P(hash_sm3(bytes.fromhex(hash_sm3(params + tags)))) # 参数加上 "cus"进行二次加密
# print(f"array4 => {str(array4).replace(' ', '')}")
array5 = P(hash_sm3(bytes.fromhex(hash_sm3(tags)))) # cus两次加密结果数组
# print(f"array5 => {str(array5).replace(' ', '')}")
# code = "ckdp1h4ZKsUB80/Mfvw36XIgR25+WQAlEi7NLboqYTOPuzmFjJnryx9HVGDaStCe"
array6 = P(hash_sm3(get_ua_code("\u0000\u0001\u000e", ua, base_key["a1"]))) # 计算请求头的数组
# print(f"array6 => {str(array6).replace(' ', '')}")
array7 = get_array(timestamp2) # 加载时间戳
# print(f"array7 => {str(array7).replace(' ', '')}")
h1 = exchange_array(array1, array2, array3, array4, array5, array6, array7) # 整合所有数组
# print(f"h1 => {str(h1).replace(' ', '')}")
h2 = get_h2() # 获取上半段数据
# print(f"h2 => {str(h2).replace(' ', '')}")
h3 = reduce(lambda x, y: int(x) ^ int(y), h1)
# print(f"h3 => {str(h3).replace(' ', '')}")
h = []
h.extend(h1)
h.extend(h2)
h.append(h3)
# print(f"h => {len(h)} {str(h).replace(' ', '')}")
a_bogus = get_original("yyy", h, base_key["a2"])
# print(f" a_bogus {len(a_bogus)}=> {a_bogus}")
return a_bogus
def run(params, ua):
base_key = {
"a1": "ckdp1h4ZKsUB80/Mfvw36XIgR25+WQAlEi7NLboqYTOPuzmFjJnryx9HVGDaStCe",
"a2": "Dkdpgh2ZmsQB80/MfvV36XI1R45-WUAlEixNLwoqYTOPuzKFjJnry79HbGcaStCe="
}
timestamp1 = 1718786088339 # 后者
timestamp2 = 1718786087904 # js加载时间
timestamp2 = int(time.time() * 1000)
tmp = random.randint(300, 600)
timestamp1 = timestamp2 + tmp
return main(params, ua, timestamp1, timestamp2, base_key)
if __name__ == '__main__':
params = "device_platform=webapp&aid=6383&channel=channel_pc_web&aweme_id=7123849705431272712&update_version_code=170400&pc_client_type=1&version_code=190500&version_name=19.5.0&cookie_enabled=true&screen_width=1440&screen_height=900&browser_language=zh-CN&browser_platform=MacIntel&browser_name=Chrome&browser_version=125.0.0.0&browser_online=true&engine_name=Blink&engine_version=125.0.0.0&os_name=Mac+OS&os_version=10.15.7&cpu_core_num=2&device_memory=8&platform=PC&downlink=10&effective_type=4g&round_trip_time=50&webid=7382044487177143862&msToken=Ru8XaSvg7YcHk135aj68vgAK247SND6YxUW8KgdHWeRJHk_On01S3Acja3fqH4INQjtIwnpz-FDy9BtVQ_qO_MeIkErjRima9r6t461khRCmTXZcHs7NMRrj7pC43w%3D%3D"
ua = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"
a_bogus = run(params, ua)