本帖最后由 SkyCatcher 于 2015-4-22 10:50 编辑
对近期的各种压测等攻击的总结和防御措施 —— 尤其是BungeeCord跨服群组
因为我并不是学计算机的,文中不可避免的有描述不正确或不准确的内容,还请大家多多包涵
最近各类压测器、代码的分发层出不穷,一开始应该是从贴吧那边传出来的,而且其中的一些软件被恶意写入了木马,也就是一旦使用且没有杀毒软件或防火墙去隔离掉的话,就会让你的电脑沦为“肉鸡”,也就是发布这些木马的黑客能够从远程控制你的电脑偷偷做一些事情(比如说发动一大批肉鸡去攻击别人,抑或是出售这些肉鸡资源给别人)。
不过现在被直接发布出来的代码和软件等的攻击效果有限,如果在攻击者数量不大/攻击者网络等性能不强的情况下,一些现有的反压测攻击的插件可以起到一定防御作用。但是前几天@zhh0000zhh 用VB写了个压测器然后对我的小白鼠服务器进行了测试,并且在服务器上面运行了压测器,然后我两千多人上限的测试服务器在几秒内就被打满人数了(貌似是一万并发),然后BungeeCord端就因为过量的连接而反映缓慢,并且导致了新玩家无法连接+老玩家反映迟缓的问题,也就是说基本上已经被攻克了。从这个测试里面我才发现压测这种攻击的凶残之处,于是在这里写出这个帖子来供大家讨论,看看有没有遇到其他的攻击手段,并对当前的攻击提出一些解决方案。 压测主要是利用了mc协议漏洞(未加密的通讯过程),从而用软件模拟出很多很多的虚假的玩家不停登陆登出服务器,甚至用虚假玩家进行跑图等消耗资源的事情,从而消耗服务器的CPU、内存、网络资源并最终导致服务器崩溃或反映迟缓无法正常连接。下面分点列一下各种不同的攻击手段(主要针对BungeeCord跨服群组,因为我发现经过BC以后比直接使用Spigot更容易被打垮)。
这篇帖子就不介绍诸如使用“/co l”查OP密码、用各种商店插件或者骨粉BUG刷物品等等这种原因导致的安全漏洞,这里主要介绍最近出现的、危害较大的、主要集中于BungeeCord群组的安全漏洞和解决方案。Mod服务器和使用专用验证客户端的服务器不在讨论之列,Mod服务器可以通过改压测器源码也达到攻击目的,专用客户端理论上比较安全。
1.使用“md_5”游戏名进入群组,然后利用管理员权限使用 /end 命令关闭BungeeCord端,或者 /server 等指令跳转到其他服务器,然后OP自己或其他小号,然后做一些乱七八糟的事情。
这个攻击手段最没技术含量,其实这个和老生常谈的没有删除玩家的“/server”权限本质是一回事。应该很多使用BC跨服的服主都知道如果给了玩家 “/server <服务器名>” 的权限,就可以在没登陆的情况下直接跳转到其他服务器,如果其他服务器没有布置登陆插件的话,这时候就相当于绕开了登陆插件。如果玩家使用了OP的账号,这种情况下就直接可以使用子服务器的OP权限了。
而之所以使用"md_5"这个游戏名,是因为和/server权限是默认分配给所有玩家一样,md_5这个游戏名是默认的bungeecord服务器管理员(因为就是他写的bc)
打开你的bungeecord文件夹根目录下的config.yml,看最顶端
想必看到这里你应该懂了,因为这个ID是BC的管理员,所以直接绕过了登陆插件的判定,可以使用很多的BC管理命令,包括/end这种关闭群组端的命令。 解决方案也很简单:
1.修改config.yml里面上面代码段为 注意:有空格,而且后面不是[],是大括号{},同时记得本文件的编码格式是UTF-8
2.同样在config.yml里面设置所有组的权限都为空,这样在服务端就没人能执行BC命令了 - permissions:
- default: []
- admin: []
复制代码 3.使用登陆插件的BC端桥接插件,让玩家在未登录之前无法执行BC命令即可,具体的方案这里不详细解释,因为只能对很少一部分版本有效所以请自行百度,不作为普适解决方案
|
2.BC权限设置得当,管理员也删除了,但是仍然发现有人绕过了登陆插件到了子服务器取得OP权限
这种问题比较隐蔽,也是最近才发现的。有的群组服务器设置了登陆服务器,并且强制玩家只能先从登陆服务器进入群组,其他子服务器的spigot.yml里面设置了 bungeecord: true ,也就是不能直接用IP+端口访问到子服务器,而是需要通过BC端。
然后,这些服务器在登陆服务器设置了authme等登陆插件,其他子服务器没设置,并且也关闭了/server等命令权限而使用牌子或星门等传送方式。但是,却发现有人竟然能神不知鬼不觉的绕过了登录服务器直接进入了子服务器,并用OP账号做了乱七八糟的事情。
这个问题是为什么呢?
其实,bungeecord: true 只是限制了想登入此服务器必须通过bungeecord端,但是他并没说这个BC端是在哪里的!
也就是说,其实这些人是在自己电脑本地部署了BungeeCord端,然后直接指向了子服务器,从而能直接不验证密码登入进去。
事实上,我记得在1.6的时代spigot.yml里面bungeecord: true这附近还有个设置源IP的选项,但是1.7的时候不见了,可能是为了一些多BC指向同子服务器方便吧,但是这给了一些熊孩子可乘之机,让他们不是用密码便登录了OP的账号。
解决方案:
1.【网页面板需要看服务商的设置】将每个子服务器根目录下的server.properties文件中的“server-ip=”填为“server-ip=127.0.0.1”,这样子服务器就只接受来自本地的连接了(不影响子服务器里面获取玩家真实源IP),其他地方的连入请求都会被拒绝。如果你是跨IP的跨服群组,自行修改对应IP即可。
2.【此方案对网页面板/软件后台服务器无效】据说因为MC协议的漏洞,甚至可以伪造连入的IP(我没证实过,我觉得TCP这种需要握手的通讯应该是无法伪造IP的),为了以防万一,建议在上面的基础上,给你的服务器防火墙规则上面加几条,也就是把指向你的子服务器端口的连入请求一律拒绝。这种行为不影响你的内网BC端的分发请求。或者你把你的服务器放到虚拟机中,然后主机到虚拟机只开放一个BC端的端口,其他端口不开放。这样子也能实现对子服务器的保护
|
3.BungeeCord遭受大规模压测攻击时处理缓慢或崩溃
这个是遭受到来自专业服务器的大流量、高效率压测器,或者来自一堆肉鸡的共同攻击时出现的问题。
因为所有连入子服务器的连接都要先经过BC,从而导致BC端的压力非常大。正常情况下BC只需要很少的内存即可流畅运行,但是在被万数级别的并发攻击时,即使你服务端上面有各种反攻击手段,但是因为BC端是直接通过所有数据的,消耗会骤升,然后proxy不稳定以后,服务器的正常玩家连接也就不稳定了,即使没宕机,也差不多等于被攻击成功了。
我尝试过调整bungeecord端的connection_throttle: 4000连接延迟,但是我发现这个是无效的!也许是因为压测器的假人仅仅是初次握手的缘故吧,具体原因不清楚,已经向md_5反馈了,但是因为md_5多次表示不支持盗版模式,所以可能不了了之。
甚至我在子服务器封禁攻击IP的情况下(BC端没封禁IP功能),都因为并发攻击数量太大而导致BC端处理不过来信息的情况。
解决方案(对网页面板/软件后台服务器无效):
【以下方案对网页面板/软件后台服务器无效】
1.如果你是linux服务器,请使用iptables限制每个IP的同时连接数,以起到限制攻击速度的目的。
2.如果你是windows服务器,请使用防火墙软件来限制短时间内的同IP大量TCP连接,超限即中断此IP连接一段时间(目前还不会用windows自带高级安全防火墙实现这样的功能,如果你会的话请在下面回复)
3.使用@bangbang93 的mc-proxy(这是一个基于node.js的程序而不是插件)http://www.mcbbs.net/thread-384708-1-1.html,将mc-proxy放在bungeecord端前面作为防护,最新版的mc-proxy已经加入了限制IP的并发连接数,所以能防御这种攻击。缺点是经过了多次转发,子服务器里面无法获取到玩家的真实IP了,也就是不能ban-ip了。这个反代程序一开始是为了转发玩家源IP到虚拟机的spigot服务端上的,后面发现node.js的优良并发性能可以顺便反压测,也算是意外收获了。
|
4.普通单服务器遭到大规模压测
因为单服务端的处理性能有限,所以也许并不需要很大规模的压测就可以让你挂掉,也是中小服务器服主最常见的压测攻击。原理就是利用大量的假人登入登出来消耗服务器资源。
解决方案:
1.使用各类型的反压测防护插件,比如说我曾经发过的IP-Check http://www.mcbbs.net/thread-184777-1-1.html 虽然当初还没压测这回事,但是能对同IP登陆多个不同的玩家进行自动判别并封禁IP,也达到了一定防御效果。同样在插件版也有很多原创的专门针对压测的防御插件,各位不妨试试。
【以下方案对网页面板/软件后台服务器无效】
2.如果你是linux服务器,请使用iptables限制每个IP的同时连接数,以起到限制攻击速度的目的。
3.如果你是windows服务器,请使用防火墙软件来限制短时间内的同IP大量TCP连接。
4.使用bangbang93 的mc-proxy http://www.mcbbs.net/thread-384708-1-1.html,将mc-proxy放在spigot/caruldron端前面作为防护,最新版的mc-proxy已经加入了限制IP的并发连接数,所以能防御这种攻击。在你服务器的spigot.yml中设置bungeecord: true,即可以获取到玩家源IP,不影响正常的插件工作。
这个方案是最为简单的一种方案,当然,也对网页面板服务器无效,只能用于独立主机或者是VPS远程桌面。
|
5.利用服务端的TAB补全命令功能来消耗资源
如果你的服务端是craftbukkit,那么貌似这种攻击是无解的。这种攻击是因为攻击者发现用压测被防火墙拦截无效,所以使用了所谓的“穿透”攻击,也就是模拟单人或者少量的假人进入服务器,然后利用在聊天栏打出“/”后再按TAB能自动补全命令的功能,来不停的消耗服务器的资源。这种攻击方法并不只局限在按TAB上面,也可以不停的刷/list 或者/glist(BC群组)等命令来消耗服务器资源。
如果你的服务端是spigot或caruldron的话,你就可以通过合理的设置来避免这种攻击。
解决方案:
打开服务端根目录下的spigot.yml,1.7以下的服务端设置
1.7以上的服务端设置
这里的数字是你必须输入多少个字母才可以启用tab补全,例如你设置为3,那么输入/tpa 这么长的命令以后再按TAB才有效,如果只是/tp 然后按TAB是不补全命令的。设置为0是关闭自动补全功能
2.对于使用/list或/glist攻击的,可以严格管控玩家可以用命令的权限,从而避免这种情况
|
6.通过刷服务器Motd信息和服务器Logo来消耗服务器带宽
Motd就是你在客户端的服务器列表里面看到的服务器名下面的显示的一行字,一般服务器都将其设置为彩色的一串,有的用插件将其设置为了可变化的,每次刷新都得到不同的信息。
Logo就是1.7及以上的服务器在客户端的服务器列表里面左边显示的那个方形图片。也就是服务端根目录下的server-icon.png
因为这个特性,攻击者可以用程序来模拟获取motd和logo,然后如果模拟的并发数量很大,那么服务器会发送大量的信息给攻击者,从而导致带宽被占用。
这种攻击方式我还没真实验证过,所以不确定是否真的有效,下面给出的解决方案也基于理论并未实测。
理论上为了获取motd图片需要发送很多连接,而且这种方式连接数多了才对服务器有效,所以应该能被防火墙识别
解决方案:
1.【网页面板可能需要联系服务商】将服务器的motd设置为空,也就是在server.properties里面将motd=后面空着,并将server-icon.png删除
2.【此方案对网页面板/软件后台服务器无效】利用服务器防火墙软件,限制同IP的连接数(防DoS)和每个IP的获取速度或者流量大小,从而避免短时间内因为发送motd消耗了大量的带宽
|
7.利用服务端发送当前延迟的ping来消耗服务器CPU与内存
这种方式的特点是攻击后服务端无任何显示,且CPU和内存急剧飙升
这里有个帖子详细介绍了这种攻击方法:http://www.mcbbs.net/thread-402883-1-1.html
我这里简要介绍下,本攻击通过不停获取对方服务器的延迟ping来消耗对方服务器的CPU与内存
这是开始攻击前的服务器状态
然后开始攻击
服务器CPU瞬间打满(测试服务器为双核),内存开始稳步增加
5秒后,内存增加到了顶峰,CPU略有下降
然后停止攻击,CPU降为正常值,内存因为Java的回收机制太差,无法释放
至此已经完成了整个攻击过程,如果服务器人多或者是性能差的话,这时候应该已经蹦服了
对于攻击者来说总共只花了十来秒,但是服务器的内存却得不到释放
解决方案:
1.使用BungeeCord作为前端,BC端能自动对此类攻击进行防御
2.使用一些动态motd插件,例如
,因为这种插件为了实现自身的功能,碰巧将ping关闭掉了,所以显示为红叉叉,也进而防御了这种攻击,这种解决方案的缺点就是看不到服务器延迟了
3.【此方案对网页面板/软件后台服务器无效】使用bangbang93 的mc-proxy http://www.mcbbs.net/thread-384708-1-1.html,将mc-proxy放在spigot/caruldron端前面作为防护,需要开启Proxy的PingHandle功能。在你服务器的spigot.yml中设置bungeecord: true,即可以获取到玩家源IP,不影响正常的插件工作。
|
8.对使用BungeeCord跨服的服务器伪造IP,从而登陆OP账号(2015.2.22更新)
这个安全漏洞由@
1277832129 发现并进行了测试。
因为经过BungeeCord端以后,真实IP会被转发,用了Spigot端开启bungeecord: true选项后,可以从BC端获取真实IP。
现在这种攻击方式就是,伪造BC端发给Spigot的数据包,从而可以伪造出任意IP地址登陆子服务器。
如果你的整个群组服务器暴露在公网环境下(也就是可以直接端口号访问到子服务器,即使不能登陆进去,只要访问到就在此列),而且只有登陆服务器加装了登陆插件,那么攻击者通过伪造一个虚假的IP地址(比如说本地IP),就可以用OP用户名登陆到子服务器,然后就能不输入密码直接登陆子服务器获取OP权限
解决方案:
1.在server.properties里设置server-ip=127.0.0.1 ,这样就只侦听本地IP传来的数据(侦听本地时会直接丢弃外网传来的伪造IP数据,这种情况下即使其伪造为本地IP,也会被丢弃),不会被假数据所利用
【以下方案对网页面板/软件后台服务器无效】
2.在服务器的防火墙上面封禁外网登录到子服务器的端口,比如说Win下面用高级安全防火墙限制端口
3.将整个群组移入虚拟机中,虚拟机只开放连入BungeeCord端的端口(推荐)。这种方式可以规避很多此类漏洞造成的安全风险
|
9.使用Spigot1.8.3/官服1.8.4 之前版本的服务器,可能被伪造客户端发NBT数据包攻击蹦服(2015.4.19更新)
1.8.4是一次安全更新,详细信息在这里:http://www.mcbbs.net/thread-434972-1-1.html
由于游戏存在NBT数据传输的漏洞,所以有可能会出现有攻击者通过发送大量的嵌套NBT数据来崩掉服务器的可能性。
解决方案:
Linux下使用iptables来防御的具体实现方法请看这篇帖子(z25096708提供):http://www.mcbbs.net/thread-404025-1-1.html