home *** CD-ROM | disk | FTP | other *** search
- Subject: v21i023: System ecurity analysis tool, Part01/05
- Newsgroups: comp.sources.unix
- Approved: rsalz@uunet.UU.NET
- X-Checksum-Snefru: 03f906ff a4064d7a 431652ed 3dcdc63e
-
- Submitted-by: Dan Farmer <df@sei.cmu.edu>
- Posting-number: Volume 21, Issue 23
- Archive-name: cops/part01
-
- COPS is a security tool that is useful to system administrators, system
- programmers, or for anyone who would like to learn about UNIX security.
- It does not restrict a system's environment by placing constraints on
- activity; it is a purely diagnostic tool that checks and reports on the
- current status of a given UNIX machine.
-
- Written in Bourne shell, generic commands (awk, sed, etc.) and some C, the
- system is basically a shell script that runs several small security
- programs. Theoretically (at least), it attempts to find the following
- problems (among others) on a generic UNIX system, and then mails or saves
- the results, if indeed any problems do exist:
- --Checks /dev/*mem and all devs listed in "/etc/fstab" for world
- read/writability.
- --Checks special/important directories and files for "bad" (world
- writable, whatever) modes. (/etc/passwd, /bin, etc.)
- --Checks against /etc/passwd for crummy passwords (user selectable, it
- can be as vigorous or as lax as you wish.)
- --Checks /etc/passwd for non-unique uids, invalid fields, non-numeric
- user ids, etc. Also includes a password checker.
- --Checks /etc/group for non-unique groups, invalid fields, non-numeric
- group ids, etc.
- --Checks all users' home directories and their
- .login/.cshrc/.rhosts/.profile/etc. files
- --Checks all commands and paths listed in /etc/rc* and crontabs for
- world writability.
- --Checks for bad root paths, world exportable NFS systems, some other
- misc stuff.
- --Includes the Kuang expert system. Written by Robert Baldwin, this
- basically checks to see if a given user (by default root) is
- compromisible, given that certain rules are true. Kind of hard to
- explain in a sentence, but worth the price of admission.
- --Checks the system for _changes_ in SUID status. This is the one (the
- only) program that should be run as superuser, because it runs a
- "find" on all SUID programs from the / directory, and then uses that as
- a reference file for future runs.
-
- The "README" file tells how to install, run, and interpret any results
- found by COPS.
-
-
- # This is a shell archive.
- # Remove everything above and including the cut line.
- # Then run the rest of the file through sh.
- #----cut here-----cut here-----cut here-----cut here----#
- #!/bin/sh
- mkdir cops 2>/dev/null
- mkdir cops/docs 2>/dev/null
- mkdir cops/src 2>/dev/null
- mkdir cops/extensions 2>/dev/null
- # shar: Shell Archiver
- # Run the following text with /bin/sh to create:
- # cops/MANIFEST
- # cops/README
- # cops/XTRA_CREDIT
- # cops/chk_strings
- # cops/cops
- # cops/cron.chk
- # cops/dev.chk
- # cops/dir.chk
- # cops/dir.chklst
- # cops/disclaimer
- # cops/file.chk
- # cops/file.chklst
- # cops/group.chk
- # cops/init_kuang
- # cops/kuang
- # cops/makefile
- # cops/pass.words
- # cops/passwd.chk
- # This archive created: Tue Jan 30 23:35:07 1990
- # By: dan (Purdue University)
- echo shar: extracting cops/MANIFEST '(763 characters)'
- cat << \SHAR_EOF > cops/MANIFEST
- File Name
- ==================
- MANIFEST
- README
- XTRA_CREDIT
- chk_strings
- cops
- cron.chk
- dev.chk
- dir.chk
- dir.chklst
- docs
- file.chk
- file.chklst
- group.chk
- init_kuang
- kuang
- makefile
- pass.words
- passwd.chk
- rc.chk
- reconfig
- root.chk
- stop.sample
- suid.chk
-
- docs/COPS.report
- docs/KUANG.README
- docs/SUID.README
- docs/cops
- docs/cron
- docs/dev
- docs/dir
- docs/file
- docs/group
- docs/home
- docs/is_able
- docs/kuang.1
- docs/kuang.man
- docs/pass
- docs/passwd
- docs/rc
- docs/release.notes
- docs/root
- docs/suid.man
- docs/tilde
- docs/user
- docs/warnings
-
- extensions/THINGS_2_DO
- extensions/YAR
- extensions/netstuff
- extensions/passwords
- extensions/questions
-
- src/addto.c
- src/clearfiles.c
- src/filewriters.c
- src/home.chk.c
- src/is_readable.c
- src/is_writable.c
- src/members.c
- src/pass.c
- src/tilde.c
- src/user.chk.c
- SHAR_EOF
- echo shar: extracting cops/README '(14146 characters)'
- cat << \SHAR_EOF > cops/README
-
- Welcome! You now hold in your hands (terminal?) a collection
- of security tools that are designed specifically to aid the typical
- UNIX systems administrator, programmer, operator, or consultant in
- the oft neglected area of computer security.
- The package, which will be henceforth be referred to as COPS
- (Computer Oracle and Password System), can be broken down into three
- key parts. The first is the actual set of programs that attempt
- to automate security checks that are often performed manually (or
- perhaps with self written short shell scripts or programs) by a systems
- administrator. The second part is the documentation, which details
- how to set up, operate, and to interpret any results given by the
- programs. Finally, COPS is an evolving beast. It includes a list
- of possible extensions that might appear in future releases, as well
- as pointers to other works in UNIX security that could not be included
- at this time, due to space or other restrictions.
- This document contains six sections:
-
- 1) What is COPS?
- 2) What COPS is _not_
- 3) How to Configure/Install COPS
- 4) Running COPS for the 1st Time
- 5) Continued Use of COPS
- 6) Disclaimer and End Notes
-
-
- 1) What is COPS?
- -----------------
-
- COPS is a collection of about a dozen programs that each attempt
- to tackle a different problem area of UNIX security. Among the areas
- checked are file, directory, and device permissions/modes, passwords,
- contents of password and group files, the contents of /etc/rc && cron
- files, changes in SUID status, the writability of users home directories
- and startup files (.profile, .cshrc, etc), and a few others as well.
- It also includes the Kuang expert system, written by Bob Baldwin, that
- takes a set of rules and tries to determine if your system can be
- compromised. For a more complete list of all of the checks, look at the
- file "release.notes" or "cops.report."
- All of the programs merely warn the user of a potential problem --
- COPS DOES NOT ATTEMPT TO CORRECT OR EXPLOIT ANY OF THE POTENTIAL PROBLEMS
- IT FINDS! COPS either mails or creates a file (user selectable) of any
- of the problems it finds while running on your system. And because COPS
- does not correct potential hazards it finds, it does _not_ have to be
- run by a privileged account (i.e. root or whomever.) The only security
- check that should be run by root to get maximum results is the SUID checker;
- although it can be run as an unprivileged user, to find all the SUID files
- in a system, it should be run as root.
- The programs are mostly written in Bourne shell (using awk, sed, grep,
- etc. as well) for (hopefully) maximum portability. A few are written
- in C for speed (most notably the Kuang expert system and for implementing
- fast user home directory searching), but the entire system should run on
- most BSD and System V machines with a minimum of tweaking.
-
- 2) What COPS is _not_
- ----------------------
-
- COPS merely provides a method of checking for common procedural errors.
- It is not meant to be used as a replacement for common sense or user/
- operator/administrative alertness! Think of it as an aid, a first line
- of defense -- not as an impenetrable shield against security woes. An
- experienced wrong-doer could easily circumnavigate _any_ protection that
- COPS can give. However, COPS _can_ aid a system in protecting its users
- from (their own?) ignorance, carelessness, and the occasional malcontent
- user.
- Once again, COPS does not correct any errors found. There are several
- reasons for this; first and foremost, computer security is a slippery
- beast. What is a major breach in security at one site may be a standard
- policy of openness at another site. Additionally, in order to correct all
- problems it finds, it would have to be run as a privileged user; and I'm
- not going to go into the myriad problems of running SUID shell scripts
- (See the bibliography at the end of the technical report "cops.report"
- for pointer to a good paper on this subject by Matt Bishop.)
- At this time, COPS does not attempt to detect bugs or features (such
- as infamous ftpd, fingerd, etc) that may cause security problems. Although
- this may change in future versions, the current line of reasoning to avoid
- general publication of programs such as these is that all the problems that
- COPS detects can be repaired on any system it runs on. However, many bugs
- can be readily repaired only be having source code (and possibly a good
- vendor to repair it), and many sites would have serious troubles if they
- suddenly discovered unrepairable problems that could compromise their
- livelihood. It is possible that a more controlled release may come out
- in the future to address such problems (but don't mail to me about getting
- them -- unless you want to help write them! :-))
-
- 3) How to Configure/Install COPS
- ---------------------------------
-
- System V users, other Non-BSD systems, or sites with commands in
- strange places -- you may have to run a shell script called "reconfig"
- to change the pathnames of the executable programs called when using
- COPS. If your system does not use the paths listed in the shell
- scripts, try running "reconfig". This will reconfigure the pathnames
- used by COPS to your system; COPS should run fine then, if it
- can find all of the commands (reconfig should tell you if it
- cannot.) If trouble persists, you will have to change the paths
- to your executable files (awk, sed, etc) by hand. A drag, I know.
- This all may change without notice, anyway.
-
- 4) Running COPS for the 1st Time
- ---------------------------------
-
- Since most of COPS was written and tested mostly on just a few machines
- (at least compared to the total number out there!), you may have significant
- differences that were not anticipated -- unfortunately, or fortunately,
- UNIX is not quite standardized yet.
- COPS is run by simply typing "cops". "cops" is a Bourne shell script
- that runs each of the smaller programs, accumulates the output, and then
- mails or stores any results. "suid.chk", since it can take a long, long time
- to run, is the only "standalone" program in the COPS package; look at
- suid.man for more information.
-
- To run COPS for the first time, I suggest doing the following:
-
- -- Look at the disclaimer, file "disclaimer". Don't sue me.
- Actually, this holds for all the times you use COPS (1/4 :-))
- -- Type "make" to create the formatted manual pages, to compile the
- C programs, and to make the shell programs executable.
- -- Read the technical report to understand what COPS is doing and
- what is going on -- "cops.report". This gives a look at the
- philosophies, design notes, and finally a general outlay of the
- COPS system and UNIX security.
- -- Next, change lines 36 and 37 in the "cops" shell file from:
- SECURE=/usr/foo/bar
- SECURE_USERS="foo@bar.edu"
- SECURE should be the same directory as the directory that contains
- the cops programs, and SECURE_USERS should be your own login id, or
- to whomever you designate as the recipient of the output (your enemy?)
- -- Set "MAIL=NO" in the "cops" shell file (line 22). This will prevent
- a large mail file from choking the mailer. All of the output will be
- put into a file called "report.$$", where $$ is the process
- number that cops had while running.
- -- Look at the directory and file configuration files, "dir.chklst"
- and "file.chklst". They contain critical files that COPS checks
- for world writability. Add or delete whatever files/directories
- you wish; if a file doesn't exist, COPS will effectively ignore it.
- (If you don't know or are uncertain what files/directories are
- important, what is given there is a good set to start with on most
- systems.
- -- You may wish to comment out the password checker (line 72 in the
- "cops" shell file). Although this is not necessary, it will speed
- up the package if you wish for immediate gratification.
-
- You should be ready to roll. COPS is run by simply typing "cops" (you
- may wish to put in the background....) If you followed my advice and
- set "MAIL=NO" in the "cops" shell file, after COPS is finished, there
- will be a report file created "report.$$" that lists the time and machine
- it was created on. Otherwise, COPS mails the report to the user listed
- on the line 'SECURE_USERS="foo@bar.edu"'. There is a file "warnings", which
- contains most of the warning messages COPS uses, as well as a brief
- explanation of how the message might pertain to your system as well as how
- to "fix" any problem.
-
- NOTE: Change the shell script "cops" to reflect who you want the output
- sent to and where the location of the program is BEFORE running the program.
-
-
- 5) Continued Use of COPS
- -------------------------
-
- Once you are satisfied that COPS indeed does something useful
- (hopefully this will occur :-)), a good way to use it is to run it
- on at least a semi-regular basis. Even if it doesn't find any problems
- immediately, the types of problems and holes it can detect are of the
- sort that can pop up at any given time. One way of running COPS
- might be to run it as an "at" job or by cron.
- I highly advise that whatever directory COPS is placed in is to be
- readable, writable, and executable only by the owner (typing
- "chmod 700 /usr/foo/bar" or whatever the name is will do this) of the
- directory. This is to prevent prying eyes from seeing any security
- problems your site may have. Even if you don't think of them as
- important, someone else might come around and change your mind. Since
- COPS is fairly configurable, an intruder could easily change the paths
- and files that COPS checks for, hence making it fairly worthless. Again,
- this comes back to the point that COPS is only a tool -- don't put down
- your defensive shields merely because COPS says "all clear". If this
- sounds paranoid, it is! Security people are traditionally paranoid,
- for a reason.... In any case, it is probably not a good idea to advertise
- any (even) potential weaknesses.
-
- After running COPS, if any warnings are given that compromise any
- individual users accounts (such as world writable .profiles, home
- directories, guessed passwords, etc.), and the warnings are not corrected
- immediately (or you are not sure whether or not it is worth hassling
- the user to change it), try this:
- Edit the file "init_kuang", and add the compromised user(s) uids and
- groups in their respective target lines (below lines 21 and 27,
- respectively), and run kuang again to see if the users can compromise
- the entire system. You may change your mind about not thinking
- they are a problem! In addition, kuang does not have to have "root"
- as a target (the last line). Try putting in system administrators or
- other powerful figures to see if they are in danger as well.
-
- 6) Disclaimer and End Notes
- ----------------------------
-
- COPS is meant to be a tool to aid in the tightening of security, not
- as a weapon to be used by an enemy to find security flaws in a system.
- It may be argued that allowing anyone to have access to such a tool may
- be dangerous. But hopefully the overall benefit for systems that use
- this package will outweigh any negative impact. To me it is akin to a
- law enforcement problem -- that although telling the public how to break
- into a house may foster a slight rise in break-in attempts, the overall
- rise in public awareness on how to defend themselves would actually result
- in a drop in break-ins. The crackers with black hats already know how
- to crush system defenses and have similar tools, I'm sure. It's time
- we fought back.
-
- COPS is not the final answer to anyone's security woes. You can use
- the system as long as you realize that COPS has no warranty, implied
- or otherwise, and that any problems that you may have with it are
- not my or any of the other authors fault. I will certainly attempt to
- help you solve them, if I am able, but please don't try to sue me or
- anything... Let's all make COPS a collective effort that helps people, ok?
- If you have ideas for additional programs, or a better implementation of
- any of the programs here, I would be very interested in seeing them.
- COPS was the work of a LOT of people, both in writing code and in the
- testing phase (thanks beta testers!). For a complete list of contributors,
- look at the file "XTRA_CREDIT".
-
- So good luck, and I hope you find COPS useful as we plunge into UNIX
- of the 1990's.
-
- dan farmer
- January 31, 1989
-
-
- # include "disclaimer.h"
-
- -------------------- Cut here for disclaimer -------------------------
-
- /***********************************************************************
- * Copyright 1989, 1990 by Purdue University and Dan Farmer. All rights
- * reserved. Some individual files may be covered by other copyrights.
- *
- * This material was written and compiled by Dan Farmer while at Purdue
- * University in 1989 and 1990, under the direction and sponsorship of
- * Professor Gene Spafford. Other material was contributed as noted
- * elsewhere.
- * Redistribution and use in source and binary forms are permitted
- * provided that this entire copyright notice is duplicated in all such
- * copies, and that any documentation, announcements, and other
- * materials related to such distribution and use acknowledge that the
- * software was developed at Purdue University, W. Lafayette, IN. No
- * charge, other than an "at-cost" distribution fee, may be charged for
- * copies, derivations, or distributions of this material without the
- * express written consent of the copyright holders. Neither the
- * name of the University, the name of the author, nor the name of this
- * project's sponsor may be used to endorse or promote products
- * derived from this material without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTIBILITY AND FITNESS FOR ANY PARTICULAR PURPOSE.
- ************************************************************************/
- ---------------------- End disclaimer -------------------------------
- SHAR_EOF
- echo shar: extracting cops/XTRA_CREDIT '(2063 characters)'
- cat << \SHAR_EOF > cops/XTRA_CREDIT
-
- Code credits are where code credits are due. If I miss anyone, please
- forgive (and notify) me!
-
- Gene Spafford -- overall design help.
-
- Robert Baldwin -- the kuang package.
-
- Craig Leres, Seth Alford, Roger Southwick, Steve Dum, and Rick Lindsley
- all get credit for the password guessing program.
-
- Prentiss Riddle -- the suid checker.
-
- And of course lots of credit goes to my great Beta-release sweatshop team;
- especially Adri Verhoef for tightening up lots of my crummy code (cops,
- group.chk, root.chk, is_writable, dev.chk, dir.chk & file.chk among others),
- Steve Romig for good ideas _and_ letting me use a system V machine to test
- on (how many people do you know that would let you test a security
- system on their system with no strings attached!) Jason Levitt, Jim
- Kimble, Jim Rowan, Stefan Vorkoetter, Judy Scheltema, Pete Troxell (all
- the Sun C2 stuff....), Dennis Conley, and of course John Sechrest.
- Tony Petrost pointed out some of my incorrect assumptions and helped
- fix cron.chk. Kudos also to Bruce Spence for giving me some good
- implementation ideas at LISA II.
-
- If strings is not available to you, a version is available on uunet;
- also a nifty install program written by Kevin Braunsdorf that can be used
- as a super directory/file mode checker/security device should be
- available soon in comp.sources.unix (these programs large sizes preculudes
- their inclusion in COPS, but I recommend looking into them.)
- Both can be gotten via anonymous ftp. Strings is in comp.unix.sources
- directory, install should be in the same.
- Everything else not explicitely mentioned in the COPS.report.ms paper
- or here was written by me. Not mentioned execpt in the source code are
- some small changes made by myself to make everything fit in as a cohesive
- whole; I tried to make comments in the source code if I changed it (never
- to drastic in any case.)
-
- For a good story on the subject, you might want to read _The Cuckoo's
- Egg_, by Clifford Stoll. This is a true tale of a sysadmin's fight
- against beaurocracy and a hacker (the bad kind.) Good stuff.
-
- SHAR_EOF
- echo shar: extracting cops/chk_strings '(1559 characters)'
- cat << \SHAR_EOF > cops/chk_strings
- #!/bin/sh
- #
- # Usage: chk_strings filename
- #
- # This will check pathnames inside executable files for writability,
- # using the "strings" command and egrep.
- #
- # I have identified three basic types of strings containing paths to files:
- # 1)
- # /path1/path2/file /* standard */
- # 2)
- # '/path1/path2/file' /* standard, in single quotes */
- # 3)
- # :/path1/file1:/path2/file2 /* a path for searching */
- #
- # For the first two, I simply test the writability; for the last, I
- # parse it into seperate paths and check each one in turn.
- #
- AWK=/bin/awk
- EGREP=/usr/bin/egrep
- TEST=/bin/test
- ECHO=/bin/echo
- SORT=/usr/bin/sort
- STRINGS=/usr/ucb/strings
-
- if test ! -s $STRINGS
- then
- exit 0
- fi
-
- if test $# -eq 0
- then
- $ECHO "Usage: $0 file"
- exit 2
- fi
-
- while test 0 -ne $#
- do
- # $ECHO Checking $1...
- # get the first two types:
- test_files=`$STRINGS $1 | $EGREP "/.*/" | $AWK '{for (i=1;i<=NF;i++)
- if ((res=substr($i,1,1))=="/")
- printf("%s\n",$i)
- else if ((res!=":") && (res=substr($i,2,1))=="/")
- printf("%s\n",substr($i,2,length($i)-2))}'| $SORT -u`
-
- # and type number three, parse into separate paths as well:
- paths=`$STRINGS $1|$EGREP "/.*/" |$AWK '{for (i=1;i<=NF;i++)
- if ((substr($i,1,1)==":") && (substr($i,2,1))=="/")
- printf("%s",$i)}'`
- paths=`$ECHO $paths | $AWK -F: '{for (i=1;i<=NF;i++) printf("%s\n",$i)}'| $SORT -u`
-
-
- all_files=$test_files$paths
-
- for i in $all_files
- do
- if ./is_writable $i
- then
- $ECHO " Warning! File $i (inside root executed file $1) is _World_ writable!"
- fi
- done
- shift
- done
-
- # end of script
- SHAR_EOF
- echo shar: extracting cops/cops '(2872 characters)'
- cat << \SHAR_EOF > cops/cops
- #!/bin/sh
- #
- # Usage: cops
- #
- # This will change into the $SECURE directory, ensure all the security
- # programs (listed below) indeed do exist, and run all of the security
- # programs. If any of the programs find any security problems, they
- # send mail to everyone in the $SECURE_USERS list. It then destroys all
- # temporary files, and exits the program. Programs that are run
- # (besides this one):
- #
- # root.chk dev.chk dir.chk
- # file.chk group.chk home.chk
- # rc.chk passwd.chk pass.chk
- # user.chk cron.chk
- # The U-kuang system runs these additional programs:
- # init_kuang kuang addto
- # clearfiles filewriters members
- #
- # If this is changed to "NO", the report that cops creates
- # will not be deleted and the results will not be mailed to anyone.
- MMAIL="YES"
-
- # Where is everyone?
- ECHO=/bin/echo
- TEST=/bin/test
- RM=/bin/rm
- CAT=/bin/cat
- MAIL=/bin/mail
- DATE=/bin/date
- CHMOD=/bin/chmod
-
- ######################
- # Change these lines!
- ######################
- SECURE=/usr/foo/bar
- SECURE_USERS="foo@bar.edu"
- ######################
-
- SECURE_PROGRAMS="root.chk dev.chk dir.chk file.chk group.chk \
- home.chk rc.chk passwd.chk pass.chk \
- cron.chk user.chk init_kuang kuang addto \
- clearfiles filewriters members"
-
- if $TEST ! -d "$SECURE"
- then
- $ECHO "Error -- Security directory $SECURE doesn't exist"
- exit 1
- fi
-
- $CHMOD 700 $SECURE
- cd $SECURE
-
- for i in $SECURE_PROGRAMS
- do
- if $TEST ! -s "$i"
- then
- $ECHO "Error -- Security program $i doesn't exist"
- exit 1
- fi
- done
-
- $SECURE/root.chk > $SECURE/result.$$ 2> /dev/null
- $SECURE/dev.chk >> $SECURE/result.$$ 2> /dev/null
- $SECURE/dir.chk >> $SECURE/result.$$ 2> /dev/null
- $SECURE/file.chk >> $SECURE/result.$$ 2> /dev/null
- $SECURE/rc.chk >> $SECURE/result.$$ 2> /dev/null
- $SECURE/cron.chk >> $SECURE/result.$$ 2> /dev/null
- $SECURE/group.chk >> $SECURE/result.$$ 2> /dev/null
- $SECURE/home.chk >> $SECURE/result.$$ 2> /dev/null
- $SECURE/passwd.chk >> $SECURE/result.$$ 2> /dev/null
- $SECURE/pass.chk >> $SECURE/result.$$ 2> /dev/null
- $SECURE/user.chk >> $SECURE/result.$$ 2> /dev/null
- $SECURE/kuang > /dev/null 2> /dev/null
- if $TEST -s "$SECURE/Success"
- then
- $CAT $SECURE/Success >> $SECURE/result.$$
- fi
- $RM -f $SECURE/Success
-
-
- #
- # Mail the final report to $SECURE_USERS and remove the evidence
- if $TEST -s "$SECURE/result.$$"
- then
- $ECHO ATTENTION: > $SECURE/report.$$
- $ECHO "Security Report for "`$DATE` >> $SECURE/report.$$
-
- #
- # Thanks to arbitron for this idea...
- HOSTNAME=`/bin/sh -c "/bin/uname -n || /usr/bin/uuname -l || /bin/hostname" 2>&-`
- $ECHO "from host $HOSTNAME" >> $SECURE/report.$$
- $ECHO >> $SECURE/report.$$
- $ECHO >> $SECURE/report.$$
- $CAT $SECURE/result.$$ >> $SECURE/report.$$
-
- if $TEST "$MMAIL" = "YES"
- then
- $MAIL $SECURE_USERS < $SECURE/report.$$
- $RM -f $SECURE/report.$$
- fi
-
- fi
- $RM -f $SECURE/result.$$
-
- # end it all....
- exit 0
- SHAR_EOF
- echo shar: extracting cops/cron.chk '(2248 characters)'
- cat << \SHAR_EOF > cops/cron.chk
- #!/bin/sh
- #
- # Usage: cron.chk
- #
- # This checks pathnames and files inside the cron files /usr/lib/crontab
- # for writability.
- #
- # Mechanism: The commands inside the file /usr/lib/crontab are executed
- # by root. This shell script greps for commands/paths that begins with
- # "/" and takes each potential problem-string and uses the program
- # "is_writable" to determine if it is world writable. All results are
- # echoed to standard output.
- # In addition, it throws away everything that has a /tmp, /dev/null, or
- # tty in the writable string, and everything after a ">"; e.g. if crontab
- # is writing to a file it doesn't care.
- #
- # Cron.chk will try to find a file in /usr/lib/crontab first (bsd),
- # and then if it isn't there, it will look in the any alternate
- # possible locations next -- right now, /usr/spool/cron/crontab -- to
- # see if a directory exists, and, if it does, it checks all the cron
- # files in turn.
- #
- # WARNING!
- #
- # Spurious messages can occur; a more stringent method (if perhaps less
- # careful of a check) would be to test just the 6th field, instead of
- # all the fields after the fifth. Also throwing away /tmp, etc. could
- # be a mistake.
- #
-
- # Location of stuff:
- AWK=/bin/awk
- SED=/bin/sed
- ECHO=/bin/echo
- EGREP=/usr/bin/egrep
- TEST=/bin/test
- CAT=/bin/cat
-
- # Possible location of crontab file:
- cron=/usr/lib/crontab
- # alternate reality locations of crontab file:
- alt_cron="/usr/spool/cron/crontabs"
-
- if $TEST ! -s $cron
- then
- cron=""
- for i in "$alt_cron"
- do
- if $TEST -d $i
- then
- cron=`$ECHO $alt_cron/*`
- fi
- done
-
- if $TEST -z "$cron"
- then
- exit
- fi
- fi
-
- # finally, do the checking -- maybe for one, maybe for lots of
- # cron-ites:
-
- for cron_kid in $cron
- do
- # A typical crontab entry might look something like this:
- #
- # 0,15,30,45 * * * * /bin/sh /usr/adm/newsyslog
- #
- risky_stuff=`$AWK '{for (i=6;i<NF;i++) printf("%s ", $i);
- if (NF!=6) printf("%s\n",$NF)}' $cron_kid | $SED -e 's/>.*//' |
- $AWK '{for (i=1;i<=NF;i++) if (substr($i,1,1)=="/") print $i}'`
-
- for i in $risky_stuff
- do
- if $TEST `echo $i | $EGREP "/tmp|/dev/null|tty"`
- then
- continue
- fi
- if ./is_writable $i
- then
- $ECHO "Warning! $i (in $cron_kid) is World writable!"
- fi
- done
- done # for all the cron-kids
- SHAR_EOF
- echo shar: extracting cops/dev.chk '(2691 characters)'
- cat << \SHAR_EOF > cops/dev.chk
- #!/bin/sh
- #
- # dev.chk [-g]
- #
- # This shell script checks the permissions of /dev/mem, /dev/kmem, and
- # all devs listed in the file /etc/fstab (the "mount" command would be
- # a preferable way of getting the file system name, but the syntax of the
- # output is variable from machine to machine), and flags them if they are
- # readable by using the "is_readable" command. It also checks for
- # unrestricted NFS mountings. By default, dev_check will flag devs only
- # if world readable or writable. The -g option tells it to print out devs
- # that are also group readable/writable.
- #
- AWK=/bin/awk
- LS=/bin/ls
- ECHO=/bin/echo
- TEST=/bin/test
-
- # locations of vital stuff...
- mtab=/etc/fstab
- exports=/etc/exports
-
- # Optional List of assorted files that shouldn't be
- # readable (mix 'n match; add to the list as desired):
- opt_files='/usr/adm/sulog /etc/btmp /.netrc'
-
- group=no
-
- if $TEST $# -gt 1
- then
- $ECHO "Usage: $0 [-g]"
- exit 2
- fi
-
- if $TEST $# -eq 1
- then
- if $TEST "X$1" = "X-g"
- then
- group=yes
- else
- $ECHO "Usage: $0 [-g]"
- exit 2
- fi
- fi
-
- # Testing filesystems and devices for improper read/write permissions...
-
- # NEVER want these readable!
- always_crit_files="/dev/kmem /dev/mem"
-
- # grab devices from "/etc/fstab"....
- #
- # Format of /etc/fstab: /dev/zd0e +junk(:-)
- #
- # Or NFS mounted: uther:/usr/spaf +junk(:-)
- #
- # Not sure what to do with NFS stuff, so we'll ignore it. Seems that
- # this doesn't tell us anything about what we want anyway....
- crit_devs=$always_crit_files" "`$AWK 'index($1, "/")==1 {print $1}' $mtab`
-
- # Alternate way; grab devices from "mount [-p]"....
- # Format of output from mount (some machines use -p option, some
- # don't. Check your local man page... :
- # crit_devs=$always_crit_files" "`/etc/mount -p|$AWK 'index($1, "/")==1
- # {print $1} \
- # }'`
-
- #
- # However, do check for single line entries in /etc/exports:
- if $TEST -s $exports
- then
- $AWK '{while(getline >0) if ($0 !~ /^#/ && NF == 1) \
- printf("Warning! NFS file system %s exported with no restrictions.\n",$0)}' $exports
- fi
-
- for i in $crit_devs
- do
- if ./is_readable $i
- then
- $ECHO Warning! $i is _World_ readable!
- fi
- if ./is_writable $i
- then
- $ECHO Warning! $i is _World_ writable!
- fi
- if $TEST "$group" = "yes"
- then
- if ./is_readable -g $i
- then
- $ECHO Warning! $i is group readable!
- fi
- if ./is_writable -g $i
- then
- $ECHO Warning! $i is group readable!
- fi
- fi
- done
-
- # Do the mix 'n match assorted no-read files:
- for i in $opt_files
- do
- if ./is_readable $i
- then
- $ECHO Warning! $i is _World_ readable!
- fi
- if $TEST "$group" = "yes"
- then
- if ./is_readable -g $i
- then
- $ECHO Warning! $i is group readable!
- fi
- fi
- done
-
- # end of script
- SHAR_EOF
- echo shar: extracting cops/dir.chk '(1459 characters)'
- cat << \SHAR_EOF > cops/dir.chk
- #!/bin/sh
- #
- # dir.chk [-g]
- #
- # This shell script checks the permissions of all directories listed
- # in the configuration file "dirs.755.dirlist", and flags them if they
- # are world-writable. The -g option tells it to print out directories
- # that are also group writable. See the config file for the format of
- # the configuration file.
- #
- # Mechanism: This shell script simply takes each line from the
- # configure file and uses the "is_writable" program to check if any of
- # the directories in question are writable by world/group. All results
- # are written to standard output.
- #
- AWK=/bin/awk
- TEST=/bin/test
- ECHO=/bin/echo
-
- dir_list=dir.chklst
- group=no
-
- if $TEST $# -gt 1
- then
- $ECHO "Usage: $0 [-g]"
- exit 2
- fi
-
- if $TEST $# -eq 1
- then
- if $TEST "X$1" = "X-g"
- then
- group=yes
- else
- $ECHO "Usage: $0 [-g]"
- exit 2
- fi
- fi
-
- # Testing directories in file $dir_list for potential write mode problems
-
- # Read from $dir_list (e.g. "dirs.755.dirlist") what dirs to check.
- #
- # Comments are lines starting with a "#".
- #
- while read i
- do
- case $i in
- "#"* | "" )
- continue;;
- esac
-
- # exit code 0 is writable, 1 is not
- dirs=`$ECHO $i`
- for d in $dirs
- do
- if ./is_writable $d
- then
- echo "Warning! Directory $d is _World_ writable!"
- fi
- done
-
- if $TEST "$group" = "yes"
- then
- for d in $dirs
- do
- if ./is_writable -g $d
- then
- echo "Warning! Directory $d is group writable!"
- fi
- done
- fi
-
- done < $dir_list
-
- # end of script
- SHAR_EOF
- echo shar: extracting cops/dir.chklst '(377 characters)'
- cat << \SHAR_EOF > cops/dir.chklst
- #
- # This lists any/all sensitive files the administration wants to ensure
- # non-writability of. Comments are lines starting with a "#".
- #
- # Lines are of the format:
- #
- # /path/to/file
- #
- /
- # /*
- /etc
- /usr
- /bin
-
- /usr/spool
- /usr/adm
- /usr/etc
- /usr/lib
- /usr/local
- /usr/local/bin
- /usr/local/lib
- /usr/bin
- /usr/etc
- /usr/spool/mail
- /usr/spool/news
- /usr/spool/uucp
- /usr/spool/at
- /Mail
- SHAR_EOF
- echo shar: extracting cops/disclaimer '(1468 characters)'
- cat << \SHAR_EOF > cops/disclaimer
- /***********************************************************************
- * Copyright 1989, 1990 by Purdue University and Dan Farmer. All rights
- * reserved. Some individual files may be covered by other copyrights.
- *
- * This material was written and compiled by Dan Farmer while at Purdue
- * University in 1989 and 1990, under the direction and sponsorship of
- * Professor Gene Spafford. Other material was contributed as noted
- * elsewhere.
- * Redistribution and use in source and binary forms are permitted
- * provided that this entire copyright notice is duplicated in all such
- * copies, and that any documentation, announcements, and other
- * materials related to such distribution and use acknowledge that the
- * software was developed at Purdue University, W. Lafayette, IN. No
- * charge, other than an "at-cost" distribution fee, may be charged for
- * copies, derivations, or distributions of this material without the
- * express written consent of the copyright holders. Neither the
- * name of the University, the name of the author, nor the name of this
- * project's sponsor may be used to endorse or promote products
- * derived from this material without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTIBILITY AND FITNESS FOR ANY PARTICULAR PURPOSE.
- ************************************************************************/
- SHAR_EOF
- echo shar: extracting cops/file.chk '(1423 characters)'
- cat << \SHAR_EOF > cops/file.chk
- #!/bin/sh
- #
- # file.chk [-g]
- #
- # This shell script checks the permissions of all files listed
- # in the configuration file "files.chklst", and flags them if they
- # are world-writable. The -g option tells it to print out files
- # that are also group writable. See the config file the format of
- # the configuration file.
- #
- # Mechanism: This shell script simply takes each line from the
- # configure file and uses the "is_writable" program to check if any of
- # the files in question are writable by world/group. All results
- # are written to standard output.
- #
- AWK=/bin/awk
- TEST=/bin/test
- ECHO=/bin/echo
-
- file_list=file.chklst
- group=no
-
- if $TEST $# -gt 1
- then
- $ECHO "Usage: $0 [-g]"
- exit 2
- fi
-
- if $TEST $# -eq 1
- then
- if $TEST "X$1" = "X-g"
- then
- group=yes
- else
- $ECHO "Usage: $0 [-g]"
- exit 2
- fi
- fi
-
- # Checking files in file $file_list for potential write mode problems
-
- # Read from $file_list (e.g. "files.chklst") what files to check.
- #
- # Comments are lines starting with a "#".
- #
- while read i
- do
- case $i in
- "#"* | "" )
- continue;;
- esac
-
- # exit code 0 is writable, 1 is not
- files=`$ECHO $i`
- for f in $files
- do
- if ./is_writable $f
- then
- echo "Warning! File $f is _World_ writable!"
- fi
- done
-
- if $TEST "$group" = "yes"
- then
- for f in $files
- do
- if ./is_writable -g $f
- then
- echo "Warning! File $f is group writable!"
- fi
- done
- fi
-
- done < $file_list
-
- # end of script
- SHAR_EOF
- echo shar: extracting cops/file.chklst '(523 characters)'
- cat << \SHAR_EOF > cops/file.chklst
- #
- # This lists any/all sensitive files the administration wants to ensure
- # non-writability of. Comments are lines starting with a "#".
- #
- # Lines are of the format:
- #
- # /path/to/file
- #
- /.*
- # /.login
- # /.profile
- # /.cshrc
- # /.crontab
- # /.rhost
- /etc/*
- # /etc/passwd
- # /etc/group
- # /etc/inittab
- # /etc/rc
- # /etc/rc.local
- # /etc/rc.boot
- # /etc/hosts.equiv
- # /etc/profile
- # /etc/syslog.conf
- # /etc/export
- /usr/etc/yp*
- /usr/lib/crontab
- /usr/lib/aliases
- /usr/lib/sendmail
- # /usr/spool/L.sys
- # /usr/adm/sulog
- /usr/adm/*
- /bin/*
- SHAR_EOF
- echo shar: extracting cops/group.chk '(5099 characters)'
- cat << \SHAR_EOF > cops/group.chk
- #!/bin/sh
- #
- # group.chk
- #
- # Check group file -- /etc/group -- for incorrect number of fields,
- # duplicate groups, non-alphanumeric group names, and non-numeric group
- # id's.
- #
- # Awk part based on _passwd_ from _The AWK Programming Language_, page 78
- #
- # Mechanism: Group.check uses awk to ensure that each line of the group
- # has 4 fields, as well as examining each line for any duplicate groups or
- # any duplicate user id's in a given group by using "sort -u" to ferret
- # out any duplications. It also checks to make sure that the password
- # field (the second one) is a "*", meaning the group has no password (a
- # group password is usually not necessary because each member listed on
- # the line has all the privilages that the group has.) All results are
- # echoed to standard output. Finally it ensures that the group names
- # are alphanumeric, that the group id's are numeric, and that there are
- # no blank lines. For yellow pages groups, it does the same checking,
- # but in order to get a listing of all members of the groups, it does a
- # "ypcat group > ./$$" and uses that temporary file for a groupfile.
- # It removes the tmp file after using it, of course.
- # The /etc/group file has a very specific format, making the task
- # fairly simple. Normally it has lines with 4 fields, each field
- # separated by a colon (:). The first field is the group name, the second
- # field is the encrypted password (an asterix (*) means the group has no
- # password, otherwise the first two characters are the salt), the third
- # field is the group id number, and the fourth field is a list of user
- # ids in the group. If a line begins with a plus sign (+), it is a yellow
- # pages entry. See group(5) for more information.
- #
- #
- AWK=/bin/awk
- SED=/bin/sed
- ECHO=/bin/echo
- TEST=/bin/test
- SORT=/usr/bin/sort
- UNIQ=/usr/bin/uniq
- YPCAT=/usr/bin/ypcat
- RM=/bin/rm
-
- # Used for Sun C2 security group file. FALSE (default) will flag
- # valid C2 group syntax as an error, TRUE attempts to validate it.
- # Thanks to Pete Troxell for pointing this out.
- C2=FALSE
-
- etc_group=/etc/group
- yp_group=./$$
- yp=false
-
- if $TEST -f $YPCAT
- then
- if $TEST -s $YPCAT
- then
- $YPCAT group > $yp_group
- if $TEST $? -eq 0
- then
- yp=true
- fi
- fi
- fi
-
- # Testing $etc_group for potential problems....
-
- # First line is for a yellow pages entry in the group file.
- # It really should check for correct yellow pages syntax....
- $AWK 'BEGIN {FS = ":" } {
- if (substr($1,1,1) != "+") { \
- if ($0 ~ /^[ ]*$/) { printf("Warning! Group file, line %d, is blank\n", NR) } else {
- if (NF != 4) { printf("Warning! Group file, line %d, does not have 4 fields: %s\n", NR, $0) } \
- if ($1 !~ /[A-Za-z0-9]/) {
- printf("Warning! Group file, line %d, nonalphanumeric user id: %s\n", NR, $0) } \
- if ($2 != "" && $2 != "*") {
- if ("'$C2'" != "TRUE")
- printf("Warning! Group file, line %d, group has password: %s\n", NR, $0)
- else {
- if ("#$"$1 != $2)
- printf("Warning! Group file, line %d, group has invalid field for C2:\n%s\n", NR, $0) } \
- } \
- if ($3 !~ /[0-9]/) {
- printf("Warning! Group file, line %d, nonnumeric group id: %s\n", NR, $0) }}}} ' $etc_group
-
- #
- # Look for duplications in groups in $etc_group
- #
- result=`$AWK -F: '{print $1}' $etc_group | $SORT |$UNIQ -d`
- if $TEST "$result"
- then
- $ECHO "Warning! Duplicate Group(s) found in $etc_group:"
- $ECHO $result
- fi
-
- #
- # Next, check for duplicate users in a group in /etc/group. Let
- # awk do all the work (thanks, adri!)
- #
-
- # Ignore all groups with less than two members.
- #
- awk -F: '
- split($4, users, ",") > 1 {
- ct = 0
- for (i in users) {
- curuser = users[i]
- for (j in users) {
- if (j > i && curuser == users[j]) {
- if (ct++ == 0) print "Warning! Group "$1" has duplicate user(s):"
- print curuser
- }
- }
- }
- }
- ' $etc_group
-
-
- #
- # Test yellow pages groups as well
- if $TEST "$yp" = "true"
- then
- $AWK 'BEGIN {FS = ":" } {
- if ($0 ~ /^[ ]*$/) { printf("Warning! YGroup file, line %d, is blank\n", NR) } else {
- if (NF != 4) { printf("Warning! YGroup file, line %d, does not have 4 fields: %s\n", NR, $0) } \
- if ($1 !~ /[A-Za-z0-9]/) {
- printf("Warning! YGroup file, line %d, nonalphanumeric user id: %s\n", NR, $0) } \
- if ($2 != "" && $2 != "*") {
- printf("Warning! YGroup file, line %d, group has password: %s\n", NR, $0) } \
- if ($3 !~ /[0-9]/) {
- printf("Warning! YGroup file, line %d, nonnumeric group id: %s\n", NR, $0) }}} ' $yp_group
-
- #
- # Look for duplications in groups in yellow pages groups
- #
- yresult=`$AWK -F: '{print $1}' $yp_group | $SORT |$UNIQ -d`
- if $TEST "$yresult"
- then
- $ECHO "Warning! Duplicate Group(s) found in yellow pages group:"
- $ECHO $result
- fi
- #
- # Next, check for duplicate users in a group in yellow groups. Let
- # awk do all the work (thanks, adri!)
-
- # ignore all groups with one member.
- #
- awk -F: '
- split($4, users, ",") > 1 {
- ct = 0
- for (i in users) {
- curuser = users[i]
- for (j in users) {
- if (j > i && curuser == users[j]) {
- if (ct++ == 0) print "Warning! YGroup "$1" has duplicate user(s):"
- print curuser
- }
- }
- }
- }
- ' $yp_group
-
- fi
-
- $RM -f $yp_group
-
- # end
- SHAR_EOF
- echo shar: extracting cops/init_kuang '(773 characters)'
- cat << \SHAR_EOF > cops/init_kuang
- # /* Copyright 1985 Robert W. Baldwin */
- # /* Copyright 1986 Robert W. Baldwin */
- ###############################################
- # Kuang: Rule based computer security checker.
- ###############################################
-
- CAT=/bin/cat
- ECHO=/bin/echo
-
- #
- # Initialization.
- #
- ./clearfiles
- #
- # First setup what we have access to.
- # The uids.k file must include the user 'OTHER' meaning the world access bits.
- # Add any other UIDs accessible to the attacker (e.g., ftp, daemon).
- #
- # Directly accessible user IDs.
- $CAT >uids.k <<END
- OTHER
- END
- #
- # Directly accessible group IDs.
- # This usually includes a group like 'users', which most users are in.
- #
- $CAT >gids.k <<END
- END
- #
- # Setup the primary goal(s).
- #
- $ECHO Setting up goal #>/dev/tty
- ./addto uids root DO ANYTHING
- SHAR_EOF
- echo shar: extracting cops/kuang '(5967 characters)'
- cat << \SHAR_EOF > cops/kuang
- # /* Copyright 1985 Robert W. Baldwin */
- # /* Copyright 1986 Robert W. Baldwin */
- #
- # Jan 1990, Ported to bourne shell from Csh. Dan Farmer
- #
- # Took out some comments, combined four of Bob's shell
- # scripts into one (the target script remains separate for
- # easy editing of targets.) More or less a straight line
- # for line translation; a rewrite that goes for speed will
- # come later. Maybe just rewrite it in C. Yeah, that's it....
-
- ###############################################
- # Kuang: Rule based computer security checker.
- ###############################################
-
- # commands used....
- SH=/bin/sh
- MV=/bin/mv
- TEST=/bin/test
- ECHO=/bin/echo
- AWK=/bin/awk
- RM=/bin/rm
-
- # Initialization.
- $SH ./init_kuang
-
- # Main loop
- #
- $ECHO Starting main loop #>/dev/tty
- while $TEST -f uids.n -o -f gids.n -o -f files.n
- do
- if $TEST -f uids.n ; then
- $MV uids.n uids.x
-
- # Process a list of uids from stdin.
- # Usage: douids username comments
- $ECHO Called douids #>/dev/tty
- i=1
- while $TEST "1"
- do
- nextuid=`$AWK '{if (NR=="'$i'") print $0}' uids.x`
- i=`expr $i + 1`
-
- if $TEST -z "$nextuid" ; then
- break;
- fi
-
- user=`$ECHO $nextuid | $AWK '{print $1}'`
-
- $ECHO " " User $user #>/dev/tty
-
- # Rules mapping uids to files.
- #
- next=`$ECHO $nextuid | $AWK '{for (i=2;i<=NF;i++) printf("%s ", $i)}'`
- ./addto files /etc/passwd replace grant $user $next
- ./addto files /usr/lib/aliases replace trojan $user $next
-
- # hsh = home sweet home = home directory of $user
- hsh=`./tilde $user`
-
- if $TEST -f $hsh/.rhosts ; then
- ./addto files $hsh/.rhosts write grant $user $next
- fi
-
- if $TEST -f $hsh/.login ; then
- ./addto files $hsh/.login replace trojan $user $next
- fi
-
- if $TEST -f $hsh/.cshrc ; then
- ./addto files $hsh/.cshrc replace trojan $user $next
- fi
-
- if $TEST -f $hsh/.profile ; then
- ./addto files $hsh/.profile replace trojan $user $next
- fi
-
- if $TEST "$user" = "root" ; then
- if $TEST -f /usr/lib/crontab ; then
- ./addto files /usr/lib/crontab replace create supershell $next
- else
- ./addto files /usr/spool/cron/crontabs replace create supershell $next
- fi
- ./addto files /etc/rc replace trojan $user $next
- ./addto files /etc/rc.local replace trojan $user $next
- fi
-
- if $TEST "$user" != "root" ; then
- ./addto files /etc/hosts.equiv replace allow rlogin $next
- fi
-
- if $TEST "$user" != "root" -a -f /etc/hosts.equiv -a -s /etc/hosts.equiv
- then
- ./addto files /etc/hosts replace fake HostAddress $next
- fi
-
- done
- fi
-
- if $TEST -f gids.n ; then
- $MV gids.n gids.x
-
- $ECHO Called dogids #>/dev/tty
- i=1
- while $TEST "1"
- do
- nextgid=`$AWK '{if (NR=="'$i'") print $0}' gids.x`
- i=`expr $i + 1`
-
- if $TEST -z "$nextgid" ; then
- break;
- fi
-
- group=`$ECHO $nextgid | $AWK '{print $1}'`
- $ECHO " " Group $group #>/dev/tty
-
- # Rules mapping gids to uids.
- #
- next=`$ECHO $nextgid | $AWK '{for (i=2;i<=NF;i++) printf("%s ", $i)}'`
- use=`./members $group`
- for user in $use
- do
- ./addto uids $user grant $group $next
- done
-
- # Rules mapping gids to files.
- #
- ./addto files /etc/group replace grant $group $next
- done
- fi
-
- if $TEST -f files.n ; then
- $MV files.n files.x
-
- # A list of file names is read from successive lines of stdin.
- # Each file is examined for ways to access it.
- # The input format is:
- # <filename> <whitespace> <mode> <comments>
- # The <mode> is either "write" or "replace".
- #
- $ECHO Called dofiles. #>/dev/tty
- i=1
- while $TEST "1"
- do
- nextfile=`$AWK '{if (NR=='"$i"') print $0}' files.x`
- i=`expr $i + 1`
- if $TEST -z "$nextfile" ; then
- break;
- fi
-
- file=`$ECHO $nextfile | $AWK '{print $1}'`
- mode=`$ECHO $nextfile | $AWK '{print $2}'`
-
- $ECHO " File $file, mode $mode" #>/dev/tty
-
- # Rules converting filename goals into UserName or GroupName goals.
- #
- next=`$ECHO $nextfile | $AWK '{for (i=3;i<=NF;i++) printf("%s ", $i)}'`
-
- writers=`./filewriters $file`
- numwriters=`$ECHO $writers | $AWK '{print NF}'`
- if $TEST "$numwriters" = "3" ; then
- owner=`$ECHO $writers | $AWK '{print $1}'`
- group=`$ECHO $writers | $AWK '{print $2}'`
- other=`$ECHO $writers | $AWK '{print $3}'`
-
- $ECHO " Writers are $owner $group $other" #>/dev/tty
- ./addto uids $owner $mode $file $next
- if $TEST "$group" != "NONE" ; then
- ./addto gids $group $mode $file $next
- fi
- if $TEST "$other" != "NONE" ; then
- ./addto uids $other $mode $file $next
- fi
- else
- $ECHO " $file does not exist" #>/dev/tty
- continue
- fi
-
- # Rules converting filename goals into other filename goals.
- #
- if $TEST "$mode" != "replace" ; then
- continue
- fi
-
- parent=`$ECHO $file | $AWK -F/ '{if (NF == 2) {
- printf("/%s", $1)}
- else if (NF>2) {for (i=2;i<NF;i++) printf("/%s", $i)}
- else printf("")'}`
-
- basename=`$ECHO $file | $AWK -F/ '{print $NF}'`
-
- $ECHO -n " " Parent directory is $parent #>/dev/tty
- $ECHO ", " basename is $basename #>/dev/tty
- if $TEST -n "$parent" ; then
- ./addto files $parent write replace $basename $next
- fi
- done
-
- fi
- done
-
- # destroy the evidence.... Need "Success" file for report, though.
- $RM files.? gids.? uids.?
- SHAR_EOF
- echo shar: extracting cops/makefile '(2721 characters)'
- cat << \SHAR_EOF > cops/makefile
- # Simple Makefile for the COPS system; compiles, and chmods
- # the programs.
- #
- # make all -- makes everything
- # make <program_name> -- make a given program
- EXECUTABLE = home.chk user.chk is_readable is_writable pass.chk \
- addto clearfiles filewriters members tilde
- C_SRC = home.chk.c user.chk.c is_readable.c is_writable.c pass.c \
- addto.c clearfiles.c filewriters.c members.c tilde.c
- SHELL_PROGS= chk_strings root.chk dev.chk dir.chk cron.chk \
- file.chk cops group.chk rc.chk passwd.chk \
- suid.chk kuang init_kuang reconfig
- SUPPORT = dir.chklst file.chklst makefile stop.sample \
- COPS.READ.1ST Beta.info SUID.README MANIFEST
- DOCS = COPS.report.ms suid.man.ms kuang.man.ms
- MAN = cops.1 cron.1 dev.1 dir.1 file.1 group.1 passwd.1 \
- is_able.1 home.1 user.1 pass.1
- CFLAGS = -O
- ROFFLAGS = -ms
-
- #
- # Where the programs are....
- #
- CHMOD=/bin/chmod
- MKDIR=/bin/mkdir
- CP=/bin/cp
- CC=/bin/cc
- NROFF=/usr/bin/nroff
-
- # make all
- all: $(EXECUTABLE) $(DOCS) $(MAN)
- $(CHMOD) 700 $(SHELL_PROGS)
-
- # make the programs
- addto: src/addto.c
- $(CC) $(CFLAGS) -o addto src/addto.c
-
- clearfiles: src/clearfiles.c
- $(CC) $(CFLAGS) -o clearfiles src/clearfiles.c
-
- filewriters: src/filewriters.c
- $(CC) $(CFLAGS) -o filewriters src/filewriters.c
-
- members: src/members.c
- $(CC) $(CFLAGS) -o members src/members.c
-
- home.chk: src/home.chk.c
- $(CC) $(CFLAGS) -o home.chk src/home.chk.c
-
- user.chk: src/user.chk.c
- $(CC) $(CFLAGS) -o user.chk src/user.chk.c
-
- is_readable: src/is_readable.c
- $(CC) $(CFLAGS) -o is_readable src/is_readable.c
-
- is_writable: src/is_writable.c
- $(CC) $(CFLAGS) -o is_writable src/is_writable.c
-
- pass.chk: src/pass.c
- $(CC) $(CFLAGS) -o pass.chk src/pass.c
-
- tilde: src/tilde.c
- $(CC) $(CFLAGS) -o tilde src/tilde.c
-
- # 'roff out those docs
- COPS.report.ms: docs/COPS.report
- $(NROFF) $(ROFFLAGS) docs/COPS.report > docs/COPS.report.ms
-
- kuang.man.ms: docs/kuang.man
- $(NROFF) $(ROFFLAGS) docs/kuang.man > docs/kuang.man.ms
-
- suid.man.ms: docs/suid.man
- $(NROFF) $(ROFFLAGS) docs/suid.man > docs/suid.man.ms
-
- cops.1: docs/cops
- $(NROFF) -man docs/cops > docs/cops.1
-
- cron.1: docs/cron
- $(NROFF) -man docs/cron > docs/cron.1
-
- dev.1: docs/dev
- $(NROFF) -man docs/dev > docs/dev.1
-
- dir.1: docs/dir
- $(NROFF) -man docs/dir > docs/dir.1
-
- file.1: docs/file
- $(NROFF) -man docs/file > docs/file.1
-
- group.1: docs/group
- $(NROFF) -man docs/group > docs/group.1
-
- passwd.1: docs/passwd
- $(NROFF) -man docs/passwd > docs/passwd.1
-
- pass.1: docs/pass
- $(NROFF) -man docs/pass > docs/pass.1
-
- is_able.1: docs/is_able
- $(NROFF) -man docs/is_able > docs/is_able.1
-
- home.1: docs/home
- $(NROFF) -man docs/home > docs/home.1
-
- user.1: docs/user
- $(NROFF) -man docs/user > docs/user.1
-
- # the end
- SHAR_EOF
- echo shar: extracting cops/pass.words '(3278 characters)'
- cat << \SHAR_EOF > cops/pass.words
- aaa
- academia
- aerobics
- airplane
- albany
- albatross
- albert
- alex
- alexander
- algebra
- aliases
- alphabet
- ama
- amorphous
- analog
- anchor
- andromache
- animals
- answer
- anthropogenic
- anvils
- anything
- aria
- ariadne
- arrow
- arthur
- athena
- atmosphere
- aztecs
- azure
- bacchus
- bailey
- banana
- bananas
- bandit
- banks
- barber
- baritone
- bass
- bassoon
- batman
- beater
- beauty
- beethoven
- beloved
- benz
- beowulf
- berkeley
- berliner
- beryl
- beverly
- bicameral
- bob
- brenda
- brian
- bridget
- broadway
- bumbling
- burgess
- campanile
- cantor
- cardinal
- carmen
- carolina
- caroline
- cascades
- castle
- cat
- cayuga
- celtics
- cerulean
- change
- charles
- charming
- charon
- chester
- cigar
- classic
- clusters
- coffee
- coke
- collins
- commrades
- computer
- condo
- cookie
- cooper
- cornelius
- couscous
- creation
- creosote
- cretin
- daemon
- dancer
- daniel
- danny
- dave
- december
- defoe
- deluge
- desperate
- develop
- dieter
- digital
- discovery
- disney
- dog
- drought
- duncan
- eager
- easier
- edges
- edinburgh
- edwin
- edwina
- egghead
- eiderdown
- eileen
- einstein
- elephant
- elizabeth
- ellen
- emerald
- engine
- engineer
- enterprise
- enzyme
- ersatz
- establish
- estate
- euclid
- evelyn
- extension
- fairway
- felicia
- fender
- fermat
- fidelity
- finite
- fishers
- flakes
- float
- flower
- flowers
- foolproof
- football
- foresight
- format
- forsythe
- fourier
- fred
- friend
- frighten
- fun
- fungible
- gabriel
- gardner
- garfield
- gauss
- george
- gertrude
- ginger
- glacier
- gnu
- golfer
- gorgeous
- gorges
- gosling
- gouge
- graham
- gryphon
- guest
- guitar
- gumption
- guntis
- hacker
- hamlet
- handily
- happening
- harmony
- harold
- harvey
- hebrides
- heinlein
- hello
- help
- herbert
- hiawatha
- hibernia
- honey
- horse
- horus
- hutchins
- imbroglio
- imperial
- include
- ingres
- inna
- innocuous
- irishman
- isis
- japan
- jessica
- jester
- jixian
- johnny
- joseph
- joshua
- judith
- juggle
- julia
- kathleen
- kermit
- kernel
- kirkland
- knight
- ladle
- lambda
- lamination
- larkin
- larry
- lazarus
- lebesgue
- lee
- leland
- leroy
- lewis
- light
- lisa
- louis
- lynne
- macintosh
- mack
- maggot
- magic
- malcolm
- mark
- markus
- marty
- marvin
- master
- maurice
- mellon
- merlin
- mets
- michael
- michelle
- mike
- minimum
- minsky
- moguls
- moose
- morley
- mozart
- nancy
- napoleon
- nepenthe
- ness
- network
- newton
- next
- noxious
- nutrition
- nyquist
- oceanography
- ocelot
- olivetti
- olivia
- oracle
- orca
- orwell
- osiris
- outlaw
- oxford
- pacific
- painless
- pakistan
- pam
- papers
- password
- patricia
- penguin
- peoria
- percolate
- persimmon
- persona
- pete
- peter
- philip
- phoenix
- pierre
- pizza
- plover
- plymouth
- polynomial
- pondering
- pork
- poster
- praise
- precious
- prelude
- prince
- princeton
- protect
- protozoa
- pumpkin
- puneet
- puppet
- rabbit
- rachmaninoff
- rainbow
- raindrop
- raleigh
- random
- rascal
- really
- rebecca
- remote
- rick
- ripple
- robotics
- rochester
- rolex
- romano
- ronald
- rosebud
- rosemary
- roses
- ruben
- rules
- ruth
- sal
- saxon
- scamper
- scheme
- scott
- scotty
- secret
- sensor
- serenity
- sharks
- sharon
- sheffield
- sheldon
- shiva
- shivers
- shuttle
- signature
- simon
- simple
- singer
- single
- smile
- smiles
- smooch
- smother
- snatch
- snoopy
- soap
- socrates
- sossina
- sparrows
- spit
- spring
- springer
- squires
- strangle
- stratford
- stuttgart
- subway
- success
- summer
- super
- superstage
- support
- supported
- surfer
- suzanne
- swearer
- symmetry
- tangerine
- tape
- target
- tarragon
- taylor
- telephone
- temptation
- thailand
- tiger
- toggle
- tomato
- topography
- tortoise
- toyota
- trails
- trivial
- trombone
- tubas
- tuttle
- umesh
- unhappy
- unicorn
- unknown
- urchin
- utility
- vasant
- vertigo
- vicky
- village
- virginia
- warren
- water
- weenie
- whatnot
- whiting
- whitney
- will
- william
- williamsburg
- willie
- winston
- wisconsin
- wizard
- wombat
- woodwind
- wormwood
- yacov
- yang
- yellowstone
- yosemite
- zap
- zimmerman
- SHAR_EOF
- echo shar: extracting cops/passwd.chk '(5023 characters)'
- cat << \SHAR_EOF > cops/passwd.chk
- #!/bin/sh
- #
- # passswd.chk
- #
- # Check passsword file -- /etc/passswd -- for incorrect number of fields,
- # duplicate uid's, non-alphanumeric uids, and non-numeric group id's.
- #
- # Awk part from _The AWK Programming Language_, page 78
- #
- # Mechanism: Passwd.check uses awk to ensure that each line of the file
- # has 7 fields, as well as examining the file for any duplicate users
- # by using "sort -u". It also checks to make sure that the password
- # field (the second one) is either a "*", meaning the group has no password,
- # or a non-null field (which would mean that the account has a null
- # password.) It then checks to ensure that all uids are alphanumeric,
- # and that all user id numbers are indeed numeric. For yellow pages
- # passwords, it does the same checking, but in order to get a listing of
- # all members of the password file, it does a "ypcat passwd > ./$$" and
- # uses that temporary file for a passfile. It removes the tmp file after
- # using it, of course.
- # The /etc/passwd file has a very specific format, making the task
- # fairly simple. Normally it has lines with 7 fields, each field
- # separated by a colon (:). The first field is the user id, the second
- # field is the encrypted password (an asterix (*) means the group has no
- # password, otherwise the first two characters are the salt), the third
- # field is the user id number, the fourth field is the group id number,
- # the fifth field is the GECOS field (basically holds miscellaneous
- # information, varying from site to site), the sixth field is the home
- # directory of the user, and lastly the seventh field is the login shell
- # of the user. No blank lines should be present.
- # If a line begins with a plus sign (+), it is a yellow pages entry.
- # See passwd(5) for more information, if this applies to your site.
- #
- AWK=/bin/awk
- TEST=/bin/test
- ECHO=/bin/echo
- SORT=/usr/bin/sort
- UNIQ=/usr/bin/uniq
- RM=/bin/rm
- YPCAT=/usr/bin/ypcat
-
- # Used for Sun C2 security group file. FALSE (default) will flag
- # valid C2 passwd syntax as an error, TRUE attempts to validate it.
- # Thanks to Pete Troxell for pointing this out.
- C2=FALSE
-
- #
- # Important files:
- etc_passwd=/etc/passwd
- yp_passwd=./$$
-
- yp=false
-
- # Testing $etc_passwd for potential problems....
- if $TEST -f $YPCAT
- then
- if $TEST -s $YPCAT
- then
- $YPCAT passwd > $yp_passwd
- if $TEST $? -eq 0
- then
- yp=true
- fi
- fi
- fi
-
- result=`$AWK -F: '{print $1}' $etc_passwd | $SORT |$UNIQ -d`
- if $TEST "$result"
- then
- $ECHO "Warning! Duplicate uid(s) found in $etc_passwd:"
- $ECHO $result
- fi
-
-
- # First line is for a yellow pages entry in the password file.
- # It really should check for correct yellow pages syntax....
- $AWK 'BEGIN {FS = ":" } \
- {if (substr($1,1,1) != "+") { \
- if ($0 ~ /^[ ]*$/) { printf("Warning! Password file, line %d, is blank\n", NR) } else {
- if (NF != 7) {
- printf("Warning! Password file, line %d, does not have 7 fields: \n\t%s\n", NR, $0) } \
- if ($1 !~ /[A-Za-z0-9]/) {
- printf("Warning! Password file, line %d, nonalphanumeric login: \n\t%s\n", NR, $0) } \
- if ($2 == "") {
- printf("Warning! Password file, line %d, no password: \n\t%s\n", NR, $0) } \
- if ("'$C2'" == "TRUE" && $2 ~ /^##/ && "##"$1 != $2) {
- printf("Warning! Password file, line %d, invalid password field for C2: \n\t%s\n", NR, $0) } \
- if ($3 !~ /[0-9]/) {
- printf("Warning! Password file, line %d, nonnumeric user id: \n\t%s\n", NR, $0) } \
- if ($3 == "0" && $1 != "root") {
- printf("Warning! Password file, line %d, user %s has uid = 0 and is not root\n\t%s\n", NR, $1, $0) } \
- if ($4 !~ /[0-9]/) {
- printf("Warning! Password file, line %d, nonnumeric group id: \n\t%s\n", NR, $0) } \
- if ($6 !~ /^\//) {
- printf("Warning! Password file, line %d, invalid login directory: \n\t%s\n", NR, $0) } \
- }}}' $etc_passwd
-
- #
- # Test yellow pages passwords as well
- if $TEST "$yp" = "true"
- then
- yresult=`$AWK -F: '{print $1}' $yp_passwd | $SORT |$UNIQ -d`
- if $TEST "$yresult"
- then
- $ECHO "Warning! Duplicate uid(s) found in yellow page passwords:"
- $ECHO $yresult
- fi
-
- $AWK 'BEGIN {FS = ":" } \
- { if ($0 ~ /^[ ]*$/) { printf("Warning! YPassword file, line %d, is blank\n", NR) } else {
- if (NF != 7) {
- printf("Warning! YPassword file, line %d, does not have 7 fields: \n\t%s\n", NR, $0) } \
- if ($1 !~ /[A-Za-z0-9]/) {
- printf("Warning! YPassword file, line %d, nonalphanumeric login: \n\t%s\n", NR, $0) } \
- if ($2 == "") {
- printf("Warning! YPassword file, line %d, no password: \n\t%s\n", NR, $0) } \
- if ($3 !~ /[0-9]/ && $3 != "-2") {
- printf("Warning! YPassword file, line %d, nonnumeric user id: \n\t%s\n", NR, $0) } \
- if ($3 == "0" && $1 != "root") {
- printf("Warning! YPassword file, line %d, user %s has uid = 0 and is not root\n\t%s\n", NR, $1, $0) } \
- if ($4 !~ /[0-9]/ && $4 != "-2") {
- printf("Warning! YPassword file, line %d, nonnumeric group id: \n\t%s\n", NR, $0) } \
- if ($6 !~ /^\//) {
- printf("Warning! YPassword file, line %d, invalid login directory: \n\t%s\n", NR, $0) } \
- }}' $yp_passwd
-
- fi
-
- $RM -f $yp_passwd
-
- # end
- SHAR_EOF
- # End of shell archive
- exit 0
-
-