• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

COPS.reportH A D27-Mar-199231.1 KiB690687

COPS.texH A D27-Mar-199230.2 KiB656567

CRC.READMEH A D27-Mar-19924.2 KiB8769

KUANG.READMEH A D27-Mar-1992886 2517

SUID.READMEH A D27-Mar-1992501 149

bug.chkH A D25-Mar-19932.6 KiB7473

copsH A D27-Mar-19924.2 KiB142141

cron.chkH A D27-Mar-1992969 2827

dev.chkH A D27-Mar-1992789 3534

ftp.chkH A D27-Mar-19922.9 KiB7573

group.chkH A D27-Mar-1992662 2625

home.chkH A D27-Mar-1992270 109

is_ableH A D25-Mar-19931.1 KiB2726

is_able.chkH A D27-Mar-1992983 3736

is_writableH A D27-Mar-1992665 2625

kuang.1H A D27-Mar-19922.7 KiB6456

kuang.manH A D27-Mar-199235.7 KiB848830

makefileH A D27-Mar-19922.1 KiB9457

misc.chkH A D27-Mar-1992696 2524

obligatory.albumH A D27-Mar-1992226 63

obligatory.jokeH A D27-Mar-1992885 1915

pass.chkH A D27-Mar-19921.7 KiB6766

pass_diff.chkH A D27-Mar-1992745 3837

passwd.chkH A D27-Mar-1992943 2726

rc.chkH A D27-Mar-1992782 2827

readme.C2H A D25-Mar-199320.1 KiB684677

readme.apolloH A D27-Mar-19921.7 KiB6243

readme.cfilterH A D27-Mar-19925 KiB12791

readme.filtersH A D27-Mar-19921.6 KiB3325

readme.ibmH A D27-Mar-1992322 106

readme.sequentH A D27-Mar-1992207 94

readme.shadowH A D27-Mar-19922.7 KiB8875

readme.svr4H A D27-Mar-1992102 63

readme.xenixH A D27-Mar-1992720 2918

readme.ypH A D27-Mar-1992591 1610

release.notesH A D27-Mar-19924.9 KiB133105

root.chkH A D27-Mar-1992521 2120

suid.manH A D27-Mar-19921.8 KiB8382

tildeH A D27-Mar-1992230 1110

user.chkH A D27-Mar-1992508 2019

warningsH A D27-Mar-199216.1 KiB432328

CRC.README

1
2  This README.suid and everything but the C programs has been hacked up be
3me, so all problems you have are probably due to me, unless you can't compile
4the files.  Then blame Jon :-)
5
6  This checks for unexpected file system corruption or security breaches.
7It's nice to be able to say that you know all your files are as they should
8be.  Mark Mendel wrote most of crc.c and Jon Zeef wrote crc_check.c.  Seems
9to work fine on BSD or SYS V.
10
11To use it:
12
131) You first create a crc list with the script "crc.chk", which takes one
14argument, the seed for the crc generator.  It reads the file "crc_list"
15for a list of files to check; what I have are some of the more interesting
16binaries, but you can add or delete from this list to your hearts content.
17Wildcards or specific file names are fine.  The first time you run it,
18it will create a file called "crc.files", which contains all the crc
19values you generated.  Optionally, you can do a:
20
21find / -mount -print | sort | xargs ./crc -v > crc.tmp
22
23  However, "xargs" is a security problem, when combined with find.  Use
24this judiciously, if at all, unless your vendor puts some "safe" options
25to find in.
26
272) You can now use "crc.chk" to compare this "crc.files" file to a crc list
28created each time you run the shell program.  If everything is ok, nothing
29is outputted, otherwise, the results are either mailed to the user INFORM,
30on line xxx, or saved to a file "crc.results".  You *MUST* use the same
31seed each time you run the program, or the numbers generated will be
32different each time you run the program, which kind of makes it useless.
33
34IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT
35IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT
36IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT
37
38  Have I got your attention?  Good.  There are some fundamental problems
39with using a crc program like this.  *If* you use a seed that is hardcoded
40in the program, or no seed at all, this is *bad*.  That means to really
41use this program usefully, you can't run it in crontab, like the rest
42of COPS.  Even worse, you should really store the results offline, since
43anyone who breaks into your machine can modify a binary file, run the
44crc checker again, then put the new values in your file.  That's the
45right way.  But I know that most of you won't do this, so by default,
46"crc.chk" just stores everything like everything else, in the COPS secure
47directory.  It can still help you, if the attacker doesn't know where
48you keep stuff, or doesn't know enough to trash your database of old
49crc values.  If nothing else, be sure that you keep your older values
50on tape or secondary medium, so when your system gets kicked around a
51bit, you can grab the crc program off the tape (the intruder could modify
52that, too, you know), run it on your binaries, and finally compare it
53to your old values.  Believe me, this is a lot easier, though still not
54perfect, than reloading everything on your system from tape, then still
55not knowing.  I've put it in the "cops" shell script, but left it commented
56out, on line 123, so if you want to use it this way, just uncomment this
57line.
58  One thing you can do, if you keep the numbers online, is do a crc on the
59file of values you keep; write it down, or memorize it, then if it is ever
60tampered with, you can detect it.
61
62  Jon goes on about the initial crc value, and other stuff:
63
64=========================================================================
65  ... don't tell anyone what this is, you can
66  make it nearly impossible for anyone to modify a file in such a way
67  that it has the same crc value as the old one (primarily because they
68  don't know what the old one was).  If anyone does discover a way to
69  make files of the same size that produce the same unknown crc value
70  for any unknown -i value, let me know.
71
72  To really do it right, you need to
73
74  1) Run find_crc in single user mode (unless you modify the crc source).
75  2) Store all crc results offline.
76  3) Don't let anyone see your -i value or the crc results.
77
78  Please send me any modifications you make.
79
80  Jon Zeeff
81  zeeff@b-tech.ann-arbor.mi.us
82=========================================================================
83
84  Send 'em to me, too!
85
86 -- dan
87

KUANG.README

