|
|
探讨关于整个字节全系的X-bogus和A-bogus。算了直接给代码了:
- import hashlib
- import random
- from time import time
- from urllib.parse import urlencode
- # SM3 哈希(Python 3.11+ 标准库支持;更低版本可装 gmssl 替代)
- def sm3_hex(data: bytes) -> str:
- return hashlib.new('sm3', data).hexdigest()
- def sm3_to_array(data) -> list:
- """把 str/list 做 sm3 后输出 32 字节的 int 列表"""
- if isinstance(data, str):
- b = data.encode('utf-8')
- else:
- b = bytes(data)
- h = sm3_hex(b)
- return [int(h[i:i + 2], 16) for i in range(0, len(h), 2)]
- class ABogus:
- __end_string = "cus"
- __str = {
- "s0": "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
- "s1": "Dkdpgh4ZKsQB80/Mfvw36XI1R25+WUAlEi7NLboqYTOPuzmFjJnryx9HVGcaStCe=",
- "s2": "Dkdpgh4ZKsQB80/Mfvw36XI1R25-WUAlEi7NLboqYTOPuzmFjJnryx9HVGcaStCe=",
- "s3": "ckdp1h4ZKsUB80/Mfvw36XIgR25+WQAlEi7NLboqYTOPuzmFjJnryx9HVGDaStCe",
- "s4": "Dkdpgh2ZmsQB80/MfvV36XI1R45-WUAlEixNLwoqYTOPuzKFjJnry79HbGcaStCe",
- }
- def __init__(self, user_agent: str = "", platform: str = None):
- self.user_agent = user_agent
- self.ua_code = self.generate_ua_code(user_agent)
- self.browser = self.generate_browser_info(platform)
- self.browser_len = len(self.browser)
- self.browser_code = self.char_code_at(self.browser)
- # ---------- UA 指纹 ----------
- def generate_ua_code(self, user_agent: str) -> list:
- numbers = [0.00390625, 1, 14]
- key_string = ''.join(chr(int(num)) for num in numbers)
- return sm3_to_array(self.generate_result(self.rc4_encrypt(user_agent, key_string), "s3"))
- # ---------- 随机列表 ----------
- def list_1(self, a=170, b=85, c=45) -> list:
- return self.random_list(a, b, 1, 2, 5, c & a)
- def list_2(self, a=170, b=85) -> list:
- return self.random_list(a, b, 1, 0, 0, 0)
- def list_3(self, a=170, b=85) -> list:
- return self.random_list(a, b, 1, 0, 5, 0)
- def random_list(self, b=170, c=85, d=0, e=0, f=0, g=0) -> list:
- r = random.random() * 10000
- v = [r, int(r) & 255, int(r) >> 8]
- v.append(v[1] & b | d)
- v.append(v[1] & c | e)
- v.append(v[2] & b | f)
- v.append(v[2] & c | g)
- return v[-4:]
- def from_char_code(self, *args):
- return "".join(chr(code) for code in args)
- def generate_string_1(self):
- return (self.from_char_code(*self.list_1())
- + self.from_char_code(*self.list_2())
- + self.from_char_code(*self.list_3()))
- # ---------- 参数指纹 ----------
- def generate_string_2(self, url_params: str, method="GET") -> str:
- a = self.generate_string_2_list(url_params, method)
- e = self.end_check_num(a)
- a.extend(self.browser_code)
- a.append(e)
- return self.rc4_encrypt(self.from_char_code(*a), "y")
- def generate_string_2_list(self, url_params: str, method="GET") -> list:
- start_time = int(time() * 1000)
- end_time = start_time + random.randint(4, 8)
- params_array = self.generate_params_code(url_params)
- method_array = self.generate_method_code(method)
- return self.list_4(
- (end_time >> 24) & 255,
- params_array[21],
- self.ua_code[23],
- (end_time >> 16) & 255,
- params_array[22],
- self.ua_code[24],
- (end_time >> 8) & 255,
- (end_time >> 0) & 255,
- (start_time >> 24) & 255,
- (start_time >> 16) & 255,
- (start_time >> 8) & 255,
- (start_time >> 0) & 255,
- method_array[21],
- method_array[22],
- int(end_time / 256 / 256 / 256 / 256) >> 0,
- int(start_time / 256 / 256 / 256 / 256) >> 0,
- self.browser_len,
- )
- def list_4(self, a, b, c, d, e, f, g, h, i, j, k, m, n, o, p, q, r) -> list:
- return [
- 44, a, 0, 0, 0, 0, 24, b, n, 0, c, d, 0, 0, 0, 1, 0, 239, e, o, f, g, 0, 0,
- 0, 0, h, 0, 0, 14, i, j, 0, k, m, 3, p, 1, q, 1, r, 0, 0, 0]
- def end_check_num(self, a: list):
- r = 0
- for i in a:
- r ^= i
- return r
- # ---------- base64 变体 ----------
- def generate_result(self, s, e="s4"):
- r = []
- for i in range(0, len(s), 3):
- if i + 2 < len(s):
- n = (ord(s[i]) << 16) | (ord(s[i + 1]) << 8) | ord(s[i + 2])
- elif i + 1 < len(s):
- n = (ord(s[i]) << 16) | (ord(s[i + 1]) << 8)
- else:
- n = ord(s[i]) << 16
- for j, k in zip(range(18, -1, -6), (0xFC0000, 0x03F000, 0x0FC0, 0x3F)):
- if j == 6 and i + 1 >= len(s):
- break
- if j == 0 and i + 2 >= len(s):
- break
- r.append(self.__str[e][(n & k) >> j])
- r.append("=" * ((4 - len(r) % 4) % 4))
- return "".join(r)
- def generate_method_code(self, method: str = "GET") -> list:
- return sm3_to_array(sm3_to_array(method + self.__end_string))
- def generate_params_code(self, params: str) -> list:
- return sm3_to_array(sm3_to_array(params + self.__end_string))
- # ---------- 浏览器指纹 ----------
- def generate_browser_info(self, platform: str = "Win32") -> str:
- inner_width = random.randint(1280, 1920)
- inner_height = random.randint(720, 1080)
- outer_width = random.randint(inner_width, 1920)
- outer_height = random.randint(inner_height, 1080)
- screen_x = 0
- screen_y = random.choice((0, 30))
- value_list = [
- inner_width, inner_height, outer_width, outer_height,
- screen_x, screen_y, 0, 0,
- outer_width, outer_height, outer_width, outer_height,
- inner_width, inner_height, 24, 24, platform,
- ]
- return "|".join(str(i) for i in value_list)
- def char_code_at(self, s):
- return [ord(char) for char in s]
- # ---------- rc4 ----------
- def rc4_encrypt(self, plaintext, key):
- s = list(range(256))
- j = 0
- for i in range(256):
- j = (j + s[i] + ord(key[i % len(key)])) % 256
- s[i], s[j] = s[j], s[i]
- i = 0
- j = 0
- cipher = []
- for k in range(len(plaintext)):
- i = (i + 1) % 256
- j = (j + s[i]) % 256
- s[i], s[j] = s[j], s[i]
- t = (s[i] + s[j]) % 256
- cipher.append(chr(s[t] ^ ord(plaintext[k])))
- return ''.join(cipher)
- # ---------- 对外接口 ----------
- def generate_a_bogus(self, url_params: dict | str) -> str:
- if isinstance(url_params, dict):
- url_params = urlencode(url_params)
- string_1 = self.generate_string_1()
- string_2 = self.generate_string_2(url_params)
- string = string_1 + string_2
- return self.generate_result(string, "s4")
- if __name__ == "__main__":
- bogus = ABogus("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36")
- print(bogus.generate_a_bogus({"aweme_id": "7400044629845970202", "cursor": "0", "count": "20"}))
复制代码 这是X-bogus:
- import hashlib
- import random
- def rc4_bytes(key: bytes, data: bytes) -> bytes:
- S = list(range(256))
- j = 0
- for i in range(256):
- j = (j + S[i] + key[i % len(key)]) % 256
- S[i], S[j] = S[j], S[i]
- i = j = 0
- result = bytearray()
- for byte in data:
- i = (i + 1) % 256
- j = (j + S[i]) % 256
- S[i], S[j] = S[j], S[i]
- k = S[(S[i] + S[j]) % 256]
- result.append(byte ^ k)
- return bytes(result).decode('iso-8859-1')
- qlist = {'bogusIndex': 0, 'envcode': 1}
- ucode = {'ubcode': 0}
- def action_valid():
- bits = [random.getrandbits(1) for _ in range(8)]
- ucode['ubcode'] = bits[0] | bits[1] | bits[2] | bits[3] | bits[4] | bits[5] | bits[6] | bits[7]
- ucode['ubcode'] &= ~126
- def xbogus_fun(protocol, revent_flag, arg3, in_salt, data):
- """生成 X-Bogus。data 是 query 字符串的 md5 字节"""
- action_valid()
- in_salt = in_salt or ''
- in_salt_md5 = hashlib.md5(in_salt.encode('utf-8')).digest()
- if data is None:
- data = b'00000000000000000000000000000000'
- uArray = bytearray(9)
- pad_string = (protocol << 6) | (revent_flag << 5) | ((int(random.random() * 100) & 1) << 4) | 0
- qlist['bogusIndex'] += 1
- bogusIndex = qlist['bogusIndex'] & 0x3f
- uArray[0] = (arg3 << 6) | bogusIndex
- uArray[1] = (qlist['envcode'] >> 8) & 255
- uArray[2] = qlist['envcode'] & 255
- uArray[3] = ucode['ubcode']
- in_salt_md5_md5 = hashlib.md5(in_salt_md5).digest()
- uArray[4] = in_salt_md5_md5[14]
- uArray[5] = in_salt_md5_md5[15]
- data_md5 = hashlib.md5(data).digest()
- uArray[6] = data_md5[14]
- uArray[7] = data_md5[15]
- uArray[8] = int(random.random() * 255) & 255
- return xcrypto(pad_string, uArray)
- def xcrypto(pad_string, ostring):
- length = len(ostring)
- uarray = bytearray(length + 1)
- ieor = 0
- for i in range(length):
- uarray[i] = ostring[i]
- ieor ^= ostring[i]
- uarray[length] = ieor
- random_key = random.randint(0, 255)
- crypted_text = rc4_bytes(bytes([random_key]), bytes(uarray))
- result = chr(pad_string) + chr(random_key) + crypted_text
- return dy_base64(result, 's1')
- def dy_base64(data: str, mindex: str, pad: str = "=") -> str:
- letters = {
- "s1": "Dkdpgh4ZKsQB80/Mfvw36XI1R25+WUAlEi7NLboqYTOPuzmFjJnryx9HVGcaStCe=",
- "s4": "Dkdpgh2ZmsQB80/MfvV36XI1R45-WUAlEixNLwoqYTOPuzKFjJnry79HbGcaStCe",
- }
- ua_table = letters[mindex]
- data_bytes = data.encode('iso-8859-1')
- out = ""
- i = 0
- while i < len(data_bytes):
- c1 = data_bytes[i]; i += 1
- c2 = data_bytes[i] if i < len(data_bytes) else None; i += 1
- c3 = data_bytes[i] if i < len(data_bytes) else None; i += 1
- combined = ((c1 & 0xff) << 16) | ((c2 & 0xff) << 8 if c2 is not None else 0) | (c3 & 0xff if c3 is not None else 0)
- out += ua_table[(combined >> 18) & 0x3f]
- out += ua_table[(combined >> 12) & 0x3f]
- out += ua_table[(combined >> 6) & 0x3f] if c2 is not None else pad
- out += ua_table[combined & 0x3f] if c3 is not None else pad
- return out
- def generate(params: dict) -> str:
- """便捷接口:传入参数字典,返回 X-Bogus"""
- query = '&'.join(f'{k}={v}' for k, v in params.items())
- data_md5 = hashlib.md5(query.encode()).digest()
- return xbogus_fun(1, False, 0, None, data_md5)
- if __name__ == "__main__":
- print(generate({'device_platform': 'android', 'aid': '6383', 'count': '1'}))
复制代码
|
|