|
Message-ID: <c7a49799-a042-656d-874e-c5da9f0cf0aa@orlitzky.com> Date: Thu, 21 Sep 2017 19:53:54 -0400 From: Michael Orlitzky <michael@...itzky.com> To: oss-security <oss-security@...ts.openwall.com> Subject: CVE-2017-14681: P3Scan privilege escalation via PID file manipulation Product: P3Scan (transparent email proxy server) Versions-affected: 3.0_rc1 and earlier (all versions) Bug-report: https://sourceforge.net/p/p3scan/bugs/33/ Author: Michael Orlitzky == Summary == The p3scan daemon creates its PID file after dropping privileges to a non-root user. That may be exploited (through init scripts or other management tools) by the unprivileged user to kill root processes, since when the daemon is stopped, root usually sends a SIGTERM to the contents of the PID file (which are under the control of the runtime user). P3Scan itself ships two init scripts vulnerable to this attack. == Details == The purpose of the PID file is to hold the PID of the running daemon, so that later it can be stopped, restarted, or otherwise signaled (many daemons reload their configurations in response to a SIGHUP). To fulfil that purpose, the contents of the PID file need to be trustworthy. If the PID file is writable by a non-root user, then he can replace its contents with the PID of a root process. Afterwards, any attempt to signal the PID contained in the PID file will instead signal a root process chosen by the non-root user. The creation of the PID file can be traced to the following code in p3scan.c (modulo some whitespace changes): cuid=getuid(); if (cuid == 0) { do_log(LOG_DEBUG, "Changing uid (we are root)"); pws = getpwnam(config->runasuser); // Emergency: main: Unknown user in configuration file if (pws == NULL) do_log(LOG_EMERG, "ERR: Unknown User '%s'", config->runasuser); if (setgid(pws->pw_gid)) do_log(LOG_DEBUG, "setgid returned: %s", strerror(errno)); if (setuid(pws->pw_uid)) do_log(LOG_DEBUG, "setuid returned: %s", strerror(errno)); } cuid=getuid(); guid=getgid(); pws = getpwuid(cuid); grp = getgrgid(guid); do_log(LOG_DEBUG, "Running as user: %s group: %s", pws->pw_name, grp->gr_name); if ((pd=fopen(config->pidfile, "w+")) != NULL) { fprintf(pd, "%i\n", getpid()); fclose(pd); } This is commonly exploitable through init scripts that are run as root and which blindly trust the contents of their PID files. The p3scan package ships two such init scripts, 1. etc/init.d/p3scan 2. etc/rc.d/rc.p3scan both containing essentially the same code: stop) # Stop p3scan if [ -a /var/run/p3scan/p3scan.pid ]; then kill `cat /var/run/p3scan/p3scan.pid` &>/dev/null rm -f /var/run/p3scan/p3scan.pid echo "P3Scan terminated" P3Scan is unable to run in the foreground, preventing the typical workaround where the init system is allowed to manage its PID file. == Exploitation == An example exploit involving an init script is, 1. I run "/etc/init.d/p3scan start" to start the daemon. 2. p3scan drops to the "p3scan" user. 3. p3scan writes its PID file, now owned by the "p3scan" user. 4. Someone compromises the daemon, which sits on the network. 5. The attacker is generally limited in what he can do because the daemon doesn't run as root. However, he can write "1" into the PID file, and he does. 6. I run "/etc/init.d/p3scan stop" to stop the daemon while I investigate the weird behavior resulting from the hack. 7. The machine reboots, because I killed PID 1 (this is normally restricted to root).
Powered by blists - more mailing lists
Please check out the Open Source Software Security Wiki, which is counterpart to this mailing list.
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.