Computer Security
[EN] securityvulns.ru
no-pyccku



Related information

  vim multiple security vulnerabilities

  Vim: Arbitrary Code Execution in Commands: K, Control-], g]

  Vim 7.2c.002 Fixes Arbitrary Command Execution when Handling Tar Archives

  Vim: Netrw: FTP User Name and Password Disclosure

  Vim: Flawed Fix of Arbitrary Code Execution Vulnerability in filetype.vim

From:Jan Minar <rdancer_(at)_rdancer.org>
Date:08.08.2008
Subject:Vim: Unfixed Vulnerabilities in Tar Plugin Version 20

Vim: Unfixed Vulnerabilities in Tar Plugin Version 20

1. SUMMARY

Product  : Vim -- Vi IMproved
Version  : Vim >= 7.0 (possibly older), present in 7.2c.002
          autoload/tar.vim >= 9 (possibly older), present in version 20
Impact   : Arbitrary code execution
Wherefrom: Local, remote
CVE      : CVE-2008-2712
Original : http://www.rdancer.org/vulnerablevim-tarplugin-update.html

The Vim Tar Plugin vulnerabilities published in our previous advisories
have been addressed, but the changes do not provide fix for all attack
vectors.  We analyses some of the vulnerabilities remaining in
``$VIMRUNTIME/autoload/tar.vim''.


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

``When one edits a *.tar file, this plugin will handle displaying a
  contents page.  Select a file to edit by moving the cursor atop
  the desired file, then hit the <return> key.  After editing, one may
  also write to the file.''

               -- Tar File Interface (pi_tar.txt)


3. ATTEMPTED FIX

