找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2448|回复: 33

[建设意见] 地图作者和服务器管理员必看!请检查自己的地图中是否存在此类漏洞!

[复制链接]
发表于 2023-4-13 12:43:04 | 显示全部楼层 |阅读模式
游戏昵称 用户89189|U币余额 846
本帖最后由 根林大老虎 于 2023-4-14 17:53 编辑

>
        4月12日,贴主于凌晨发现一个关于Vscript脚本的严重地图漏洞,该漏洞在ze地图中应该是第一次被发现。此漏洞影响十分严重,建议各位地图作者与服务器管理员务必检查自己或服务器地图池的地图中有无此类漏洞,有则迅速修补。也建议服务器管理员暂时对有漏洞的地图进行下架处理,在漏洞修补后再进行上传,避免服务器运行受到影响。

        视频:[【给服务器一点小小的权限震撼】]( https://www.bilibili.com/video/BV1Dj411c7SR/?share_source=copy_web&vd_source=7f0c8d4962d6d4cfa4085779103c5671)



##### 1. 漏洞类型

         Vscript脚本注入漏洞



##### 2. 漏洞危害

        地图中存在此漏洞时,任意玩家可以使用此漏洞在服务器地图中执行任意Vscript脚本语句、对实体操作(任意触发实体IO或增删实体)、使地图中玩家执行部分客户端控制台指令、执行部分服务器控制台指令、使服务端崩溃、越权使用部分管理员指令等。



##### 3. 漏洞原理

        测试地图:ze_pizzatime_v9(披萨时间)

​        这张地图中使用了监听player_say事件的监听器实体。该实体在监听到玩家发送聊天框消息的player_say事件后,会自动执行Vscript脚本中的特定函数,所执行的函数的定义及注释如下:

```squirrel
// 语言:Squirrel 2.2.3 stable

// 监听器监听到player_say事件后会执行此函数,其中参数event_data由监听器传入,是一张Squirrel表(Squirrel语言的基本数据类型)
// 参数event_data,表中含有此次事件的信息,比如发送聊天框消息的玩家的用户ID,发送的消息内容等
::OnGameEvent_player_say_raw <- function(event_data)
{

        // 这里定义了一个变量code,该变量的值为若干个字符串和事件信息拼接而成的字符串
        // event_data.userid的值为发送聊天框消息的玩家的用户ID
        // event_data.text的值为发送的消息内容

        local code = " OnPlayerChat(" + event_data.userid + ",\"" + event_data.text + "\"); ";


        // 这里执行了EntFire()函数,该函数的功能为触发一个实体的输入(Input)
        // 其中,"event_manager"是目标实体的targetname
        // "RunScriptCode"是输入的类型,该输入类型的作用为将参数code字符串视作一行Vscript语句,进行编译和执行
        // 0.00和null这两个参数我们可以不用管

        EntFire("event_manager", "RunScriptCode", code, 0.00, null);
}
```

         简单来说,就是每当有一个玩家在聊天框发送消息,就会有以下格式的字符串会被当作Vscript代码被编译和执行:

```squirrel
OnPlayerChat(玩家用户ID,"发送的消息内容");
```
         其中OnPlayerChat()是一个定义在其他地方的函数,作用是根据玩家ID和发送消息内容执行一些指令,具体定义内容可以不用管。



​         先举个正常的例子,如果一名玩家(假定用户ID为1)在聊天框中发送了以下消息:

> 能不能给我订张格里斯?

​         那么监听器将监听到player_say事件,自动执行OnGameEvent_player_say_raw()函数。而在此函数的此次执行过程中,参数code被构建成一个这样的字符串:

```squirrel
OnPlayerChat(1,"能不能给我订张格里斯?");
```

        以上字符串会在EntFire()函数中,在"RunScriptCode"的作用下被编译并执行。此次编译执行十分正常,似乎没有什么不妥。



        但是如果一名玩家(假定用户ID为2)在聊天框中发送了以下消息:

> " + print("xxx狗都不玩") + "

        那么参数code构建的字符串如下所示:

```squirrel
OnPlayerChat(2,"" + print("xxx狗都不玩") + "");
```

         在"RunScriptCode"编译并执行以上code时,可以发现,OnPlayerChat()函数的第二个参数的形式与之前玩家用户ID为1的情况有所不同。在第二个参数中,"" 是一个空字符串,紧接着使用了 + 运算符将该空字符串 "" 和一个Vscript函数 print("xxx狗都不玩") 与另一个空字符串 "" 进行了拼接。由于print()函数执行后返回null,而在Squirrel语言中,字符串可以与null拼接,因此整条语句是可以通过编译的。那么根据Squirrel语言的规则,在整条语句编译后执行时,print("xxx狗都不玩")  这一函数在服务器地图上被执行,该函数作用是在服务器控制台打印”xxx狗都不玩“这一字符串。

        至此,我们可以看到,在用户ID为2的玩发送了经过精心构造的特殊的聊天框消息后,服务器执行了一个由用户ID为2的玩家插入在聊天消息中的Vscript函数print(),这是一个非常典型的注入漏洞。



        除了上述OnGameEvent_player_say_raw()函数外,以下函数同样存在着类似的漏洞:

```squirrel
// 与之前的漏洞利用方法类似,不过这里不是在聊天框输入消息,而是修改自己的Steam用户名为  "+print("xxx狗都不玩")+"
// 之后再连接到服务器,监听器监听到player_connect事件后,此函数被执行,被插入在用户名中的函数print()被编译执行
// event_data.name的值为玩家的Steam用户名
::OnGameEvent_player_connect_raw <- function(event_data)
{
        local code = " OnPlayerConnect(\"" + event_data.name + "\"," + event_data.userid + ",\"" + event_data.networkid + "\"); ";
        EntFire("event_manager", "RunScriptCode", code, 0.00, null);
        code = " CheckConnected(\"" + event_data.name + "\"," + event_data.userid + ",\"" + event_data.networkid + "\"); ";
        EntFire("event_manager", "RunScriptCode", code, 0.00, null);
}

// 该函数在玩家更改名字时执行
// 例如将名字改为 print("xxx狗都不玩")
::OnGameEvent_player_changename_raw <- function(event_data)
{
        local code = " OnPlayerChangeName(" + event_data.userid + "," + event_data.oldname + "," + event_data.newname+"); ";
        EntFire("event_manager", "RunScriptCode", code, 0.00, null);
}

// 该函数在玩家与服务器断开连接时执行
::OnGameEvent_player_disconnect_raw <- function(event_data)
{
        local code = " OnPlayerDisconnect("+event_data.userid + ",\"" + event_data.reason + "\",\"" + event_data.name + "\",\"" + event_data.networkid + "\"); ";
        EntFire("event_manager", "RunScriptCode", code, 0.00,null);
}
```

        用一句话总结漏洞原理,即地图作者编写了一份不严谨的地图的Vscript,在其中使用了一些函数的功能将一个字符串进行了编译并执行,而该字符串包含或拼接了一些可以由玩家控制内容的字符串,而且脚本中没有对这些字符串进行检查、过滤或转换,导致注入漏洞产生。



##### 4. 哪些地图存在漏洞?

        目前,发现以下地图均存在相同的漏洞:

>        ze_pizzatime_v9(披萨时间)
>
>        ze_eternal_grove_v3(永恒之森)
>
>        ze_best_korea_v1(最美朝鲜)
>
>        ze_touhou_gensokyo_o4(幻想乡:阿尔法突袭)

        以上地图均在Vscript脚本的监听器触发函数OnGameEvent_XXXX()中,使用了EntFire()函数进行触发"RunScriptCode"输入,且参数中包含玩家可控制内容的字符串如聊天框消息和玩家Steam用户名。

        有很大可能还存在其它有相同漏洞的地图,只是贴主没有发现。贴主已经托人联系了Luffaren,协助其修补自己的地图的漏洞。也十分建议各位地图作者与服务器管理员对已有的地图进行漏洞排查和修复。



##### 5. 如何检查地图是否存在漏洞?

        逐一检查地图中.nut脚本文件和.vmf文件,对使用到"RunScriptCode"输入的语句和compilestring()函数的语句,检查其参数中是否含有可由玩家控制内容的组成部分,若有且未对其进行过滤或转换,则存在注入漏洞。



##### 6. 对已存在漏洞的地图如何修复?

        参考Luffaren的修复方法(在完成测试后会上传至gamebanana),同时使用stripper和Vscript文件。

        主要思路为,通过stripper添加logic_relay实体,在每回合开始时自动触发Vscript文件的脚本函数,在函数中对存在漏洞的原有函数进行覆写。

        在stripper中添加logic_relay实体:

```
; 将文件命名为  地图名.cfg
add:
{
        "classname" "logic_relay"
        "targetname" "fix_inject"
        "vscripts" "fix_inject.nut"
        
        "OnSpawn" "!self,Trigger,,0.00,-1"
        "OnSpawn" "!self,Trigger,,0.05,-1"
        "OnSpawn" "!self,Trigger,,0.20,-1"
        "OnTrigger" "!self,RunScriptCode,FixInject(),0.00,-1"
}
```

​               

        fix_inject.nut(请根据实际漏洞存在情况进行增删改):

```squirrel
// 放在 csgo/scripts/vscripts 文件夹中
FixInject <- function()
{
        // 对存在漏洞的函数进行覆写
        ::OnGameEvent_player_say_raw <- function(event_data)
        {
                local ent = Entities.FindByName(null, "event_manager");
                if(ent.IsValid() && ent.ValidateScriptScope())
                {
                         // 使用此语句代替  EntFire("event_manager", "RunScriptCode", code, 0.00, null);
                         ent.GetScriptScope().OnPlayerChat(event_data.userid, event_data.text);
                }
        }

        // ... ... 对其他有漏洞的函数进行覆写
}
FixInject();
```



##### 7. 如有错漏请斧正。

##### ~~8. 这编辑器怎么老吞我代码:(~~





评分

参与人数 6威望 +12 U点 +218 贡献 +12 收起 理由
kiss呆呆 + 50 赞一个!
Guaneaer + 50 赞一个!
Nexon + 6
夏末未央 + 6 + 6 + 6 赞一个!
澪酱 + 100 赞一个!
Amuro + 6 + 6 + 6 赞一个!

查看全部评分

回复

使用道具 举报

头像被屏蔽
发表于 2023-4-13 12:47:44 | 显示全部楼层
游戏昵称 一颗堡包|U币余额 165815
回复

使用道具 举报

发表于 2023-4-13 12:55:45 | 显示全部楼层
游戏昵称 PIcACG|U币余额 307278
回复

使用道具 举报

发表于 2023-4-13 13:03:59 | 显示全部楼层
游戏昵称 Please Shut Up|U币余额 1000
回复

使用道具 举报

发表于 2023-4-13 13:07:20 | 显示全部楼层
游戏昵称 Jiaodu|U币余额 4105
是地图BUG就好
回复 支持 反对

使用道具 举报

发表于 2023-4-13 13:08:00 | 显示全部楼层
游戏昵称 我菜逼|U币余额 17809
游戏昵称 琉紫璃音|U币余额 163268
回复 支持 反对

使用道具 举报

发表于 2023-4-13 13:11:27 | 显示全部楼层
游戏昵称 夏末未央|U币余额 348079
带老虎真专业
回复 支持 反对

使用道具 举报

发表于 2023-4-13 13:13:03 | 显示全部楼层
游戏昵称 黑月铁骑i|U币余额 37836
这个貌似只能地图作者去尝试修复    插件修复  可能会导致地图出现各种BUG
回复 支持 反对

使用道具 举报

发表于 2023-4-13 13:35:46 | 显示全部楼层
游戏昵称 深海宝箱|U币余额 1465
回复

使用道具 举报

发表于 2023-4-13 13:41:40 | 显示全部楼层
游戏昵称 Eurf130|U币余额 693
回复

使用道具 举报

发表于 2023-4-13 13:47:31 | 显示全部楼层
游戏昵称 Qi骑空士|U币余额 15811
nb
回复

使用道具 举报

发表于 2023-4-13 13:48:03 | 显示全部楼层
游戏昵称 大萌新|U币余额 8436
回复

使用道具 举报

发表于 2023-4-13 13:56:23 | 显示全部楼层
游戏昵称 凉糕✧|U币余额 15097
回复

使用道具 举报

发表于 2023-4-13 13:58:50 | 显示全部楼层
游戏昵称 聖誕老人|U币余额 3890
回复

使用道具 举报

发表于 2023-4-13 14:10:48 | 显示全部楼层
游戏昵称 西施酱の摆烂兔子|U币余额 31639
佬!牛!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|UB游戏社区 ( 闽ICP备2021016118号-1 )

GMT+8, 2024-10-6 17:22

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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