52
How to really obfuscate your PDF malware Sebastian Porst - ReCon 2010 Email: [email protected] Twitter: @LambdaCube 1

How to really obfuscate your pdf malware

Embed Size (px)

Citation preview

Page 1: How to really obfuscate   your pdf malware

How to really obfuscateyour PDF malware

Sebastian Porst - ReCon 2010Email: [email protected]

Twitter: @LambdaCube1

Page 2: How to really obfuscate   your pdf malware

Targeted Attacks 2008

2

Adobe Acrobat Reader; 28.61%

Microsoft PowerPoint;

16.87%Microsoft Excel; 19.97%

Microsoft Word; 34.55%

http://www.f-secure.com/weblog/archives/00001676.html

Page 3: How to really obfuscate   your pdf malware

Targeted Attacks 2009

3

Adobe Acrobat Reader; 48.87%

Microsoft PowerPoint;

4.52%Microsoft

Excel; 7.39%

Microsoft Word; 39.22%

Page 4: How to really obfuscate   your pdf malware

Exploited in the wild

CVE-2007-5659

CVE-2008-2992

CVE-2009-0658

CVE-2009-0927

CVE-2009-1492

CVE-2009-3459

CVE-2009-4324

CVE-2010-0188

Page 5: How to really obfuscate   your pdf malware

Four common exploit paths

5

Broken PDF Parser

Vulnerable JavaScript Engine

Vulnerable external libraries

/Launch

Page 6: How to really obfuscate   your pdf malware

PDF Malware Obfuscation

6

Different tricks for different purposes

Make manual analysis more difficult

Resist automated analysis

Avoid detection by virus scanners

Page 7: How to really obfuscate   your pdf malware

PDF Malware Obfuscation

7

Conflicting goals

Avoid detection by being

wellformed

Make analysis difficult by being

malformed

Page 8: How to really obfuscate   your pdf malware

How to achieve these goals

8

Being harmless Being evil

• Avoid JavaScript

• Do not use unusual encodings

• Do not try to break parser-based tools

• Ideally use an 0-day

• Use heavy obfuscation

• Try to break tools

Page 9: How to really obfuscate   your pdf malware

9

Let‘s be evil

Page 10: How to really obfuscate   your pdf malware

Breaking tools

Page 11: How to really obfuscate   your pdf malware

11

Rule #1: Do the unexpected

Page 12: How to really obfuscate   your pdf malware

This is what tools expect

• ASCII Strings

• Boring encodings like #41 instead of A

• Wellformed or only moderately malformed PDF file structure

12

Page 13: How to really obfuscate   your pdf malware

Malformed documents

• Adobe Reader tries to load malformed PDF files

• Very, very liberal interpretation of the PDF specification

• Parser-based analysis tools need to know about Adobe Reader file correction

13

Page 14: How to really obfuscate   your pdf malware

Malformed PDF file – Example I

14

7 0 obj

<<

/Type /Action

/S /JavaScript

/JS (app.alert('whatever');)>>

endobj

Page 15: How to really obfuscate   your pdf malware

Malformed PDF file – Example II

15

5 0 obj

<< /Length 45 >>

stream

some data

endstream

endobj

Page 16: How to really obfuscate   your pdf malware

Further reading

16

Page 17: How to really obfuscate   your pdf malware

Obfuscating JavaScript code

Page 18: How to really obfuscate   your pdf malware

Goal of JavaScript obfuscation

18

Hide the shellcode

Page 19: How to really obfuscate   your pdf malware

JavaScript obfuscation in the wild

• Screwed up formatting

• Name obfuscation

• Eval-chains

• Splitting JavaScript code

• Simple anti-emulation techniques

• callee-trick

• ...

19

Page 20: How to really obfuscate   your pdf malware

Screwed up formatting

• Basically just remove all newlines

• Completely useless: jsbeautifier.org

20

Page 21: How to really obfuscate   your pdf malware

Name obfuscation

• Variables or function names are renamed to hide their meaning

• Most JavaScript obfuscators screw this up

21

Page 22: How to really obfuscate   your pdf malware

