开始
目标
aHR0cHM6Ly93d3cuY2hkdHAuY29tL2hkc2Mv
获取首页html源码信息
1、请求
请求后,发现第一次请求会返回一个461,并且set两个cookie BIGipServerpool_web
L36AgdkajqEqbLBH3
经过js混淆生成cookie T89MlEJgG337C6knS
后再次请求。
2、逆向思路
既然已经得知是CK加密。我们只需要 hook set_cookie的地方即可,用插件,或者油猴脚本即可快速断点
提供一个 油猴插件 拦截
// ==UserScript==
// @name 拦截并调试 set_cookie
// @namespace http://tampermonkey.net/
// @version 0.1
// @description 在 https://www.chdtp.com/hdsc/ 中拦截并调试 set_cookie
// @author ZHY
// @match https://www.chdtp.com/hdsc/
// @grant none
// ==/UserScript==
(function() {
'use strict';
// 重写 document.cookie 的 getter 和 setter
const originalCookieSetter = Object.getOwnPropertyDescriptor(document, 'cookie').set;
Object.defineProperty(document, 'cookie', {
set: function(value) {
// 打印出被设置的 cookie 值
console.log('拦截到 set_cookie:', value);
// 触发调试器暂停脚本执行,进入调试模式
debugger; // 调试暂停,方便调试时查看 cookie 内容
// 这里可以根据需要调整是否允许设置 cookie
// 如果想要正常运行,可以调用原始的 setter
originalCookieSetter.call(document, value);
}
});
})();
set_cookie
主要加密函数
简单跟栈后就发现了这个网站的加密地方,加密方法也很简单。加密思路
浏览器环境校验 加密 + 随机字符串 + |符号 + 一个时间戳 除了时间戳其他所有参数可以写死。
3、一些发现
注意:浏览器环境校验大部分校验了一些不痛不痒的参数,但是还校验了 Canvas。也叫 Canvas指纹。每个内核不同的浏览器生成的 Canvas 的图片都是不一样的。所以我们如果写死这个地方,ua也需要同步写死。(但是此网站并没有强校验 canvas 和ua的关系)
4、部分代码
# !/usr/bin/env python
# -*- coding: UTF-8 -*-
# @project :爬虫
# @author :zhy
# @date :2024-12-26 17:16
import hashlib
import time
import requests
import base64
import binascii
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
headers = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
'Accept-Encoding': 'gzip, deflate, br, zstd',
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
'Host': 'www.chdtp.com.cn',
'Pragma': 'no-cache',
'Referer': 'https://www.chdtp.com.cn/hdsc/',
'Sec-Fetch-Dest': 'document',
'Sec-Fetch-Mode': 'navigate',
'Sec-Fetch-Site': 'same-origin',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
# 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 Edg/128.0.0.0',
'sec-ch-ua': '"Chromium";v="128", "Not;A=Brand";v="24", "Microsoft Edge";v="128"',
'sec-ch-ua-platform': '"Windows"',
}
def cookie_string_to_dict(cookie_string):
# 将字符串按'; '分割成单独的cookie项
cookie_items = cookie_string.split('; ')
cookie_dict = {}
print(cookie_items)
for item in cookie_items:
# 检查是否包含'=',以确保它是一个键值对
if '=' in item:
key, value = item.split('=', 1) # 分割一次,以处理值中可能包含'='的情况
cookie_dict[key.strip()] = value.strip()
return cookie_dict
def get_req(url, headers, cookies = None):
if cookies is None:
cookies = {}
rsp = requests.get(url, headers=headers, cookies = cookies)
return rsp.status_code, rsp
def first_get_index():
INDEX_URL = 'https://www.chdtp.com.cn/hdsc/'
code, rsp = get_req(INDEX_URL, headers)
set_cookie = rsp.headers['Set-Cookie']
BIGipServerpool_web = set_cookie.split('BIGipServerpool_web=')[-1].split(';')[0]
L36AgdkajqEqbLBH3 = set_cookie.split('L36AgdkajqEqbLBH3=')[-1].split(';')[0]
return {
"L36AgdkajqEqbLBH3": L36AgdkajqEqbLBH3,
"BIGipServerpool_web": BIGipServerpool_web
}
def get_index(cookie):
INDEX_URL = 'https://www.chdtp.com.cn/hdsc/'
code, rsp = get_req(INDEX_URL, headers, cookies=cookie)
print(code, rsp.text)
def get_script_js(cookies):
SCRIPT_URL = 'https://www.chdtp.com.cn/45i5xfip730ih5uh/sgodapt2y.js?t=1735052919'
code, rsp = get_req(SCRIPT_URL, headers, cookies = cookies)
class AESUtil(object):
config = {
'ECB': 1,
'CBC': 2,
'CFB': 3,
'OFB': 5,
'CTR': 6,
'OPENPGP': 7,
'CCM': 8,
'EAX': 9,
'SIV': 10,
'GCM': 11,
'OCB': 12
}
@classmethod
def encrypt(cls, text, key, iv = None, encoding = 'b64', mode = 'ECB', padding = 'pkcs7'):
key = key.encode() # 秘钥,b就是表示为bytes类型
iv = iv.encode()
text = text.encode()
if padding:
text = pad(text, AES.block_size, style = 'pkcs7') # 选择pkcs7补全
aes = AES.new(key, mode = cls.config[mode], iv = iv) # 创建一个aes对象
encrypt_aes = aes.encrypt(text)
if encoding == 'b64':
encrypted_text = str(base64.encodebytes(encrypt_aes), encoding = 'utf-8') # 解码
elif encoding == 'hex':
encrypted_text = str(binascii.b2a_hex(encrypt_aes), encoding = 'utf-8')
else:
raise ValueError('错误的编码')
encrypted_text_str = encrypted_text.replace("\n", "")
return encrypted_text_str
def sha1(message):
# 创建 SHA-1 哈希对象
sha1 = hashlib.sha1()
# 更新哈希对象(传入要加密的数据)
sha1.update(message.encode('utf-8')) # 将字符串编码为字节(bytes)
# 获取哈希值,返回十六进制格式
hashed_message = sha1.hexdigest()
print("SHA-1 Hash:", hashed_message)
return hashed_message
if __name__ == '__main__':
set_cookie = first_get_index() # 第一次请求 461 拿 set_cookie
_0x36a41f = int(time.time()) - 5 # 生成 ck T89MlEJgG337C6knS
_0x2897e9, _0x35c285 = "1" * 16, "1" * 16
_0x4d8507 = "bec04770139bcfb8b9d43be66da429b1" + '|' + 'false' + '|' + str(_0x36a41f) + "|" + "1" * 3 + '|' + "1" * 3 + '|' + "1"
# _0x4d8507 = "a9c5ace1abb3af24671afc06daa50768" + '|' + 'false' + '|' + str(_0x36a41f) + "|" + "1" * 3 + '|' + "1" * 3 + '|' + "1"
_0x4d8507 = AESUtil.encrypt(_0x4d8507, key = _0x2897e9, iv = _0x35c285, mode = 'CBC', encoding = 'hex')
_0x2897e9 = AESUtil.encrypt((_0x2897e9 + _0x35c285), key = _0x4d8507[:16], iv = _0x4d8507[len(_0x4d8507) - 16:], mode = 'CBC', encoding = 'hex')
_0x4d8507 = _0x4d8507 + "." + _0x2897e9
_0x4d8507 = sha1(_0x4d8507) + "." + _0x4d8507
set_cookie['T89MlEJgG337C6knS'] = _0x4d8507
get_index(set_cookie) # 200 携带ck请求
参考文章和鸣谢
~