如何实现cloudflare五秒盾突破?

3,722 阅读4分钟

遇到了一个奇葩的网站,网页打开后会出现检查站点是否安全的提示,如下所示:

image.png

  • 结合之前的了解感觉像是五秒盾,进去抓下包看看如何:

image.png

果不其然就是大名鼎鼎的cloudflare,那既然知道了是五秒盾,如何应对呢?

1. 首先我们分析下业务请求的必要参数:

通过chrome抓包找到业务请求接口,扣取curl进行代码转换,操作过程如下所示:

image.png

猿人学的工具可以直接转换:tool.yuanrenxue.cn/curl

选择自己想要的语言就行,我这边使用的是python

image.png

经过本地验证分析,发现cf_clearance这个参数是比较关键的(分析过程异常痛苦,涉及到tls指纹请求,有需要可以参考:juejin.cn/post/722977…

2. 开始进行重放攻击验证:

之前听说有个成熟的库CloudScraper可以捅穿五秒盾,我尝试跑了一下,结果发现根本过不去

image.png

其实还是绕不开cf_clearance这个参数,接下来就需要考虑如何生成这个参数。

简单分析了下请求链路和参数生成的过程,发现还是非常复杂的,有没有办法绕过,不通过js逆向完成参数生成呢?答案是有的

3. 生成cf_clearance参数:

逛github的时候无意间发现了一个框架,可以自动化生成该参数,而且可以通过接口进行调用非常方便,项目地址如下:github.com/vvanglro/cf…

首先来看下这个框架的简介:

image.png

大致的意思就是可以生成cloudflare v2的可通过的参数,其实就是cf_clearance,注意点就是需要保证同样的IP和useragent,使用接口模式时候不能启用无头模式,也可以使用docker部署在linux等无界面服务器上,但是需要安装xvfb

这个框架是基于playwright的,相比selenium,这个框架更加灵活,更加不易被网站识别为自动化浏览器,具体玩法可以参照崔大大的博客:blog.51cto.com/u_15023263/…

Docker部署命令:

docker run -d --restart always --network host --name cf-clearance vvanglro/cf-clearance:latest \
--host 0.0.0.0 --port 8000 --workers 1

调用的curl命令:

curl http://localhost:8000/challenge -H "Content-Type:application/json" -X POST \
-d '{"proxy": {"server": "socks5://localhost:7890"}, "timeout":20, "url": "https://nowsecure.nl"}'

python代码命令:

import requests

proxy = "socks5://localhost:7890"
resp = requests.post("http://localhost:8000/challenge",
                     json={"proxy": {"server": proxy}, "timeout": 20,
                           "url": "https://nowsecure.nl"})
if resp.json().get("success"):
    ua = resp.json().get("user_agent")
    cf_clearance_value = resp.json().get("cookies").get("cf_clearance")
    # use cf_clearance, must be same IP and UA
    headers = {"user-agent": ua}
    cookies = {"cf_clearance": cf_clearance_value}
    res = requests.get('https://nowsecure.nl', proxies={
        "all": proxy
    }, headers=headers, cookies=cookies)
    if '<title>Just a moment...</title>' not in res.text:
        print("cf challenge success")

当然也可以直接安装pip包,本地化调用:

pip install cf-clearance

本地调用代码:

from playwright.sync_api import sync_playwright
from cf_clearance import sync_cf_retry, sync_stealth
import requests

# not use cf_clearance, cf challenge is fail
proxies = {
    "all": "socks5://localhost:7890"
}
res = requests.get('https://nowsecure.nl', proxies=proxies)
if '<title>Just a moment...</title>' in res.text:
    print("cf challenge fail")
# get cf_clearance
with sync_playwright() as p:
    browser = p.chromium.launch(headless=False, proxy={"server": "socks5://localhost:7890"})
    page = browser.new_page()
    sync_stealth(page, pure=True)
    page.goto('https://nowsecure.nl')
    res = sync_cf_retry(page)
    if res:
        cookies = page.context.cookies()
        for cookie in cookies:
            if cookie.get('name') == 'cf_clearance':
                cf_clearance_value = cookie.get('value')
                print(cf_clearance_value)
        ua = page.evaluate('() => {return navigator.userAgent}')
        print(ua)
    else:
        print("cf challenge fail")
    browser.close()
# use cf_clearance, must be same IP and UA
headers = {"user-agent": ua}
cookies = {"cf_clearance": cf_clearance_value}
res = requests.get('https://nowsecure.nl', proxies=proxies, headers=headers, cookies=cookies)
if '<title>Just a moment...</title>' not in res.text:
    print("cf challenge success")

一番操作下来之后,发现确实能获取cf_clearance参数,携带后也能通过示例代码上的cloudflare五秒盾,但当我尝试我遇到的那个网站时候,发现接口请求并不行,有点崩溃

4. 未解决的问题:

我这边测试了下有痕和无痕的同一浏览器生成的参数互换位置进行请求,结果发现无法通过

又测试了下不同虚拟主机的同一浏览器生成的参数互换位置进行请求是可以通过的

基于以上两点测试看,该站点的五秒盾参数生成是基于浏览器指纹的,并且发起请求的客户端指纹也需要和生成参数时的指纹保持一致才可以访问,这块目前能想到的就只能使用同一浏览器生成的参数来发起请求

虽然通过全套的playwright自动化方案能够解决这个网站的五秒盾问题,但毕竟自动化的效率是比较低的,还是想通过代码实现请求,这块我会持续进行跟踪调研,有进展会同步更新下

5. 后续:

待更新