1
2  The U-Kuang system is currently setup in a minimum configuration; e.g.
3it assumes only that world modes/permissions are to be used.  To fully
4use the system, if the password checkers and the home-directory checker
5come back with any positive results (i.e. with an account that can be
6broken), modify the init_kuang file to reflect this.
7  To use this system to it's full capabilities, be sure to read the
8manual, kuang.man.ms.
9
10This directory contains the various programs and shell scripts
11that make up the Kuang security checking system.
12
13The file, kuang.man.1, documents the system in the style of a UNIX
14manual page.  The file, kuang.mss, is a draft of a paper on
15this system.
16
17
18To run the system:
19
200. Execute 'make' to build the programs.
211. Read kuang.man.1
222. Modify the file, init_kuang, to set the initial set of privileges.
233. Execute "sh kuang" (or run the COPS system.)
24
25

SUID.README

1Findsuid is a little utility we dreamt up to watch for potential Trojan horse
2programs by keeping an eye on our suid and sgid files and telling us when
3they change unexpectedly.
4
5We run it using the following line in crontab:
6
7	40 3 * * * /etc/findsuid/findsuid >/etc/findsuid/fserror 2>&1
8
9Included here is the findsuid shell script, a man page, a makefile, and a
10sample "stop" file.
11
12--- Prentiss Riddle ("Aprendiz de todo, maestro de nada.")
13--- {ihnp4,harvard,seismo,gatech,ctvax}!ut-sally!riddle
14

readme.C2

