7.4 KiB
AliYun (Alibaba Cloud) Slider Captcha Bypass
AliYun captcha (Aliyun Captcha / 阿里云验证码) — слайдер-пазл, часто встречается на китайских платформах (z.ai, Alibaba Cloud, и т.д.).
Обходится через программную эмуляцию MouseEvent-ов через browser_console.
Как выглядит
В accessibility tree:
DIV|aliyun-captcha|Click to start verification
DIV|slider-move initial| ← ползунок
StaticText "Please drag the slider to complete the puzzle"
StaticText "CertifyId: InL9BEM6kF"
Этап 1: Активация капчи
Кликнуть на Click to start verification (ref=e13 в snapshot):
browser_click(ref="e13")
После клика появляется окно с пазлом и ползунком.
Этап 2: Получение координат слайдера
slider = document.querySelector('.slider-move');
rect = slider.getBoundingClientRect();
// {left: 682, top: 551.5, width: 40, height: 40}
Этап 3: Эмуляция перетаскивания
var s = document.querySelector('.slider-move');
// 1. mousedown
var d1 = new MouseEvent('mousedown', {
bubbles: true, clientX: 682, clientY: 551.5, button: 0
});
s.dispatchEvent(d1);
// 2. Серия mousemove с шагом ~5px (от 5 до 220 с шагом 5)
for (var i = 5; i <= 220; i += 5) {
var d2 = new MouseEvent('mousemove', {
bubbles: true, clientX: 682 + i, clientY: 551.5, button: 0
});
s.dispatchEvent(d2);
}
// 3. mouseup
var d3 = new MouseEvent('mouseup', {
bubbles: true, clientX: 682 + 220, clientY: 551.5, button: 0
});
s.dispatchEvent(d3);
⚠️ Выполнять через browser_console одной строкой, т.к. многострочные функции в браузерной консоли могут давать SyntaxError.
Рабочий однострочник:
var s=document.querySelector('.slider-move');var d1=new MouseEvent('mousedown',{bubbles:true,clientX:682,clientY:551.5,button:0});s.dispatchEvent(d1);for(var i=5;i<=220;i+=5){var d2=new MouseEvent('mousemove',{bubbles:true,clientX:682+i,clientY:551.5,button:0});s.dispatchEvent(d2)};var d3=new MouseEvent('mouseup',{bubbles:true,clientX:682+220,clientY:551.5,button:0});s.dispatchEvent(d3);'done'
Проверка результата
После успешного прохождения:
- В accessibility tree исчезает блок капчи
- Появляется
StaticText "Verification Passed!" - В консоли:
🎉 验证码滑动成功! 参数: eyJ...(закодированный токен верификации)
Неудача: капча остаётся на месте, текст не меняется.
Тонкая настройка
- Расстояние (220px): может варьироваться в зависимости от размера пазла. Если не сработало, попробуйте 180-260px.
- Шаг (5px): можно уменьшить до 2px для более плавной эмуляции, увеличить до 10px для скорости.
- Координаты Y: должны совпадать с центром слайдера (
rect.top + rect.height/2). - MouseEvent vs PointerEvent: AliYun captcha реагирует на
MouseEvent. PointerEvent не обязателен.
Почему это работает (для ПРОСТОГО слайдера)
AliYun captcha проверяет наличие последовательности событий mousedown → (mousemove × N) → mouseup с реалистичными координатами. Она НЕ проверяет:
- Физическое движение мыши (через CDP/Playwright)
- Timestamp событий (можно все在同一毫秒)
- requestAnimationFrame
- PointerEvent (fallback на MouseEvent)
Слабость: полагается только на JS-события, которые можно диспатчить программно.
Pateway PUZZLE captcha (отличается от простого слайдера!)
Pateway использует PUZZLE-версию Aliyun captcha, где нужно перетащить ползунок на ТОЧНУЮ позицию, совпадающую с вырезом в фоновом изображении. Это НЕ "slide to end" — позиция уникальна для каждой капчи.
Правильные селекторы (Pateway)
- Ползунок:
#aliyunCaptcha-sliding-slider(НЕ#aliyunCaptcha-sliding-wrapper, НЕ.slider-move) - Трек:
#aliyunCaptcha-sliding-body(300px ширина) - Маска/оверлей:
#aliyunCaptcha-mask - Пазл:
#aliyunCaptcha-puzzle - Изображение:
#aliyunCaptcha-img
Метод: CDP Input.dispatchMouseEvent (НЕ JS MouseEvent!)
JS MouseEvent.dispatchEvent() НЕ работает для puzzle captcha Pateway. Нужно использовать CDP Input.dispatchMouseEvent:
# Python + websocket через CDP (port 9222)
def cdp_drag(ws, sx, sy, ex, ey, steps=30):
ws.send(json.dumps({"id": rid, "method": "Input.dispatchMouseEvent",
"params": {"type": "mousePressed", "x": sx, "y": sy, "button": "left", "clickCount": 1}}))
time.sleep(0.05)
for i in range(1, steps + 1):
p = i / steps
if p < 0.2: e = p * 0.3
elif p > 0.8: e = 0.8 + (p - 0.8) * 0.5
else: e = 0.3 + (p - 0.2) * 0.833
cx = sx + (ex - sx) * e
cy = ey + (random.random() - 0.5) * 4
ws.send(json.dumps({"id": rid, "method": "Input.dispatchMouseEvent",
"params": {"type": "mouseMoved", "x": cx, "y": cy, "button": "left"}}))
time.sleep(random.uniform(0.005, 0.02))
time.sleep(random.uniform(0.05, 0.15))
ws.send(json.dumps({"id": rid, "method": "Input.dispatchMouseEvent",
"params": {"type": "mouseReleased", "x": ex, "y": ey, "button": "left"}}))
Стратегия перебора дистанций
Puzzle позиция неизвестна заранее. Перебирать фракции трека:
for fraction in [0.3, 0.5, 0.7, 0.85]:
ex = body_x + body_w * fraction
# drag from slider center to ex
# check if mask disappeared
Подтверждено: 0.5 (130px из 260px трека) сработало для Pateway. 260px (полный трек) → "验证失败,请重试".
Проверка успеха
# Капча решена если:
mask = cdp_eval("document.getElementById('aliyunCaptcha-mask')?.style.display")
# mask == 'none' или элемент не найден → решена
# Текст слайдера: "验证失败,请重试" → НЕ решена, пробовать другую фракцию
Когда НЕ работает
- Cloudflare Turnstile — требует реального браузерного fingerprint
- Google reCAPTCHA v2/v3 — анализирует поведение мыши через CDP
- hCaptcha — требует решения визуальной задачи
- AliYun CAPTCHA v2 (более новая) — может добавлять PointerEvent проверку
- Pateway puzzle captcha через JS MouseEvent — нужен CDP Input.dispatchMouseEvent