|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T c
Length: 61427 (0xeff3) Types: TextFile Names: »cops103.beta.04«
└─⟦4f9d7c866⟧ Bits:30007245 EUUGD6: Sikkerheds distributionen └─⟦this⟧ »./cops/1.03.beta/shell/cops103.beta.04«
#!/bin/sh # this is cops103.beta.04 (part 4 of a multipart archive) # do not concatenate these parts, unpack them in order with /bin/sh # file beta/docs/kuang.man continued # if test ! -r _shar_seq_.tmp; then echo 'Please unpack part 1 first!' exit 1 fi (read Scheck if test "$Scheck" != 4; then echo Please unpack part "$Scheck" next! exit 1 else exit 0 fi ) < _shar_seq_.tmp || exit 1 if test ! -f _shar_wnt_.tmp; then echo 'x - still skipping beta/docs/kuang.man' else echo 'x - continuing file beta/docs/kuang.man' sed 's/^X//' << 'FOO_BAR' >> 'beta/docs/kuang.man' && .ul <Goal/Condition/Subgoal/Note> .PP Become U Exists(~U/.login) Replace ~U/.login\** .FS This file contains the commands read when a user logs in. The conditional should really test to see if the user is actually using the /bin/csh command interpreter. If csh is being used, then this rule will work even if the file .login doesn't exist, so the conditional is overly strict. .FE .PP Become U Exists(~U/.cshrc) Replace ~U/.cshrc\** .FS This file is read each time a /bin/csh is executed such as at login and when a command file is executed. The conditional is also overly strict. .FE .PP Become U Exists(~U/.profile) Write ~U/.profile\** .FS Same trick for the /bin/sh command interpreter. .FE .sp } .PP \fBcron\fP .PP Cron is a program that is forked off when a Unix system is booted. This means that it runs with super-user privileges. Cron reads a database (/usr/lib/crontab) that describes the commands that should be executed periodically. By default these commands are executed with \*Qroot\*U privileges. .sp Rules{ .sp .ul <Goal/Condition/Subgoal/Note> X Become root none Replace /usr/lib/crontab .sp } .PP \fBsendmail\fP .PP The Unix mail system has many features that allow flexible forms of information sharing. The most interesting feature (to system builders and to attackers) is that receiving mail can trigger the invocation of a program which is passed the mail message as its input. The file /usr/lib/aliases specifies the human readable form of a binary database that describes mailing lists, mail forwarding, and programs to invoke when mail is received by certain mailboxes. Being able to modify this database allows an attacker to get access to other people's user and group IDs because the mail sending program runs with the privileges of the user who invokes it. If the destination of the message is on the same host as the source, then the receiving program (also sendmail) will run with the invoker's privileges. If the source of the message is on another computer, then sendmail will run under the UID \*Qdaemon\*U. .sp Rules{ .sp .ul <Goal/Condition/Subgoal/Note> .PP Become daemon none Replace /usr/lib/aliases\** .FS This assumes that the command to build the binary database can be executed by everyone, or that it is executed automatically when the mailer detects that the binary database is out of date. There should also be rules to see if the binary database can be written directly. .FE .PP Become root none Replace /usr/lib/aliases\** .FS Assumes that \*Qroot\*U sends mail to some user on this machine. Such users can be found by scanning the mail logs, which are usually World readable. If such a user exists, the aliases database can be set up to tell sendmail to deliver mail to the recipient and invoke the attacker's program. Next time root sends mail to that user, the attacker's program will be invoked with root privileges. The program would test to see if it was running with \*Qroot\*U privileges, and if so plant a trap door such as making /.rhosts publicly writable. .FE .sp } .PP \fBboot\fP .PP When a Unix reboots, it executes the commands in the file /etc/rc. This file usually executes the commands in the file /etc/rc.local. .sp Rules{ .sp .ul <Goal/Condition/Subgoal/Note> X Become root Exists(/etc/rc) Replace /etc/rc X Become root Exists(/etc/rc.local) Replace /etc/rc.local } .PP \fBExtensions to the Unix model\fP (extensions) .PP This section lists some of the important pieces of the Unix protection system that were left out of the SU-Kuang's model. Most of these pieces could be added easily. .PP The major deficiency of the model is that it does not include all of the programs that run with super-user privileges. Each of these programs must be modeled if there is some way that an attacker could use the programs' databases to get access to root privileges. .PP Locating all the programs that run with super-user privileges is not easy. Many ordinary programs are executed inside of command files that are run with root privileges. This points out another shortcoming of SU-Kuang. It does not look inside of command files. For example, on system restart, Unix executes the commands in the file /etc/rc with super-user privileges. That file executes additional commands in the file /rc.local, so those commands also runs as root. The prototype has an explicit rule that covers this case, whereas it should deduce this and other cases by parsing the commands in /etc/rc. .PP The prototype does not understand search paths. On Unix, as with most systems, users do not specify the full pathname of the programs they want to execute. Instead, users specify a sequence of directories that should be searched to find the program. Often users tell their command interpreter to first look in a private directory of commands, and quite often that directory is writable by any member of the user's primary group. If an attacker can write a user's private command directory, then the attacker can plant a trojan horse on that user. For example, the user may want to execute /usr/local/gnuemacs, but the user may end up executing the attacker's program in /usr/smith/@_bin/gnuemacs. To model this attack, SU-Kuang would need to be able to read each user's startup command file to determine each user's search path. .PP The file goals considered by the model only include write and replace access to a file. Read access is not considered. To include read access, each piece of the protection system must be re-examined to see if it could provide read access to an arbitrary file. For example, the Unix finger program, which displays information about users, runs with super-user privileges so it can read an information file (.plan) in the specified user's home directory. Unfortunately, some implementations of the finger program allow the .plan file to be a symbolic link to another file, and thus the finger program allows read access to any file on the system. .PP The rules that model the file system do not include the fact that the disks can be accessed via the raw device files. Reading and writing the device files can be used to read and write arbitrary blocks on the disks. These files should only be accessible to the super-user, but often anyone can read them. If so, an attacker can read any file on the disk. .PP A different kind of deficiency in the model is that it does not allow the attacker to guess at passwords. On a system that allows users to pick their own passwords, an attacker can usually guess a few of the passwords. Assuming that an attacker can read the password file, \** .FS Protecting the password file from users logged in on a guest account or using anonymous file transfer is a good idea. However, protecting it from ordinary users is hard. Many programs need read access to the non-password information kept in that file, and making all those programs run with special privileges may create more problems than it solves. .FE the attacker can test passwords at the rate of about ten per second.\** .FS There are lots of tricks that speed up the execution of the Unix salted DES function on a 32 bit machine. .FE A 2000 word dictionary of common passwords can be processed at the rate of a few minutes per account. .PP As in any kind of modeling, the better the model, the better the results. Fortunately, in the case of Unix, making the model more detailed does not require using a more complicated framework. The rule-based framework of SU-Kuang is flexible enough to model all the features described in this section. .PP \fBPrototype Implementation\fP (implementation) .PP The SU-Kuang program described in this paper is easy to implement. The primary inputs to the program are a list of groups (privileges) accessible to the attacker (including the special group \*QWorld\*U), and the target goal (usually \*Qbecome root\*U). The program examines the protection configuration of the machine it is running on, so this can be considered a secondary input. The primary output is a list of the ways that an attacker can achieve the target goal from the initial privileges. Internally, the program builds a goal-tree based on a set of rules that are compiled into the program. When a node of the goal-tree can be directly achieved using the initial privileges, the program prints out the sequence of steps that describe the path from the given node of the goal-tree to the root of the goal-tree. .PP In classic Unix style, the prototype was initially implemented by a set of shell scripts (command files). Later, to improve performance, some of the shell scripts were re-written in C. The top level shell script keeps track of the goal-tree, and invokes other shell scripts to generate successive levels of the goal-tree. For each of the three kinds of goals (user, group, and file), there is a shell script that reads a list of goals of that kind and produces a list of subgoals. .PP Associated with each node of the goal-tree is a human readable comment that describes the path from each node to the root of the goal-tree. This comment is appended to a list of 'successes' if the associated goal can be directly achieved using the initial privileges of the attacker. Since each comment specifies the sequence of steps an attacker could use to achieve the target goal given the current goal, it is easy to derive the comments for subgoals from the comments of parent goals. The subgoal comments is the parent goal's comment plus an indication of which rule was used to derive the subgoal. .PP The basic data abstraction used by SU-Kuang is a goal-table. There are three goal-tables, one for each type of goal. The operations on a goal table are: .ul new, .ul addto, and .ul next. The .ul new operation creates an empty goal table. It takes a set of initial goals that are directly achievable by the attacker. The .ul addto operation adds a goal and a comment to the table. If the goal is already in the table, the table is not changed. If the goal is in the set of directly achievable goals, then .ul addto also appends the comment to the file that contains a list of successes. The operation, .ul next, examines a goal-table and returns any goal-comment pair that it has not already returned. The .ul addto operation is effectively the inner loop of a rule interpreter. .PP The goal-table abstraction is implemented by four files. One file keeps track of all of the goals in the table and it is used to avoid duplicate goals. Another file holds the list of goals initially available to the attacker. Two files are used to support the next operation. One file records all the goal-comment pairs that have been returned by the next operations, the other file lists the goal-comment pairs that have been added to the table but not yet selected by the next operation. .PP Using the goal-table abstraction it is easy to express rules as lines of a shell script. Figure .ul shell rule shows a rule and its shell script implementation. The conditional part of the rules are expressed by shell script conditionals (e.g., \*Q-z\*U means that a file exists and has a length of zero, \*Q!\*U and \*Q&&\*U mean logical negation and conjunction). .sp Rules{ .sp .ul <Goal/Condition/Subgoal> X Become root NotEmpty(/.rhosts) Replace /etc/hosts .sp } X .nf # $User and $OldComment are set by the goal-table next operation. # $FileGoals refers to the goal-table object for file type goals. if (($User == "root") && (! -z /.rhosts)) then X set NewComment="Fake HostAddress, $OldComment" X set SubGoal="Replace /etc/hosts" X addto $FileGoals $SubGoal $NewComment endif .fi Sample rule and corresponding shell script line. X .PP The implementation of SU-Kuang is straight forward. The only reason for describing it in this paper is to demonstrate how easy it is to process the attacker-oriented rules that describe a protection system. .PP \fBExperience\fP (experience) .PP The SU-Kuang system has been run on a large number of sites managed by personnel with a wide range of skills and interests in security. It has almost always found a hole. A Kuang that incorporates the extensions described in section .ul extensions would find more holes. .PP I believe that holes are created because users do not understand how the various pieces of the protection system interact. The main evidence for this is that fact that most holes are found in the protection databases that are maintained by ordinary users (e.g., .login and .rhosts). Also, users who have recently been given special privileges tend to create holes that allow anyone to achieve super-user privileges. When I tell users about the problems SU-Kuang finds, they often do not understand what was wrong with the decision they made. .PP Users create security holes periodically. When I ran SU-Kuang periodically on one computer that had a large complicated protection configuration (e.g., the authorization databases included 300 users and 25 groups), SU-Kuang found new holes every week or two. Often these new holes were created when someone modified a security database. One common procedure for modifying a database is to first rename the original, then copy of the original into a file with the proper name, and finally edit the copy. The motivation for the first rename step is to preserve the timestamp that indicates when the database was last written. Unfortunately, the file copy step does not copy the protection information from the original database. The protection for the copy is determined by the defaults for the currently running process. It is not determined by the original. The file UID is set to the UID of the process that performs the copy, and the GID is set to the GID of the directory that contains the file. The permission bits are set to a default value specified in the copier's login command file. .PP The holes found by SU-Kuang point out that it is hard to set up multiple separate security groups under BSD4.2 Unix. For example, a group that allows its members to install programs in the /etc directory, also allows its members to replace the authentication database in /etc/passwd. The fact that users run with their full privileges (i.e., they can access multiple groups in the same process), makes Berkeley Unix easier to use than other versions of Unix that force users to access one group at a time. However, that same feature makes it easier for an attacker to plant a trojan horse on a user that is a member of a lower privilege group (e.g., the implementors of some project) and a member of a high privilege group (e.g., staff). .PP The impression I have gotten from running SU-Kuang is that most of the features that make Unix easy to use also make Unix hard to secure. However, SU-Kuang does make it easier to build a secure protection configuration for Unix. X .PP \fBDiscussion\fP (conclusions) .PP To increase the usefulness of computers, systems designers have provided an increasing number of mechanisms that allow users to execute commands and share information. Since these new mechanisms must be considered part of the protection system, this trend has made protection systems larger and progressively harder to understand. As a protection system becomes more complex, it becomes unlikely that all the protection decisions are made correctly, and these mistakes can ruin the overall security of the information and resources controlled by computers. The commercial environment presents a special problem because usability is the primary goal of commercial information systems, but security cannot be neglected. There needs to be some way to manage the complexity of the protection systems that arise on information systems that stress usability. .PP This paper presents one approach for achieving both usability and security. The idea is to use rule-based systems to analyze the interactions between all the decisions that make up a computer's protection configuration. If analyzing a protection configuration is easy, then the manager of a system can ensure that the system meets the security objectives of its users. A program that performs a simple analysis of a Unix protection configuration was presented to illustrate that this sort of rule-based system is easy to build if the protection system is described from the attacker's viewpoint. This simple Unix analysis system, called SU-Kuang, answered the question "given access to a particular set of privileges, can an attacker achieve super-user privileges?". Using SU-Kuang, a security manager could ensure that a system did not allow ordinary user to achieve super-user privileges. .PP SU-Kuang is just one of many helpful Kuang-type systems. For example, many security objectives are expressed in terms of limiting the set of people who have access to particular privileges. A Kuang-type system that computed the set of privileges accessible to each user would help a security manager determine whether the security objectives are being met. Even better, if the bulk of the security objectives can be expressed in computer understandable form, then the bulk of the work of checking computer security could be automated. X FOO_BAR echo 'File beta/docs/kuang.man is complete' && chmod 0600 beta/docs/kuang.man || echo 'restore of beta/docs/kuang.man failed' Wc_c="`wc -c < 'beta/docs/kuang.man'`" test 36594 -eq "$Wc_c" || echo 'beta/docs/kuang.man: original size 36594, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= beta/docs/rc.chk ============== if test -f 'beta/docs/rc.chk' -a X"$1" != X"-c"; then echo 'x - skipping beta/docs/rc.chk (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting beta/docs/rc.chk (Text)' sed 's/^X//' << 'FOO_BAR' > 'beta/docs/rc.chk' && .TH RC.CHK 1 "December 31, 1989" .UC 4 .SH NAME rc.chk \- Checks contents of /etc/rc* file(s) for potential danger. .SH SYNOPSIS .B rc.chk .SH DESCRIPTION .I rc.chk This checks pathnames and files inside the shell script files /etc/rc* (e.g. /etc/rc, /etc/rc.local, etc.) for writability. It filters out all paths or files that have a /tmp, /dev/null, or /dev/*ty, plus everything after a ">"; e.g. if crontab is writing to a file it doesn't care. .SH FILES /etc/rc* .SH BUGS Awk runs out of room ("bails out") if too many files are found in the /etc/rc* files. .PP Spurious messages can occur -- .I rc.chk only uses a approximation of which files should be checked. Also, Unless a file has a full pathname (i.e. begins with a "/", it will not be checked for writability. FOO_BAR chmod 0600 beta/docs/rc.chk || echo 'restore of beta/docs/rc.chk failed' Wc_c="`wc -c < 'beta/docs/rc.chk'`" test 775 -eq "$Wc_c" || echo 'beta/docs/rc.chk: original size 775, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= beta/docs/is_able.chk ============== if test -f 'beta/docs/is_able.chk' -a X"$1" != X"-c"; then echo 'x - skipping beta/docs/is_able.chk (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting beta/docs/is_able.chk (Text)' sed 's/^X//' << 'FOO_BAR' > 'beta/docs/is_able.chk' && .TH IS_ABLE.CHK 1 "Jan 4, 1991" .UC 4 .SH NAME is_able.chk \- Check for write/read\-ability of files listed a configuration file. .SH SYNOPSIS .B is_able.chk .SH DESCRIPTION .I is_able.chk checks all files listed in the file .I is_able.lst to see if files are either write/read-able by group or by all, or if they are setuid/setgid, or a combination of these. .PP .I is_able.lst is merely a list of files (or regular expressions representing a file or files), one per line, that are checked by .I is_able. Any line starting with a "#" is ignored, and any file checked for writability also checks the parent directories (if a complete path is given) for writeability. .SH EXAMPLE .EX 0 # Lines are of the format: # /path/to/file /etc/* /.profile .EE .SH FILES is_able.lst .SH Bugs When using wildcards and checking a directory with a lot of files, overflow of the shell variables can occur, causing incorrect arguments to be passed to the driving program, .I is_able .SH See Also is_able(1) FOO_BAR chmod 0600 beta/docs/is_able.chk || echo 'restore of beta/docs/is_able.chk failed' Wc_c="`wc -c < 'beta/docs/is_able.chk'`" test 992 -eq "$Wc_c" || echo 'beta/docs/is_able.chk: original size 992, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= beta/docs/release.notes ============== if test -f 'beta/docs/release.notes' -a X"$1" != X"-c"; then echo 'x - skipping beta/docs/release.notes (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting beta/docs/release.notes (Text)' sed 's/^X//' << 'FOO_BAR' > 'beta/docs/release.notes' && X X Brief Info-Capsule of COPS programs and files (release 1.02): ------------------------------------------------------------------------- X Programs and some important files that are included in this release: ------------------------------------------------------------------------- X X cops A driving shell script for most of the programs X below. It tosses output to /dev/null except X what it wants, and mails any pertinent output X to the users $SECURE_USER listed in the COPS file. X Usage: cops X X suid.chk Checks the system for _changes_ in SUID status. X This is the one program that should be run as X superuser. You must first run a find on all X SUID programs from the / directory, and then use X that as a "stop file" (see man page below.) X suid.man Manual for COPS.suid X findsuid.stop The database originally set up with "find". X Usage: suid.chk X X X makefile A makefile for programs enclosed. X Type "make" to make 'em (see Makefile for more X information.) X X chk_strings Checks for writable paths/files in a file. X Usage: chk_strings <file> X X cron.chk Checks for writable paths/files in /usr/lib/crontab. X Usage: cron.chk X X dev.chk Checks /dev/*mem and all devs listed by "/etc/fstab" X command for world read/writability (respectively.) X In addition, checks a small group of files for X non-world readability (/usr/adm/sulog, etc.) X Usage: dev.chk [-g] X (-g checks for group read/writability as well) X X dir.chk Checks directories listed in "dirs.chklst" X for writability. X dir.chklst List of directories for above. X Usage: dir.chk [-g] X (-g checks for group writability as well) X X file.chk Checks files listed in "files.chklst" X for writability. X file.chklst List of directories for above. X Usage: file.chk [-g] X (-g checks for group writability as well) X X group.chk Checks /etc/group for non-unique groups, invalid X fields, non-numeric group ids, etc. X Usage: group.chk X X home.chk.c Checks all users home-dirs listed in /etc/passwd X for bad modes (basically world write, strangeness). X Usage: home.chk X X rc.chk Checks all commands and paths listed in /etc/rc* X for writability. X Usage: rc.chk X X reconfig Changes the paths for the programs used in COPS. X Example: changes /bin/awk --> /usr/bin/awk X file.paths Data file for reconfig (created by reconfig.) X Usage: reconfig X X is_readable Checks a file/directory and determines readability X status; returns a "0" if is readable, a "1" X otherwise. X Usage: is_readable [-g] filename X X is_writable Checks a file/directory and determines writability X status; returns a "0" if is writable, a "1" X otherwise. X Usage: is_writable [-g] filename X X kuang The U-Kuang expert system. Read the accompanying X instructions in kuang.man. It basically checks X to see if a given user (by default root) is X compromisible, given that certain rules are true X (i.e. /etc/passwd writable gives root access, etc.) X Usage: kuang X init_kuang Contains the targets for the kuang system. X X misc.chk Checks various miscellaneous things -- tftp, decode X alias, rexd. X Usage: misc.chk X X passwd.chk Checks /etc/passwd for non-unique uids, invalid X fields, non-numeric user ids, etc. X Usage: passwd.chk X X pass.chk Checks /etc/passwd for crummy passwords. X pass.words Data file for pass.chk; use "pass -w pass.words" X to use them. Defaults to checking for the users' id. X Usage: pass.chk [-flags] X X pass_diff.chk A wrapper for pass.chk. Only checks passwords in X accounts that have changed, though. X Usage: pass_diff.chk [-flags] X X user_chk.c Checks all users listed in /etc/passwd; looks at X .login/.cshrc/.rhosts/.profile, etc., for bad X modes (basically world write, strangeness). X Usage: user_chk X FOO_BAR chmod 0600 beta/docs/release.notes || echo 'restore of beta/docs/release.notes failed' Wc_c="`wc -c < 'beta/docs/release.notes'`" test 3833 -eq "$Wc_c" || echo 'beta/docs/release.notes: original size 3833, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= beta/docs/suid.man ============== if test -f 'beta/docs/suid.man' -a X"$1" != X"-c"; then echo 'x - skipping beta/docs/suid.man (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting beta/docs/suid.man (Text)' sed 's/^X//' << 'FOO_BAR' > 'beta/docs/suid.man' && findsuid \- find changes in setuid and setgid files .sp SYNOPSIS .sp .ul findsuid .sp DESCRIPTION .PP Findsuid is a shell script intended to be run periodically by .ul cron (8) in order to spot changes in files with the suid or sgid bits set. .PP .ul Findsuid uses .ul find (1) to search system directories for all files with the 4000 or 2000 permission bits set. It then compares these files with the contents of a ``stop file'' (by default .ul suid.stop ) containing .ul \*Qls -lga\*U output for known setuid or setgid programs. In addition, it flags any setuid or setgid programs that are shell scripts. Any additions or changes to this list represent potential security problems, so they are reported by mail to system administrators for further investigation. .sp FILES .sp .nf suid.stop the ``stop file'' .fi .sp SEE ALSO .sp find(1), chmod(1), cron(8) .sp BUGS .sp The location of the stop file, the directories to be searched and the names of users to be informed of changes are all defined by shell variables in the source. .PP Keeping the stop files up to date with changes to all the suid files on more than a couple of hosts is a royal pain! FOO_BAR chmod 0600 beta/docs/suid.man || echo 'restore of beta/docs/suid.man failed' Wc_c="`wc -c < 'beta/docs/suid.man'`" test 1157 -eq "$Wc_c" || echo 'beta/docs/suid.man: original size 1157, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= beta/docs/tilde ============== if test -f 'beta/docs/tilde' -a X"$1" != X"-c"; then echo 'x - skipping beta/docs/tilde (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting beta/docs/tilde (Text)' sed 's/^X//' << 'FOO_BAR' > 'beta/docs/tilde' && .TH TILDE 1 "December 31, 1989" .UC 4 .SH NAME tilde \- returns a user's home directory. .SH SYNOPSIS .B tilde user .SH DESCRIPTION This merely prints a user's home directory, or "Error" if not found. Named for the Csh feature. FOO_BAR chmod 0600 beta/docs/tilde || echo 'restore of beta/docs/tilde failed' Wc_c="`wc -c < 'beta/docs/tilde'`" test 230 -eq "$Wc_c" || echo 'beta/docs/tilde: original size 230, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= beta/docs/warnings ============== if test -f 'beta/docs/warnings' -a X"$1" != X"-c"; then echo 'x - skipping beta/docs/warnings (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting beta/docs/warnings (Text)' sed 's/^X//' << 'FOO_BAR' > 'beta/docs/warnings' && X X This file contains a list of most of the security warnings that you might see while using the COPS system. Not included here are messages that you may receive from the Kuang system and the ftp checker. For help on using those tools, read the appropriate documentation on each of those ("kuang.doc" and "ftp.1".) X X First, I'll define some arbitrary terms which I'll use when describing any problems you may encounter, then I'll list the messages, what they may mean, and how you can change your system to eliminate any danger posed. Some almost identical warnings were eliminated from the list; however most warnings should have an analogous entry that is very close syntactically to it in this file. All messages in COPS are prepended by "Warning!"; this has been excluded here for brevity. X X There may be more than one way to overcome any problem listed here. If you are unsure about whether to change a problem, try looking at some of the references listed at the end of the technical report (cops.report) for more information on how an attacker may compromise your system. Some of the more dangerous security holes include writable directories and key files (such as /etc/passwd), root owned SUID files writable to world or that give a root shell, null passwords, and writable files that are executed by root. They are more or less aranged in like groups (all the writable files/dirs/ whatever in one part, etc.) X X Don't take everything that COPS says as gospel! What may be a serious security hole on one machine may not be on your own, and vice-versa. However, the more you value the information on your machine, the more you should be concerned about security. X X Some terms I'll use: xyz -- An arbitrary number. Usually a line number in a file. foo_file -- stands for a file you might see in your warning message. foo_file2 -- Same as "foo_file", stands for a different file than the X first (used when two filenames are needed in one message.) foo_dir -- a typical directory. Group file -- /etc/group or the yellow pages group. If the warning starts X with "Group", it is the former, "YGroup" is the latter. foo_group -- either /etc/group or ygroup. Password file -- /etc/passwd or the yellow pages password. If the warning X starts with "Password", it is the former, "YPassword" refers X to the latter. foo_pass -- either /etc/passwd or ypasswd. cron_file -- will be either /usr/cron or X /usr/spool/cron/crontabs/foo_file. foo -- anything that doesn't fit above. Usually an arbitrary X name, or group name, or whatever. bar -- As "foo", if more than one name is needed in one message. foo_bar -- As "foo", if more than two names are needed in one message. X X X WARNING MESSAGES X ----------------- X 0) foo_file is _World_ writable! foo_file is group readable! X X This simply means that a file is world writable; e.g. Anyone can modify or delete this file. This can be especially bad if the file can (even indirectly) give root access, such as the system password file, "/etc/passwd". X To fix, type: X chmod a-w foo_file This removes write access for group "all/world". X 1) foo_file (in cron_file) is World writable!" File foo_file (inside root executed file foo_file2) is _World_ writable!" File foo_file (in /etc/rc*) is _World_ writable!" X X Similar to the above messages, but potentially more serious. Files in this group are being used by root, and either being utilized as input, output, or for execution. Examine the file they are inside and see how it is being used. Files being executed are the most dangerous because if they are changed, the new file gets executed with root privileges. Input files are next, because changing them can alter what the executing program does and cause undesirable side affects. Even output files can be dangerous, however, because they may be used as an output or even as a program file later on. X To fix, either delete the reference to foo_file inside the cron/rc*/foo_file2/whatever file, or type: X chmod a-w foo_file to remove write access for group "all/world". X 2) Directory foo_dir is _World_ writable! X X This simply means that a directory (or it's parent directories) is world writable; e.g. Anyone can delete this directory, as well as mess with the files and subdirectories inside of it. For instance, if /usr/spool is world writable, even if cron is not writable, this is a problem, because the cron directory can be replaced and new crontab files put in (which all run with root privileges.) As a general rule, if you wish to have a file or directory secure, all directories that are parent directories must be secure. X To fix, type: X chmod a-w foo_dir X and/or X chmod a-w [foo_dir's parent directory] This removes write access for group "all/world". X 3) Directory foo_dir is _World_ writable and in roots path! X X This is the same as (2), but the directory was found to be in the path variable set either in /.login or /.profile. This is a bad thing because if it is writable, a trojan horse can be placed there, and root will execute the command. See also (23). X 4) Duplicate Group(s) found in foo_group: X X This means that one or more duplicate group names have been found. This is mostly a system accounting problem; when adding or deleting names from a group you will have problems. X To fix, remove all but one instance of each group in your /etc/group file. X 5) Group foo_bar has duplicate user(s): X X Similar to (4), a group has the same user listed more than once. If all instances of the user is not deleted, they probably will remain with their old privileges. X To fix, remove all but one instance of a user in each group of your /etc/group file. X 6) Group file, line xyz, non-numeric group id: foo X X Group id's must be numeric. Testing a non-numeric id will give unpredictable results. X To fix, change the old id to a valid group id. X 7) Group file, line xyz, is blank X X To fix, remove all blank lines. X 8) Group file, line xyz, does not have 4 fields: foo X X More trouble. Testing of one or more of the groups will result in invalid results, depending which is the missing field(s). X To fix, ensure group has four valid fields. X 9) Group file, line xyz, nonalphanumeric user id: foo X X As (6). X To fix, change the old id to a valid group id. X 10) Group file, line xyz, group has password: foo X X To fix, change the old password to an asterisk ("*"). X 11) Password Problem: Guessed: foo shell: bar passwd: foo_bar X X If an account has a guessed password, it is susceptible to other password guessing programs (the one in COPS is rather crude and slow). Obviously, if the password is known, the account is compromised. X To fix, either have the user change her/his password or change it yourself. X 12) Password Problem: null passwd: foo shell: bar Password file, line xyz, no password: foo X X If an account has no password, anyone can log into the account at will. X To fix, either have the user change her/his password or change it yourself. X 13) Duplicate uid(s) found in foo_passwd: X X This is a problem, especially if the accounts have different permissions or privileges. When the user's account is deleted, one or more accounts may remain active. X To fix, simply delete all but one occurrence of the users account. X 14) Password file, line xyz, user foo has uid = 0 and is not root bar X X Ideally, no one but root should have uid = 0. Anyone with uid=0 is superuser, for all purposes. Occasionally, a maintenance account has uid=0, or perhaps a small group of administrators. Be very careful! X To fix, change the uid from 0 to some other valid number. If the account or person really needs root privileges, have them su to the root account so you can keep track of who is using root. X 15) Password file, line xyz, nonalphanumeric login: foo X X Another maintenance problem. Someone's been messing with the password file, or you have some bugs in your software that fools around with it. X To fix, delete or change the login to a valid login. X 16) Password file, line xyz, invalid login directory: foo User foo's home directory bar is not a directory! X X A user has a non-existent or invalid login directory listed in the password file. Sometimes these are maintenance accounts, but it is discouraged. Examine the account to see if it should really exist. X To fix, either delete the account or put in a valid login directory. X 17) Password file, line xyz, nonnumeric group id: foo Password file, line xyz, nonnumeric user id: foo X X A user has a invalid user or group id. Dangerous if, when checked, it translates to invalid number (who knows what would happen), or worse yet, 0. X To fix, change the field to a legal, numeric value. X 18) Password file, line xyz, negative user id: foo X X A user id is negative. This is most common with user name "nobody", and with an id of "-2". This can be dangerous, especially if you are running a Sun, with 4.xx SunOS. It is uncertain if it is dangerous for other versions or machines. Changing it to 32767 is the usual course of action. X 19) Password file, line xyz, does not have 7 fields: foo X X Dangerous, because when a program checks for a field value it will come up with who knows what. X To fix, ensure all fields have legal values. X 20) Password file, line xyz, is blank X X To fix, delete all blank lines. This can be very bad, because a blank line can give a uid=0 account with no password. X 21) NFS file system foo exported with no restrictions. X X Anyone can mount the file system. May or may not be a problem, but look over closely, if you value ANY of the info on it! X To fix, put in a valid list of hosts that may mount it. X 22) Root's umask set to xyz X X If root's umask is set incorrectly, any files that it creates will be have bad permissions (e.g. world writable if 000, x00, or xy0). X To fix, put a "safe" value; 077 or whatever. X 23) "." (or current directory) is in roots path! X X Trojan horses traditionally play upon having the current directory in a users path. A bad user will put a trojan horse with a the same name as a common system command ("ls" is a favorite) and place it in a location that s/he thinks might be executed. When the trojan horse is executed, it will not only execute the command, but will also either steal your account privileges or have your account perform some action that they desire. X 24) A "+" entry in foo_file! X X Host.equiv files specify which machines are equivalent; e.g., user foo on another machine listed in your hosts.equiv can log in as user foo onto your machine. A "+" means your machine trusts everyone (I trust no one :-)), which is usually not desired, at least in these troubled times. Sun, in it's infinite stupidity, makes this the default on all of it's machines. X X To fix, either remove the "+", put in your own list of trusted machines, or delete the file. X 25) rexd is enabled in foo_file! X X This can allow commands to be excecuted remotely. (foo_file is usually /etc/inetd.conf, of course.) X X To fix, comment it out of foo_file (put a "#" sign in front of the line.) X 25) User foo's home directory foo_dir is mode xyz! X X If a user's home directory is writable, you have the same problems as (3), except all of the user's files are in jeopardy this time. X X To fix, type: X chmod a-w foo_dir X 26) User foo: .bar is mode xyz! X X In this case, ".bar" stands for one of the user's initialization files, such as .login, .profile, .exrc, ect. If the user's file is world writable, then anyone can modify that file, and whenever the user logs in or executes a command (such as "vi", when referring to ".exrc"), they will execute whatever commands the bad girl/boy wants them to. X X To fix, type: X chmod a-w foo_file X 27) tftp is enabled on foo_host! X X This means that people can steal your password file remotely, and run a password cracking program on it. Bad news, unless you _really_ have great password security, or you're running shadowpasswords. But even then, they can still steal any world readable file on your system. X X To fix, comment out (put a pound sign ("#") in the front of the line) tftp -- usually a line in your /etc/inetd.conf file. X 28) uudecode is enabled in foofile! X X If the decode mail alias is a valid mail address, people can mail to it, and create files on your system. If the uudecode is SUID root, or something equally insane, it can overwrite any file. X X To fix, comment out the alias in your (usually /usr/lib/alias) mail alias file. X 29) uudecode creates setuid files! X X A common problem, it seems. Uudecode should not create any kind of special files; if combined with (30), you can create hidden SUID files, perfect for an attacker. If combined with (28), then it can be an even worse remote attack. X 30) uudecode is suid! X X Worse and worse. If this is true, then you can create files that are owned by whomever it is SUID to. X X To fix, just make it non-suid. If it has to be suid for some unknown reason, make it SUID to user nobody, or guest, or something relatively inoccuous, even though it won't be. X 31) ROOT owned SUID file foo_file is type: foo_type! X X No root owned SUID file should be anything other than an executable binary; however, since this test depends on the "file" command, it may get confused, especially when using NFS, since, for example, a Sun won't recognize a MIPS executable binary as such. In any case, examine all SUID root files *very* carefully. And under *no* circumstance should it be a shell script. No, no, no. X 32) User: foo SUID file is type: foo_type! X X As (31), but possibly less severe. X FOO_BAR chmod 0600 beta/docs/warnings || echo 'restore of beta/docs/warnings failed' Wc_c="`wc -c < 'beta/docs/warnings'`" test 13863 -eq "$Wc_c" || echo 'beta/docs/warnings: original size 13863, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= beta/docs/root.chk ============== if test -f 'beta/docs/root.chk' -a X"$1" != X"-c"; then echo 'x - skipping beta/docs/root.chk (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting beta/docs/root.chk (Text)' sed 's/^X//' << 'FOO_BAR' > 'beta/docs/root.chk' && .TH ROOT.CHK 1 "Jan 4, 1991" .UC 4 .SH NAME root.chk \- Checks contents of root owned startup files as well as a variety of miscellaneous potential dangers. .SH SYNOPSIS .B root.chk .SH DESCRIPTION .I root.chk This checks the paths inside root's startup files for the current directory being used as a valid path and for improper umask settings (world writable). Also checks to see if /bin, /etc, /.login, /.cshrc, /.rhosts, and /.profile are all owned by root. .SH FILES .EX 0 /.login /.cshrc /.profile .EE FOO_BAR chmod 0600 beta/docs/root.chk || echo 'restore of beta/docs/root.chk failed' Wc_c="`wc -c < 'beta/docs/root.chk'`" test 509 -eq "$Wc_c" || echo 'beta/docs/root.chk: original size 509, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= beta/docs/cron.chk ============== if test -f 'beta/docs/cron.chk' -a X"$1" != X"-c"; then echo 'x - skipping beta/docs/cron.chk (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting beta/docs/cron.chk (Text)' sed 's/^X//' << 'FOO_BAR' > 'beta/docs/cron.chk' && .TH CRON.CHK 1 "December 31, 1989" .UC 4 .SH NAME cron.chk \- Checks contents of cron file(s) for potential danger. .SH SYNOPSIS .B cron.chk .SH DESCRIPTION .I cron.chk checks pathnames and files inside the cron files for writability. It filters out all paths or files that have a /tmp, /dev/null, or /dev/*ty, plus everything after a ">"; e.g. if crontab is writing to a file it doesn't care. .PP Since cron is run with root privileges, any file that root uses as input inside the cron files or any program that root executes is potential danger. World writable files can be changed by anyone to cause a root owned process to give away unwarranted privileges. .SH FILES /usr/lib/cron /usr/spool/cron/crontabs/* .SH "SEE ALSO" is_writable(1) .SH BUGS 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. FOO_BAR chmod 0600 beta/docs/cron.chk || echo 'restore of beta/docs/cron.chk failed' Wc_c="`wc -c < 'beta/docs/cron.chk'`" test 973 -eq "$Wc_c" || echo 'beta/docs/cron.chk: original size 973, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= beta/docs/group.chk ============== if test -f 'beta/docs/group.chk' -a X"$1" != X"-c"; then echo 'x - skipping beta/docs/group.chk (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting beta/docs/group.chk (Text)' sed 's/^X//' << 'FOO_BAR' > 'beta/docs/group.chk' && .TH GROUP.CHK 1 "December 31, 1989" .UC 4 .SH NAME group.chk \- Checks group file(s) for inconsistencies. .SH SYNOPSIS .B group.chk .SH DESCRIPTION .I group.chk checks the group files -- /etc/group and ypgroup if yellow pages are being used -- for incorrect number of fields, duplicate groups, non-alphanumeric group names, blank lines, and non-numeric group id's. .SH FILES .Ps /etc/group group.chk uses the process id as a temporary file name for the ypchecking. .Pe .SH "SEE ALSO" .Ps group(5) .Pe Awk part based on _passwd_ from _The AWK Programming Language_, page 78. .SH BUGS It doesn't use the exact syntax of yellow pages to check for errors. FOO_BAR chmod 0600 beta/docs/group.chk || echo 'restore of beta/docs/group.chk failed' Wc_c="`wc -c < 'beta/docs/group.chk'`" test 654 -eq "$Wc_c" || echo 'beta/docs/group.chk: original size 654, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= beta/docs/pass_diff.chk ============== if test -f 'beta/docs/pass_diff.chk' -a X"$1" != X"-c"; then echo 'x - skipping beta/docs/pass_diff.chk (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting beta/docs/pass_diff.chk (Text)' sed 's/^X//' << 'FOO_BAR' > 'beta/docs/pass_diff.chk' && .TH PASS_DIFF.CHK 1 "Jan 4, 1991" .UC 4 .SH NAME pass_diff.chk \- Checks passwords of accounts that have changed their passwords since the last run. .SH SYNOPSIS .B pass_diff.chk [ options ] .SH DESCRIPTION .I pass_diff.chk is a front end for the .I pass.chk program. All it does is run a diff on the last password file checked, and pass the accounts with changed passwords to .I pass.chk, along with any options it is called with. It will not run .I pass.chk at all if no difference was found. .PP .SH FILES .EX 0 old_passwd passwd.diff pass.chk .EE .SH "SEE ALSO" pass.chk(1) .SH BUGS It calls .I pass.chk with the -P option in order to pass the difference from the last run. So calling .I pass_diff.chk with the -P option is pointless. FOO_BAR chmod 0600 beta/docs/pass_diff.chk || echo 'restore of beta/docs/pass_diff.chk failed' Wc_c="`wc -c < 'beta/docs/pass_diff.chk'`" test 743 -eq "$Wc_c" || echo 'beta/docs/pass_diff.chk: original size 743, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= beta/docs/user.chk ============== if test -f 'beta/docs/user.chk' -a X"$1" != X"-c"; then echo 'x - skipping beta/docs/user.chk (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting beta/docs/user.chk (Text)' sed 's/^X//' << 'FOO_BAR' > 'beta/docs/user.chk' && .TH USER.CHK 1 "Jan 4, 1991" .UC 4 .SH NAME user.chk \- Checks key files in user home directories for world writability. .SH SYNOPSIS .B user.chk .SH DESCRIPTION This checks the following "." files in all of the user home directories (it calls getpwent() to get user directories) for world writability: .EX 0 profile login emacsrc cshrc bashrc kshrc tcshrc rhosts netrc forward dbxinit distfile exrc .EE And the netrc file for readability, as well. FOO_BAR chmod 0600 beta/docs/user.chk || echo 'restore of beta/docs/user.chk failed' Wc_c="`wc -c < 'beta/docs/user.chk'`" test 481 -eq "$Wc_c" || echo 'beta/docs/user.chk: original size 481, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= beta/docs/makefile ============== if test -f 'beta/docs/makefile' -a X"$1" != X"-c"; then echo 'x - skipping beta/docs/makefile (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting beta/docs/makefile (Text)' sed 's/^X//' << 'FOO_BAR' > 'beta/docs/makefile' && # Simple Makefile for the COPS documentation # # make all -- makes everything # make <doc-name> -- make a given doc DOCS = COPS.report.ms suid.man.ms kuang.man.ms MAN = cops.1 cron.chk.1 dev.chk.1 group.chk.1 is_able.chk.1 \ X passwd.chk.1 is_able.1 home.chk.1 user.chk.1 pass.chk.1 \ X root.chk.1 rc.chk.1 pass_diff.chk.1 misc.chk.1 DOC_SOURCE = COPS.report suid.man kuang.man cops cron.chk dev.chk is_able.chk \ X dir.chk file.chk group.chk passwd.chk is_able home.chk \ X user.chk pass.chk root.chk rc.chk pass_diff.chk misc.chk ROFFLAGS = -ms X # # Where the programs are.... # NROFF=/usr/bin/nroff RM=/bin/rm -f X # make all all: $(DOCS) $(MAN) X clean: X $(RM) -f $(DOCS) $(MAN) X # 'roff out those docs COPS.report.ms: COPS.report X $(NROFF) $(ROFFLAGS) COPS.report > COPS.report.ms X kuang.man.ms: kuang.man X $(NROFF) $(ROFFLAGS) kuang.man > kuang.man.ms X suid.man.ms: suid.man X $(NROFF) $(ROFFLAGS) suid.man > suid.man.ms X cops.1: cops X $(NROFF) -man cops > cops.1 X cron.chk.1: cron.chk X $(NROFF) -man cron.chk > cron.chk.1 X dev.chk.1: dev.chk X $(NROFF) -man dev.chk > dev.chk.1 X dir.chk.1: dir.chk X $(NROFF) -man dir.chk > dir.chk.1 X file.chk.1: file.chk X $(NROFF) -man file.chk > file.chk.1 X group.chk.1: group.chk X $(NROFF) -man group.chk > group.chk.1 X passwd.chk.1: passwd.chk X $(NROFF) -man passwd.chk > passwd.chk.1 X pass.chk.1: pass.chk X $(NROFF) -man pass.chk > pass.chk.1 X is_able.1: is_able X $(NROFF) -man is_able > is_able.1 X is_able.chk.1: is_able.chk X $(NROFF) -man is_able.chk > is_able.chk.1 X home.chk.1: home.chk X $(NROFF) -man home.chk > home.chk.1 X user.chk.1: user.chk X $(NROFF) -man user.chk > user.chk.1 X root.chk.1: root.chk X $(NROFF) -man root.chk > root.chk.1 X rc.chk.1: rc.chk X $(NROFF) -man rc.chk > rc.chk.1 X pass_diff.chk.1: pass_diff.chk X $(NROFF) -man pass_diff.chk > pass_diff.chk.1 X misc.chk.1: misc.chk X $(NROFF) -man misc.chk > misc.chk.1 X # the end FOO_BAR chmod 0600 beta/docs/makefile || echo 'restore of beta/docs/makefile failed' Wc_c="`wc -c < 'beta/docs/makefile'`" test 1948 -eq "$Wc_c" || echo 'beta/docs/makefile: original size 1948, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= beta/docs/passwd.chk ============== if test -f 'beta/docs/passwd.chk' -a X"$1" != X"-c"; then echo 'x - skipping beta/docs/passwd.chk (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting beta/docs/passwd.chk (Text)' sed 's/^X//' << 'FOO_BAR' > 'beta/docs/passwd.chk' && .TH PASSWD.CHK 1 "January 7th, 1991" .UC 4 .SH NAME passwd.chk \- Checks password file(s) for inconsistencies. .SH SYNOPSIS .B passwd.chk .SH DESCRIPTION .I passwd.chk checks the password files -- /etc/passwd and yppasswd if yellow pages are being used -- for incorrect number of fields, duplicate ids, non-alphanumeric login names, nonnumeric user ids', users with uid = 0 and not root, blank lines, accounts with no passwords, invalid login directories, and non-numeric password id's. If you run C2 sun security, or have uid's of greater than length 8 characters, you need to change "C2=TRUE" and "OVER_8=YES", on lines 46 and 50, respectively. .SH FILES .Ps /etc/passwd passwd.chk uses the process id as a temporary file name for the ypchecking. .Pe .SH "SEE ALSO" .Ps passwd(5) .Pe Awk part based on _password_ from _The AWK Programming Language_, page 78. .SH BUGS It doesn't use the exact syntax of yellow pages to check for errors. FOO_BAR chmod 0600 beta/docs/passwd.chk || echo 'restore of beta/docs/passwd.chk failed' Wc_c="`wc -c < 'beta/docs/passwd.chk'`" test 941 -eq "$Wc_c" || echo 'beta/docs/passwd.chk: original size 941, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= beta/docs/misc.chk ============== if test -f 'beta/docs/misc.chk' -a X"$1" != X"-c"; then echo 'x - skipping beta/docs/misc.chk (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting beta/docs/misc.chk (Text)' sed 's/^X//' << 'FOO_BAR' > 'beta/docs/misc.chk' && .TH MISC.CHK 1 "Jan 4, 1991" .UC 4 .SH NAME misc.chk \- Checks contents of root owned startup files as well as a variety of miscellaneous potential dangers. .SH SYNOPSIS .B misc.chk .SH DESCRIPTION .I misc.chk This shell script checks a variety of miscellaneous potential security problems that really don't belong anywhere else. Currently, it looks for to see if tftp & rexecd are enabled, checks if the uudecode alias is in the mail alias file and not commented out, and if uudecode is either SUID, or can produce SUID files. .SH FILES .EX 0 /etc/motd /etc/inetd.conf /usr/lib/aliases .EE FOO_BAR chmod 0600 beta/docs/misc.chk || echo 'restore of beta/docs/misc.chk failed' Wc_c="`wc -c < 'beta/docs/misc.chk'`" test 593 -eq "$Wc_c" || echo 'beta/docs/misc.chk: original size 593, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= beta/docs/ftp.chk ============== if test -f 'beta/docs/ftp.chk' -a X"$1" != X"-c"; then echo 'x - skipping beta/docs/ftp.chk (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting beta/docs/ftp.chk (Text)' sed 's/^X//' << 'FOO_BAR' > 'beta/docs/ftp.chk' && X This shell script checks to see if you've set up (mainly anonymous) ftp correctly. The "-a" option checks your anon-ftp setup; without that, this script doesn't do a whole lot -- just check to see if your ftpusers file doesn't have any root accounts in it. X There is no "right" way to set up ftp, but there are lots of wrong ways :-) I suggest everything be owned by either root or ftp, everthing important owned by root only, especially if you have the "chmod" command in your version of ftp. Nothing should be world writable, with the exception of a ~ftp/incoming directory or something like that (if desired). You can change the owners via the $primary and $secondary variables (default root), and the publically writable directory is $incoming (default ~ftp/incoming). Do not make ~ftp/pub world writable, if you are storing data or programs for people to use; you're inviting intruders to write all over the files and programs, and leave all kinds of nasties... X Here are the assumptions I made for anon-ftp: X o If your system allows the "chmod" command, you should not let _anything_ X be owned by ftp. In general, it's probably a good idea to not have anything X be owned by ftp anyway. X o User "ftp" should have a non-valid password ("*", whatever) and a invalid X shell, but a valid home directory -- this is where all the anonymous X stuff gets stashed. This checks for the passwd and valid home dir only. X I would suggest a .rhosts file of 0 size, owned by root, but that's X personal preference. This will complain if a .rhosts file exists, and X is either non-0 or non-root owned. X o All root equivalent accounts (uid=0) with valid passwords should be in X /etc/ftpusers X o The home dir for ftp is in /etc/passwd, should be a valid directory, and X should not be "/" (if the dir is invalid, ftpd should choke.) X o The ~ftp/etc/{passwd|group} files should be different than their X counterparts in /etc (don't want password files available via anon-ftp.) X In addition, it seems as though the entries in ~ftp/etc/{passwd|group} X files don't do a whole lot -- some versions of ftp seem to use the X passwords in the file, some don't. If a file is created, you might see X something like: X X With the entries: X drwxr-xr-x 8 cert ftp 512 Nov 7 16:56 pub/ X Without: X drwxr-xr-x 8 8001 105 512 Nov 7 16:56 pub/ X X Some versions of ftpd allow you to leave the files off entirely; that X is the preferred method, IMHO; else, you might try putting a null file X there. Experiment... you can uncomment line 178: X X crit_files=$ftpls X X And the checker won't look for password and group files. X o ~ftp, ~ftp/bin, ~/ftp/etc should all be non-world-writeable, and owned X by either root or ftp. The ls command should be mode 111, the password X and group files 444. X FOO_BAR chmod 0600 beta/docs/ftp.chk || echo 'restore of beta/docs/ftp.chk failed' Wc_c="`wc -c < 'beta/docs/ftp.chk'`" test 2838 -eq "$Wc_c" || echo 'beta/docs/ftp.chk: original size 2838, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= beta/extensions/THINGS_2_DO ============== if test ! -d 'beta/extensions'; then echo 'x - creating directory beta/extensions' mkdir 'beta/extensions' fi if test -f 'beta/extensions/THINGS_2_DO' -a X"$1" != X"-c"; then echo 'x - skipping beta/extensions/THINGS_2_DO (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting beta/extensions/THINGS_2_DO (Text)' sed 's/^X//' << 'FOO_BAR' > 'beta/extensions/THINGS_2_DO' && X X Possible improvements/extensions of the COPS package might (will?) include (other than merely fixing bugs existing in the package) : X X 0) Smarter detection of problems -- a lot of problems can be found in configuration files; the way they are set up, not merely if they are writable. These aren't neccessarily hard to check for, but take someone with a good understanding for the file to write. X X 1) Detecting Bugs. A very touchy subject, with so many sites without source code to fix the bugs. Depends a lot on how people react to this package, and what the demand is for a package that finds bugs. It would be similar to the approach used in the rest of the package in that it would point out the bugs, not tell how to exploit them. For instance, an example would be "Warning! fingerd bug present!" X X 2) Better and more thorough Yellow Pages checking. X X 3) Ditto for UUCP stuff. X X 4) Once again for NFS things. X X 5) Problems that are specific to a certain flavor of UNIX. For instance, HP-UX has different files in different places. Perhaps the system could look for and hunt for the vital files in the various places rather than having to be put in a configuration file. Also support for various secure UNIX varieties; e.g. C2 level Sun, IBM's secure AIX, etc. X X 6) More problems to be added; by no means are all security problems detected by COPS. More potential hazards should not be difficult to detect -- merely adding another module to the system or simply modifying what is here might suffice. X X 7) Trying to detect what kind of machine you are on, then acting on that, possibly using larry wall's configure program. FOO_BAR chmod 0600 beta/extensions/THINGS_2_DO || echo 'restore of beta/extensions/THINGS_2_DO failed' Wc_c="`wc -c < 'beta/extensions/THINGS_2_DO'`" test 1638 -eq "$Wc_c" || echo 'beta/extensions/THINGS_2_DO: original size 1638, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= beta/extensions/YAR ============== if test -f 'beta/extensions/YAR' -a X"$1" != X"-c"; then echo 'x - skipping beta/extensions/YAR (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting beta/extensions/YAR (Text)' sed 's/^X//' << 'FOO_BAR' > 'beta/extensions/YAR' && X X X (YAR -- Yet Another README file) X X This is where the odds 'n ends go. X "THINGS_2_DO" is a file that says what I'd like to see done, either in COPS or in other packages. X "questions" is a questionaire and some answers I recieved about computer security. It might prove of interest for general reading. X "netstuff" is a short list of net.references for further information. X "passwords" gives a reference for Matt Bishop's replacement passwd program, and his fast password cracker. X "crypto-stuff" tells you where you can get some programs to do secure digital signatures. FOO_BAR chmod 0600 beta/extensions/YAR || echo 'restore of beta/extensions/YAR failed' Wc_c="`wc -c < 'beta/extensions/YAR'`" test 595 -eq "$Wc_c" || echo 'beta/extensions/YAR: original size 595, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= beta/extensions/crypto-stuff ============== if test -f 'beta/extensions/crypto-stuff' -a X"$1" != X"-c"; then echo 'x - skipping beta/extensions/crypto-stuff (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting beta/extensions/crypto-stuff (Text)' sed 's/^X//' << 'FOO_BAR' > 'beta/extensions/crypto-stuff' && X FOO_BAR true || echo 'restore of beta/extensions/crypto-stuff failed' fi echo 'End of part 4' echo 'File beta/extensions/crypto-stuff is continued in part 5' echo 5 > _shar_seq_.tmp exit 0