1
2  A letter I got with source... I've never had the time to add this stuff
3in officially.  Maybe next release?  Also, to crack C2 passwords on a
4Sun, compile pass.c with the C2 defined (e.g. -DC2), and run the cracker
5as root.
6
7========================================================================
8
9Dan,
10
11  Please find enclose four (4) files: passwd.chk, passwd.file.chk, group.chk,
12and group.file.chk. These are the files to allow checking of the Sun C2
13security variations of SunOS. They will perform checking of the yellow pages
14version if so selected by the TEST_YP variable being TRUE in the passwd.chk
15and group.chk files. The testing of the SUN C2 security is performed by setting
16the SUN_SECURITY variable to TRUE in the passwd.chk and group.chk files.
17
18Pete Troxell
19
20#!/bin/sh
21# This is a shell archive (produced by shar 3.49)
22# To extract the files from this archive, save it to a file, remove
23# everything above the "!/bin/sh" line above, and type "sh file_name".
24#
25# made 04/10/1992 21:10 UTC by zen@death
26#
27# existing files will NOT be overwritten unless -c is specified
28#
29# This shar contains:
30# length  mode       name
31# ------ ---------- ------------------------------------------
32#   1613 -rwx------ group.chk
33#   6191 -rwx------ group.file.chk
34#   1654 -rwx------ passwd.chk
35#   7715 -rwx------ passwd.file.chk
36#
37# ============= group.chk ==============
38if test -f 'group.chk' -a X"$1" != X"-c"; then
39	echo 'x - skipping group.chk (File already exists)'
40else
41echo 'x - extracting group.chk (Text)'
42sed 's/^X//' << 'SHAR_EOF' > 'group.chk' &&
43#!/bin/sh
44#
45#   group.chk
46#
47#  Check group file -- /etc/group -- for incorrect number of fields,
48# duplicate groups, non-alphanumeric group names, and non-numeric group
49# id's.
50#
51ECHO=/bin/echo
52RM=/bin/rm
53TEST=/bin/test
54YPCAT=/usr/bin/ypcat
55X
56#
57# Enhanced Security Features addes by Pete Troxell:
58#
59#   Used for Sun C2 security group file.  FALSE (default) will flag
60# valid C2 group syntax as an error, TRUE attempts to validate it. When
61# using this option the script must be executed as root or su since the file
62# /etc/security/group.adjunct is read protected from everybody except root.
63#
64SUN_SECURITY=FALSE
65X
66#
67# Enable/Disable testing of the Yellow Pages group file(s)
68#
69TEST_YP=FALSE
70X
71#
72# Important files:
73#
74etc_group=/etc/group
75etc_secure_group=/etc/security/group.adjunct
76yp_group=./grp$$
77yp_secure_group=./sgrp$$
78X
79yp=false
80yp_secure=false
81X
82#
83# Testing $yp_group for potential problems....
84#
85if $TEST -f $YPCAT -a $TEST_YP = "TRUE"
86X	then
87if $TEST -s $YPCAT
88X	then
89X	$YPCAT group > $yp_group 2>/dev/null
90X	if $TEST $? -eq 0
91X		then
92X		yp=true
93X	fi
94X	if $TEST $yp = "true" -a $SUN_SECFURITY = "TRUE"
95X		then
96X		$YPCAT -t group.adjunct.byname > $yp_secure_group 2>/dev/null
97X		if $TEST $? -eq 0
98X			then
99X			yp_secure=true
100X		fi
101X	fi
102fi
103fi
104X
105#
106# Test the system group file
107#
108./group.file.chk $etc_group $etc_secure_group $SUN_SECURITY
109X
110#
111# Test yellow pages password file
112#
113if $TEST "$yp" = "true"
114X	then
115X	$ECHO
116X	$ECHO "***** Testing the Yellow Pages password file(s) ******"
117X	$ECHO
118X	./group.file.chk $yp_group $yp_secure_group $SUN_SECURITY
119X	fi
120X
121#
122# Clean up after ourselfs
123#
124$RM -f $yp_group
125$RM -f $yp_secure_group
126# end
127SHAR_EOF
128chmod 0700 group.chk ||
129echo 'restore of group.chk failed'
130Wc_c="`wc -c < 'group.chk'`"
131test 1613 -eq "$Wc_c" ||
132	echo 'group.chk: original size 1613, current size' "$Wc_c"
133fi
134# ============= group.file.chk ==============
135if test -f 'group.file.chk' -a X"$1" != X"-c"; then
136	echo 'x - skipping group.file.chk (File already exists)'
137else
138echo 'x - extracting group.file.chk (Text)'
139sed 's/^X//' << 'SHAR_EOF' > 'group.file.chk' &&
140#!/bin/sh
141#
142#   group.file.chk
143#
144# Awk part based on _passwd_ from _The AWK Programming Language_, page 78
145#
146#   Mechanism:  Group.check uses awk to ensure that each line of the group
147# has 4 fields, as well as examining each line for any duplicate groups or
148# any duplicate user id's in a given group by using "sort -u" to ferret
149# out any duplications.  It also checks to make sure that the password
150# field (the second one) is a "*", meaning the group has no password (a
151# group password is usually not necessary because each member listed on
152# the line has all the privilages that the group has.)  All results are
153# echoed to standard output.  Finally it ensures that the group names
154# are alphanumeric, that the group id's are numeric, and that there are
155# no blank lines.  For yellow pages groups, it does the same checking,
156# but in order to get a listing of all members of the groups, it does a
157# "ypcat group > ./$$" and uses that temporary file for a groupfile.
158# It removes the tmp file after using it, of course.
159#   The /etc/group file has a very specific format, making the task
160# fairly simple.  Normally it has lines with 4 fields, each field
161# separated by a colon (:).  The first field is the group name, the second
162# field is the encrypted password (an asterix (*) means the group has no
163# password, otherwise the first two characters are the salt), the third
164# field is the group id number, and the fourth field is a list of user
165# ids in the group.  If a line begins with a plus sign (+), it is a yellow
166# pages entry.  See group(5) for more information.
167#   The SUN /etc/security/group.adjunct file also has a very specific
168# format, makeing the check task simple. Each entry has 2 fields separated
169# by a colon (:). THe first field is the user name which matches the user
170# name contained in the /etc/group file. The second field is the encrypted
171# password (an asterix (*) means the group has no password, otherwise the
172# first two characters are the salt). The password contained in the
173# /etc/group file is comprised of the #$user_id where the user_id matches
174# the entry of the first field in both group files.
175#
176X
177#
178# Parameters
179#
180group_file=$1
181group_adjunct_file=$2
182SUN_SECURITY=$3
183X
184#
185# Utilities
186#
187AWK=/bin/awk
188DIFF=/usr/bin/diff
189ECHO=/bin/echo
190JOIN=/usr/bin/join
191RM=/bin/rm
192SORT=/usr/bin/sort
193TEST=/bin/test
194UNIQ=/usr/bin/uniq
195X
196#
197# Important files:
198#
199join_group_1=./grp$$.1.join
200join_group_2=./grp$$.2.join
201sort_group=./grp$$.sort
202sort_secure_group=./sgrp$$.sort
203X
204#
205# Testing the group file for problems
206#
207result=`$AWK -F: '{print $1}' $group_file | $SORT |$UNIQ -d`
208if $TEST "$result"
209X	then
210X	$ECHO "Warning!  Duplicate gid(s) found in group file:"
211X	for USER in $result
212X	do
213X		$ECHO "	$USER"
214X	done
215fi
216X
217#
218#   First line is for a yellow pages entry in the group file.
219# It really should check for correct yellow pages syntax....
220#
221$AWK 'BEGIN {FS = ":" } {
222X	if (substr($1,1,1) != "+") { \
223X	if ($0 ~ /^[ 	]*$/) { printf("Warning!  Group file, line %d, is blank\n", NR) } else {
224X	if (NF != 4) { printf("Warning!  Group file, line %d, does not have 4 fields: \n\t%s\n", NR, $0) } \
225X	if ($1 !~ /[A-Za-z0-9]/) {
226X		printf("Warning!  Group file, line %d, nonalphanumeric user id: \n\t%s\n", NR, $0) } \
227X	if ($2 != "" && $2 != "*") {
228X		if ("'$SUN_SECURITY'" != "TRUE")
229X			printf("Warning!  Group file, line %d, has password: \n\t%s\n", NR, $0)
230X		else {
231X			if ("#$"$1 != $2)
232X				printf("Warning!  Group file, line %d, invalid password field for SUN C2 Security: \n\t%s\n", NR, $0) } \
233X		} \
234X	if ($3 !~ /[0-9]/) {
235X		printf("Warning!  Group file, line %d, nonnumeric group id: \n\t%s\n", NR, $0) \
236X	}}}} ' $group_file
237X
238#
239# Ignore all groups with less than two members.
240#
241awk -F: '
242X	split($4, users, ",") > 1 {
243X		ct = 0
244X		for (i in users) {
245X			curuser = users[i]
246X			for (j in users) {
247X				if (j > i && curuser == users[j]) {
248X					if (ct++ == 0) print "Warning!  Group "$1" has duplicate user(s):"
249X					print curuser
250X				}
251X			}
252X		}
253X	}
254X	' $group_file
255X
256#
257# Perform checks on the security enhanced version of SUNOS
258#
259if $TEST $SUN_SECURITY = "TRUE"
260X	then
261X	result=`$AWK -F: '{print $1}' $group_adjunct_file | $SORT -t: | $UNIQ -d`
262X	if $TEST "$result"
263X		then
264X		$ECHO
265X		$ECHO "Warning!  Duplicate uid(s) found in group adjunct file:"
266X		for USER in $result
267X		do
268X			$ECHO "	$USER"
269X		done
270X	fi
271X	#
272X	# Check that for each entry in the group file that there is a matching
273X	# entry in the group.adjunct file.
274X	#
275X	$SORT -t: -o $sort_group $group_file
276X	$SORT -t: -o $sort_secure_group $group_adjunct_file
277X	$JOIN -t: $sort_group $sort_secure_group > $join_group_1
278X	$JOIN -t: -a1 $sort_group $sort_secure_group > $join_group_2
279X	result=`$DIFF $join_group_1 $join_group_2`
280X	if $TEST "$result"
281X		then
282X		$ECHO
283X		$ECHO "Warning!  Matching record(s) in group adjunct file not found for"
284X		$ECHO "these records in group file:"
285X		PREV=$$
286X		for USER in $result
287X		do
288X			if $TEST $PREV = ">"
289X				then
290X				$ECHO "	$USER"
291X			fi
292X			PREV=$USER
293X		done
294X	fi
295X	#
296X	# Check that for each entry in the group.adjunct file that there is a
297X	# matching entry in the group file.
298X	#
299X	$RM -f $join_group_2
300X	$JOIN -t: -a2 $sort_group $sort_secure_group > $join_group_2
301X	result=`$DIFF $join_group_1 $join_group_2`
302X	if $TEST "$result"
303X		then
304X		$ECHO
305X		$ECHO "Warning!  Matching record(s) in group file not found for"
306X		$ECHO "these records in group adjunct file"
307X		PREV=$$
308X		for USER in $result
309X		do
310X			if $TEST $PREV = ">"
311X				then
312X				$ECHO "	$USER"
313X			fi
314X			PREV=$USER
315X		done
316X	fi
317X	#
318X	# Test the fields in the group.adjunct file for validity
319X	#
320X	$AWK 'BEGIN {FS = ":" } \
321X		{if (substr($1,1,1) != "+") { \
322X		if ($0 ~ /^[ 	]*$/) { printf("\nWarning!  Group adjunct file, line %d, is blank\n", NR) } else {
323X		if (NF != 2) {
324X			printf("\nWarning!  Group adjunct file, line %d, does not have 2 fields: \n\t%s\n", NR, $0) } \
325X		if ($1 !~ /[A-Za-z0-9]/) {
326X			printf("\nWarning!  Group adjunct file, line %d, nonalphanumeric login: \n\t%s\n", NR, $0) } \
327X		if ($2 != "" && $2 != "*") {
328X			printf("\nWarning!  Group adjunct file, line %d, has password: \n\t%s\n", NR, $0) } \
329X		}}}' $group_adjunct_file
330fi
331X
332#
333# Clean up after ourself
334#
335$RM -f $join_group_1
336$RM -f $join_group_2
337$RM -f $sort_group
338$RM -f $sort_secure_group
339# end
340SHAR_EOF
341chmod 0700 group.file.chk ||
342echo 'restore of group.file.chk failed'
343Wc_c="`wc -c < 'group.file.chk'`"
344test 6191 -eq "$Wc_c" ||
345	echo 'group.file.chk: original size 6191, current size' "$Wc_c"
346fi
347# ============= passwd.chk ==============
348if test -f 'passwd.chk' -a X"$1" != X"-c"; then
349	echo 'x - skipping passwd.chk (File already exists)'
350else
351echo 'x - extracting passwd.chk (Text)'
352sed 's/^X//' << 'SHAR_EOF' > 'passwd.chk' &&
353#!/bin/sh
354#
355#   passwd.chk
356#
357#  Check passsword file -- /etc/passswd -- for incorrect number of fields,
358# duplicate uid's, non-alphanumeric uids, and non-numeric group id's.
359#
360#
361ECHO=/bin/echo
362RM=/bin/rm
363TEST=/bin/test
364YPCAT=/usr/bin/ypcat
365X
366#
367# Enhanced Security Features added by Pete Troxell:
368#
369#   Used for Sun C2 security password adjunct file.  FALSE (default) will flag
370# valid SUN C2 passwd syntax as an error, TRUE attempts to validate it. When
371# using this option, the script must be executed as root or su since the file
372# /etc/security/passwd.adjunct is read protected from everybody except root.
373#
374SUN_SECURITY=FALSE
375X
376#
377# Enable/Disable testing of the Yellow Pages password file(s)
378#
379TEST_YP=FALSE
380X
381#
382# Important files:
383#
384etc_passwd=/etc/passwd
385etc_secure_passwd=/etc/security/passwd.adjunct
386yp_passwd=./pwd$$
387yp_secure_passwd=./spwd$$
388X
389yp=false
390yp_secure=false
391X
392#
393# Testing $yp_passwd for potential problems....
394#
395if $TEST -f $YPCAT -a $TEST_YP = "TRUE"
396X	then
397if $TEST -s $YPCAT
398X	then
399X	$YPCAT passwd > $yp_passwd 2>/dev/null
400X	if $TEST $? -eq 0
401X		then
402X		yp=true
403X	fi
404X	if $TEST $yp = "true" -a $SUN_SECURITY = "TRUE"
405X		then
406X		$YPCAT -t passwd.adjunct.byname > $yp_secure_passwd 2>/dev/null
407X		if $TEST $? -eq 0
408X			then
409X			yp_secure=true
410X		fi
411X	fi
412fi
413fi
414X
415#
416# Test the system password file
417#
418./passwd.file.chk $etc_passwd $etc_secure_passwd $SUN_SECURITY
419X
420#
421# Test yellow pages password file
422#
423if $TEST "$yp" = "true"
424X	then
425X	$ECHO
426X	$ECHO "***** Testing the Yellow Pages password file(s) *****"
427X	$ECHO
428X	./passwd.file.chk $yp_passwd $yp_secure_passwd $SUN_SECURITY
429X	fi
430X
431#
432# Clean up after ourselfs
433#
434$RM -f $yp_passwd
435$RM -f $yp_secure_passwd
436# end
437SHAR_EOF
438chmod 0700 passwd.chk ||
439echo 'restore of passwd.chk failed'
440Wc_c="`wc -c < 'passwd.chk'`"
441test 1654 -eq "$Wc_c" ||
442	echo 'passwd.chk: original size 1654, current size' "$Wc_c"
443fi
444# ============= passwd.file.chk ==============
445if test -f 'passwd.file.chk' -a X"$1" != X"-c"; then
446	echo 'x - skipping passwd.file.chk (File already exists)'
447else
448echo 'x - extracting passwd.file.chk (Text)'
449sed 's/^X//' << 'SHAR_EOF' > 'passwd.file.chk' &&
450#!/bin/sh
451#
452#   passwd.file.chk
453#
454#  Check passsword file -- /etc/passswd -- for incorrect number of fields,
455# duplicate uid's, non-alphanumeric uids, and non-numeric group id's.
456#
457# Awk part from _The AWK Programming Language_, page 78
458#
459#  Mechanism:  Passwd.check uses awk to ensure that each line of the file
460# has 7 fields, as well as examining the file for any duplicate users
461# by using "sort -u".  It also checks to make sure that the password
462# field (the second one) is either a "*", meaning the group has no password,
463# or a non-null field (which would mean that the account has a null
464# password.)  It then checks to ensure that all uids are alphanumeric,
465# and that all user id numbers are indeed numeric.  For yellow pages
466# passwords, it does the same checking, but in order to get a listing of
467# all members of the password file, it does a "ypcat passwd > ./$$" and
468# uses that temporary file for a passfile.  It removes the tmp file after
469# using it, of course.
470#   The /etc/passwd file has a very specific format, making the task
471# fairly simple.  Normally it has lines with 7 fields, each field
472# separated by a colon (:).  The first field is the user id, the second
473# field is the encrypted password (an asterix (*) means the user id has no
474# password, otherwise the first two characters are the salt), the third
475# field is the user id number, the fourth field is the group id number,
476# the fifth field is the GECOS field (basically holds miscellaneous
477# information, varying from site to site), the sixth field is the home
478# directory of the user, and lastly the seventh field is the login shell
479# of the user.  No blank lines should be present.
480#   The SUN /etc/security/passwd.adjunct file also has a very specific
481# format, making the check task simple. Each entry has 7 fields, each field
482# separated by a colon (:). The first field is the user name which matches
483# the user name contained in the /etc/passwd file. The second field is the
484# encrypted password (an asterix (*) means the user login is disabled,
485# otherwise the first two characters are the salt). The password contained
486# in the /etc/passwd file is comprised of ##user_id where the user_id
487# matches the entry of the first field in both password files. The third
488# through fifth specify the minimum, maximum, and default security labels
489# for the user. The sixth and seventh fields specify which auditing flags
490# should be always or never monitored.
491#   If a line begins with a plus sign (+), it is a yellow pages entry.
492# See passwd(5) for more information, if this applies to your site.
493#
494X
495#
496# Parameters
497#
498passwd_file=$1
499passwd_adjunct_file=$2
500SUN_SECURITY=$3
501X
502#
503# Utilities
504#
505AWK=/bin/awk
506DIFF=/usr/bin/diff
507ECHO=/bin/echo
508JOIN=/usr/bin/join
509RM=/bin/rm
510SORT=/usr/bin/sort
511TEST=/bin/test
512UNIQ=/usr/bin/uniq
513X
514#
515# Important files:
516#
517join_passwd_1=./pwd$$.1.join
518join_passwd_2=./pwd$$.2.join
519sort_passwd=./pwd$$.sort
520sort_secure_passwd=./spwd$$.sort
521X
522#
523# Testing the passwd file for problems
524#
525result=`$AWK -F: '{print $1}' $passwd_file | $SORT -t: | $UNIQ -d`
526if $TEST "$result"
527X	then
528X	$ECHO
529X	$ECHO "Warning!  Duplicate uid(s) found in password file:"
530X	for USER in $result
531X	do
532X		$ECHO "	$USER"
533X	done
534fi
535X
536#
537#   First line is for a yellow pages entry in the password file.
538# It really should check for correct yellow pages syntax....
539#
540$AWK 'BEGIN {FS = ":" } \
541X	{if (substr($1,1,1) != "+") { \
542X	if ($0 ~ /^[ 	]*$/) { printf("\nWarning!  Password file, line %d, is blank\n", NR) } else {
543X	if (NF != 7) {
544X		printf("\nWarning!  Password file, line %d, does not have 7 fields: \n\t%s\n", NR, $0) } \
545X	if ($1 !~ /[A-Za-z0-9]/) {
546X		printf("\nWarning!  Password file, line %d, nonalphanumeric login: \n\t%s\n", NR, $0) } \
547X	if ($2 == "") {
548X		printf("\nWarning!  Password file, line %d, no password: \n\t%s\n", NR, $0) } \
549X 	if ("'$SUN_SECURITY'" == "TRUE" && "##"$1 != $2) {
550X		printf("\nWarning!  Password file, line %d, invalid password field for SUN C2 Security: \n\t%s\n", NR, $0) } \
551X	if ($3 !~ /[0-9]/) {
552X		printf("\nWarning!  Password file, line %d, nonnumeric user id: \n\t%s\n", NR, $0) } \
553X	if ($3 == "0" && $1 != "root") {
554X		printf("\nWarning!  Password file, line %d, user %s has uid = 0 and is not root\n\t%s\n", NR, $1, $0) } \
555X	if ($4 !~ /[0-9]/) {
556X		printf("\nWarning!  Password file, line %d, nonnumeric group id: \n\t%s\n", NR, $0) } \
557X	if ($6 !~ /^\//) {
558X		printf("\nWarning!  Password file, line %d, invalid login directory: \n\t%s\n", NR, $0) } \
559X	}}}' $passwd_file
560X
561#
562# Perform checks on the security enhanced version of SUNOS
563#
564if $TEST $SUN_SECURITY = "TRUE"
565X	then
566X	result=`$AWK -F: '{print $1}' $passwd_adjunct_file | $SORT -t: | $UNIQ -d`
567X	if $TEST "$result"
568X		then
569X		$ECHO
570X		$ECHO "Warning!  Duplicate uid(s) found in password adjunct file:"
571X		for USER in $result
572X		do
573X			$ECHO "	$USER"
574X		done
575X	fi
576X	#
577X	# Check that for each entry in the passwd file that there is a matching
578X	# entry in the passwd.adjunct file.
579X	#
580X	$SORT -t: -o $sort_passwd $passwd_file
581X	$SORT -t: -o $sort_secure_passwd $passwd_adjunct_file
582X	$JOIN -t: $sort_passwd $sort_secure_passwd > $join_passwd_1
583X	$JOIN -t: -a1 $sort_passwd $sort_secure_passwd > $join_passwd_2
584X	result=`$DIFF $join_passwd_1 $join_passwd_2`
585X	if $TEST "$result"
586X		then
587X		$ECHO
588X		$ECHO "Warning!  Matching record(s) in password adjunct file not found for"
589X		$ECHO "these records in password file:"
590X		PREV=$$
591X		for USER in $result
592X		do
593X			if $TEST $PREV = ">"
594X				then
595X				$ECHO "	$USER"
596X			fi
597X			PREV=$USER
598X		done
599X	fi
600X	#
601X	# Check that for each entry in the passwd.adjunct file that there is a
602X	# matching entry in the passwd file.
603X	#
604X	$RM -f $join_passwd_2
605X	$JOIN -t: -a2 $sort_passwd $sort_secure_passwd > $join_passwd_2
606X	result=`$DIFF $join_passwd_1 $join_passwd_2`
607X	if $TEST "$result"
608X		then
609X		$ECHO
610X		$ECHO "Warning!  Matching record(s) in password file not found for"
611X		$ECHO "these records in password adjunct file"
612X		PREV=$$
613X		for USER in $result
614X		do
615X			if $TEST $PREV = ">"
616X				then
617X				$ECHO "	$USER"
618X			fi
619X			PREV=$USER
620X		done
621X	fi
622X	#
623X	# Test the fields in the passwd.adjunct file for validity
624X	#
625X	$AWK 'BEGIN {FS = ":" } \
626X		{if (substr($1,1,1) != "+") { \
627X		if ($0 ~ /^[ 	]*$/) { printf("\nWarning!  Password adjunct file, line %d, is blank\n", NR) } else {
628X		if (NF != 7) {
629X			printf("\nWarning!  Password adjunct file, line %d, does not have 7 fields: \n\t%s\n", NR, $0) } \
630X		if ($1 !~ /[A-Za-z0-9]/) {
631X			printf("\nWarning!  Password adjunct file, line %d, nonalphanumeric login: \n\t%s\n", NR, $0) } \
632X		if ($2 == "") {
633X			printf("\nWarning!  Password adjunct file, line %d, no password: \n\t%s\n", NR, $0) } \
634X		#
635X		# Fields 3-5 are ignored since they deal with labels which are
636X		# currently unused on the SUN (perhaps a future B-level??)
637X		#
638X		# Fields 6+7 contain audit flags for the user and are selected
639X		# from the following: dr, dw, dc, da, lo, ad, p0, p1, and all.
640X		# More than 1 flag can be selected by separating flags with a
641X		# comma (,).
642X		#
643X		if ($6 != "") {
644X			j=1
645X			len=length($6)
646X			for (i=1; i<=len; i++) {
647X				if ((substr($6,i,1) != ",") && (i < len))
648X					continue
649X				if (i == len)
650X					token=substr($6,j,i-j+1)
651X				else
652X					token=substr($6,j,i-j)
653X				j=i+1
654X				if (token == "dr") continue
655X				if (token == "dw") continue
656X				if (token == "dc") continue
657X				if (token == "da") continue
658X				if (token == "lo") continue
659X				if (token == "ad") continue
660X				if (token == "p0") continue
661X				if (token == "p1") continue
662X				if (token == "all") continue
663X			printf("\nWarning!  Password adjunct file, line %d, invalid audit flag: %s\n\t%s\n", NR, token, $0) } \
664X			}
665X		}}}' $passwd_adjunct_file
666fi
667X
668#
669# Clean up after ourself
670#
671$RM -f $join_passwd_1
672$RM -f $join_passwd_2
673$RM -f $sort_passwd
674$RM -f $sort_secure_passwd
675# end
676SHAR_EOF
677chmod 0700 passwd.file.chk ||
678echo 'restore of passwd.file.chk failed'
679Wc_c="`wc -c < 'passwd.file.chk'`"
680test 7715 -eq "$Wc_c" ||
681	echo 'passwd.file.chk: original size 7715, current size' "$Wc_c"
682fi
683exit 0
684

