Phân tích giao thức mã hóa xác thực Geetest

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 challengegt

# 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ằng MD5(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ới challenge.
  • aa là biểu diễn đã mã hóa của toàn bộ quỹ đạo di chuyển chuột.
  • h9s9 có 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 w vẫ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 error thường do định dạng JSON trong dữ liệu mã hóa không hợp lệ.

Thẻ: Geetest aes RSA JavaScript reverse-engineering

Đăng vào ngày 19 tháng 6 lúc 23:04