Flare On 2014 - Challenge 4 Writeup

The fourth challenge isn't a binary file as well (at least it seems so ;) ) but a PDF called APT9001.pdf.

The headline of the PDF states: Exposing One Of China's Espionage Units; the file only has two sites where the first one is the cover page and the second one appears to be blank.

(Since this feels like digital forensics to me I don't believe anything, not even that this blank page is truly blank)

I already learned some things about forensics and analyzing PDF files at university, so I took the same approach.

After checking if something looks sketchy in a hex-editor, I analyzed the file using peepdf:

python2 peepdf.py -fil APT9001.pdf

The output of the interactive mode revealed that JavaScript code was embedded which is quite uncommon for a more or less "blank" PDF.

0Objects with JS code (1): [6]
1Suspicious elements:
2	/OpenAction (1): [1]
3	/JS (1): [5]
4	/JavaScript (1): [5]
5	Adobe JBIG2Decode Heap Corruption (CVE-2009-0658): [8]

I tried to extract the JS code using extract js > extracted.js which appeared to be successful.

Extracted code (it's a mess):

 0// peepdf comment: Javascript code located in object 6 (version 0)
 1
 2var HdPN = "";
 3var zNfykyBKUZpJbYxaihofpbKLkIDcRxYZWhcohxhunRGf = "";
 4var IxTUQnOvHg = unescape("%u72f9%u4649%u15[...]d0ff");
 5var MPBPtdcBjTlpvyTYkSwgkrWhXL = "";
 6
 7for (EvMRYMExyjbCXxMkAjebxXmNeLXvloPzEWhKA = 128; EvMRYMExyjbCXxMkAjebxXmNeLXvloPzEWhKA >= 0; --EvMRYMExyjbCXxMkAjebxXmNeLXvloPzEWhKA) MPBPtdcBjTlpvyTYkSwgkrWhXL += unescape("%ub32f%u3791");
 8ETXTtdYdVfCzWGSukgeMeucEqeXxPvOfTRBiv = MPBPtdcBjTlpvyTYkSwgkrWhXL + IxTUQnOvHg;
 9OqUWUVrfmYPMBTgnzLKaVHqyDzLRLWulhYMclwxdHrPlyslHTY = unescape("%ub32f%u3791");
10fJWhwERSDZtaZXlhcREfhZjCCVqFAPS = 20;
11fyVSaXfMFSHNnkWOnWtUtAgDLISbrBOKEdKhLhAvwtdijnaHA = fJWhwERSDZtaZXlhcREfhZjCCVqFAPS + ETXTtdYdVfCzWGSukgeMeucEqeXxPvOfTRBiv.length
12while (OqUWUVrfmYPMBTgnzLKaVHqyDzLRLWulhYMclwxdHrPlyslHTY.length < fyVSaXfMFSHNnkWOnWtUtAgDLISbrBOKEdKhLhAvwtdijnaHA) OqUWUVrfmYPMBTgnzLKaVHqyDzLRLWulhYMclwxdHrPlyslHTY += OqUWUVrfmYPMBTgnzLKaVHqyDzLRLWulhYMclwxdHrPlyslHTY;
13UohsTktonqUXUXspNrfyqyqDQlcDfbmbywFjyLJiesb = OqUWUVrfmYPMBTgnzLKaVHqyDzLRLWulhYMclwxdHrPlyslHTY.substring(0, fyVSaXfMFSHNnkWOnWtUtAgDLISbrBOKEdKhLhAvwtdijnaHA);
14MOysyGgYplwyZzNdETHwkru = OqUWUVrfmYPMBTgnzLKaVHqyDzLRLWulhYMclwxdHrPlyslHTY.substring(0, OqUWUVrfmYPMBTgnzLKaVHqyDzLRLWulhYMclwxdHrPlyslHTY.length - fyVSaXfMFSHNnkWOnWtUtAgDLISbrBOKEdKhLhAvwtdijnaHA);
15while (MOysyGgYplwyZzNdETHwkru.length + fyVSaXfMFSHNnkWOnWtUtAgDLISbrBOKEdKhLhAvwtdijnaHA < 0x40000) MOysyGgYplwyZzNdETHwkru = MOysyGgYplwyZzNdETHwkru + MOysyGgYplwyZzNdETHwkru + UohsTktonqUXUXspNrfyqyqDQlcDfbmbywFjyLJiesb;
16DPwxazRhwbQGu = new Array();
17for (EvMRYMExyjbCXxMkAjebxXmNeLXvloPzEWhKA = 0; EvMRYMExyjbCXxMkAjebxXmNeLXvloPzEWhKA < 100; EvMRYMExyjbCXxMkAjebxXmNeLXvloPzEWhKA++) DPwxazRhwbQGu[EvMRYMExyjbCXxMkAjebxXmNeLXvloPzEWhKA] = MOysyGgYplwyZzNdETHwkru + ETXTtdYdVfCzWGSukgeMeucEqeXxPvOfTRBiv;
18
19for (EvMRYMExyjbCXxMkAjebxXmNeLXvloPzEWhKA = 142; EvMRYMExyjbCXxMkAjebxXmNeLXvloPzEWhKA >= 0; --EvMRYMExyjbCXxMkAjebxXmNeLXvloPzEWhKA) zNfykyBKUZpJbYxaihofpbKLkIDcRxYZWhcohxhunRGf += unescape("%ub550%u0166");
20bGtvKT = zNfykyBKUZpJbYxaihofpbKLkIDcRxYZWhcohxhunRGf.length + 20
21while (zNfykyBKUZpJbYxaihofpbKLkIDcRxYZWhcohxhunRGf.length < bGtvKT) zNfykyBKUZpJbYxaihofpbKLkIDcRxYZWhcohxhunRGf += zNfykyBKUZpJbYxaihofpbKLkIDcRxYZWhcohxhunRGf;
22Juphd = zNfykyBKUZpJbYxaihofpbKLkIDcRxYZWhcohxhunRGf.substring(0, bGtvKT);
23QCZabMzxQiD = zNfykyBKUZpJbYxaihofpbKLkIDcRxYZWhcohxhunRGf.substring(0, zNfykyBKUZpJbYxaihofpbKLkIDcRxYZWhcohxhunRGf.length - bGtvKT);
24while (QCZabMzxQiD.length + bGtvKT < 0x40000) QCZabMzxQiD = QCZabMzxQiD + QCZabMzxQiD + Juphd;
25FovEDIUWBLVcXkOWFAFtYRnPySjMblpAiQIpweE = new Array();
26for (EvMRYMExyjbCXxMkAjebxXmNeLXvloPzEWhKA = 0; EvMRYMExyjbCXxMkAjebxXmNeLXvloPzEWhKA < 125; EvMRYMExyjbCXxMkAjebxXmNeLXvloPzEWhKA++) FovEDIUWBLVcXkOWFAFtYRnPySjMblpAiQIpweE[EvMRYMExyjbCXxMkAjebxXmNeLXvloPzEWhKA] = QCZabMzxQiD + zNfykyBKUZpJbYxaihofpbKLkIDcRxYZWhcohxhunRGf;

Time for some deobfuscation and JS beautifying:

 0// peepdf comment: Javascript code located in object 6 (version 0)
 1
 2var string_variable_2 = "";
 3var string_variable_4 = unescape("%u72f[...]u5740%ud0ff");
 4var string_variable_1 = "";
 5
 6for (counter_variable = 128; counter_variable >= 0; --counter_variable) string_variable_1 += unescape("%ub32f%u3791");
 7string_variable_3 = string_variable_1 + string_variable_4;
 8string_variable_5 = unescape("%ub32f%u3791");
 9
10
11while (string_variable_5.length < 790) string_variable_5 += string_variable_5;
12
13substring1_of_str5 = string_variable_5.substring(0, 790);
14substring2_of_str5 = string_variable_5.substring(0, string_variable_5.length - 790);
15
16while (substring2_of_str5.length + 790 < 262144) substring2_of_str5 = substring2_of_str5 + substring2_of_str5 + substring1_of_str5;
17another_array_variable = new Array();
18
19for (counter_variable = 0; counter_variable < 100; counter_variable++) another_array_variable[counter_variable] = substring2_of_str5 + string_variable_3;
20
21for (counter_variable = 142; counter_variable >= 0; --counter_variable) string_variable_2 += unescape("%ub550%u0166");
22len_str2_plus20 = string_variable_2.length + 20
23
24while (string_variable_2.length < len_str2_plus20) string_variable_2 += string_variable_2;
25
26substring1_of_str2 = string_variable_2.substring(0, len_str2_plus20);
27substring2_of_str2 = string_variable_2.substring(0, string_variable_2.length - len_str2_plus20);
28
29while (substring2_of_str2.length + len_str2_plus20 < 262144) substring2_of_str2 = substring2_of_str2 + substring2_of_str2 + substring1_of_str2;
30array_variable = new Array();
31
32for (counter_variable = 0; counter_variable < 125; counter_variable++) array_variable[counter_variable] = substring2_of_str2 + string_variable_2;

I tried a mixture of a lot of static analysis and some dynamic but had no real success with that approach.


Adobe JBIG2Decode Heap Corruption (CVE-2009-0658)

Next, I took a step back and looked at the output of peepdf again which mentioned a specific CVE. Time to poison my VM with a vulnerable version of the Adobe Acrobat Reader I guess...

I tried to set it up and analyze it on Windows 10 using Adobe Acrobat Reader 9 but Acrobat Reader always crashed before the exploit was completed. Soo, no dynamic analysis right now.

My research showed that there's a chance to convert the payload (string_variable_4) into shellcode using the following command:

cat payload.txt | sed 's/\%u//g' | xxd -r -p | dd conv=swab of=shellcode.bin

After doing so, I opened the .bin file using cutter which revealed some assembly code and showed that LoadLibraryA and MessageBoxA get called. The text for MessageBoxA is simply OWNED!!! and since I couldn't find any other interesting plaintext strings in the code, I assumed that the flag gets dynamically decrypted during runtime.

After the OWNED!!! string got pushed onto the stack and a pointer to it was saved into EBX some XOR operations take place, and afterwards a pointer is stored in ECX. This might be the decryption routine of the flag!

f4d512a45df4bf7659c6134ac37c7ae9.png

In this static analysis, EBX will hold the address 0x35e in line 0x0000035e. In line 0x00000361 the value 0xb gets added to 0x35e which results in 0x369.

At offset 0x00000368 we see a PUSH instruction pushing a static hex value onto the stack. Since the PUSH instruction (0x68) has a length of only one byte the add-operation from earlier will result in a pointer to the static hex value.

In the end, this means that 0x32bece79 gets XORed with 0x32fba316 (repeat that for the chain of XOR operations).

After performing the XOR operations, I got the following hex values:

00x00456d6f
10x632e6e6f
20x2d657261
30x5c664073
40x7431306c
50x33642e68
60x63316177

Putting them into the following recipe on CyberChef revealed the flag:

182aa7444b49ad71404b6d0d7b66a700.png

wa1ch.d3l01ts@f\are-on.comE. => [email protected]


Challenge 3 Challenge 5