readme.apollo

1
2  Try setting the $OVER_8 variable (line 50) in "passwd.chk" to "YES",
3if you get warnings about having extra long uid's.
4
5
6  This little script can be used to generate a better password file for
7the password cracker, if you use those funky more-than-one-field in field
8one of the password file; e.g., if you have something that looks like:
9
10root.foo.bar:xxxxxxxxxxxxx:0:0:Mr. Fu Bear:/:/bin/sh
11
12  This will change it to:
13
14root:xxxxxxxxxxxxx:0:0:foo bar Mr. Fu Bear:/:/bin/sh
15
16  So that you can use the extra fields as gcos information for password
17cracking.  You can substitute the normal password cracking stuff in "cops"
18("pass.chk") with something like (assuming you call this "apollo.sh"):
19
20apollo.sh > ./apollo.pw.$$
21pass.chk -P ./apollo.pw.$$
22rm -f ./apollo.pw.$$
23
24
25  In addition, you can add these 2 lines to the "passwd.chk" shell script
26(right before the start of the awk on line 82 would be fine):
27
28$AWK -F: '{print $1}' $etc_passwd | $AWK -F. '{if (NF > 3)
29		printf("Warning!  Password file, line %d, has %d sub-fields in the user field: \n\t%s\n", NR, NF, $0) }'
30
31  And if you're running YP (is that possible, with all of that?  :-)
32You can add these 2 lines before line 119:
33
34$AWK -F: '{print $1}' $yp_passwd | $AWK -F. '{if (NF > 3)
35		printf("Warning!  YPassword file, line %d, has %d sub-fields in the user field: \n\t%s\n", NR, NF, $0) }'
36
37
38:
39#
40#  apollo.pw
41#
42AWK=/bin/awk
43
44# Quote from the man page (passwd):
45# On DOMAIN systems, passwords are kept in the registry files (/registry/*).
46#
47# Important files:
48etc_passwd=/etc/passwd
49
50$AWK -F: '{split($1,temp,"."); \
51		$1=temp[1]; \
52		for (i in temp) {
53			if (i!=1) \
54				$5 = $5" "temp[i]; \
55			} \
56		for (j=1;j<=NF;j++)
57			printf("%s:",$j); \
58		printf("\n") \
59		}' $etc_passwd
60
61# end
62

