Loading ...
Sorry, an error occurred while loading the content.

More arbitrary code executions in Netrw version 125, Vim 7.2a.10

Expand Messages
  • Jan Minář
    Following my recent advisory on Vim vulnerabilities, here goes a followup: many more vulnerabile statements in Netrw. Although Netrw has been updated with the
    Message 1 of 1 , Jul 3, 2008
    View Source
    • 0 Attachment
      Following my recent advisory on Vim vulnerabilities, here goes a followup: many
      more vulnerabile statements in Netrw. Although Netrw has been updated with
      the new fnameescape() and shellescape() functions, it doesn't use them
      consistently. It is difficult *not* to find vulnerable code in Netrw.

      This writeup can be found at:
      ``http://www.rdancer.org/vulnerablevim-netrw.html''
      The archive with code that we're using can be found at:
      ``http://www.rdancer.org/vulnerablevim-netrw.tar.bz2''.

      Best results are achieved by running ``make test'' in the root
      directory of the abovementioned archive:

      $ make test
      [...]
      -------------------------------------------
      -------- Test results below ---------------
      -------------------------------------------
      filetype.vim
      tarplugin.updated: VULNERABLE
      zipplugin : VULNERABLE
      --> netrw.v2 : VULNERABLE
      --> netrw.v3 : VULNERABLE
      --> netrw.v4 : VULNERABLE


      1. Compression and Decompression (The ``mz'' Command)

      Invoking the ``mz'' command upon a file with a crafted file name can lead to
      arbitrary code execution.


      1.1 Vulnerability

      In many places, Netrw ($VIMRUNTIME/autoload/netrw.vim) fails to sanitize file
      names used as shell arguments.

      In function s:NetrwMarkFileExe() (The ``mx'' command): ``apply command to marked
      files. Substitute: filename -> % If no %, then append a space and the filename
      to the command'':

      4036 for fname in s:netrwmarkfilelist_{curbufnr}
      4037 if a:islocal
      4038 if g:netrw_keepdir
      4039 let fname= s:ComposePath(curdir,fname)
      4040 endif
      4041 else
      4042 let fname= b:netrw_curdir.fname
      4043 endif
      4044 if cmd =~ '%'
      4045 let xcmd= substitute(cmd,'%',fname,'g')
      4046 else
      4047 let xcmd= cmd.' '.fname
      4048 endif
      4049 if a:islocal
      4050 " call Decho("local: xcmd<".xcmd.">")
      --> 4051 let ret= system(xcmd)
      4052 else
      4053 " call Decho("remote: xcmd<".xcmd.">")
      --> 4054 let ret= s:RemoteSystem(xcmd)

      Following code in function s:NetrwMarkFileCompress() is run when the ``mz''
      (compress/decompress) command is invoked. The variable
      ``s:netrwmarkfilelist_{curbufnr}'' holds the marked files list.:

      159 if !exists("g:netrw_decompress")
      160 let g:netrw_decompress= { ".gz" : "gunzip" , ".bz2" : "bunzip2"
      , ".zip" : "unzip" , ".tar" : "tar -xf"}
      161 endif
      [...]
      3816 for fname in s:netrwmarkfilelist_{curbufnr}
      3817 " for every filename in the marked list
      3818 for sfx in sort(keys(g:netrw_decompress))
      3819 if fname =~ '\'.sfx.'$'
      3820 " fname has a suffix indicating that its
      compressed; apply associated decompression routine
      3821 let exe= g:netrw_decompress[sfx]
      3822 " call Decho("fname<".fname."> is compressed so
      decompress with <".exe.">")
      3823 if a:islocal
      3824 if g:netrw_keepdir
      3825 let fname= s:ComposePath(curdir,fname)
      3826 endif
      3827 else
      3828 let fname= b:netrw_curdir.fname
      3829 endif
      3830 if executable(exe)
      3831 if a:islocal
      --> 3832 call system(exe." ".fname)


      1.2. Exploit

      We exploit the statement on line 3832.

      Run ``make demo'' or ``make test'' in the netrw.v2 directory. Note: ``make
      test'' may hang when run from within vim.


      2. Copying Files (The ``mc'' Command)

      Invoking the ``mc'' command inside a directory with a crafted directory name
      can lead to arbitrary code execution.


      2.1. Vulnerability

      Netrw inappropriately uses shellescape() in many places to sanitize
      arguments of the
      ``execute'' command.

      708 exe s:netrw_silentxfer."!".g:netrw_rcp_cmd."
      ".s:netrw_rcpmode."
      ".shellescape(uid_machine.":".escape(b:netrw_fname,' ?&;')."
      ".tmpfile)
      810 exe s:netrw_silentxfer."!".g:netrw_scp_cmd.useport."
      ".shellescape(g:netrw_machine.":".escape(b:netrw_fname,g:netrw_fname_escape))."
      ".tmpfile
      831 exe s:netrw_silentxfer."!".g:netrw_http_cmd."
      ".shellescape(tmpfile)."
      ".shellescape("http://".g:netrw_machine.netrw_fname)
      842 exe s:netrw_silentxfer."!".g:netrw_http_cmd."
      ".shellescape(tmpfile)."
      ".shellescape("http://".g:netrw_machine.netrw_html)
      882 exe s:netrw_silentxfer."!".g:netrw_rsync_cmd."
      ".shellescape(g:netrw_machine.":".netrw_fname)." ".tmpfile
      907 exe s:netrw_silentxfer."!".g:netrw_fetch_cmd."
      ".tmpfile." ".shellescape(netrw_option."://".g:netrw_uid.':'.s:netrw_passwd.'@'.g:netrw_machine."/".netrw_fname)
      910 exe s:netrw_silentxfer."!".g:netrw_fetch_cmd."
      ".tmpfile." ".shellescape(netrw_option."://".g:netrw_machine."/".netrw_fname)
      923 exe s:netrw_silentxfer."!".g:netrw_sftp_cmd."
      ".shellescape(g:netrw_machine.":".netrw_fname)." ".tmpfile
      1084 exe s:netrw_silentxfer."!".g:netrw_rcp_cmd."
      ".s:netrw_rcpmode." ".shellescape(tmpfile)."
      ".shellescape(uid_machine.":".netrw_fname)
      1177 exe s:netrw_silentxfer."!".g:netrw_scp_cmd.useport."
      ".shellescape(tmpfile)."
      ".shellescape(g:netrw_machine.":".netrw_fname)
      2976 exe "silent !".viewer." ".viewopt.shellescape(fname).redir
      2981 exe 'silent !start rundll32 url.dll,FileProtocolHandler
      '.shellescape(fname)
      2987 exe "silent !gnome-open ".shellescape(fname).redir
      2992 exe "silent !kfmclient exec ".shellescape(fname)." ".redir
      2997 exe "silent !open ".shellescape(fname)." ".redir
      3656 exe "silent! !".g:netrw_local_mkdir.' '.shellescape(newdirname)
      3680 exe "silent! !".mkdircmd." ".shellescape(newdirname)
      3911 exe "silent! !".g:netrw_local_mkdir.' '.shellescape(tmpdir)
      4775 exe s:netrw_silentxfer."!".g:netrw_scp_cmd.useport."
      ".filelist." ".shellescape(tgtdir)
      5058 exe s:netrw_silentxfer."!".g:netrw_scp_cmd.useport."
      ".args." ".shellescape(machine.":".escape(tgt,g:netrw_fname_escape))
      6001 exe "silent r! ".listcmd.shellescape(s:path)
      6015 exe "silent r! ".listcmd.' "'.shellescape(s:path).'"'


      3888 let args=
      join(map(copy(s:netrwmarkfilelist_{bufnr('%')}),"b:netrw_curdir.\"/\".shellescape(v:val)"))
      3889 " call Decho("system(".g:netrw_localcopycmd." ".args."
      ".shellescape(s:netrwmftgt).")")
      --> 3890 call system(g:netrw_localcopycmd." ".args."
      ".shellescape(s:netrwmftgt))

      2.2. Exploit

      Run ``make demo'' or ``make test'' in the netrw.v3 directory. Note: ``make
      test'' may hang when run from within vim.


      2.3. Patch

      --- /usr/local/share/vim/vim72a/autoload/netrw.vim 2008-07-01
      18:38:09.000000000 +0100
      +++ - 2008-07-03 19:01:50.676582822 +0100
      @@ -3885,7 +3885,7 @@
      if a:islocal && s:netrwmftgt_islocal
      " Copy marked files, local directory to local directory
      " call Decho("copy from local to local")
      - let args=
      join(map(copy(s:netrwmarkfilelist_{bufnr('%')}),"b:netrw_curdir.\"/\".shellescape(v:val)"))
      + let args=
      join(map(copy(s:netrwmarkfilelist_{bufnr('%')}),"shellescape(b:netrw_curdir).\"/\".shellescape(v:val)"))
      " call Decho("system(".g:netrw_localcopycmd." ".args."
      ".shellescape(s:netrwmftgt).")")
      call system(g:netrw_localcopycmd." ".args."
      ".shellescape(s:netrwmftgt))



      3. Deleting Files (The ``D'' Command)

      Applying the ``D'' to a file with a crafted file name, or inside a directory
      with a crafted directory name, can lead to arbitrary code execution.


      3.1 Vulnerability

      Netrw fails to properly sanitize arguments passed to the s:System() function,
      which is a wrapper for the ``execute'' command:

      7596 fun! s:System(cmd,path)
      [...]
      7599 let path = a:path
      [...]
      7615 exe "let result= ".a:cmd."('".path."')"

      In function s:NetrwLocalRmFile():

      6724 fun! s:NetrwLocalRmFile(path,fname,all)
      [...]
      6730 let rmfile= s:ComposePath(a:path,a:fname)
      [...]
      --> 6754 let ret= s:System("delete",rmfile)
      [...]
      --> 6777 call s:System("system",g:netrw_local_rmdir.'
      '.shellescape(rmfile))
      [...]
      --> 6782 let errcode= s:System("delete",rmfile)
      [...]
      --> 6788 call s:System("system","rm ".shellescape(rmfile))

      In function s:NetrwLocalRmFile():
      6730 let rmfile= s:ComposePath(a:path,a:fname)
      [...]
      --> 6754 let ret= s:System("delete",rmfile)
      [...]
      --> 6777 call s:System("system",g:netrw_local_rmdir.'
      '.shellescape(rmfile))
      6778 " call Decho("v:shell_error=".v:shell_error)
      6779
      6780 if v:shell_error != 0
      6781 " call Decho("2nd attempt to remove directory<".rmfile.">")
      --> 6782 let errcode= s:System("delete",rmfile)
      6783 " call Decho("errcode=".errcode)
      6784
      6785 if errcode != 0
      6786 if has("unix")
      6787 " call Decho("3rd attempt to remove directory<".rmfile.">")
      --> 6788 call s:System("system","rm ".shellescape(rmfile))


      3.2 Exploit

      We exploit the statement on the line 6754. Run ``make demo'' or ``make test''
      in the netrw.v4 directory. Note: ``make test'' may hang when run from within
      vim. We use the TIOCSTY ioctl to simulate keyboard input in ``make test'' --
      avoid touching the keyboard while ``make test'' is running.

      --~--~---------~--~----~------------~-------~--~----~
      You received this message from the "vim_dev" maillist.
      For more information, visit http://www.vim.org/maillist.php
      -~----------~----~----~----~------~----~------~--~---
    Your message has been successfully submitted and would be delivered to recipients shortly.