home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume21 / cops / part02 < prev    next >
Encoding:
Internet Message Format  |  1990-03-21  |  45.2 KB

  1. Subject:  v21i024:  System ecurity analysis tool, Part02/05
  2. Newsgroups: comp.sources.unix
  3. Approved: rsalz@uunet.UU.NET
  4. X-Checksum-Snefru: 76632269 de666800 170b23ff ffd528b4
  5.  
  6. Submitted-by: Dan Farmer <df@sei.cmu.edu>
  7. Posting-number: Volume 21, Issue 24
  8. Archive-name: cops/part02
  9.  
  10. #    This is a shell archive.
  11. #    Remove everything above and including the cut line.
  12. #    Then run the rest of the file through sh.
  13. #----cut here-----cut here-----cut here-----cut here----#
  14. #!/bin/sh
  15. mkdir cops 2>/dev/null
  16. mkdir cops/docs 2>/dev/null
  17. mkdir cops/src 2>/dev/null
  18. mkdir cops/extensions 2>/dev/null
  19. # shar:    Shell Archiver
  20. #    Run the following text with /bin/sh to create:
  21. #    cops/src/addto.c
  22. #    cops/src/clearfiles.c
  23. #    cops/src/filewriters.c
  24. #    cops/src/home.chk.c
  25. #    cops/src/is_readable.c
  26. #    cops/src/is_writable.c
  27. #    cops/src/members.c
  28. #    cops/src/pass.c
  29. #    cops/src/tilde.c
  30. #    cops/src/user.chk.c
  31. #    cops/extensions/THINGS_2_DO
  32. #    cops/extensions/YAR
  33. #    cops/extensions/netstuff
  34. #    cops/extensions/passwords
  35. #    cops/extensions/questions
  36. # This archive created: Tue Jan 30 23:26:43 1990
  37. # By:    dan (Purdue University)
  38. echo shar: extracting cops/src/addto.c '(3254 characters)'
  39. cat << \SHAR_EOF > cops/src/addto.c
  40. /* Copyright 1985 Robert W. Baldwin */
  41. /* Copyright 1986 Robert W. Baldwin */
  42. static    char    *notice85 = "Copyright 1985 Robert W. Baldwin";
  43. static    char    *notice86 = "Copyright 1986 Robert W. Baldwin";
  44.  
  45. /*
  46.   August 15, added "Warning!"  To prepend warning messages.
  47.     -- dan farmer
  48. */
  49.  
  50.  
  51. /* 
  52.  * Add a goal, check for duplicates and completions.
  53.  * Trace messages written to stdout, success messages written to stderr.
  54.  * Usage: addto fileroot key comments
  55.  * Files are arranged in families based on a root name; for example,
  56.  *    uids.k  -- uids we Know how to access
  57.  *    uids.n  -- uids to process Next
  58.  *    uids.p  -- uids Pending results (for duplicate detection)
  59.  *    uids.x  -- uids being eXamined currently
  60.  */
  61.  
  62.  
  63. #include    <stdio.h>
  64.  
  65. #define    LINELEN    600        /* Max chars in a line. */
  66. #define    SUCCESS    "Success"    /* Filename to put success messages. */
  67.  
  68. main(argc, argv)
  69. int    argc;
  70. char    *argv[];
  71. {
  72.     char    *type = argv[1];
  73.     char    *key = argv[2];
  74.     int    i;
  75.     char    linebuf[LINELEN];
  76.      char    keypending[150];
  77.     char    filename[150];
  78.     FILE    *tmpfile;
  79.  
  80.     if (argc < 3)  {
  81.         fprintf(stderr, "addto: missing arguments\n");
  82.         exit(1);
  83.         }
  84.         
  85.     tmpfile = NULL;
  86.         
  87.      keypending[0] = NULL;
  88.     strcat(keypending, key);
  89.     strcat(keypending, " ");
  90. /*
  91.  * If the uid is known, print out the comments and exit.
  92.  */
  93.     filename[0] = NULL;
  94.     strcat(filename, type);
  95.     strcat(filename, ".k");
  96.     if ((tmpfile = fopen(filename, "r")) == NULL)  {
  97.         fprintf(stderr, "addto: can't open %s.\n", filename);
  98.         exit(1);
  99.         }
  100.     while (fgets(linebuf, LINELEN, tmpfile) != NULL)  {
  101.         if (strncmp(linebuf, key, strlen(key)) == 0)  {
  102.             if ((tmpfile = freopen(SUCCESS,"a",tmpfile)) == NULL) {
  103.                 fprintf(stderr, "addto: can't open %s.\n",
  104.                     SUCCESS);
  105.                 exit(1);
  106.                 }
  107.             fprintf(stderr, "Success^G^G\t");
  108.             fprintf(tmpfile, "Warning!  ");
  109.             for (i = 1 ; i < argc ; i++)  {
  110.                 fprintf(tmpfile, argv[i]);
  111.                 fprintf(tmpfile, " ");
  112.                 fprintf(stderr, argv[i]);
  113.                 fprintf(stderr, " ");
  114.                 }
  115.             fprintf(tmpfile, "\n");
  116.             fprintf(stderr, "\n");
  117.             
  118.             exit(0);
  119.             }
  120.         }
  121. /*
  122.  * If a duplicate, don't add it.
  123.  */
  124.     filename[0] = NULL;
  125.     strcat(filename, type);
  126.     strcat(filename, ".p");
  127.     if (freopen(filename, "r", tmpfile) == NULL)  {
  128.         fprintf(stderr, "addto: can't open %s.\n", filename);
  129.         exit(1);
  130.         }
  131.     while (fgets(linebuf, LINELEN, tmpfile) != NULL)  {
  132.         if (strncmp(linebuf, keypending, strlen(keypending)) == 0)  {
  133.             exit(0);    /* Its a duplicate. */
  134.             }
  135.         }
  136. /*
  137.  * Add the goal to the pending file. 
  138.  */
  139.     filename[0] = NULL;
  140.     strcat(filename, type);
  141.     strcat(filename, ".p");
  142.     if (freopen(filename, "a", tmpfile) == NULL)  {
  143.         fprintf(stderr,"addto: can't open %s for append.\n", filename);
  144.         exit(1);
  145.         }
  146.     fprintf(tmpfile, keypending);
  147.     fprintf(tmpfile, "\n");
  148. /*
  149.  * Add the goal to the next goal (type) file.
  150.  */
  151.     filename[0] = NULL;
  152.     strcat(filename, type);
  153.     strcat(filename, ".n");
  154.     if (freopen(filename, "a", tmpfile) == NULL)  {
  155.         fprintf(stderr,"addto: can't open %s for append.\n", filename);
  156.         exit(1);
  157.         }
  158.     fprintf(stdout, "        ");
  159.     fprintf(stdout, "%s %s ", argv[0], argv[1]);
  160.     for (i = 2 ; i < argc ; i++)  {
  161.         fprintf(tmpfile, argv[i]);
  162.         fprintf(tmpfile, " ");
  163.         fprintf(stdout, argv[i]);
  164.         fprintf(stdout, " ");
  165.         }
  166.     fprintf(tmpfile, "\n");
  167.     fprintf(stdout, "\n");
  168.     exit(0);
  169. }
  170.  
  171.  
  172.  
  173. SHAR_EOF
  174. echo shar: extracting cops/src/clearfiles.c '(702 characters)'
  175. cat << \SHAR_EOF > cops/src/clearfiles.c
  176. /* Copyright 1985 Robert W. Baldwin */
  177. /* Copyright 1986 Robert W. Baldwin */
  178. static    char    *notice85 = "Copyright 1985 Robert W. Baldwin";
  179. static    char    *notice86 = "Copyright 1986 Robert W. Baldwin";
  180.  
  181. /*
  182.  * Reset the info files used by Kuang.
  183.  */
  184.  
  185.  
  186. #include    <stdio.h>
  187.  
  188. char    *filelist[] = {
  189.     "uids.k",
  190.     "Success",
  191.     "uids.k",
  192.     "uids.p",
  193.     "uids.n",
  194.     "uids.x",
  195.     "gids.k",
  196.     "gids.p",
  197.     "gids.n",
  198.     "gids.x",
  199.     "files.k",
  200.     "files.p",
  201.     "files.n",
  202.     "files.x",
  203.     "",
  204.     };
  205.  
  206. main(argc, argv)
  207. int    argc;
  208. char    *argv[];
  209. {
  210.     int    i;
  211.  
  212.     for (i = 0 ; filelist[i][0] != NULL ; i++)  {
  213.         if (freopen(filelist[i], "w", stdout) == NULL)  {
  214.             fprintf(stderr, "%s: can't open %s.\n",
  215.                 argv[0], filelist[i]);
  216.             exit(1);
  217.             }
  218.         }
  219. }
  220.  
  221. SHAR_EOF
  222. echo shar: extracting cops/src/filewriters.c '(2374 characters)'
  223. cat << \SHAR_EOF > cops/src/filewriters.c
  224. /* Copyright 1985 Robert W. Baldwin */
  225. /* Copyright 1986 Robert W. Baldwin */
  226.  
  227. /*
  228.    August 15, 1989: Dan Farmer
  229.    One line changed -- #38 is the old line, #41 is my version.
  230.    See comment for details...
  231. */
  232. static    char    *notice85 = "Copyright 1985 Robert W. Baldwin";
  233. static    char    *notice86 = "Copyright 1986 Robert W. Baldwin";
  234.  
  235. /*
  236.  * Useage: filewriters pathname
  237.  * Writes on stdout the list of people who can write the file.
  238.  * This writer's list contains three tokens, the owner, the group, and
  239.  * the 'all others' group, respectively.
  240.  * If either group does not have write access, then that token is
  241.  * replace with the token "NONE".  If the 'all others' group has
  242.  * write access then that token is "OTHER".
  243.  *
  244.  * Notice that the owner of a file can always write it because the
  245.  * owner can change the file access mode.
  246.  *
  247.  * BUG: should handle links correctly.
  248.  */
  249.  
  250. #include    <stdio.h>
  251. #include    <sys/types.h>
  252. #include    <sys/stat.h>
  253. #include    <grp.h>
  254. #include    <pwd.h>
  255.  
  256. /*
  257.   changed this line from upper to lower case 's'.
  258.   Ultrix barfed 'cause already defined in sys/stat.h,
  259.   no one else seemed to mind...
  260.  
  261. #define    S_GWRITE    (S_IWRITE >> 3)
  262. */
  263.  
  264. #define    s_GWRITE    (S_IWRITE >> 3)        /* Group write access. */
  265. #define    S_OWRITE    (S_IWRITE >> 6)        /* Other write access. */
  266.  
  267.  
  268. main(argc, argv)
  269. int    argc;
  270. char    *argv[];
  271. {
  272.     int    i;
  273.     struct    stat    buf;
  274.  
  275. /*
  276.  * Make sure the file exists.
  277.  */
  278.      if (argc != 2)  {
  279.         fprintf(stderr, "%s: wrong number of args.\n", argv[0]);
  280.         exit(1);
  281.         }
  282.     if (stat(argv[1], &buf) != 0)  {
  283.         fprintf(stderr, "%s: File %s does not exist.\n",
  284.             argv[0], argv[1]);
  285.         exit(1);
  286.         }
  287. /*
  288.  * Produce list of writers.
  289.  * Owner can always write.
  290.  */
  291.     printf("        ");
  292.     print_uid(stdout, buf.st_uid);
  293.     printf(" ");
  294.     if (s_GWRITE & (buf.st_mode))  {
  295.         print_gid(stdout, buf.st_gid);
  296.         }
  297.     else {
  298.         printf("NONE");
  299.         }
  300.     printf(" ");
  301.     if (S_OWRITE & buf.st_mode)  {
  302.         printf("OTHER");
  303.         }
  304.     else {
  305.         printf("NONE");
  306.         }
  307.     printf("\n");
  308.     exit(0);
  309. }
  310.  
  311.  
  312. print_uid(out, uid)
  313. FILE    *out;
  314. int    uid;
  315. {
  316.     struct    passwd    *pwent;
  317.     
  318.     if ((pwent = getpwuid(uid)) == NULL)  {
  319.         fprintf(stderr, "Bad user id %d.\n", uid);
  320.         exit(1);
  321.         }
  322.     fprintf(out, "%s", pwent->pw_name);
  323. }
  324.  
  325.  
  326. print_gid(out, gid)
  327. FILE    *out;
  328. int    gid;
  329. {
  330.     struct    group    *grpent;
  331.     
  332.     if ((grpent = getgrgid(gid)) == NULL)  {
  333.         fprintf(stderr, "Bad group id %d.\n", gid);
  334.         exit(1);
  335.         }
  336.     fprintf(out, "%s", grpent->gr_name);
  337.  
  338. }
  339.  
  340. SHAR_EOF
  341. echo shar: extracting cops/src/home.chk.c '(2916 characters)'
  342. cat << \SHAR_EOF > cops/src/home.chk.c
  343. /*
  344.  
  345. -------------------------------------------------------------------------
  346. Modification: Aug 2, 1989
  347. Author: Dan Farmer
  348.  
  349.   I made a minor change to this; it uses a bit mask instead of comparing
  350. to various ok modes.  Otherwise it is unchanged....
  351. -------------------------------------------------------------------------
  352.  
  353. Original Comment:
  354.  
  355. This was posted to comp.unix.wizards and net.sources, but I also wanted to
  356. send it here, both for those that don't read or get news, and so that it
  357. will be in the archives for posterity....
  358.  
  359. On the UNIX Security list, quite a while back, mention was made of
  360. problems that could occur when home directories of users are writable.
  361. (Installing |"some command" in ~uucp/.forward remotely and things like
  362. that.)  This prompted me to write the enclosed program, both to check
  363. for this, and to help protect users against themselves.
  364.  
  365. The program looks at all the home directories listed in /etc/passwd,
  366. and prints a message if they don't exist, are not directories, or
  367. their mode is not in the "table" of "OK" modes.  I'm using stat()
  368. instead of lstat(), so symbolic links are perfectly acceptable, as
  369. long as they point to directories....  This program should run on any
  370. version of UNIX that I can think of; if it doesn't, please let me
  371. know.
  372.  
  373. The list of good modes is, of course, subjective.  I initially used
  374. the first set, then added the second set based on the output of the
  375. first run.  I didn't add all the mismatched modes I found; just the
  376. ones that were fairly normal and that I didn't want to hear about....
  377.  
  378. The program is surprisingly (to me) fast.  It took under a second on
  379. our decently loaded VAX-11/785 running 4.3BSD with 501 passwd entries!
  380.  
  381. This program is placed in the public domain - you have only your
  382. conscience to stop you from saying "hey, look at this neat program I
  383. wrote"....
  384.  
  385.     Enjoy!
  386.  
  387. John Owens        Old Dominion University - Norfolk, Virginia, USA
  388. john@ODU.EDU        old arpa: john%odu.edu@RELAY.CS.NET
  389. +1 804 440 3915        old uucp: {seismo,harvard,sun,hoptoad}!xanth!john
  390. */
  391.  
  392. #include <pwd.h>
  393. #include <sys/types.h>
  394. #include <sys/stat.h>
  395.  
  396.  
  397. /* mask for modes.... (world writable) */
  398. #define DMODE 002
  399.  
  400. main(argc,argv)
  401. char **argv;
  402. {
  403.     register int mode;
  404.     register int *p;
  405.     struct passwd *pp;
  406.     static struct stat statb;
  407.  
  408.     if (argc != 1) {
  409.         printf("Usage: %s\n",argv[0]);
  410.         exit(1);
  411.     }
  412.  
  413.     while ((pp = getpwent()) != (struct passwd *)0) {
  414.         if (stat(pp->pw_dir,&statb) < 0) {
  415.         /*
  416.             perror(pp->pw_dir);
  417.         */
  418.             continue;
  419.         }
  420.  
  421.         if ((statb.st_mode & S_IFMT) != S_IFDIR) {
  422.             printf("Warning!  User %s's home directory %s is not a directory! (mode 0%o)\n",
  423.                 pp->pw_name,pp->pw_dir,statb.st_mode);
  424.             continue;
  425.         }
  426.  
  427.         mode = statb.st_mode & ~S_IFMT;
  428.  
  429.         if (!(mode & DMODE)) goto ok;
  430.  
  431.                 /* note that 3.3 will print 4 if needed */
  432.         printf("Warning!  User %s's home directory %s is mode 0%3.3o!\n",
  433.                pp->pw_name,pp->pw_dir,mode);
  434. ok:    ;
  435.     }
  436.  
  437.     exit(0);
  438.  
  439. }
  440. SHAR_EOF
  441. echo shar: extracting cops/src/is_readable.c '(562 characters)'
  442. cat << \SHAR_EOF > cops/src/is_readable.c
  443. #include <sys/types.h>
  444. #include <math.h>
  445. #include <sys/stat.h>
  446.  
  447. #define G_WRITE 0040    /* group readable */
  448. #define W_WRITE 0004    /* world readable */
  449.  
  450. main(argc,argv)
  451. char **argv;
  452. {
  453.     register int group = 0, xmode = 0;
  454.     static struct stat statb;
  455.  
  456.     if (argc < 2) {
  457.         printf("Usage: %s [-g] file\n",argv[0]);
  458.         exit(0);
  459.     }
  460.  
  461.     if (argc > 2) {
  462.         if (!strcmp(argv[1], "-g")) {
  463.             group = 1;
  464.             argc--;
  465.             argv++;
  466.         }
  467.     }
  468.  
  469.     if (stat(*++argv,&statb) < 0) {
  470.         exit(2);
  471.     }
  472.  
  473.     if (group) xmode = statb.st_mode & G_WRITE;
  474.     else xmode = statb.st_mode & W_WRITE;
  475.  
  476.     exit(!xmode);
  477. }
  478. SHAR_EOF
  479. echo shar: extracting cops/src/is_writable.c '(563 characters)'
  480. cat << \SHAR_EOF > cops/src/is_writable.c
  481. #include <sys/types.h>
  482. #include <math.h>
  483. #include <sys/stat.h>
  484.  
  485. #define G_WRITE 0020    /* group writable */
  486. #define W_WRITE 0002    /* world writable */
  487.  
  488. main(argc,argv)
  489. char **argv;
  490. {
  491.     register int group = 0, xmode = 0;
  492.     static struct stat statb;
  493.  
  494.     if (argc < 2) {
  495.         printf("Usage: %s [-g] file\n",argv[0]);
  496.         exit(0);
  497.     }
  498.  
  499.     if (argc > 2) {
  500.         if (!strcmp(argv[1], "-g")) {
  501.             group = 1;
  502.             argc--;
  503.             argv++;
  504.         }
  505.     }
  506.  
  507.     if (stat(*++argv,&statb) < 0) {
  508.         exit(2);
  509.     }
  510.  
  511.     if (group) xmode = statb.st_mode & G_WRITE;
  512.     else xmode = statb.st_mode & W_WRITE;
  513.  
  514.     exit(!xmode);
  515. }
  516.  
  517. SHAR_EOF
  518. echo shar: extracting cops/src/members.c '(1213 characters)'
  519. cat << \SHAR_EOF > cops/src/members.c
  520. /* Copyright 1985 Robert W. Baldwin */
  521. /* Copyright 1986 Robert W. Baldwin */
  522. static    char    *notice85 = "Copyright 1985 Robert W. Baldwin";
  523. static    char    *notice86 = "Copyright 1986 Robert W. Baldwin";
  524.  
  525. /*
  526.  * useage: members GroupName
  527.  * Writes to stdout the list of UserNames that are in the given group.
  528.  * The UserNames are separated by space or newline characters.
  529.  *
  530.  */
  531.  
  532. #include    <stdio.h>
  533. #include    <grp.h>
  534. #include    <pwd.h>
  535.  
  536.  
  537.  
  538. main(argc, argv)
  539. int    argc;
  540. char    *argv[];
  541. {
  542.     int    i;
  543.     int    gid;
  544.     struct    group    *grent;
  545.     struct    passwd    *pwent;
  546.     char    **user;
  547.  
  548. /*
  549.  * Print the list of group members from /etc/group.
  550.  */
  551.     if ((grent = getgrnam(argv[1])) == NULL)  {
  552.         fprintf(stderr, "%s: Bad group name %s.\n",
  553.             argv[0], argv[1]);
  554.         exit(1);
  555.         }
  556.     gid = grent->gr_gid;
  557.     for (user = grent->gr_mem ; *user != NULL ; user++)  {
  558.         fprintf(stdout, "%s ", *user);
  559.         }
  560.     fprintf(stdout, "\n");
  561.     endgrent();
  562. /*
  563.  * The passwd file must also be examined to find members of the group.
  564.  * Duplicates may occur, but the higher level code shouldn't care about them.
  565.  */
  566.     while ((pwent = getpwent()) != NULL)  {
  567.         if (pwent->pw_gid != gid)
  568.             continue;
  569.         fprintf(stdout, "%s ", pwent->pw_name);
  570.         }
  571.     fprintf(stdout, "\n");
  572.     endpwent();
  573. }
  574.  
  575. SHAR_EOF
  576. echo shar: extracting cops/src/pass.c '(12598 characters)'
  577. cat << \SHAR_EOF > cops/src/pass.c
  578. #include <stdio.h>
  579. #include <pwd.h>
  580. #include <ctype.h>
  581.  
  582. #ifndef lint
  583. static char *rcsid = "$Header: pwchkr.c,v 1.1 85/09/10 16:00:56 root Exp $";
  584. #endif
  585.  
  586. /*
  587.  * Warning: this program burns a lot of cpu.
  588.  */
  589. /*
  590.  * Insecure - find accounts with poor passwords
  591.     Date: Tue, 29 Nov 83 18:19:32 pst
  592.     From: leres%ucbarpa@Berkeley (Craig Leres)
  593.         Modified by Seth Alford, Roger Southwick, Steve Dum, and
  594.         Rick Lindsley for Tektronix
  595.  */
  596.  
  597. /*
  598.  *    $Log:    pwchkr.c,v $
  599.  *    Revision 1.1  85/09/10  16:00:56  root
  600.  *    Initial revision
  601.  *    
  602.  *
  603.  * By default, this program only checks for accounts with passwords the same
  604.  * as the login name. The following options add more extensive checking. (The
  605.  * tradeoff is cpu time -- with all options enabled it can run into the 100's
  606.  * of MINUTES.) Any argument that does not begin with a "-" is assumed to be
  607.  * a file name. (A single '-' means stdin.) If no file name is given,
  608.  * /etc/passwd is used.
  609.  *
  610.  * Options:
  611.  *
  612.  *        -v:    verbose -- list all guesses on stdout
  613.  *        -u:    output the username on the line of the password file
  614.  *            currently being checked. If the program stops
  615.  *            abruptly you will then know how far it got.
  616.  *        -w file: use the list of words contained in "file" as likely
  617.  *            passwords. Words in the file are one to a line.
  618.  *        -b:     check all guesses backwards too
  619.  *        -g:    use the Full Name portion of the gecos field to
  620.  *            generate more guesses
  621.  *        -s:    check the single letters a-z, A-Z, 0-9 as passwords
  622.  *        -c:    with each guess, check for all-lowercase and
  623.  *            all-uppercase versions too.
  624.  *        -n:    complain about null passwords (default is to keep quiet)
  625.  *        -p:    print the password when guessed
  626.  */
  627.  
  628. int verbose = 0, singles = 0, backwards = 0, checkgecos = 0, checkcase = 0,
  629.     chknulls = 0, printit = 0, users = 0, chkwords = 0;
  630.  
  631. char *my_index(), *reverse();
  632. long atol();
  633. FILE *fopen();
  634. char *fgets();
  635.  
  636. char PASSWD[] = "/etc/passwd";
  637. char EMPTY[] = "";
  638. static FILE *pwf = NULL, *wlf = NULL;
  639. char line[BUFSIZ+1];
  640. struct passwd passwd;
  641. char    *Curpw, *Wordlist = NULL;
  642.  
  643. main(argc, argv)
  644. char **argv;
  645. {
  646.     register int i;
  647.     register char *arg;
  648.     int onedone = 0;
  649.  
  650.     /*
  651.     You have to decide whether or not to include these lines....
  652.  
  653.     if (getuid()) {
  654.     printf("Did you really think we would let you run this?\n");
  655.     exit(1);
  656.     }
  657.  
  658.     */
  659.  
  660.     for (i = 1; i < argc; i++)
  661.     if ((arg = argv[i]) && *arg == '-')
  662.         while (*++arg) {
  663.         switch (*arg) {
  664.             case 'n':
  665.             /*
  666.              * complain about null passwords
  667.              */
  668.             chknulls++;
  669.             break;
  670.             case 'c':
  671.             /*
  672.              * check cases
  673.              */
  674.             checkcase++;
  675.             break;
  676.             case 'g':
  677.             /*
  678.              * use gecos
  679.              */
  680.             checkgecos++;
  681.             break;
  682.             case 'v':
  683.             /*
  684.              * turn on motormouth
  685.              */
  686.             verbose++;
  687.             break;
  688.             case 'b':
  689.             /*
  690.              * check all attempts forwards and backwards
  691.              */
  692.             backwards++;
  693.             break;
  694.             case 's':
  695.             /*
  696.              * carry out a more intensive search, checking for
  697.              * single letter passwords
  698.              */
  699.             singles++;
  700.             break;
  701.             case 'p':
  702.             /*
  703.              * print out the password when found
  704.              */
  705.             printit++;
  706.             break;
  707.             case 'u':
  708.             /*
  709.              * print out users as testing
  710.              */
  711.             users++;
  712.             break;
  713.             case 'w':
  714.             /*
  715.              * consult word list of likely passwords
  716.              */
  717.             if ((Wordlist = argv[i+1]) == NULL) {
  718.                 fprintf(stderr,
  719.                 "%s: No file supplied with -w option\n",
  720.                 argv[0]);
  721.                 exit (1);
  722.                 }
  723.             argv[i+1] = NULL;
  724.             break;
  725.             case '\0':
  726.             /*
  727.              * read from stdin
  728.              */
  729.             break;
  730.             default:
  731.             fprintf(stderr,
  732.                 "%s: unknown option '%c'. Options are:\n",argv[0],
  733.                 *arg);
  734.             /* FALL THRU */
  735.             case '-':
  736.             fprintf(stderr,"-v:\t\tverbose -- list all guesses on stdout\n");
  737.             fprintf(stderr,"-u:\t\toutput the username currently being checked\n");
  738.             fprintf(stderr,"-w file:\tconsult the indicated file for words to check as passwords\n");
  739.             fprintf(stderr,"-b:\t\tcheck all guesses forwards and backwards\n");
  740.             fprintf(stderr,"-g:\t\tuse the Full name portion of the gecos field for more guesses\n");
  741.             fprintf(stderr,"-s:\t\tcheck the single letters a-z, A-Z, 0-9 as passwords\n");
  742.             fprintf(stderr,"-c:\t\tcheck the all-upper and all-lower case version of each guess\n");
  743.             fprintf(stderr,"-n:\t\tcomplain about null passwords\n");
  744.             fprintf(stderr,"-p:\t\tprint the password when guessed\n");
  745.             exit(1);
  746.             }
  747.         argv[i] = NULL;
  748.         }
  749.     
  750.     for (i = 1; i < argc; i++) {
  751.     if (argv[i] == NULL) continue;
  752.     onedone++;
  753.     if (*(argv[i]) == '-') {
  754.         /*
  755.          * read from stdin; we'll cheat and set pwf directly
  756.          */
  757.         pwf = stdin;
  758.         chkpw();
  759.         /*
  760.          * don't fclose stdin!
  761.          */
  762.         clearerr(stdin);
  763.         }
  764.     else {
  765.         if (setpwent(argv[i])) {
  766.         perror(argv[i]);
  767.         continue;
  768.         }
  769.         Curpw = argv[i];
  770.         chkpw();
  771.         endpwent();
  772.         }
  773.     }
  774.     if (!onedone) {
  775.     Curpw = NULL;
  776.     chkpw();
  777.     }
  778.     exit(0);
  779. }
  780.  
  781. /*
  782.  * Added by Jacob Gore, March 12, 1987.
  783.  *
  784.  * Finds the pointer of the leftmost occurance within the character string
  785.  * 'string' of any character found within the character string 'chars'.
  786.  *
  787.  * If none of the characters in 'chars' appear in 'string', NULL is retutned.
  788.  *
  789.  */
  790. char *
  791. indexm (string, chars)
  792.     char *string, *chars;
  793. {
  794.     while (*string) {
  795.     if (my_index(chars, *string) != NULL) {
  796.         return string;
  797.     }
  798.     string++;
  799.     }
  800.     return NULL;
  801. }
  802.  
  803. #define ARB_CONST    80
  804.  
  805. chkpw()
  806.  
  807. {
  808.     register char    *cp, *cp2;
  809.     register struct passwd *pwd;
  810.     struct passwd    *getpwent();
  811.     char        guess[100];
  812.     char        *wordarray[ARB_CONST];
  813.     char        *malloc(), **wordptr, **endptr;
  814.     int            done = 0;
  815.  
  816.  
  817.     if (Wordlist)
  818.     {
  819.     if ((wlf = fopen(Wordlist,"r")) == NULL)
  820.     {
  821.         perror(Wordlist);
  822.         exit(1);
  823.     }
  824.  
  825.     wordptr = wordarray;
  826.     /*
  827.      * note that endptr points to space OUTSIDE of wordarray
  828.      */
  829.     endptr = wordarray + (sizeof(wordarray)/sizeof(char *));
  830.  
  831.     while (fscanf(wlf,"%[^\n]\n",guess) != EOF)
  832.     {
  833.   /* SunOs 4.03 on a Sun 3/80 didn't work properly, needed this one line fix */
  834.         if (feof(wlf)) break;
  835.  
  836.         if (wordptr == endptr)
  837.         {
  838.         fprintf(stderr,"Ran out of wordlist space. ARB_CONST %d must be too small.\n", ARB_CONST);
  839.         exit(1);
  840.         }
  841.         if ((*wordptr = malloc(1+strlen(guess))) == NULL)
  842.         {
  843.         fprintf(stderr,"malloc: no more memory for wordlist\n");
  844.         exit (1);
  845.         }
  846.         strcpy(*wordptr,guess);
  847.         wordptr++;
  848.     }
  849.     *wordptr = NULL;
  850.     }
  851.  
  852.     while ((pwd = getpwent()) != 0 ) {
  853.  
  854.     if (verbose || users) {
  855.         if (Curpw == NULL)
  856.         printf("\t%s \"%s\"\n", pwd->pw_name, pwd->pw_gecos);
  857.         else
  858.         printf("%s -- \t%s \"%s\"\n", Curpw, pwd->pw_name,
  859.             pwd->pw_gecos);
  860.         fflush(stdout);
  861.         }
  862.     if (*pwd->pw_passwd == '\0') {
  863.         if (chknulls) {
  864.         if (Curpw == NULL)
  865.             printf("Warning!  Password Problem: null passwd:\t%s\tshell: %s\n",
  866.             pwd->pw_name, pwd->pw_shell);
  867.         else
  868.             printf("Warning!  %s -- Password Problem: null passwd:\t%s\tshell: %s\n",
  869.             Curpw, pwd->pw_name, pwd->pw_shell);
  870.         fflush(stdout);
  871.         }
  872.         continue;
  873.     }
  874.     /*
  875.      * Try the user's login name
  876.      */
  877.     if (uandltry(pwd,pwd->pw_name))
  878.         continue;
  879.  
  880.     /*
  881.      * Try names from the gecos field
  882.      */
  883.     if (checkgecos) {
  884.         strcpy(guess, pwd->pw_gecos);
  885.         cp = guess;
  886.         if (*cp == '-') cp++;        /* special gecos field */
  887.         if ((cp2 = my_index(cp, ';')) != NULL)
  888.         *cp2 = '\0';
  889.  
  890.         for (;;) {
  891.         /* use both ' ' and ',' as delimiters -- Jacob */
  892.         if ((cp2 = indexm(cp, " ,")) == NULL) {
  893.             if (uandltry(pwd,cp))
  894.             done++;
  895.             break;
  896.             }
  897.  
  898.         *cp2 = '\0';
  899.  
  900.         if (uandltry(pwd,cp)) {
  901.             done++;
  902.             break;
  903.             }
  904.         cp = ++cp2;
  905.         }
  906.         }
  907.         
  908.     if (!done && Wordlist)
  909.     {
  910.         /*
  911.          * try the words in the wordlist
  912.          */
  913.         wordptr = wordarray;
  914.         while (endptr != wordptr)
  915.         {
  916.         if (*wordptr == NULL)
  917.             break;
  918.         if (uandltry(pwd,*wordptr++))
  919.         {
  920.             done++;
  921.             break;
  922.         }
  923.         }
  924.     }
  925.     if (!done && singles) {
  926.         /*
  927.          * Try all single letters
  928.          * (try digits too .  --Seth)
  929.          */
  930.         guess[1] = '\0';
  931.         for (guess[0]='a'; guess[0] <= 'z'; guess[0]++)
  932.         if (try(pwd,guess))
  933.             break;
  934.         for (guess[0]='A'; guess[0] <= 'Z'; guess[0]++)
  935.         if (try(pwd,guess))
  936.             break;
  937.         for (guess[0]='0'; guess[0] <= '9'; guess[0]++)
  938.         if (try(pwd,guess))
  939.             break;
  940.         }
  941.     }
  942. }
  943.  
  944. /*
  945.  * Stands for "upper and lower" try.  Calls the "real" try, below,
  946.  * with the supplied version of the password, and with
  947.  * an upper and lowercase version of the password. If the user doesn't
  948.  * want to try upper and lower case then we just return after the one
  949.  * check.
  950. */
  951.  
  952. uandltry (pwd,guess)
  953. char *guess;
  954. struct passwd *pwd;
  955. {
  956.     register char *cp;
  957.     char buf[100];
  958.     int alllower, allupper;
  959.  
  960.     alllower = allupper = 1;
  961.  
  962.     if (try(pwd,guess) || (backwards && try(pwd,reverse(guess)))) return (1);
  963.  
  964.     if (!checkcase) return(0);
  965.  
  966.     strcpy (buf, guess);
  967.     cp = buf-1;
  968.     while (*++cp) {
  969.     if (isupper(*cp))
  970.         alllower = 0;
  971.     if (islower(*cp))
  972.         allupper = 0;
  973.     }
  974.  
  975.     if (!allupper) {
  976.     for ( cp=buf; *cp != '\0'; cp++)
  977.         if (islower (*cp))
  978.         *cp += 'A' - 'a';
  979.  
  980.     if (try(pwd,buf) || (backwards && try(pwd,reverse(buf)))) return (1);
  981.     }
  982.  
  983.     if (!alllower) {
  984.     for ( cp = buf; *cp != '\0'; cp++)
  985.         if (isupper (*cp))
  986.         *cp += 'a' - 'A';
  987.  
  988.     if (try(pwd,buf) || (backwards && try(pwd,reverse(buf)))) return (1);
  989.     }
  990.     return (0);
  991. }
  992.  
  993. try(pwd,guess)
  994. char *guess;
  995. register struct passwd *pwd;
  996. {
  997.     register char  *cp;
  998.     char   *crypt ();
  999.  
  1000.     if (verbose) {
  1001.     if (Curpw == NULL)
  1002.         printf ("Trying \"%s\" on %s\n", guess, pwd -> pw_name);
  1003.     else
  1004.         printf ("%s -- Trying \"%s\" on %s\n", Curpw, guess,
  1005.         pwd -> pw_name);
  1006.     fflush (stdout);
  1007.     }
  1008.     if (! guess || ! *guess) return(0);
  1009.     cp = crypt (guess, pwd -> pw_passwd);
  1010.     if (strcmp (cp, pwd -> pw_passwd))
  1011.     return (0);
  1012.     if (Curpw == NULL)
  1013.     if (printit)
  1014.         printf ("Warning!  Password Problem: Guessed:\t%s\tshell: %s passwd: %s\n",
  1015.         pwd -> pw_name, pwd -> pw_shell, guess);
  1016.     else
  1017.         printf ("Warning!  Password Problem: Guessed:\t%s\tshell: %s\n", pwd -> pw_name,
  1018.         pwd -> pw_shell);
  1019.     else
  1020.     if (printit)
  1021.         printf ("Warning!  %s -- Password Problem: Guessed:\t%s\tshell: %s passwd: %s\n",
  1022.         Curpw, pwd -> pw_name, pwd -> pw_shell, guess);
  1023.     else
  1024.         printf ("Warning!  %s -- Password Problem: Guessed:\t%s\tshell: %s\n",
  1025.         Curpw, pwd -> pw_name, pwd -> pw_shell);
  1026.     fflush (stdout);
  1027.     return (1);
  1028. }
  1029. /* end of PW guessing program */
  1030.  
  1031. #define MAXUID 0x7fff    /* added by tonyb 12/29/83 */
  1032.             /* altered to a reasonable number - mae 8/20/84 */
  1033.  
  1034. /*
  1035.  * Add a parameter to "setpwent" so I can override the file name.
  1036.  */
  1037.  
  1038. setpwent(file)
  1039. char *file;
  1040. {
  1041.     if ((pwf = fopen(file,"r")) == NULL)
  1042.         return(1);
  1043.     return(0);
  1044. }
  1045.  
  1046. endpwent()
  1047.  
  1048. {
  1049.     fclose(pwf);
  1050.     pwf = NULL;
  1051. }
  1052.  
  1053. char *
  1054. pwskip(p)
  1055. register char *p;
  1056. {
  1057.     while(*p && *p != ':' && *p != '\n')
  1058.         ++p;
  1059.     if(*p == '\n')
  1060.         *p = '\0';
  1061.     else if(*p)
  1062.         *p++ = '\0';
  1063.     return(p);
  1064. }
  1065.  
  1066. struct passwd *
  1067. getpwent()
  1068. {
  1069.     register char *p;
  1070.     long    x;
  1071.  
  1072.     if(pwf == NULL)
  1073.         if (setpwent(PASSWD)) {
  1074.         perror(PASSWD);
  1075.         return(NULL);
  1076.         }
  1077.     p = fgets(line, BUFSIZ, pwf);
  1078.     if(p == NULL)
  1079.         return(0);
  1080.     passwd.pw_name = p;
  1081.     p = pwskip(p);
  1082.     passwd.pw_passwd = p;
  1083.     p = pwskip(p);
  1084.     x = atol(p);    
  1085.     passwd.pw_uid = (x < 0 || x > MAXUID)? (MAXUID+1): x;
  1086.     p = pwskip(p);
  1087.     x = atol(p);
  1088.     passwd.pw_gid = (x < 0 || x > MAXUID)? (MAXUID+1): x;
  1089.     passwd.pw_comment = EMPTY;
  1090.     p = pwskip(p);
  1091.     passwd.pw_gecos = p;
  1092.     p = pwskip(p);
  1093.     passwd.pw_dir = p;
  1094.     p = pwskip(p);
  1095.     passwd.pw_shell = p;
  1096.     (void) pwskip(p);
  1097.  
  1098.     p = passwd.pw_passwd;
  1099.  
  1100.     return(&passwd);
  1101.  
  1102. }
  1103.  
  1104.  
  1105. /*
  1106.  * reverse a string
  1107.  */
  1108. char *reverse(str)
  1109. char *str;
  1110.  
  1111. {
  1112.     register char *ptr;
  1113.     register int len;
  1114.     char    *malloc();
  1115.  
  1116.     if ((ptr = malloc((len = strlen(str))+1)) == NULL)
  1117.     return(NULL);
  1118.     ptr += len;
  1119.     *ptr = '\0';
  1120.     while (*str && (*--ptr = *str++))
  1121.     ;
  1122.     return(ptr);
  1123. }
  1124. /* taken from comp.binaries.ibm.pc.d:
  1125. Some users have reported trouble compiling the freely distributable
  1126. uudecode I posted.  It seems that Berkeley moved the "index" function
  1127. to one of their system libraries and some systems don't have it.
  1128. Here is the missing "index" function, excerpted from an earlier freely
  1129. distributable uudecode.  Just add it on the end of the uudecode I posted.
  1130. */
  1131. /*
  1132. --Keith Petersen
  1133. Maintainer of SIMTEL20's CP/M, MSDOS, & MISC archives [IP address 26.2.0.74]
  1134. Internet: w8sdz@WSMR-SIMTEL20.Army.Mil, w8sdz@brl.arpa  BITNET: w8sdz@NDSUVM1
  1135. Uucp: {ames,decwrl,harvard,rutgers,ucbvax,uunet}!wsmr-simtel20.army.mil!w8sdz
  1136. */
  1137.  
  1138. /*
  1139.  * Return the ptr in sp at which the character c appears;
  1140.  * NULL if not found
  1141.  */
  1142.  
  1143. #define    NULL    0
  1144.  
  1145. char *
  1146. my_index(sp, c)
  1147. register char *sp, c;
  1148. {
  1149.     do {
  1150.         if (*sp == c)
  1151.             return(sp);
  1152.     } while (*sp++);
  1153.     return(NULL);
  1154. }
  1155.  
  1156.  
  1157. SHAR_EOF
  1158. echo shar: extracting cops/src/tilde.c '(401 characters)'
  1159. cat << \SHAR_EOF > cops/src/tilde.c
  1160. #include <pwd.h>
  1161. #include <sys/types.h>
  1162. #include <sys/stat.h>
  1163.  
  1164. main(argc,argv)
  1165. int argc;
  1166. char **argv;
  1167. {
  1168. struct passwd *pp;
  1169.  
  1170. if (argc != 2) {
  1171.     printf("Usage: %s\n",argv[0]);
  1172.     exit(1);
  1173. }
  1174.  
  1175. /* print directory of user, else "Error"  -- need to print
  1176.   something, or kuang won't parse dir correctly */
  1177. if ((pp = getpwnam(argv[1])) != (struct passwd *)0)
  1178.     printf("%s", pp->pw_dir);
  1179. else
  1180.     printf("Error");
  1181.  
  1182. }
  1183. SHAR_EOF
  1184. echo shar: extracting cops/src/user.chk.c '(1411 characters)'
  1185. cat << \SHAR_EOF > cops/src/user.chk.c
  1186. #include <stdio.h>
  1187. #include <pwd.h>
  1188. #include <sys/types.h>
  1189. #include <sys/stat.h>
  1190.  
  1191. /* Any file writable by all will be flagged */
  1192. #define DMODE 002
  1193.  
  1194. /* #define DMODE2 020 */
  1195.  
  1196. /* potentially dangerous files */
  1197. char *ftable[] = {
  1198.     "rhost",
  1199.     "profile",
  1200.     "login",
  1201.     "cshrc",
  1202.     "bashrc",
  1203.     "kshrc",
  1204.     "tcshrc",
  1205.     "rhost",
  1206.     "netrc",
  1207.     "forward",
  1208.     "dbxinit",
  1209.     "distfile",
  1210.     "exrc",
  1211.     "emacsrc"
  1212. };
  1213. char *ft;
  1214. char *ftr, *malloc();
  1215.  
  1216. char generic_file[100];
  1217.  
  1218. main(argc,argv)
  1219. int argc;
  1220. char **argv;
  1221. {
  1222. register int fmode;
  1223. /*
  1224. int index;
  1225. */
  1226. register int index;
  1227. struct passwd *pp;
  1228. static struct stat statb;
  1229.  
  1230. if (argc != 1) {
  1231.     printf("Usage: %s\n",argv[0]);
  1232.     exit(1);
  1233. }
  1234.  
  1235. ft = malloc(100);
  1236. ftr = malloc(100);
  1237.  
  1238. while ((pp = getpwent()) != (struct passwd *)0) {
  1239.     if (stat(pp->pw_dir,&statb) < 0) {
  1240.         continue;
  1241.     }
  1242.  
  1243.     index = 0;
  1244.     /*
  1245.      *   Use the home-dir, and add on each potential security threat
  1246.      * file to the path one at a time.  Then check each file to see
  1247.      * if it breaks with the modes established up above
  1248.      *
  1249.     */
  1250.     for (ft = ftable[index]; index < 13; ft = ftable[++index]) {
  1251.         if (strlen(pp->pw_dir) != 1)
  1252.             sprintf(generic_file, "%s/.%s", pp->pw_dir,ft);
  1253.         else 
  1254.             sprintf(generic_file, "%s.%s", pp->pw_dir,ft);
  1255.  
  1256.         if (stat(generic_file,&statb) < 0)
  1257.             continue;
  1258.  
  1259.         if (statb.st_mode & DMODE) 
  1260.             printf("Warning!  User %s:\t%s is mode \t0%3.3o!\n",
  1261.                    pp->pw_name,generic_file,statb.st_mode&~S_IFMT);
  1262.  
  1263.     }
  1264.  
  1265. }
  1266.  
  1267. exit(0);
  1268. }
  1269. SHAR_EOF
  1270. echo shar: extracting cops/extensions/THINGS_2_DO '(1515 characters)'
  1271. cat << \SHAR_EOF > cops/extensions/THINGS_2_DO
  1272.  
  1273.  Possible improvements/extensions of the COPS package might (will?) include
  1274. (other than merely fixing bugs existing in the package) :
  1275.  
  1276.  0) Smarter detection of problems -- a lot of problems can be found in
  1277. configuration files; the way they are set up, not merely if they are
  1278. writable.  These aren't neccessarily hard to check for, but take someone
  1279. with a good understanding for the file to write.
  1280.  
  1281.  1) Detecting Bugs.  A very touchy subject, with so many sites without
  1282. source code to fix the bugs.  Depends a lot on how people react to this
  1283. package, and what the demand is for a package that finds bugs.  It would
  1284. be similar to the approach used in the rest of the package in that it
  1285. would point out the bugs, not tell how to exploit them.  For instance,
  1286. an example would be "Warning!  fingerd bug present!"
  1287.  
  1288.  2) Better and more thorough Yellow Pages checking.
  1289.  
  1290.  3) Ditto for UUCP stuff.
  1291.  
  1292.  4) Once again for NFS things.
  1293.  
  1294.  5) Problems that are specific to a certain flavor of UNIX.  For
  1295. instance, HP-UX has different files in different places.  Perhaps
  1296. the system could look for and hunt for the vital files in the various
  1297. places rather than having to be put in a configuration file.  Also
  1298. support for various secure UNIX varieties; e.g. C2 level Sun, IBM's
  1299. secure AIX, etc.
  1300.  
  1301.  6) More problems to be added; by no means are all security problems detected
  1302. by COPS.  More potential hazards should not be difficult to detect -- merely
  1303. adding another module to the system or simply modifying what is here might
  1304. suffice.
  1305. SHAR_EOF
  1306. echo shar: extracting cops/extensions/YAR '(377 characters)'
  1307. cat << \SHAR_EOF > cops/extensions/YAR
  1308.  
  1309.  
  1310.   (YAR -- Yet Another README file)
  1311.  
  1312.     This is where the odds 'n ends go.
  1313.     "THINGS_2_DO" is a file that says what I'd like to see done, either
  1314. in COPS or in other packages.
  1315.     "questions" is a questionaire and some answers I recieved about
  1316. computer security.  It might prove of interest for general reading.
  1317.     "netstuff" is a short list of net.references for further information.
  1318.     "passwords" gives a reference for fast password cracking.
  1319.  
  1320. SHAR_EOF
  1321. echo shar: extracting cops/extensions/netstuff '(1717 characters)'
  1322. cat << \SHAR_EOF > cops/extensions/netstuff
  1323.  
  1324.  
  1325.     For additional information, help on various subjects, etc., there
  1326. are various resources available on the net.  By no means is this list
  1327. exclusive:
  1328.  
  1329.    comp.risks -- a moderated newsgroup that talks about the risks of
  1330. computing, often discussing computer security.
  1331.  
  1332.    comp.unix.wizards -- a high noise free-for-all group that has
  1333. some choice tidbits of information.
  1334.  
  1335.    Security Mailing list -- moderated by Neil Gorsuch, fits and bursts
  1336. of information that can be gotten nowhere else.  Hard to join the elite
  1337. who are on the list, and a long wait for acceptance.  Security programs
  1338. can be snarfed off of this list at times.
  1339.  
  1340.    CERT -- the Computer Emergency Response Team has a mailling list
  1341. devoted to the development of security tools.  As quoted from
  1342. their initial mailing:
  1343.  
  1344. "The Computer Emergency Response Team Coordination Center (CERT/CC) has
  1345. established a new Internet mailing list named CERT-TOOLS.  This new
  1346. mailing list is now available.
  1347.  
  1348. The purpose of this new mailing list is to encourage the exchange of
  1349. information on security tools and security techniques.  The list
  1350. should not be used for security problem reports.
  1351. [...]
  1352. Mailing list problems, additions, changes, and deletions requests should
  1353. be sent to:
  1354.         cert-tools-request@cert.sei.cmu.edu
  1355.  
  1356. [...]
  1357. CERT/CC is planning to collect many of the tools and will make the
  1358. archive available via anonymous ftp on the cert.sei.cmu.edu system.
  1359. A trusted archive service will also be available for tools not intended
  1360. for general public usage.
  1361.  
  1362. All mail intended to be redistributed should be mailed to:
  1363.     cert-tools@cert.sei.cmu.edu
  1364.  
  1365. Computer Emergency Response Team
  1366. Email: cert@cert.sei.cmu.edu
  1367. Telephone: 412-268-7090 (answers 24 hours a day)"
  1368. SHAR_EOF
  1369. echo shar: extracting cops/extensions/passwords '(432 characters)'
  1370. cat << \SHAR_EOF > cops/extensions/passwords
  1371.  
  1372.    For those who need _fast_ password cracking, for whatever reason,
  1373. Matt Bishop wrote a fairly incredible password cracking engine, which
  1374. is detailed in:
  1375.  
  1376. "An Application of a Fast Data Encryption Standard Implementation",
  1377. Matt Bishop, Computing Systems 1(3) pp. 221-254 (Summer 1988).
  1378.  
  1379.   If you have a valid reason for using it, you can mail to Matt at:
  1380.     
  1381.    bishop@bear.dartmouth.edu
  1382.  
  1383.   for more information on his package.
  1384.  
  1385. SHAR_EOF
  1386. echo shar: extracting cops/extensions/questions '(13339 characters)'
  1387. cat << \SHAR_EOF > cops/extensions/questions
  1388.    
  1389.    I polled a security mailing list and got about 40 responses to a
  1390. selected number of questions dealing with security; it might be useful
  1391. for inclusion on how the net (at least some of the security minded ones)
  1392. view security.  The answers to these questions shaped some of the philosophies
  1393. of COPS and might be indicative of the type of security tools to be
  1394. developed in the future.  My questions start with a number and a ")".
  1395.  
  1396.    1)  What kinds of problems should a software security system (SSS)
  1397.    such as COPS check for? (Mention specific examples, if you can.)
  1398.  
  1399.   Just about everyone agreed that the more things checked, the better.
  1400. Some specific wants of items I didn't mention, more or less in the order
  1401. of # of requests:
  1402.  
  1403.   Some kind of _secure_ checksum method for checking up on binary files.
  1404.  
  1405.   Checking binaries for known security problems - sendmail, fingerd,
  1406. ftpd, ect.
  1407.  
  1408.   Checking the validity of the _format_ of key files rather than merely
  1409. checking if they are writable.
  1410.  
  1411.   Checking for potential trojan horses; files such as "ls" in a users
  1412. account.
  1413.  
  1414.   Finding things hidden under mount points.
  1415.  
  1416.   Keeping track of accounts in a seperate file from /etc/passwd and
  1417. run periodic checks to see if any accounts have been added by any
  1418. unauthorized user.
  1419.   
  1420.   Report unusual system activity, such as burning lots of CPU time.
  1421.  
  1422.   Record unsuccessful login attempts and su's to root, when and by whom
  1423. if possible.
  1424.  
  1425.  
  1426.    2)  Are there any security problems too sensitive to be checked
  1427.    by a SSS?  That is, what things should *not* be built into a SSS?
  1428.  
  1429.      Boy, this was a landslide.  Over 90% said NO, and not only no,
  1430. but basically "Hell No".  The only concerns I got were against password
  1431. cracking and problems that could not be easily fixed.  There was also
  1432. a small amount of concern about limiting access to root, but most realized
  1433. that no matter what, the benifits would outweigh any losses if the programs
  1434. were put out.
  1435.  
  1436.    3) What should the primary goal of a SSS be -- discovering as many
  1437.    security holes as possible in a given system (including bugs or
  1438.    design flaws that may not be easily fixed -- especially without
  1439.    source code), or merely uncovering correctable errors (due to
  1440.    ignorance, carelessness, etc)?
  1441.  
  1442.      Another landslide.  Of all the responses, only one person objected
  1443. to finding all holes, although a few did say that finding the fixable
  1444. holes was top priority.
  1445.  
  1446.     One view:
  1447.  
  1448.   My use for an SSS is as a system monitor, not as a diagnostic tool.
  1449. I suppose the diagnostic version also has its uses, but writing and
  1450. distributing such a program is asking for trouble.  I don't see
  1451. anything wrong with writing it and distributing only the binaries.
  1452.  
  1453.  
  1454.    4)  Do you feel that SSS are a security threat themselves?
  1455.  
  1456.      Some dissent begins to show.... It was almost even here, with the
  1457. no's beating out the yes's by a single vote.  However, 2/3 of the yes
  1458. votes qualified there answer by stating something like "a tool can be
  1459. misused" and whatnot.  Here are some typical responses:
  1460.  
  1461. Of course.  They point to way for bad guys.  Such is life.
  1462. They are a tool.  They have the potential for anything.  The
  1463. security threat lies in how they are used....
  1464.  
  1465. No, as long as they don't breed complacency. Just by running
  1466. a SSS each night should not make you thinks your systems are
  1467. secure.
  1468.  
  1469. Fire is also dangerous but VERY useful.
  1470.  
  1471.  
  1472.    5) Do you think that the SSS should be restricted to be used only
  1473.    by system administrators (or other people in charge), or should
  1474.    they be accessible to all?
  1475.  
  1476.      Here's where the problems start :-)  Everyone wants as many
  1477. features as possible, but quite a few of you don't want anyone else
  1478. to have it.  Hmm...   Out of 35 responses on this question:
  1479.   12 - Yes, only SA's.
  1480.   10 - No.
  1481.    6 - It would be nice to have it restricted, but... How?
  1482.    5 - Have two versions; one restricted, one not.  Needless to say,
  1483.         the dangerous stuff should go in the first.
  1484.    1 - Restrict only parts that detect bugs/whatever that cannot be
  1485.         repaired.
  1486.    1 - Argh!  Help!
  1487.  
  1488.      Some quotable quotes:
  1489.  
  1490. I don't see how it could be restricted.
  1491.  
  1492. Admins, etc only. (possibly said because I'm an admin. From an
  1493. intellectual standpoint, I would want to know about this stuff even
  1494. if I was just a user)
  1495.  
  1496. I think the SSS should be restricted to system
  1497. administrators with the realisation that others can probably
  1498. get their hands on the code if they want to. 
  1499.  
  1500. Definitely available to all, SA's can be as lazy as anyone and should not be 
  1501. allowed to hide behind a veil of secrecy if, in doing so, they expose the 
  1502. systems they administer.
  1503.  
  1504. It seems to me that only an "administrator type" will have sufficient
  1505. privilege levels to make _effective_ use of such a tool.  Ordinary users
  1506. may be able to garner _some_ benefit though, if run on their own files.
  1507. If possible, can there be an "administrator" mode and a (restriced/limited)
  1508. "user" mode?
  1509.  
  1510. (and finally, my personal favorite...)
  1511.  
  1512. I think that a check for a hole that can't be closed shouldn't be a part of
  1513. the check, if that hole is widespread.  I have no examples of any such hole,
  1514. but a weak spot that can't be closed and has no workaround is one of the few
  1515. candidates for the security by secrecy concept.  I have mixed feelings about
  1516. this, but if I can't fix the hole, I'd rather not have it's existence be
  1517. "public" knowledge.  A freely available routine to locate the hole would
  1518. spread it's existence far and wide.....(?)
  1519. But, if I didn't know about it beforehand then it would be good to have a
  1520. tool to tell me it existed.  Gads, I hate moral conflicts!
  1521.  
  1522.  
  1523.    6) When a SSS finds a security flaw in a system, do you want it to 
  1524.    indicate how they flaw could be used to compromise your system, or
  1525.    would you just accept the conclusion and apply a fix?
  1526.  
  1527.       This question was ill worded and gramatically incorrect, but still
  1528. managed to conjure up a lot of comments.  Some thought it was asking if
  1529. the system should apply a fix.
  1530.       In any case, almost 3/4 said Yes, indicate exactly how to exploit
  1531. any potential hole.  As usual, there were a few with reservations about
  1532. the info getting out, but.... 
  1533.    Here are some of the more interesting comments:
  1534.  
  1535.                 (Think about this one!)
  1536.   *I* would like to know to futher my knowledge of Unix, but more importantly
  1537. to make sure that the version I have was not modified by a cracker to
  1538. put security holes *into* a system.  (That'd be sneaky :-)
  1539.  
  1540.    Security by obfuscation doesn't work.
  1541.  
  1542.    By definition, a SSS is a software system, and therefore has bugs in it.
  1543. If it reported a problem which would cause quite a bit of inconvenience if
  1544. fixed, or would be difficult to fix, then I would be much more apt to make
  1545. the fix if I knew how the problem could be exploited.  This is important,
  1546. because many, if not most, sites require only a moderate level of security,
  1547. and many security holes are fiendishly difficult to exploit.
  1548.  
  1549.    We cannot assume that end-purchasers of a system can be as aware of 
  1550. the internal workings of a system as the designers of the system (or SSS)
  1551. are.  If a security flaw is discovered, the administrators need to be
  1552. informed about what changes are necessary to remove that flaw, and what
  1553. repercussions they may have.
  1554.    [...]
  1555.    Imagine a SSS that knew sendmail(8) was a security flaw
  1556. allowing a worm to enter systems.  It would report that sendmail is a 
  1557. security flaw, please disable it like....  If the vendor had released
  1558. a patch, and the SSS didn't know how it, the administrator (in blind
  1559. faith to this SSS program) might disable a *very* useful program
  1560. unnecessarily.
  1561.  
  1562.  
  1563.    7)  Do you think that there is too much, not enough, or just about
  1564.    the right amount of concern over computer security?  How about at 
  1565.    your computer site?  At other sites?
  1566.  
  1567.       The "not enough"s won, but not by much.  I thought that given
  1568. the paranoia of a security group, this would be a larger victory.
  1569. Lots of people said it depends -- on the type of facility, the size, etc.
  1570. Large sites seem to have a healthier view of security (paranoia :-)) than
  1571. smaller/non-governmental.  Only 4 or 5 said there was enough concern.
  1572. A couple of people mentioned _The Cuckoo's Egg_ as suggested reading
  1573. (I heartily agree.)
  1574.  
  1575.    More quotes:
  1576.  
  1577.   (I don't know if the next answer is true, but I like it anyway!)
  1578.  
  1579.   This is really a deep philosophical question---something to talk about
  1580. over a few beers at the bar, but not here.
  1581.  
  1582.   I think it's a site dependent problem, and all the above are
  1583. true: too much, too little, and just right. Computer is not a
  1584. "one size fits all" situation. Having offered that opinion, I
  1585. think an assessment of my site or other sites is extraneous, and I
  1586. will reserve that opinion.
  1587.  
  1588.   ... more attention to unauthorized use of the networks.
  1589.  
  1590.    8)  Do you think that there should be a ruling body that governs
  1591.    and enforces rules and regulations of the net -- sort of a net.police?
  1592.  
  1593.      Some of you wondered what this had to do with software security, but
  1594. just about everyone answered anyway.  This one scared me!  The "No's" only
  1595. beat out the "yes's" by one vote.  Yikes!  Maybe I'm from the old school
  1596. of thought, but....  Several people said that it couldn't be done anyway;
  1597. a couple mentioned they a CERT-like agency to help out, but not control,
  1598. and finally two said that the laws and government were already there to
  1599. do this.
  1600.  
  1601.    It's there, defacto.  The free market is working pretty well.
  1602.  
  1603.    Absolutely. I quarrel with the "net.police" designation, per se, of
  1604. course, as do many others. But perhaps something more like a recognized
  1605. trade association, and providing similar services. Also, it is time that
  1606. the basic duties which must be reasonably performed by a site in order for
  1607. it to remain on the net should become a requirement rather than a matter
  1608. of individual whim.
  1609.  
  1610.    Yuck!  This is very distasteful to me.  It will probably be necessary
  1611. though as more and more people participate in the net.  Enforcement will
  1612. have to be judicious until secure networking is developed and implemented
  1613. generally.
  1614.  
  1615.    No.  Aside from the fact that it'd never work, I like Usenet as an
  1616. anarchy.  It has some rough edges, but for the most part it works.  What
  1617. does this question have to do with SSS-type programs?
  1618.  
  1619.    Enforcement will be tough and may hold back legitimate users.  But
  1620. we have to start somewhere.  So I suppose that I agree with having
  1621. net.police, as long as they don't turn things into a police.state.net. 
  1622.  
  1623.  
  1624.    9)  Do you believe that breaking into other people's systems should
  1625.    continue to be against the law?
  1626.  
  1627.       Only one said "no", and s/he had a smiley following the answer.
  1628. But there were some of you who voiced concern that it wasn't really
  1629. against the law to begin with.  In _The Cuckoo's Nest_, Cliff Stoll talked
  1630. about a (Canadian, I think) case that the only reason the cracker was
  1631. prosecuted was for stealing electricity!  Less than a watt or something.
  1632. A few of you mentioned denial of services as being a just reason, but
  1633. what if they break in only at night, when no one else is on, and they
  1634. really don't take anything at all?  Should that be less punishable than
  1635. someone who sucks away user CPU/disk/whatever?
  1636.  
  1637.    Breakins should be encouraged and rewarded (1/2 :-).
  1638.  
  1639.    Yes.  Unquestionably.  However, those laws should not attempt to regulate
  1640. inter-system traffic to cause these things to happen.
  1641.  
  1642.    Yes - and as a felony in all cases, without exception.
  1643.  
  1644.    Yes but murder, rape, robbery... are more important and laws and
  1645. sentencing should reflect this. There are some around who want to treat
  1646. cracking as a capital crime!
  1647.  
  1648.    Yes, from the denial of services standpoint.  I pay $XXX,XXX.XX for a
  1649. system, and joe blow slides in and sucks away at those resources, there
  1650. should be a nontrivial penalty for getting caught.  Don't behead the guy,
  1651. but monetary fines or community service would be just fine.
  1652.  
  1653.  
  1654.    I don't know.  I'm not a philosopher.  Certainly causing
  1655. damage to others is wrong, including denial of service,
  1656. compromising sensitive info, or whatever.  I'm concerned
  1657. though that clamping down on young kids will discourage them
  1658. from becoming computer geeks.  I think we need to encourage
  1659. our young people to become technically literate.  If we
  1660. don't become a more expert society we can kiss it goodbye;
  1661. all we'll have left is our military solutions, like some
  1662. brainless jock bully...
  1663.  
  1664.    I'm not sure that it is everywhere - but: Yes.  Should attempting 
  1665. to break in be against the law: No.  Is this vague: Yes.
  1666.  
  1667.    I did not know that it was. The laws about it have not been tested and 
  1668. are vague and unclear. You need to be very clear about what the laws
  1669. are going to do. 
  1670.  
  1671.    **HELL FUCKING YES** Those of us who started in UNIX years ago have
  1672. for the most part *always* respected others!! This I can't stress strong
  1673. enough.
  1674.  
  1675.  
  1676.   10)  Is your site academic, government, or commercial in nature?
  1677.  
  1678.       Just over 1/2 of those that answered claimed university ties,
  1679. with about 1/4 being commercial, 1/6 government, a few research sites,
  1680. and a couple that were a mixture.  Sites included Sun, AT&T, SCO (Xenix),
  1681. the DoD, and the Army, among others.
  1682.  
  1683. (Guess where this one came from :-)
  1684.  
  1685. Research.  We invented Unix.
  1686.  
  1687. Academic with commercial applications.
  1688.  
  1689. Primarily academic, but we are part of the government.
  1690.  
  1691. Academic, except when collecting student fees *) *)
  1692. SHAR_EOF
  1693. #    End of shell archive
  1694. exit 0
  1695.  
  1696.