These are all the ``execute'' and system() calls in the current code
(autoload/tar.vim version 20, 2008-07-30) code.  It can be seen that all
the vulnerable statements have been changed.  Unfortunately, not all the
changes provide a sufficient fix.  (We analyse the vulnerabilities in
section 4 below):

   133   let tarfile=substitute(system("cygpath -u
".s:Escape(tarfile,0)),'\n$','',
'e')
   138   exe "silent r! gzip -d -c -- ".s:Escape(tarfile,1)." |
".g:tar_cmd." -".g:tar_browseoptions." - "
   141   exe "silent r! cat -- ".s:Escape(tarfile,1)."|gzip -d -c
-|".g:tar_cmd." -".g:tar_browseoptions." - "
   144   exe "silent r! bzip2 -d -c -- ".s:Escape(tarfile,1)." |
".g:tar_cmd." -".g:tar_browseoptions." - "
   147   exe "silent r! ".g:tar_cmd." -".g:tar_browseoptions."
".s:Escape(tarfile,1)
   163   exe "r ".fnameescape(a:tarfile)
   198   let tarfile=substitute(system("cygpath -u
".s:Escape(tarfile,0)),'\n$','',
'e')
   223   let tarfile=substitute(system("cygpath -u
".s:Escape(tarfile,0)),'\n$','',
'e')
   244   exe "silent r! gzip -d -c -- ".s:Escape(tarfile,1)."|
".g:tar_cmd." -".g:tar_readoptions." - ".s:Escape(fname,1).decmp
   247   exe "silent r! cat -- ".s:Escape(tarfile,1)." | gzip -d -c
- | ".g:tar_cmd." -".g:tar_readoptions." - ".s:Escape(fname,1).decmp
   250   exe "silent r! bzip2 -d -c -- ".s:Escape(tarfile,1)."|
".g:tar_cmd." -".g:tar_readoptions." - ".s:Escape(fname,1).decmp
   253   exe "silent r! ".g:tar_cmd." -".g:tar_readoptions."
".s:Escape(tarfile,1)." -- ".s:Escape(fname,1).decmp
   262  exe "file tarfile::".fnameescape(fname)
   308   exe "cd ".fnameescape(tmpdir)
   332   call system("gzip -d -- ".s:Escape(tarfile,0))
   336   call system("gzip -d -- ".s:Escape(tarfile,0))
   341   call system("bzip2 -d -- ".s:Escape(tarfile,0))
   359     let dirpath = substitute(system("cygpath
".s:Escape(dirpath, 0)),'\n','','e')
   368   exe "w! ".fnameescape(fname)
   370    let tarfile = substitute(system("cygpath
".s:Escape(tarfile,0)),'\n','',
'e')
   375   call system("tar --delete -f ".s:Escape(tarfile,0)." --
".s:Escape(fname,0))
   384    call system("tar -".g:tar_writeoptions."
".s:Escape(tarfile,0)." -- ".s:Escape(fname,0))
   391     call system(compress)
   407    exe "e! ".fnameescape(tarfile)
   419  exe "cd ".fnameescape(curdir)
   431   call system("/bin/rm -rf -- ".s:Escape(a:fname,0))
   434    call system("/bin/rm -rf -- ".s:Escape(a:fname,0))
   436    call system("del /S ".s:Escape(a:fname,0))

This is the listing from section ``3.4.2.3.1.'' of the original
advisory[1], for reference:

    99  exe "$put ='".'\"'." Browsing tarfile ".a:tarfile."'"
   107   let tarfile=substitute(system("cygpath -u ".tarfile),'\n$','','e')
   112   exe "silent r! gzip -d -c ".g:tar_shq.tarfile.g:tar_shq."|
".g:tar_cmd." -".g:tar_browseoptions." - "
   115   exe "silent r! bzip2 -d -c ".g:tar_shq.tarfile.g:tar_shq."|
".g:tar_cmd." -".g:tar_browseoptions." - "
   118   exe "silent r! ".g:tar_cmd." -".g:tar_browseoptions."
".g:tar_shq.tarfile.g:tar_shq
   134   exe "r ".a:tarfile
   169   let tarfile=substitute(system("cygpath -u ".tarfile),'\n$','','e')
   192   let tarfile=substitute(system("cygpath -u ".tarfile),'\n$','','e')
   199   exe "silent r! gzip -d -c ".g:tar_shq.tarfile.g:tar_shq."|
".g:tar_cmd." -".g:tar_readoptions." - '".fname."'"
   202   exe "silent r! bzip2 -d -c ".g:tar_shq.tarfile.g:tar_shq."|
".g:tar_cmd." -".g:tar_readoptions." - '".fname."'"
   205   exe "silent r! ".g:tar_cmd." -".g:tar_readoptions."
".g:tar_shq.tarfile.g:tar_shq." ".g:tar_shq.fname.g:tar_shq
   208  exe "file tarfile:".fname
   278   call system("gzip -d ".tarfile)
   282   call system("gzip -d ".tarfile)
   287   call system("bzip2 -d ".tarfile)
   303     let dirpath = substitute(system("cygpath ".dirpath),'\n','','e')
   312   exe "w! ".fname
   314    let tarfile = substitute(system("cygpath ".tarfile),'\n','','e')
   319   call system("tar --delete -f '".tarfile."' '".fname."'")
   335     call system(compress)
   351    exe "e! ".tarfile


4. VULNERABILITIES

4.1. Untrusted File Names Interpreted as Optional Argument

4.1.1. POSIX Systems

The POSIX end-of-options double-dash (--) is missing from some of the
commands invoked by system() -- line 244 a.o.:

   244   exe "silent r! gzip -d -c -- ".s:Escape(tarfile,1)."|
".g:tar_cmd." -".g:tar_readoptions." - ".s:Escape(fname,1).decmp

The resulting command looks like this:

   gzip -d -c -- TARBALL | tar -OPxf - MEMBER

MEMBER can be interpreted by tar(1) as a command line option.  This can
be still used to execute arbitrary shell commands (cf. e.g. the
``--compress-program'' option of tar(1)).


4.1.2. Other Systems

With implementations of tar(1) (and other programs) that do not
understand the double-dash convention, another mechanism must be used to
prevent the file name from being interpreted as command line options.
At the same time, the current code may confuse such programs.

It is not possible for Vim to know the invocation syntax of external
programs.  As the double-dash security measure may not be present in any
given external command, the security of commands that pass untrusted
input to these external commands is not be guaranteed.


4.2 Unspecified Behaviour of system() and  ``!''

4.2.1. The system() Function

system(), does not invoke /bin/sh to run the commands, as does the C
Standard Library function of the same name.  Rather, it uses the program
specified in the Vim internal option 'shell'.  The full details of how
system() works can be found in the Vim Manual:

 ``system({expr} [, {input}])                          *system()* *E677*
   [...]
   The command executed is constructed using several options:
   'shell' 'shellcmdflag' 'shellxquote' {expr} 'shellredir' {tmp} 'shellxquote'
   ({tmp} is an automatically generated file name).  For Unix and OS/2
   braces are put around {expr} to allow for concatenated commands.''

               -- Vim Reference Manual (``eval.txt'')

As the particularities of how this program interprets the command can
not be known, it is inherently impossible to say anything meaningful as
to whether there are security issues.  In fact, it is not possible to
say anything about how the command will be interpreted, or if it will be
interpreted at all.  In the absence of a baseline specification, the
behaviour of system() as implemented by Vim can only be described as
"unspecified".

By setting the respective options to known values, it may be possible to
reach the C Standard Library system() functionality.  There will still
be problems on systems without /bin/sh, and on systems where /bin/sh is
not POSIX-conformant.


4.2.2. The ``!'' Command

The same applies to the ``!'' command, as used e.g. on line 138:

   138   exe "silent r! gzip -d -c -- ".s:Escape(tarfile,1)." |
".g:tar_cmd." -".g:tar_browseoptions." - "

The ``r!'' means the ``read'' command reads the output of the ``!''
command, which in turn executes shell commands, in a way similar to
system().


5. EXPLOIT

No exploit code is provided.


6. REFERENCES

[1] Collection of Vulnerabilities in Fully Patched Vim 7.1
   http://www.rdancer.org/vulnerablevim.html


7. COPYRIGHT

This advisory is Copyright 2008 Jan Minar <rdancer@rdancer.org>

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.


8. HISTORY

2008-08-08 Sent to: <bugs@vim.org>, <vim-dev@vim.org>,
          <full-disclosure@lists.grok.org.uk>,
          <bugtraq@securityfocus.com>,
          Charles E Campbell, Jr (Vim Tar Plugin Maintainer)
          <drchip@campbellfamily.biz>

About | Terms of use | Privacy Policy
© SecurityVulns, 3APA3A, Vladimir Dubrovin
 



Рейтинг@Mail.ru