Evernote RCE:从PDF.js字体注入到监听远程代码执行,XSS全平台Electron暴露ipcRendererBrokerBridge
就在本周,我发现了应用程序Javascript Injection -> Remote-Code Execution中的一项关键漏洞Evernote。只需单击font-injection嵌入恶意的共享糖衣注释PDF,攻击者就可以利用内置事件侦听器 * * 中预加载和暴露的Electron API,在不可见的情况下自发执行任意命令和文件。尽管我为从这个完全隐藏的大型应用程序中创建 4 步调用链有效载荷而付出了艰辛的努力(尽管我花了很长时间才写这篇博客),但我仍然认为这将是一个值得分享和查看的好材料:)(有趣的是,我在错误的轨道上走了大约 2 个小时,然后意识到这实际上是关键,这意味着当我发现这是 0day 时,我开始寻找相关方面的接收器)ipcRendererInter-Process-CommunicationEvernoteIPC’BrokerBridge’Main Process6 hoursscratchIPC IPCRCEipcRenderer。
在今天的文章中,我们将探索Evernote XSS->RCE包含以下内容的旅程:
-
了解Electron模型Multi-Process、IPC处理程序和preload.js功能;
-
了解PDF.jsJavaScriptfont-injection注入的工作原理;
-
逆向工程和调试Evernote的asar-packed模糊源来自250 million users (根据随机 reddit 帖子)和16多年维护的Electron项目完全从 NULL到1;
-
深入研究Electron->IPC在构建真实实例中事件通信,以及我们如何RCE通过两个Inter-process具有复杂设计的桥梁利用向量。
PDF.js:字体注入
这次攻击开启了地球上使用最广泛的文件格式——.PDF
Evernote作为一款出色的笔记集成应用程序,它允许用户PDF在笔记中嵌入文件以供查看和标记,这确实是一项很棒的功能Evernote,然而,它也是我们开发链的起点,将一个有用的功能变成了一个关键的漏洞。
对于集成PDF交互,Evernote使用了最常用的 PDF 插件之一 – PDF.js,它允许您与 进行交互和解释,PDFs而无需这些经过大量编译的二进制文件;您只需导入使用 构建的包C++即可轻松访问;为了在生产环境中运行,维护团队必须为和开发自己的逻辑和代码,但意外问题就在这里发生。PDFspdfjs-distJavascriptPDF.jsextractingrendering PDF metadata
喜爱的字体
我们都使用它的原因PDFs是它PDFs可以保存文件而不受渲染环境的影响,例如,.docx你老师发给你的文件在你的电脑上看起来总是很奇怪;作为 的超能力之一PDFs,PDFs它可以将字体嵌入元数据中,以便在渲染过程中进一步使用,这实际上变成了glyphs像curves图像(也称为vectorization)。为了迅速实现这一点,PDF.js的优化团队引入了pre-compiled path generator function这些glyphs:
// If we can, compile cmds into JS for MAXIMUM SPEED...
if (this.isEvalSupported && FeatureTest.isEvalSupported) {
const jsBuf = [];
for (const current of cmds) {
const args = current.args !== undefined ? current.args.join(",") : "";
jsBuf.push("c.", current.cmd, "(", args, ");n");
}
// eslint-disable-next-line no-new-func
console.log(jsBuf.join(""));
return (this.compiledGlyphs[character] = new Function(
"c",
"size",
jsBuf.join("") // Kaboom!
));
}
这是通过创建一个 JavaScriptFunction对象来实现的,该对象有一个 body ( jsBuf),其中包含构成路径的指令
然而,正如我们的黑客本能所触发的,如果我们能够控制被cmds解析的new Function(;那么就有可能控制的执行流程,PDFs因为我们的有效载荷也将由evaluated解析new Function(,因此,让我们从源到接收器了解源如何cmds被解析;
compileGlyph(code, glyphId) {
if (!code || code.length === 0 || code[0] === 14) {
return NOOP;
}
let fontMatrix = this.fontMatrix;
...
const cmds = [
{ cmd: "save" },
{ cmd: "transform", args: fontMatrix.slice() },
{ cmd: "scale", args: ["size", "-size"] },
];
this.compileGlyphImpl(code, cmds, glyphId);
cmds.push({ cmd: "restore" });
return cmds;
}
extractFontHeader(properties) {
let token;
while ((token = this.getToken()) !== null) {
if (token !== "/") {
continue;
}
token = this.getToken();
switch (token) {
case "FontMatrix":
const matrix = this.readNumberArray();
properties.fontMatrix = matrix;
break;
该extractFontHeader方法似乎FontMatrix从中提取了 token 值metadata,在本例中为readNumberArray,这意味着我们将完全陷入数字输入,使得不可能Javascript Injections!不过,请记住永远不要放弃寻找解决方案,在本例中,我们的FontMatrix可能还来自PartialEvaluator.translateFont(…)加载大量PDF与字体相关的属性的:
const properties = {
type,
name: fontName.name,
subtype,
file: fontFile,
...
fontMatrix: dict.getArray("FontMatrix") || FONT_IDENTITY_MATRIX,
...
bbox: descriptor.getArray("FontBBox") || dict.getArray("FontBBox"),
ascent: descriptor.get("Ascent"),
descent: descriptor.get("Descent"),
xHeight: descriptor.get("XHeight") || 0,
capHeight: descriptor.get("CapHeight") || 0,
flags: descriptor.get("Flags"),
italicAngle: descriptor.get("ItalicAngle") || 0,
...
};
https://0reg.dev/blog/evernote-rce
感谢您抽出
.
.
来阅读本文
点它,分享点赞在看都在这里
原文始发于微信公众号(Ots安全):Evernote RCE:从PDF.js字体注入到监听远程代码执行,XSS全平台Electron暴露ipcRendererBr