Creating, obfuscating and
            analyzing malware JavaScript



                     Krzysztof Kotowicz
                     PHP Developer

                     http://web.eskot.pl
OWASP                Medycyna Praktyczna
                     krzysztof@kotowicz.net
June 2010

                Copyright © The OWASP Foundation
                Permission is granted to copy, distribute and/or modify this document
                under the terms of the OWASP License.




                The OWASP Foundation
                http://www.owasp.org
Plan

 Theory - Obfuscation and analysis
  in general
  in JavaScript
 Practice - evading automatic code analyzers
  jsunpack
  JavaScript unpacker
  Capture-HPC


                                      OWASP     2
Theory



         OWASP
Obfuscation
        Goal - make analysis harder




                                      OWASP   4
Obfuscation

 There is no perfect obfuscation                [cs.princeton.edu]

 Analysis as debugging

Debugging is twice as hard as
writing a program in the first
place. So if you're as clever as
you can be when you write it,
how will you ever debug it?
Brian Kernighan, The Elements of Programming Style
                                                       OWASP          5
Obfuscation methods

   for     while + if
   Iteration   recursion
   Complex logical tests
   Dummy code branches
   Quasitautologies [blog.didierstevens.com]
   Enigmatic variable names




                                                OWASP   6
Obfuscation methods in JS

JavaScript is a dynamic and functional language
 Code created at runtime – eval
 String.fromCharCode, unescape
 Regular expressions - String.replace
     Packers, e.g.
     [dean.edwards.name]
     [developer.yahoo.com]
     [malwareguru.org]
     [closure-compiler.appspot.com]

     Others - e.g. WhiteSpace Obfuscation   [ktcorpsecurity.com]




                                                      OWASP         7
Active defense against analysis

    Function.toString /
     arguments.callee.toString               [isc.sans.org]

    autoencryption [isc.sans.org]
    browser detection
     DOM
     window, navigator
     timings
     cookies
     mouse position, screen resolution
    Malware served only once per IP      [research.zscaler.com]

                                                   OWASP           8
Active defense - know thy language


function is_even(n) {
    var parameter_is_even =
      (n % 2) == 0 ? true : false;

     return
       parameter_is_even;
}

alert(is_even(16));


                                     OWASP   9
Result




         OWASP   10
How to analyze malware JavaScript?

 Know JavaScript!
 Run the code & observe effects in a
  controlled environment
 Overload functions
    eval
    String.fromCharCode
 Deobfuscate parts of code
 Be patient and creative

                                        OWASP   11
JavaScript analysis...

   Is rather heuristics than algorithm
   Is rather manual than automatic
   Human is required
   Tools help greatly, but they're not perfect




                                         OWASP    12
Practice



      OWASP
jsunpack

 Runs JS inside SpiderMonkey      [mozilla.org]
   JS fetched from URL, PCAP, JS/HTML file…
 SM is modified to include:
   DOM emulation
   browser objects emulation
   onload() event
 monitors eval(), setTimeout() and
  others
 scans the code using signatures file

                                                   OWASP   14
jsunpack - weak points

 Emulates browser
 Code that won't run (dead
  branches) will be checked with
  signatures only




                               OWASP   15
Evading detection


 if (fake_browser) {
   do_no_harm();
 } else {
   redirect_to_malicious_website();
   // or obfuscate an exploit
 }


 We need to detect being run in jsunpack

                                     OWASP   16
How to detect jsunpack?

Many, many ways:
 Bad implementation of
   window.location
  fake_browser = window.location.host.match('/'); pliku
  window.location.host = ścieżka do


 It adds its own global variables
  fake_browser = (typeof my_location != "undefined");
  // my_navigator, my_activex, my_element,
  // the_activex, app, ...


                                                OWASP     17
How to detect jsunpack?

 It overloads some functions
fake_browser = (window.open.toString().match(/print/));
fake_browser = (alert.toString().match(/{s*}/));


 Objects emulation has missing spots

 fake_browser = (typeof
     PluginArray.prototype.refresh == "undefined");

 fake_browser = (document.title == 'My Title');




                                                  OWASP   18
Jsunpack - bonus

 jsunpack runs not only JavaScript

<script type="text/dummy">
  // good enough for jsunpack
</script>

 Code will be run in jsunpack, but not in
  browsers


                                      OWASP   19
Note to online viewers:
 Demos require checking and running the files locally - see attached docs



         DEMO 1
index.php / js.js - sandbox detection
(modify js.js to test different techniques)

jekyll2.html - Dr Jekyll attack

js.js - HTML hack
(shortest jsunpack disabler)




 github.com/koto/owasp-malicious-javascript/
                                                                     OWASP   20
