Vim: Flawed Fix of Arbitrary Code Execution Vulnerability in filetype.vim
1. SUMMARY
Product : Vim -- Vi IMproved
Version : Tested with Vim 7.2b.10, filetype.vim 2008-07-17
Impact : Arbitrary code execution
Wherefrom: Local and remote
CVE : CVE-2008-2712
Original : http://www.rdancer.org/vulnerablevim-filetype.vim.updated.html
http://www.rdancer.org/vulnerablevim-filetype.vim.updated.patch
http://www.rdancer.org/vulnerablevim-latest.tar.bz2
This is an update of a previous advisory[1]. Vim patch 7.1.300 which
purported to fix the ``filetype.vim'' vulnerability did not fix the
vulnerability.
2. BACKGROUND
``Vim is an almost compatible version of the UNIX editor Vi. Many new
features have been added: multi-level undo, syntax highlighting,
command line history, on-line help, spell checking, filename
completion, block operations, etc.''
-- Vim README.txt
``Problem: Value of asmsyntax argument isn't checked for valid
characters.
Solution: Only accepts letters and digits.''
-- Vim Patch 7.1.300[2]
3. VULNERABILITY
This is the ``filetype.vim'' vulnerability, described in the sections
3.4.2.1. and 3.4.2.2. of the original advisory[1]. It can lead to
arbitrary code execution upon Vim opening a crafted file. The file can
be either local or remote, and the filename must match one of the
following glob patterns:
*.asm
*.s
*.S
*.a
*.A
*.mac
*.lst (with the exception of /boot/grub/menu.lst)
*.i
4. PURPORTED FIX
Quoting the original advisory[1]:
``[A]bsent sanitization on line 190, followed by the execute
statements at filetype.vim lines 181 or 1267:
``The code looks in the first five lines [of the file being opened]
for a statement of the form ``asmsyntax=FOO'', where FOO can contain
any characters except Tab and Space. FOO is then executed, without
any sanitization.''
187 let head = " ".getline(1)." ".getline(2)." ".getline(3)."
".getline(4).
188 \" ".getline(5)." "
189 if head =~ '\sasmsyntax=\S\+\s'
*190 let b:asmsyntax = substitute(head,
'.*\sasmsyntax=\(\S\+\)\s.*','\1', "")
[... logical flow of the code then jumps to line 181 ...]
*181 exe "setf " . b:asmsyntax
[... or line 1267 ...]
*1267 exe "setf " . b:asmsyntax
Patch 7.1.300 changed the regular expression in the substitute() call on
line 190:
let b:asmsyntax = substitute(head,
'.*\sasmsyntax=\([a-zA-Z0-9]\+\)\s.*','\1', "")
This would work if substitute() were a matching function -- returning a
matching string, or an empty string if the pattern failed to match. But
substitute() always returns its first argument -- substituting the
matching string (if any). If the pattern fails to match, substitute()
returns its first argument as-is:
| pattern matches | no match
------------------+-----------------+--------------------
substitute() | alter match | return as-is
------------------+-----------------+--------------------
matching function | return match | return empty string
The previous line of code (line 189) remains unchanged, leaving two
different regular expressions. It is easy to create a payload matching
the first regular expression, but not the second one. As a matter of
fact, the payload in the test suite[3] that accompanied the original
advisory did just that.
It may be also worth noting that the failure to sanitize the input may
not have been fatal if the ``execute'' statements on lines 181 and 1276
were updated to use the fnameescape() function to sanitize the
arguments.
5. EXPLOIT
The exploit needed a small update in order to work with the current Vim.
It produces error messages, and the exploit text is not hidden. Making
the exploit fully compatible would be just a matter of spending some
more time. The updated exploit is called ``filetype.vim.updated'':
-------------------------------------------
-------- Test results below ---------------
-------------------------------------------
Vim version 7.2b, included patches: 1-10
filetype.vim revision date: 2008 Jul 17
zip.vim version: v21
netrw.vim version: v127
-------------------------------------------
filetype.vim
strong : EXPLOIT FAILED
weak : EXPLOIT FAILED
filetype.vim.updated
--> strong : VULNERABLE
--> weak : VULNERABLE
tarplugin : EXPLOIT FAILED
tarplugin.updated: EXPLOIT FAILED
tarplugin.v2: EXPLOIT FAILED
zipplugin : EXPLOIT FAILED
zipplugin.v2: EXPLOIT FAILED
xpm.vim
xpm : EXPLOIT FAILED
xpm2 : EXPLOIT FAILED
remote : EXPLOIT FAILED
gzip_vim : EXPLOIT FAILED
netrw : EXPLOIT FAILED
netrw.v2 : EXPLOIT FAILED
netrw.v3 : EXPLOIT FAILED
netrw.v4 : EXPLOIT FAILED
netrw.v5 : VULNERABLE
shellescape: EXPLOIT FAILED
6. PATCH
A copy of a patch that fixes this vulnerability can be found at the URL
below[4].
7. REFERENCES
[1] Collection of Vulnerabilities in Fully Patched Vim 7.1
http://www.rdancer.org/vulnerablevim.html
[2] Patch 7.1.300
http://groups.google.com/group/vim_dev/msg/5a882ab234f02377
http://ftp.vim.org/pub/vim/patches/7.1/7.1.300
[3] The Vulnerable Vim Test Suite
http://www.rdancer.org/vulnerablevim-latest.tar.bz2
[4] Proposed patch
http://www.rdancer.org/vulnerablevim-filetype.vim.updated.patch
8. COPYRIGHT
This advisory is Copyright 2008 Jan Minar <rdancer@xxxxxxxxxxx>
Copying welcome, under the Creative Commons ``Attribution-Share Alike''
License http://creativecommons.org/licenses/by-sa/2.0/uk/
Code included herein, and accompanying this advisory, may be copied
according to the GNU General Public License version 2, or the Vim
license. See the subdirectory ``licenses''.
Various portions of the accompanying code were written by various
parties. Those parties may hold copyright, and those portions may be
copied according to their respective licenses.
9. HISTORY
2008-07-23 Sent to: <bugs@xxxxxxx>, <vim-dev@xxxxxxx>,
<full-disclosure@xxxxxxxxxxxxxxxxx>, <bugtraq@xxxxxxxxxxxxxxxxx>