readme.cfilter

1
2A quick primer on "cops_filter"
3
4  "cops_filter" is a mechanism for eliminating warning messages in
5the final COPS report that you deem spurious.  It's a simple awk
6program that looks at a list of regular expressions and prunes
7out any that match.  As simple as it is, however, it is an extremely
8dangerous program -- a slip of the ol' regular expression and bam --
9you don't get notified that /etc/passwd is world writable, or something
10like that.  Hence this file, in hopes to enlighten the masses (yeah,
11right, like I can do that... anyway, on to business.)
12
13  Awk uses regular expressions to search for things, which means you
14can use wildcards or even a part of a line to nuke a warning.  For
15instance -- let's say on a particular host you have NIS explicitly
16included in your password file (e.g. no "+" there), but you are a
17member of a NIS domain that does have NIS password maps.  Since COPS
18isn't smart enough right now to figure out that you might not care
19about the NIS password maps on your machine (and I'm not sure that
20it would be a good idea to ignore this anyway), it checks everything...
21you might get a warning like:
22
23Warning!  YPassword file, line 9, no password:
24	ypg::2200:10:YP guest acct:/tmp:/bin/rsh
25
26  There are several things you can do to eliminate this message.
27If you're familiar with awk, there are some example lines in
28"cops_filter"; you can just change those to do what you want.  If
29you're not an awk hacker, run out and by the book by aho, kernighan,
30and weinberger, and learn awk.  Well, no, you don't have to -- it's
31very easy to do simple things.
32
33
34
35IMPORTANT!  All filter lines in "cops_filter" will *ONLY* match the
36first line of this multi-line warning message (at least, and do the
37right thing.)  Do not try to filter out the second line -- it won't
38work.
39
40
41
42(No new information below to awk/shell people that you couldn't get
43by just glancing at the filter file -- you can go play with "cops_filter"
44now if you wish.)
45
46  The simplest thing to do is to add a line (actually 4 lines, as you'll
47see below -- but the most important one is the first line) that exactly
48matches what you want to get rid of; e.g., for the above example,
49you could put something like:
50
51if ($0 ~ /Warning!  YPassword file, line 9, no password:/) {
52	skip_next = 1
53	next
54	}
55
56  An explanation.  In awk, every line of code in the awk program
57will act on every line in the input file.  In most programming languages
58you need to put a loop around the program, but in awk, it is implied.
59The $0 here refers to the current input line that the awk program
60is looking at.  This line says that if the current input line is
61equal to "Warning!  YPassword file, line 9, no password:", then
62you should do what it says between the two curly braces.  In this case,
63you just set a variable (don't worry about exactly what it does right
64now), and then skip to the next line of input from the COPS report file.
65That's all there is to it.  Notice that at the bottom half of the awk
66program, there are places where information gets printed out -- all
67those mean is that unless awk sees a pattern that it matches and gets
68told to go to the next line, it will print out the current line.
69
70  Well, this is probably as clear as mud, but the basic idea is
71that you'll be putting a regular expression inbetween two forward
72slanting lines ("/"), and if awk matches that, then it will not
73print that out in the final COPS report file.
74
75  If you don't want to use an exactly matching line, either because
76you're a poor typist or lazy or perhaps you have a group of warnings,
77all alike, and you'd like to get rid of them, then you can use
78wildcards, or even a part of the line(s) in question -- be careful with
79this, and make sure you test your awk program out before inflicting it
80for real on your cops reports.
81
82  For instance, to match the above example, you could say:
83
84	if ($0 ~ /Warning!  YPassword file, line 9, no password:/)
85
86or:
87
88	if ($0 ~ /YPassword file, line 9, no password/)
89
90or, if you really don't want to see any YP/NIS messages, you could use:
91
92	if ($0 ~ /YPassword file/)
93
94alternately, an example with wildcards:
95
96	if ($0 ~ /YP.* no password/)
97
98  All of these would match the example line.  However, the bottom two
99would match other lines as well -- something like:
100
101Warning!  YPassword file, line 12, invalid login directory:
102
103  Would also be eliminated from the result file.  Be careful especially
104when you're dealing with anything that is in the report file that looks
105like a regular expression -- characters like "*", "+", and "?", as
106well as the forward slash "/" (to keep it separate from the awk
107regular expression separator character) should be preceded with a
108backslash -- e.g. something like:
109
110	if ($0 ~ /\/usr\/spool\/mail is _World_ writable!/)
111
112  Check your awk program as described before, and compare the output
113with the old report file with diff -- does it do what you thought?
114Be careful.
115
116
117
118  Almost the last Important note -- you can test your filter by saying
119something like:
120
121awk -f cops_filter cops_result_file
122
123  Where cops_result_file is usually named something like "1992_Dec_31".
124Well, that's about it -- good luck!
125
126 -- dan
127

