154 lines
7.4 KiB
Markdown
154 lines
7.4 KiB
Markdown
# 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):
|
||
```python
|
||
browser_click(ref="e13")
|
||
```
|
||
|
||
После клика появляется окно с пазлом и ползунком.
|
||
|
||
## Этап 2: Получение координат слайдера
|
||
|
||
```javascript
|
||
slider = document.querySelector('.slider-move');
|
||
rect = slider.getBoundingClientRect();
|
||
// {left: 682, top: 551.5, width: 40, height: 40}
|
||
```
|
||
|
||
## Этап 3: Эмуляция перетаскивания
|
||
|
||
```javascript
|
||
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.
|
||
|
||
**Рабочий однострочник:**
|
||
```javascript
|
||
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
|
||
# 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 позиция неизвестна заранее. Перебирать фракции трека:
|
||
```python
|
||
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 (полный трек) → "验证失败,请重试".
|
||
|
||
### Проверка успеха
|
||
```python
|
||
# Капча решена если:
|
||
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 |