UNIX Password Hacker
by The Infidel
When you're hacking a UNIX system, it's always good to have at least one spare account on hand in case you lose your current one, or in case your current permissions aren't great enough to allow you to get root access. (I'm assuming the reader has a basic understanding of the UNIX operating system - there have been quite a few articles about the topic here in the past.)
This program automates the process of hacking users' passwords. A while back, Shooting Shark wrote a similar program, but its major weaknesses were that it could be easily detected by a system administrator and it could only hack one user's password at a time.
Background
The theory behind this program is relatively simple. Each user has an entry in the /etc/passwd file, which contains the username, an encrypted copy of the user's - password, and some other relevant information, such as the user's ID, group ID, home directory, and login process. At any rate, what's important here is the copy of the encrypted password.
One of the available system calls to the C programmer under the UNIX operating system is crypt(). Built into every UNIX kernel is a data encryption algorithm, based on the DES encryption method. When a user enters the passwd command to change his password (or when the system administrator assigns a new user a password), the crypt() system call is made, which then encrypts the selected password and places a copy of it into the file /etc/passwd, which is then referred to whenever a user tries to log in to the system.
Now, the standard UNIX password is somewhere between 1-8 characters long (various versions, such as Ultrix, allow much longer passwords). If you wrote a program that would sequentially try every possible lowercase character sequence, it would take about 3 * 1023 attempts, which translates into a little over a million years per complete password hack per user. And that was just lowercase letters...
Since I can't wait that long, there has to be a better way to do this - and there is. For the most part,average, unassuming users are pretty careless and naive. You'd be surprised what I've found being used by people for passwords: radical, joshua, computer, password, keyboard - very simple to crack passwords. These are certainly not worthy of a million year hack attempt. (However, something like Ur0dent! or lamel1te might be.)
Lucky for us, every UNIX package comes with a spelling checker, with a database usually containing upwards of 50,000 entries, located at /usr/dict/words. Since every user has read access to this file, our program will simply read each word in from the database, one at a time, encrypt it, and compare it against the encrypted passwords of our target users, which we got off the /etc/passwd file. By the way, every user must have read access to /etc/passwd in order for the available user utilities to work.
Now some system administrators reading this may just lock out read access to the online dictionary, or simply remove it from the system. Fine. Probably everyone reading this has access to a spelling checker they use for their word processor at home. Since many use simple ASCII text files as their database, you can simply upload your spelling checker database to your UNIX site and easily modify the password hacker's dict variable to use this new database instead of the default. The format of the database is simple: there must be only one word per line.
Using the Password Hacker
This program is very simple to use. I've tried to use standard C code so there would be no compatibility problems from system to system. Obviously, I haven't tested it on every version of UNIX available, but you shouldn't really have any problems. This program NOHUPs itself, meaning that even after you log off the system, it will continue to run in the background until completion. On some terminal configurations, this method of NOHUP'ing may lock up the terminal after logout until Uhacker is done. On these systems, just remove the line in the source and NOHUP it manually or run it off of the C shell.
To compile the program, simply type:
$ cc -o sort Uhacker.cand within a half minute or so, you should have a working copy online named "sort". That way, when you run this program, it will look to the system administrator that you're just running some kind of lame sorting program, which of course, you named"sort", like all good first year computer science majors do.
Uhacker will prompt you to enter each username you wish to hack, one at a time. If it's not a valid user, the program will tell you. You can hit Ctrl-C to abort out of it at any time before you terminate the batch entry. After you've entered all the usernames you wish to hack, simply enter q as the final username. The program defaults to a maximum of ten users being hacked at a time, but you can easily make it accept more.
At any rate, when the batch is complete, the program then jumps into the background, outputs the background process' ID number, and gives you your original shell back. That way, you can go on with whatever it was you were doing, while the program hacks away. The number output as "Process Number:" is the process ID number for the background process now running Uhacker. If you have to terminate the Uhacker very quickly, after it's in the background, just type: kill -9 XXX, where XXX is that process number.
When it's done, the program will send its output to the file .newsrc, a standard file that's on everyone's directory and will attract no attention. By running the program with the -d option (sort -d), it will run in debugging mode, in case you don't think things are working right. Again, .newsrc will tell you what's going on.
When I wrote this program, it was with security in mind. Non-fatal interrupts are locked out from the process, so only a kill command can terminate it once it's started. Logging out of your account will not kill it either, so you can let it run and call back later to pick up the results. There is no way any nosy system administrator can know what you are doing, even if he tries running the program himself, because there's no text in it to give it away. No usernames or dictionary file names will appear in any process lists or command accounting logs. The only way you can get caught using this is if someone reads the .newsrc file, which is written to only after the program has finished. But this is an innocent file, so no one would look at it anyway. Also, don't leave the source code online. Typing chmod 100 sort will allow you to have execute access to the program, to keep nosy users away from it, but still won't keep the superuser from running it.
So how long does this take? On a VAX, running with only five or so users, with a light load, it will take approximately ten minutes per username you've entered into the batch. With a heavy load (20+ users, load average greater than 3.00), it can take up to an hour per username in the batch. You'll really just have to experiment and see how things work on your system. Have fun!
/* * UNIX Batch Password Hacker: Uhacker.c * Written By The Infidel, BOYWare Productions, 1991 */ #include <stdio.h> #include <pwd.h> #include <signal.h> struct acct { char nam[16]; char crpwd[20]; } struct passwd *pwd; int i, batchc, count, flag; char *pw, dictwd[20]; static char dict[] = "/usr/dict/words"; static char data[] = ".newsrc"; /* Not needed by all UNIX C compilers */ int endpwent(); /* Close /etc/passwd file */ char *strcpy(), *crypt(), *getpass(), *getlogin(); struct passwd *getpwname(); main(argc, argv) int argc; char *argv[]; { FILE *fopen(), *ifp, *ofp; struct acct user[11]; if (argc == 2) { if (!(strcmp(argv[1], "-d"))) flag = 1; else { printf("Incorrect usage.\n"); exit(-1); } } if ((ifp = fopen(dict, "r")) == NULL) { printf("Invalid source file.\n\n"); exit(-1); } if ((ofp = fopen(data, "w")) == NULL) { printf("Unable to open data file.\n\n"); exit(-1); } printf("Enter input. Terminate batch with a 'q'.\n"); for (i = 1; i < 11; ++i) { printf(" #%d: ", i); scanf("%s", user[i].nam); if (!strcmp(user[i].nam, "q")) break; if (!(pwd = getpwnam(user[i].nam))) { printf("Nonexistent: %s\n", user[i].nam); --i; } else { sprintf(user[i].crpwd, "%s", pwd->pw_passwd); } } if (i == 1) { printf("Abnormal termination.\n"); exit(-1); } batchc = i; count = i - 1; i = fork(); /* Create a child process to do the scanning */ if (i) { printf("\nProcess Number: %d\n\n", i); exit(0); /* Terminate the parent process to give us our shell back */ } signal(SIGINT, SIG_IGN); /* Child now in background. Lock out interrupts */ signal(SIGQUIT, SIG_IGN); /* Lock out ctrl-\ quit signal */ signal(SIGHUP, SIG_IGN); /* If terminal locks up after logout, delete this line. System won't support self-nohups */ if (flag == 1) { fprintf(ofp, "-----------------------\n"); for (i = 1; i < batchc; ++i) fprintf(ofp, "%s - %s\n", user[i].nam, user[i].crpwd); fprintf(ofp, "-----------------------\n\n"); } while (fgets(dictwd, 20, ifp) != NULL) { if (dictwd[strlen(dictwd) - 2] == '#') dictwd[strlen(dictwd) - 2] = '\0'; else dictwd[strlen(dictwd) - 1] = '\0'; for (i = 1; 1 < batchc; ++i) { pw = crypt(dictwd, user[i].crpwd); if (!stremp(pw, user[i].crpwd)) { fprintf(ofp, "%s -=> %s\n", user[i].nam, dictwd); --count; if (count == 0) { fprintf(ofp, "Job completed.\n\n"); exit(0); } } } } if (count == batchc - 1) fprintf(ofp, "Unsuccessful.\n\n"); else fprintf(ofp, "Job completed.\n\n"); endpwent(); }Code: Uhacker.c