readme.filters

1
2  There are now three types of filters for COPS -- the one in CARP, the
3one in "cops_filter", and the one in "gen_fix".  They are all similar in
4their mechanism, but are to be used for different reasons.  This is just
5a short overview of what they do, and how they interact.
6
71) "cops_filter" (or whatever file you designate with the -f flag.)  This
8takes place *BEFORE* the "gen_fix" filter (or whatever you designate
9with the -g flag.)
10
11Philosphy -- many things are flagged by COPS as a potential problem.  Some
12	of these aren't really a problem, but it's not always practical
13	(and is undesirable, from a software engineering standpoint) to
14	hard code these things into the COPS package.  By using "cops_filter",
15	you can eliminate the warnings from the final result file.
16
172) "gen_fix" filter.  This happens *after* the "cops_filter".  It generates
18a shell fix for various warning messages generated by COPS (mostly
19permissions.)
20
21Philosophy -- some things are problems, but too sensitive or tricky to fix
22automatically.  Put them here.
23
243) CARP filter.  Strips out various warnings that might not apply to the
25entire network model, or can be used on hosts reports that didn't use
26the "cops_filter", or whatever.  This obviously takes place after the
27"cops_filter", and "gen_fix" filter doesn't affect it at all.
28
29Philosophy -- not much :-)  You can use this as an overview tool; if you
30have a problem that you fixed on all your hosts, then you can use this
31to run over your old report files and look at the next-most-serious problem.
32Alternately, you can try a "what if" kind of thing, I guess.
33

