Quy trình tham khảo
Tuyên bố miễn trừ trách nhiệm
Bài viết này chỉ nhằm mục đích học tập và trao đổi kỹ thuật. Tác giả không chịu bất kỳ trách nhiệm pháp lý nào phát sinh từ việc lạm dụng thông tin được cung cấp. Nếu có vi phạm bản quyền, vui lòng liên hệ để gỡ bỏ.
Phân tích yêu cầu và tham số mã hóa
Yêu cầu register để lấy challenge và gt
# Gửi yêu cầu đến https://www.geetest.com/demo/gt/register-slide?t=1709175113777
# Phản hồi: {"success":1,"challenge":"a79e7880ec16af4ce333dfe7ed28bd55","gt":"019924a82c70bb123aae90d483087f94","new_captcha":true}
Phân tích giá trị W đầu tiên
Giá trị w trong yêu cầu đến https://apiv6.geetest.com/get.php bao gồm hai phần chính:
i: Dữ liệu JSON chứa thông tin môi trường được mã hóa bằng AES-CBC với padding PKCS7 tùy chỉnh, sau đó mã hóa base64 theo thuật toán riêng.r: Khóa 16 byte ngẫu nhiên dùng cho AES, được mã hóa bằng RSA với khóa công khai cố định.
Cấu trúc dữ liệu gốc trước khi mã hóa AES:
{
"gt": "019924a82c70bb123aae90d483087f94",
"challenge": "a79e7880ec16af4ce333dfe7ed28bd55",
"offline": false,
"new_captcha": true,
"product": "float",
"width": "300px",
"https": true,
"api_server": "apiv6.geetest.com",
"protocol": "https://",
"type": "fullpage",
"static_servers": ["static.geetest.com/", "static.geevisit.com/"],
"beeline": "/static/js/beeline.1.0.1.js",
"voice": "/static/js/voice.1.2.4.js",
"click": "/static/js/click.3.1.0.js",
"fullpage": "/static/js/fullpage.9.1.9-r8k4eq.js",
"slide": "/static/js/slide.7.9.2.js",
"geetest": "/static/js/geetest.6.0.9.js",
"aspect_radio": {"slide":103,"click":128,"voice":128,"beeline":50},
"cc": 12,
"ww": true,
"i": "-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1"
}
Các trường cc, ww, và i có thể được giữ nguyên giá trị mặc định mà không ảnh hưởng đến quá trình xác thực.
Phân tích giá trị W thứ hai (sau khi tải captcha)
Sau khi người dùng tương tác với captcha, một yêu cầu mới được gửi kèm theo giá trị w chứa thông tin hành vi và môi trường chi tiết hơn.
Dữ liệu gốc trước khi mã hóa:
{
"lang": "zh-cn",
"type": "fullpage",
"tt": "<mã hóa quỹ đạo chuột>",
"light": "DIV_0",
"s": "<hash MD5 của chuỗi xử lý đặc biệt>",
"h": "<hash MD5 của dữ liệu môi trường mở rộng>",
"hh": "<hash MD5 của dữ liệu môi trường rút gọn>",
"hi": "<hash MD5 của chuỗi i ban đầu>",
"vip_order": -1,
"ct": -1,
"ep": {
"v": "9.1.9-r8k4eq",
"te": false,
"$_BBp": true,
"ven": "Google Inc. (Intel)",
"ren": "ANGLE (Intel, Intel(R) UHD Graphics ...)",
"fp": ["move", x, y, timestamp, "pointermove"],
"lp": ["up", x, y, timestamp, "pointerup"],
"em": {"ph":0,"cp":0,"ek":"11","wd":1,"nt":0,"si":0,"sc":0},
"tm": {<dấu thời gian chi tiết>},
"dnf": "dnf",
"by": 0
},
"passtime": <thời gian thao tác>,
"rp": "<MD5(gt + challenge + passtime)>",
"captcha_token": "<kết quả hàm băm nội bộ>",
"otpj": "jm4jwcx7"
}
Lưu ý:
s,h,hh,hiđều là kết quả MD5 (chữ thường) của các chuỗi được xử lý theo logic riêng.rpđược tính bằngMD5(gt + challenge + passtime).captcha_tokenđược sinh ra từ một hàm băm nội bộ dựa trên mã nguồn JavaScript và timestamp.
Phân tích giá trị W thứ ba (gửi kết quả xác thực)
Khi gửi kết quả giải captcha, tham số w chứa thông tin vị trí và quỹ đạo di chuyển:
{
"lang": "zh-cn",
"userresponse": "<mã hóa vị trí缺口 + challenge>",
"passtime": <thời gian kéo thanh trượt>,
"imgload": <thời gian tải ảnh (có thể random)>,
"aa": "<mã hóa quỹ đạo kéo>",
"ep": {<thông tin phiên bản và thời gian>},
"h9s9": "1816378497",
"rp": "<MD5(gt + challenge + passtime)>"
}
Trong đó:
userresponseđược tạo bằng cách kết hợp tọa độ缺口 (đã mã hóa) vớichallenge.aalà biểu diễn đã mã hóa của toàn bộ quỹ đạo di chuyển chuột.h9s9có thể sử dụng giá trị cố định.
Xác thực và lưu ý
Hệ thống có thể trả về điểm số (score) đánh giá mức độ "giống con người" của hành vi — giá trị càng thấp càng đáng tin cậy.
Một số lưu ý khi triển khai:
- Challenge trong phản hồi hình ảnh có thể dài hơn 32 ký tự, nhưng khi mã hóa
wvẫn phải dùng phiên bản 32 ký tự gốc. - Nên thêm độ trễ ngẫu nhiên giữa các bước gửi yêu cầu.
- Quỹ đạo chuột nên được tạo ngẫu nhiên theo phân phối thực tế.
- Lỗi
runtime errorthường do định dạng JSON trong dữ liệu mã hóa không hợp lệ.