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