readme.ibm

1
2  Make sure you uncomment out line 92 in dev.chk:
3
4# On an IBM/AIX box, you can try something like:
5# all_devs=`$GREP 'dev.*=' /etc/filesystems | $AWK '{print $NF}'`
6
7  So that COPS can read the right devices.  Also, read the "readme.shadow"
8file for shadow-password info, and how to crack passwords, etc, on this
9beast.
10

readme.sequent

1
2  On some sequents, I don't know why, but you'll want to have this
3line uncommented out in the makefile (line 25):
4
5SEQFLAGS   = -lseq
6
7  Also, in "src/crc_check.c", you may need to uncomment lines 36-38.
8
9

readme.shadow

1
2  Part of a conversation I had with a guy about cracking shadow passords;
3at the end of this is a script that should work with SVR3.2; I'm not
4sure about the rest, but minor changes should make it work on
5just about anything (for instance, I think on my sun, the variable
6$num_fields should be changed to 15 (or you could compile pass.c with
7the C2 flag)).  Let me know if you can't get it to work, and I'll
8*make* it work :-)  In any case, you'll need to run as root to get the
9passwords for cracking.
10
11>On system V3.2, both  AT&T, SCO, and us (Interactive) use the following format
12> /etc/passwd looks pretty much normal;
13> adm:x:4:4:0000-Admin(0000):/usr/adm:
14[...]
15> except that the passwd field always contains an "x".
16> Then, the etc/shadow file, which is owned by root and perms 400 looks
17> like;
18[...]
19> sally:e4T6g5HbjOnck:7449:0:7000
20[...]
21> The first field is the account name, the second field is the excrypted
22> passwd string, and the rest is password aging garbage.
23> Ignore the password fields above containing "LOCKED".  I do that by
24> hand to secure an account, since the output of crypt will never match it.
25
26  Try this on for size:
27
28========== shadow.stuff ================
29#!/bin/sh
30#
31#  Usage: shadow.stuff [shadow_password_file]
32#
33#   Extracts the correct info from shadow pass to use for processing with
34# pass.chk and passwd.chk.
35#
36# (written by me, modified by John F Haugh II, remodified by me.  Hope
37# it still works :-))
38#
39if test -f "$1" ; then
40	shadow=$1
41else
42	if test -f "/etc/shadow" ; then
43		shadow=/etc/shadow
44	else
45		echo "Can't find shadow password file..."
46		exit 1
47	fi
48fi
49
50# This is 15, I think, for a sun?  Others seem to want 13
51num_fields=13
52
53passwd=/etc/passwd
54foo_pass="./shadow.tmp.$$"
55ptmp="./pfile.tmp.$$"
56stmp="./sfile.tmp.$$"
57
58sed -e 's/^/p:/' $passwd | sort > $ptmp
59sed -e 's/^/s:/' $shadow | sort > $stmp
60cat ./pfile.tmp.$$ ./sfile.tmp.$$ | \
61	sort -t':' +1 -2 +0r -1 | \
62	sed -e 's/^[sp]://' > $foo_pass
63
64awk -F: '{parray[$1] = $0":"parray[$1]} END { \
65	for (line in parray) { \
66		nf=split(parray[line], pline, ":"); \
67		if (nf == '"$num_fields"') {
68			print pline[1]":"pline[9]":"pline[3]":"pline[4]":" \
69			pline[5]":"pline[6]":"pline[7]; \
70		      	} \
71		      } \
72		}' $foo_pass
73
74rm -f $ptmp $stmp $foo_pass
75==========================================
76
77  Ok, the way you use this is just to type "shadow.stuff > tempfile";
78this will create a file, "tempfile" (or whatever), that *should*
79be the equivalent to a normal password file.  Of course, you'll have
80to run this as root so that you can read the shadow password file.
81This should work, but no blame if it doesn't, please :-)  Just let
82me know if it does or not; I can put it in the normal distribution,
83if so.
84
85  Hope this helps -- 'luck!
86
87 -- dan
88