Obfuscation example: Original code

22

function executePayload(payload, delay)

{

if (delay > 1000)

{

// Whatever

}

}

function heapSpray(code, repeat)

{

for (i=0;i<repeat;i++)

{

code = code + code;

}

}

Page 23: How to really obfuscate   your pdf malware

Obfuscation without considering scope

23

function executePayload(hkof3ewhoife, fhpfewhpofe)

{

if (fhpfewhpofe > 1000)

{

// Whatever

}

}

function heapSpray(hoprwehjoprew, hoifwep43)

{

for (jnpfw93=0;jnpfw93<hoifwep43;jnpfw93++)

{

hoprwehjoprew = hoprwehjoprew + hoprwehjoprew;

}

}

Page 24: How to really obfuscate   your pdf malware

Obfuscation with considering scope

24

function executePayload(grtertttrr, hnpfefwefee)

{

if (hnpfefwefee > 1000)

{

// Whatever

}

}

function heapSpray(grtertttrr, hnpfefwefee)

{

for (hjnprew=0;hjnprew<hnpfefwefee;hjnprew++)

{

grtertttrr = grtertttrr + grtertttrr;

}

}

Page 25: How to really obfuscate   your pdf malware

Obfuscation: Going the whole way

25

function ____(____, _____)

{

if (_____ > 1000)

{

// Whatever

}

}

function _____(____, _____)

{

for (______=0; ______<_____; ______++)

{

____ = ____ + ____;

}

}

Page 26: How to really obfuscate   your pdf malware

Name obfuscation: Lessons learned

• Consider name scope

– Deobfuscator needs to know scoping rules too

• Use underscores

– Drives human analysts crazy

• Also cute: Use meaningful names that have nothing to do with the variable

– Maybe shuffle real variable names

26

Page 27: How to really obfuscate   your pdf malware

Eval chains

• JavaScript code can execute JavaScript code in strings through eval

• Often used to hide later code stages which are decrypted on the fly

• Common way to extract argument: replace eval with a printing function

27

Page 28: How to really obfuscate   your pdf malware

Eval chains: Doing it better

• Make sure your later stages reference variables or functions from earlier stages

• Re-use individual eval statements multiple times to make sure eval calls can not just be replaced

28

Page 29: How to really obfuscate   your pdf malware

JavaScript splitting

• JavaScript can be split over several PDF objects

• These scripts can be executed consecutively

• Context is preserved between scripts

• In the wild I‘ve seen splitting across 2-4 objects

29

Page 30: How to really obfuscate   your pdf malware

JavaScript splitting: Doing it better

• One line of JavaScript per object

• Randomize the order of JavaScript objects

• Admittedly it takes only one script to sort and extract the scripts from the objects

30

Page 31: How to really obfuscate   your pdf malware

Anti-emulation code

• Simple checks for Adobe Reader extensions

• Multistaged JavaScript code

31

Page 32: How to really obfuscate   your pdf malware

Current malware loads code from

32

Pages

Annotations

Info Dictionary

Page 33: How to really obfuscate   your pdf malware

Example: Loading code from annotations

33

y = app.doc;

y.syncAnnotScan();

var p = y["getAnnots"]({nPage: 0});

var s = p[0].subject;

eval(s);

Page 34: How to really obfuscate   your pdf malware

Problems with current approaches

34

Code is in the file

Easy to extract

Page 35: How to really obfuscate   your pdf malware

Anti-emulation code: Improved

35

Key ideas behind anti-emulation code

Find idiosyncrasies in the Adobe JavaScript engine

Find extensions that are difficult to emulate

Page 36: How to really obfuscate   your pdf malware

Exhibit A: Idiosyncrasy

36

cypher = [7, 17, 28, 93, 4, 10, 4, 30, 7, 77, 83, 72];

cypherLength = cypher.length;

hidden = "ThisIsNotTheKeyYouAreLookingFor";

hiddenLength = hidden.toString().length;

for(i=0,j=0;i<cypherLength;i++,j++)

{

cypherChar = cypher[i];

keyChar = hidden.toString().charCodeAt(j);

cypher[i] = String.fromCharCode(cypherChar ^ keyChar);

if (j == hiddenLength - 1)

j = -1;

}