jsunpack - summary

 You could easily detect being run in
  jsunpack sandbox
 When detected, you just skip doing bad
  stuff
 If malware code is obfuscated, it will not
  be detected with signatures

You go under the radar of jsunpack analysis

                                     OWASP     21
Dean Edwards' Unpacker

A JavaScript Decompressor [dean.edwards.name]
 Reverses Dean Edward's packer
 Packer works like this:
eval(function(p,a,c,k,e,r){/*code*/}(para,
meters))

/* which is the same as */
var packer = function(p,a,c,k,e,r) {/**/};
var s = packer(para,meters);
eval(s);


                                          OWASP   22
Unpacker - step 1

 Replace eval() with string assignment

    // packed code is in input
    var input="eval(function(p,a,c,k....";

    eval("var value=String" +
    input.slice(4)); // cut "eval"

    // executed code will be:
    var value=String(function(p,a,c,k..);

 value holds decompressed code

                                          OWASP   23
Unpacker - step 1

 Replace eval() with string assignment
     // packed code is in input
     var input="eval(function(p,a,c,k....";

     eval("var value=String" +
     input.slice(4)); // cut "eval"

     // executed code will be:
     var value=String(function(p,a,c,k..);

 value holds decompressed code
 But! we're blindly executing cut&pasted code!
                                           OWASP   24
Unpacker - step 2

 Use Function.toString() to display the code

     eval(
     "var unpacked = function() {"
     + value + "}"
     );
     alert(unpacked.toString());


 Unpacked code WILL NOT RUN, it wil just print!
   Disclaimer - the real code is a bit different, but the concept is the
    same

                                                             OWASP          25
Dean Edwards Unpacker - weak points

 Concatenating strings and executing the
  resulting code (injection, anyone?)
 Using a constant - we cut first 4 characters
  without looking at them
 eval() without any validation
 Depends on Function.toString() to
  print the code




                                          OWASP   26
Dean Edwards Unpacker - disarming

 eval() uses a single parameter
 String() uses a single parameter
 ...but you could give more :)
 eval("code");
 eval("code", "ignored");
 eval("code", malicious());
 String("code", malicious());

 Arbitrary code execution without changing
  p,a,c,k,e,r function!

                                       OWASP   27
Dean Edwards Unpacker - disarming

 eval(function(p,a,c,k,e,r){...}(para,mete
 rs),malicious());

 var
 value=String(function(p,a,c,k,e,r){...}(p
 ara,meters),malicious());

 malicious() will execute in packed code
  and in unpacker




                                    OWASP    28
Dean Edwards Unpacker - disarming

What can we do in malicious()?
 Unpacker uses Function.toString()
 Let's override it!
 malicious() is e.g. obfuscated:

Function.prototype.toString = function()
{
  return 'harmless code';
}


                                    OWASP   29
DEMO 2

demo2/evil.packed.js




github.com/koto/owasp-malicious-javascript/
                                    OWASP     30
Dean Edwards Unpacker - point of concept




                                   OWASP   31
High interaction client honeypots

Capture-HPC     [projects.honeynet.org]   as an example
 Code is run in real browser in a virtual machine
 Server serves URL list to visit
 Client starts browsers and waits…
 Code side-effects are monitored
  Filesystem
  Registry
  Processes
 If anything suspicious happens with the system, URL
  is reported to server as a malware

                                                      OWASP   32
High interaction client honeypots

 Runtime environment is the same
 There is no emulation

       Could we detect we're traced?




                                       OWASP   33
Weak point




             OWASP   34
High interaction client honeypots - robot

                      Doesn't move mouse
                      Doesn't click
                      Doesn't drag
                      Doesn't navigate
                      Is "stupid"




                                      OWASP   35
High interaction client honeypots - user

                      Moves mouse
                      Clicks
                      Drags
                      Navigates
                      Is stupid




                                      OWASP   36
Honeypots – social engineering




                                 OWASP   37
Honeypots – social engineering




                                 OWASP   38
Honeypots - summary

 No emulation layer to detect
 Code is run in real browser
 Weakest point is the lack of human
  element
 Just run the code after detecting an
  interaction with the page




                                    OWASP   39
Summary

    Obfuscation can only make analysis slower
    Code can actively defend against analysis
    Human is required to do a complete analysis
    Analysis requires strong skills
    Automatic tools can be fooled
     detect emulation differences
     errors
     lack of full interaction with a webpage


                                          OWASP    40
Links
Demo source: github.com/koto/owasp-malicious-javascript
Tools
       jsunpack.blogspot.com
       dean.edwards.name/unpacker/
       projects.honeynet.org/capture-hpc
       malzilla.sourceforge.net
Obfuscation and analysis
       isc.sans.org/diary.html
       www.malwareguru.org
       delicious.com/koto/obfuscation
       closure-compiler.appspot.com
JavaScript
       www.slideshare.net/ferrantes/just-advanced-javascript
       jsninja.com


krzysztof@kotowicz.net             http://blog.kotowicz.net
                                                                OWASP   41

Creating, obfuscating and analyzing malware JavaScript

  • 1.
    Creating, obfuscating and analyzing malware JavaScript Krzysztof Kotowicz PHP Developer http://web.eskot.pl OWASP Medycyna Praktyczna krzysztof@kotowicz.net June 2010 Copyright © The OWASP Foundation Permission is granted to copy, distribute and/or modify this document under the terms of the OWASP License. The OWASP Foundation http://www.owasp.org
  • 2.
    Plan  Theory -Obfuscation and analysis  in general  in JavaScript  Practice - evading automatic code analyzers  jsunpack  JavaScript unpacker  Capture-HPC OWASP 2
  • 3.
    Theory OWASP
  • 4.
    Obfuscation Goal - make analysis harder OWASP 4
  • 5.
    Obfuscation  There isno perfect obfuscation [cs.princeton.edu]  Analysis as debugging Debugging is twice as hard as writing a program in the first place. So if you're as clever as you can be when you write it, how will you ever debug it? Brian Kernighan, The Elements of Programming Style OWASP 5
  • 6.
    Obfuscation methods  for while + if  Iteration recursion  Complex logical tests  Dummy code branches  Quasitautologies [blog.didierstevens.com]  Enigmatic variable names OWASP 6
  • 7.
    Obfuscation methods inJS JavaScript is a dynamic and functional language  Code created at runtime – eval  String.fromCharCode, unescape  Regular expressions - String.replace  Packers, e.g.  [dean.edwards.name]  [developer.yahoo.com]  [malwareguru.org]  [closure-compiler.appspot.com]  Others - e.g. WhiteSpace Obfuscation [ktcorpsecurity.com] OWASP 7
  • 8.
    Active defense againstanalysis  Function.toString / arguments.callee.toString [isc.sans.org]  autoencryption [isc.sans.org]  browser detection  DOM  window, navigator  timings  cookies  mouse position, screen resolution  Malware served only once per IP [research.zscaler.com] OWASP 8
  • 9.
    Active defense -know thy language function is_even(n) { var parameter_is_even = (n % 2) == 0 ? true : false; return parameter_is_even; } alert(is_even(16)); OWASP 9
  • 10.
    Result OWASP 10
  • 11.
    How to analyzemalware JavaScript?  Know JavaScript!  Run the code & observe effects in a controlled environment Overload functions  eval  String.fromCharCode  Deobfuscate parts of code  Be patient and creative OWASP 11
  • 12.
    JavaScript analysis...  Is rather heuristics than algorithm  Is rather manual than automatic  Human is required  Tools help greatly, but they're not perfect OWASP 12
  • 13.
    Practice OWASP
  • 14.
    jsunpack  Runs JSinside SpiderMonkey [mozilla.org]  JS fetched from URL, PCAP, JS/HTML file…  SM is modified to include:  DOM emulation  browser objects emulation  onload() event  monitors eval(), setTimeout() and others  scans the code using signatures file OWASP 14
  • 15.
    jsunpack - weakpoints  Emulates browser  Code that won't run (dead branches) will be checked with signatures only OWASP 15
  • 16.
    Evading detection if(fake_browser) { do_no_harm(); } else { redirect_to_malicious_website(); // or obfuscate an exploit }  We need to detect being run in jsunpack OWASP 16
  • 17.
    How to detectjsunpack? Many, many ways:  Bad implementation of window.location fake_browser = window.location.host.match('/'); pliku window.location.host = ścieżka do  It adds its own global variables fake_browser = (typeof my_location != "undefined"); // my_navigator, my_activex, my_element, // the_activex, app, ... OWASP 17
  • 18.
    How to detectjsunpack?  It overloads some functions fake_browser = (window.open.toString().match(/print/)); fake_browser = (alert.toString().match(/{s*}/));  Objects emulation has missing spots fake_browser = (typeof PluginArray.prototype.refresh == "undefined"); fake_browser = (document.title == 'My Title'); OWASP 18
  • 19.
    Jsunpack - bonus jsunpack runs not only JavaScript <script type="text/dummy"> // good enough for jsunpack </script>  Code will be run in jsunpack, but not in browsers OWASP 19
  • 20.
    Note to onlineviewers: Demos require checking and running the files locally - see attached docs DEMO 1 index.php / js.js - sandbox detection (modify js.js to test different techniques) jekyll2.html - Dr Jekyll attack js.js - HTML hack (shortest jsunpack disabler) github.com/koto/owasp-malicious-javascript/ OWASP 20
  • 21.
    jsunpack - summary You could easily detect being run in jsunpack sandbox  When detected, you just skip doing bad stuff  If malware code is obfuscated, it will not be detected with signatures You go under the radar of jsunpack analysis OWASP 21
  • 22.
    Dean Edwards' Unpacker AJavaScript Decompressor [dean.edwards.name]  Reverses Dean Edward's packer  Packer works like this: eval(function(p,a,c,k,e,r){/*code*/}(para, meters)) /* which is the same as */ var packer = function(p,a,c,k,e,r) {/**/}; var s = packer(para,meters); eval(s); OWASP 22
  • 23.
    Unpacker - step1  Replace eval() with string assignment // packed code is in input var input="eval(function(p,a,c,k...."; eval("var value=String" + input.slice(4)); // cut "eval" // executed code will be: var value=String(function(p,a,c,k..);  value holds decompressed code OWASP 23
  • 24.
    Unpacker - step1  Replace eval() with string assignment // packed code is in input var input="eval(function(p,a,c,k...."; eval("var value=String" + input.slice(4)); // cut "eval" // executed code will be: var value=String(function(p,a,c,k..);  value holds decompressed code  But! we're blindly executing cut&pasted code! OWASP 24
  • 25.
    Unpacker - step2  Use Function.toString() to display the code eval( "var unpacked = function() {" + value + "}" ); alert(unpacked.toString());  Unpacked code WILL NOT RUN, it wil just print!  Disclaimer - the real code is a bit different, but the concept is the same OWASP 25
  • 26.
    Dean Edwards Unpacker- weak points  Concatenating strings and executing the resulting code (injection, anyone?)  Using a constant - we cut first 4 characters without looking at them  eval() without any validation  Depends on Function.toString() to print the code OWASP 26
  • 27.
    Dean Edwards Unpacker- disarming  eval() uses a single parameter  String() uses a single parameter  ...but you could give more :) eval("code"); eval("code", "ignored"); eval("code", malicious()); String("code", malicious());  Arbitrary code execution without changing p,a,c,k,e,r function! OWASP 27
  • 28.
    Dean Edwards Unpacker- disarming eval(function(p,a,c,k,e,r){...}(para,mete rs),malicious()); var value=String(function(p,a,c,k,e,r){...}(p ara,meters),malicious());  malicious() will execute in packed code and in unpacker OWASP 28
  • 29.
    Dean Edwards Unpacker- disarming What can we do in malicious()?  Unpacker uses Function.toString()  Let's override it!  malicious() is e.g. obfuscated: Function.prototype.toString = function() { return 'harmless code'; } OWASP 29
  • 30.
  • 31.
    Dean Edwards Unpacker- point of concept OWASP 31
  • 32.
    High interaction clienthoneypots Capture-HPC [projects.honeynet.org] as an example  Code is run in real browser in a virtual machine  Server serves URL list to visit  Client starts browsers and waits…  Code side-effects are monitored  Filesystem  Registry  Processes  If anything suspicious happens with the system, URL is reported to server as a malware OWASP 32
  • 33.
    High interaction clienthoneypots  Runtime environment is the same  There is no emulation Could we detect we're traced? OWASP 33
  • 34.
    Weak point OWASP 34
  • 35.
    High interaction clienthoneypots - robot  Doesn't move mouse  Doesn't click  Doesn't drag  Doesn't navigate  Is "stupid" OWASP 35
  • 36.
    High interaction clienthoneypots - user  Moves mouse  Clicks  Drags  Navigates  Is stupid OWASP 36
  • 37.
    Honeypots – socialengineering OWASP 37
  • 38.
    Honeypots – socialengineering OWASP 38
  • 39.
    Honeypots - summary No emulation layer to detect  Code is run in real browser  Weakest point is the lack of human element  Just run the code after detecting an interaction with the page OWASP 39
  • 40.
    Summary  Obfuscation can only make analysis slower  Code can actively defend against analysis  Human is required to do a complete analysis  Analysis requires strong skills  Automatic tools can be fooled  detect emulation differences  errors  lack of full interaction with a webpage OWASP 40
  • 41.
    Links Demo source: github.com/koto/owasp-malicious-javascript Tools  jsunpack.blogspot.com  dean.edwards.name/unpacker/  projects.honeynet.org/capture-hpc  malzilla.sourceforge.net Obfuscation and analysis  isc.sans.org/diary.html  www.malwareguru.org  delicious.com/koto/obfuscation  closure-compiler.appspot.com JavaScript  www.slideshare.net/ferrantes/just-advanced-javascript  jsninja.com krzysztof@kotowicz.net http://blog.kotowicz.net OWASP 41