readme.svr4

1
2  In bug.chk, you'll need to change this line (29) to "no":
3
4# Do you decend from 4.3 BSD?
5bsd43=yes
6

readme.xenix

1
2  Uncomment the "BRAINDEADFLAGS=-lcrypt" in the makefile, and put the line:
3
4extern char *crypt();
5
6  Right after the #include lines in "pass.c".  This apparently came from
7the makers of Xenix, about the availability of crypt(3):
8
9========================
10Subject: crypt in Xenix
11
12Due to the export restrictions on CRYPT, we do not ship it with the
13standard product.  We do ship it as an SLS: the relevant numbers are
14lng190 (for shipment inside the U.S. only) and lng225, which can be
15shipped outside the U.S..
16========================
17
18  Make the following change in dev.chk:
19
20line 39:
21> mtab=/etc/fstab
22
23To:
24< mtab=/etc/checklist
25
26
27(note to myself:
28Need to change something... checklist has has one fs per line...)
29

readme.yp

1
2  There are a couple of things to keep in mind if you're using yellow
3pages/NIS.  Automatic checks are made in the passwd.chk, group.chk, suid.chk,
4and ftp.chk.  However, if you want to crack passwords from that database,
5you need to do one of three things:
6
71)  If you're using "pass_diff.chk" to check only changed passwords (on
8line 108 of "cops"), change the flag on line 33 in "pass_diff.chk" from
9"NO" to "YES"
10
112)  If you're not running "pass_diff.chk", replace "pass.chk" with
12"yp_pass.chk" on line 109 of "cops".
13
143)  Create a password file with ypcat and run "pass.chk -P file".
15
16