eval(cypher.join(""));

Page 37: How to really obfuscate   your pdf malware

Exhibit A: Explained

37

hidden = false;

hidden = "Key";

hidden = false;

hidden = "Key";

JavaScript Standard Adobe Reader JavaScript

hidden has the value „Key“ hidden has the value „true“

Page 38: How to really obfuscate   your pdf malware

Exhibit A: Explained

38

The Adobe Reader JavaScript engine defines global variables that do not change their type on assignment.

(I suspect this happens because they are backed by C++ code)

Page 39: How to really obfuscate   your pdf malware

Exhibit B: Difficult to emulate

• Goal: Find Adobe JavaScript API functions which are nearly impossible to emulate

• Then use effects of these functions in sneaky ways to change malware behavior

• The Adobe Reader JavaScript documentation is your friend

39

Page 40: How to really obfuscate   your pdf malware

Exhibit B: Difficult to emulate

40

Functions to look for

Rendering engine

Forms extensions

Multimedia extensions

Page 41: How to really obfuscate   your pdf malware

Exhibit B: Difficult to emulate

41

crypt = "T^_]^[T IEYYD__ FuRRKBD ";

plain = Array();

key = getPageNthWordQuads(0, 0).toString().split(",")[1];

for (i=0,j=0;i<crypt.length;i++,j++)

{

plain = plain + String.fromCharCode((crypt.charCodeAt(i) ^

key.charCodeAt(j)));

if (j >= key.length)

j = 0;

}

app.alert(plain);

)

Page 42: How to really obfuscate   your pdf malware

Exhibit B: Difficult to emulate

42

Functions to avoid

Anything with security restrictions

Page 43: How to really obfuscate   your pdf malware

Exhibit C: Multi-threaded JavaScript

• Multi-threaded applications are difficult to reverse engineer

• Problem: There are no threads in JavaScript

• Solution: setTimeOut

• Example: Cooperative multi-threading with message-passing between objects

43

Page 44: How to really obfuscate   your pdf malware

Basic idea

• Multiple server objects

• String messages are passed between servers

• Messages contain new timeout value and code to evaluate

44

Page 45: How to really obfuscate   your pdf malware

45

function Server(name)

{

...

}

s1 = new Server("S1");

s2 = new Server("S2");

s1.receive(ENCODED_MESSAGE);

Page 46: How to really obfuscate   your pdf malware

46

function Server(name)

{

this.name = name;

this.receive = function(message)

{

recipient = parse_recipient(message)

delayTime = parse_delay(message)

eval_string = parse_eval_string(message)

msg_string = parse_message_string(message)

eval(eval_string);

command = "recipient.receive('" + msg_string + "')";

this.x = app.setTimeOut(command, delayTime);

}

};

Page 47: How to really obfuscate   your pdf malware

How to improve this

• Use a global string object as the message queue and manipulate the object on the fly

• Usage of non-commutative operations so thatexecution order really matters

• Message broadcasting

• Add anti-emulation code to eval-ed code

47

Page 48: How to really obfuscate   your pdf malware

callee-trick

• Not specific to Adobe Reader

• Frequently used by JavaScript code in other contexts

• Function accesses its own source and uses it as a key to decrypt code or data

• Add a single whitespace and decryption fails

48

Page 49: How to really obfuscate   your pdf malware

callee-trick Example

49

function decrypt(cypher)

{

var key = arguments.callee.toString();

for (var i = 0; i < cypher.length; i++)

{

plain = key.charCodeAt(i) ^ cypher.charCodeAt(i);

}

...

}

Page 50: How to really obfuscate   your pdf malware

More ideas for the future

• Combine anti-debugging, callee-trick, and message passing

• Find more JavaScript engine idiosyncracies: Sputnik JavaScript test suite

50

Page 51: How to really obfuscate   your pdf malware

Thanks

• Didier Stevens

• Julia Wolf

• Peter Silberman

• Bruce Dang

51

Page 52: How to really obfuscate   your pdf malware

52