目录

  1. 1. 前言
  2. 2. 基础知识
    1. 2.1. 组件介绍
    2. 2.2. manifest.json
    3. 2.3. Content scripts
      1. 2.3.1. Inject scripts
    4. 2.4. Background scripts
      1. 2.4.1. Popup
      2. 2.4.2. options_page
    5. 2.5. 通信架构
  3. 3. 漏洞分析
    1. 3.1. Content scripts
      1. 3.1.1. DOM
      2. 3.1.2. DOM Event
      3. 3.1.3. onmessage
      4. 3.1.4. window.name
      5. 3.1.5. Web Storage

LOADING

第一次加载文章图片可能会花费较长时间

要不挂个梯子试试?(x

加载过慢请开启缓存 浏览器默认开启

Chrome扩展攻击

2024/12/15 Web
  |     |   总文章阅读量:

前言

之前打 GeekGame 的时候就遇到过利用 chrome 扩展进行 xss 的题,正好看到有相关的文章,遂学习一下

参考:

https://blog.xlab.app/p/4db211d1/

https://blog.xlab.app/p/4db211d2/


基础知识

组件介绍

edge 的扩展位置在 %localappdata%\Microsoft\Edge\User Data\Default\Extensions

接下来以 GeekGame2024 里 web-crx 更新后的扩展文件 bxx 为例子来熟悉组件

manifest.json

官方文档:https://developer.chrome.google.cn/docs/extensions/reference/manifest?hl=zh-cn

扩展程序的配置清单,放在扩展程序代码的根目录,包含以下内容:

  1. 名称,描述,版本等

    最小清单:

    {
      "manifest_version": 3,
      "name": "Minimal Manifest",
      "version": "1.0.0",
      "description": "A basic example extension with only required keys",
      "icons": {
        "48": "images/icon-48.png",
        "128": "images/icon-128.png"
      },
    }
  2. API权限定义,如 读写书签/历史/Cookie 等 Chrome API

    "permissions": ["tabs", "scripting"]
  3. 网站权限定义,允许无视同源策略访问哪些网站

    "host_permissions": [
        "<all_urls>"
    ]
  4. 定义Content scripts是哪些 js,在哪里何时运行等

    "content_scripts": [
        {
            "matches": ["*://*/*"],
            "js": ["contentScript.bundle.js"]
        }
    ]
  5. 定义Background scripts是哪些 js

    "background": {
        "service_worker": "background.bundle.js"
    }
  6. CSP策略…


Content scripts

https://developer.chrome.google.cn/docs/extensions/reference/manifest/content-scripts?hl=zh-cn

在每个标签页中运行,每个扩展一个隔离环境,有独立的JavaScript变量,CSP策略等,同时拥有一部分Chrome API功能,只与网页中的JS使用同一个DOM

一般用来处理与网页DOM相关的功能,或与Background scripts通信交互完成相关功能

同源策略与所在的标签页相同

"content_scripts": [
    {
        "matches": ["*://*/*"],
        "js": ["contentScript.bundle.js"]
    }
]
  • matches:将内容脚本注入到的网址格式,这里匹配所有的网址
  • js:注入网页的 js 脚本

image-20241218194441943

image-20241218194514408


Inject scripts

由于Content scripts与网页隔离,有些功能又需要访问网页空间中的数据

那么扩展程序往往会在Content scripts中通过DOM注入各种标签,当然也包括script

这里是在 contentScript.bundle.js 里面进行插入的

var style = document.createElement('style');
style.textContent = styles;
document.head.append(style);

如果插入的是 script 标签便会引入一些攻击面


Background scripts

扩展程序的后台服务,拥有完整的Chrome API功能,但不能直接访问DOM

一般用于持续运行的功能,或依赖相关Chrome API的功能

在一定的权限设定下,无同源策略限制

在Manifest V2中是一个HTML,叫background.html,如果是JS的话会自动生成一个HTML

在Manifest V3中是一个JS,叫Service Worker

"background": {
    "service_worker": "background.bundle.js"
}

image-20241218194904970

background.bundle.js 里对应的代码

chrome.runtime.onInstalled.addListener((function(t){
    "install"===t.reason && chrome.tabs.create({url: "chrome://newtab"})
}));

监听安装行为,在安装此扩展时在浏览器打开一个新标签页


定义的位置在 action 的 default_popup

是点击扩展图标后弹出的页面,权限与Background组件相同

以 沉浸式翻译 为例子:

"action": {
    "default_icon": {
        "128": "icons/128.png",
        "256": "icons/256.png",
        "32": "icons/32.png",
        "48": "icons/48.png",
        "64": "icons/64.png"
    },
    "default_popup": "popup.html"
}

image-20241218195819564

options_page

为扩展的选项页,权限与Background组件相同


通信架构

image-20241218200053198

Webpage 是指网页 Javascript 的空间,与 Content 共享 DOM,其中 window 比较特殊,虽然是共用一个 window,但有变量隔离

由于共用 window ,Webpage 与 Content 可以使用window.postMessage进行通信

当 Content 调用chrome.runtime.sendMessage时其实在向所有 Background 页面中广播

同理,Background 页面之间使用chrome.runtime.sendMessage发送消息时也相当于在广播


漏洞分析

前端漏洞主要还是围绕 XSS 和 CSRF

而 Chrome Manifest V3 中规定禁止代码执行,禁止加载远程资源,体现在CSP中无法添加unsafe-evalunsafe-inline,也无法添加任何远程地址,导致想要在 Manifest V3 实现 XSS 非常困难

Content scripts

DOM

由于 Content scripts 与网页 JS 共享DOM

对于攻击者来说,攻击入口包括整个 DOM

DOM Event

除了Content去直接查询DOM元素,还有订阅事件

onmessage

由于Content scripts与网页使用同一个windowpostMessage将直接与Content scripts通信

如果没有校验来源,甚至可以利用 iframe 或者 window.open 获取目标window,跨域发送消息直达Content scripts完成攻击

window.name

虽然说Content与网页隔离,变量不能共享,但是window.name是个例外

Web Storage

如果在Content中使用Web Storage,其实是在使用当前网站的存储,而不是扩展程序自己的

写入Web Storage存在信息泄露,同时读取Web Storage也是用户输入