From:	CRDGW2::CRDGW2::MRGATE::"SMTP::CRVAX.SRI.COM::RELAY-INFO-VAX" 30-OCT-1989 13:17
To:	MRGATE::"ARISIA::EVERHART"
Subj:	Re: password security and worms [code included]

Received: From UCBVAX.BERKELEY.EDU by GIZMO.SRI.COM with TCP; Mon, 30 OCT 89 03:33:17 PDT
Received: by ucbvax.Berkeley.EDU (5.61/1.39)
	id AA14315; Mon, 30 Oct 89 03:22:24 -0800
Received: from USENET by ucbvax.Berkeley.EDU with netnews
	for info-vax@kl.sri.com (info-vax@kl.sri.com)
	(contact usenet@ucbvax.Berkeley.EDU if you have questions)
Date: 30 Oct 89 11:05:51 GMT
From: uhccux!munnari.oz.au!comp.vuw.ac.nz!windy!gpwd!gpwrdcs@ames.arc.nasa.gov  (Don Stokes, GPO)
Organization: Government Printing Office, Wellington, New Zealand
Subject: Re: password security and worms [code included]
Message-Id: <496@gp.govt.nz>
References: <2257@ddnvx1.afwl.af.mil>
Sender: info-vax-request@kl.sri.com
To: info-vax@kl.sri.com

In article <2257@ddnvx1.afwl.af.mil>, RIDOUT@ddnvx1.afwl.af.mil (Brian Ridout AFWL/SCEV (av) 244-1654 (505) 844-1654) writes:
> I am the system manager (among other things :-)) of a cluster of VAXes.
> A good portion of mu users are the type who could give a S' about good
> password practice.  So I would like to check the UAF for obvious passwords
> such as password is the username.  

The following is such a beast  It uses the VMS$SECUREPWD.EXE file, found
on the VMS 4.7 (probably others as well) distribution - you will have to
fish it out of the distribution tape (unless your last VMS upgrade went
horribly wrong 8-).  The procedure also gives a fairly good idea as to 
how to drive the VMS$SECUREPWD program if you want to write anything else 
around it.

Does anyone have info on how passwords are hashed - it would be nice if I 
could make this a single executable.

Don Stokes  ZL2TNM  /  /                                 vuwcomp!windy!gpwd!don 
Systems Programmer /GP/ Government Printing Office       PSI%0530147000028::DON
__________________/  /__Wellington, New Zealand__________don@gp.govt.nz________
The value of a program is proportional to the weight of its output. 

--------------------------------cut-here--------------------------------
$       verify = 'f$verify(0)'
$!++
$!              CHECKPWD.COM - List users with insecure passwords
$!
$!      Abstract:
$!
$!      This procedure utilises the VMS$SECUREPWD program "provided" in the
$!      VAX/VMS V4.7 distribution kit to search for users with insecure 
$!      passwords.
$!
$!      The procedure works by extracting a list of users from the system
$!      authorization file.  Each line is then parsed to create a list of
$!      possible insecure passwords by adding the username and each word of
$!      the name in the OWNER field of the user record to the list of standard
$!      passwords.  The username and complete password list for the user is 
$!      then fed into VMS$SECUREPWD for testing.
$!
$!      Note that bracketed information in the OWNER field is ommitted from
$!      the passwords list.  
$!
$!      If there is a match, the routine then steps through the list of 
$!      passwords to find which of the offending passwords is valid.  The
$!      password found is then written to the listing file along with the
$!      details of the user from the SYSUAF listing.  
$!
$!      Parameters:
$!
$!      P1 = User specification to search for.  If this is blank, a 
$!           specification of "*" is used.
$!      P2 = Output file for report.  Status messages go to SYS$OUTPUT.
$!           This defaults to "CHECKPWD.LIS".
$!
$!      Altering standard password list:
$!
$!      The symbol "STANDARD_PASSWORDS" specify the 'disallowed' passwords
$!      for the site.  This should include obvious passwords such as "PASSWORD"
$!      or "SYSTEM", the name of the city in which the site is located, the
$!      names of the applications being used, easy passwords to key in (such
$!      as "QWERTY"), department names etc.
$!
$!      The passwords list should be specified in upper case, with a comma
$!      between each item.  
$!
$!      Author: Don Stokes, Government Printing Office, Wellington, New Zealand
$!              PSI:    PSI%0530147000028::DON
$!              Bang:   uunet!vuwcomp!windy!gpwd!don
$!              Domain: don@gp.govt.nz
$!              Phone:  +64 4 737-320
$!
$!      Date:   15-Jul-1989
$!
$!      Disclaimer: If you break it, you own both parts.
$!
$!--
$               !
$               ! Set up symbols etc
$               ! Parse parameters.
$               !
$       standard_passwords = "PASSWORD,SYSTEM,ACCESS,COMPUTER,MANAGER," -
                           + "QWERTY,123456,ASDFGH,ZXCVBN,SECRET"
$       userspec = p1
$       outputfile = p2
$       if userspec .eqs. "" then userspec = "*"
$       if outputfile .eqs. "" then outputfile = "CHECKPWD.LIS"
$       check := $SYS$DISK:[]VMS$SECUREPWD check
$       say   := write SYS$OUTPUT
$       date = f$extract(0, 11, f$time())
$       ff[0,8] = 12
$       uaf_tmp_file = "SYS$SCRATCH:UAF_" + f$getjpi("", "PID") + ".TMP;"
$               !
$               ! Extract UAF listing
$               !
$       on control_Y then goto abort
$       say "%CHECKPWD-I-UAF, extracting UAF listing"
$       privs = f$setprv("SYSPRV")
$       assign/user 'uaf_tmp_file' SYS$OUTPUT
$       assign/user SYS$SYSTEM:SYSUAF.DAT SYSUAF
$       mc authorize show 'userspec'/brief
$       privs = f$setprv(privs)
$               !
$               ! Initialise line & page counters
$               ! Skip over UAF listing headings
$               !
$       say "%CHECKPWD-I-SEARCHING, extracting users with insecure passwords"
$       open/read in 'uaf_tmp_file'
$       open/write out 'outputfile'
$       lines_printed = 0
$       pages_printed = 0
$       read in rubbish
$       read in rubbish
$               !
$               ! Main loop:
$               ! Extract owner field and username.
$               ! Add username, account and collapsed full owner name to 
$               ! standard passwords list.
$               !
$ loop:
$       read in line/end=all_done
$       username = f$edit(f$extract(21, 12, line), "TRIM")
$       account = f$edit(f$extract(50, 8, line), "TRIM")
$       owner = f$extract(0, 20, line)
$       owner = f$extract(0, f$locate("(", owner), owner)
$       owner = f$edit(owner, "COMPRESS,UPCASE")
$       pwd_list = standard_passwords + "," + username + "," + account + "," -
                 + """" + f$edit(owner, "COLLAPSE") + """"
$       index = 0
$               !
$               ! Loop through words of owner field and add each word to 
$               ! list of passwords to search for this user.
$               !
$ get_pwds:
$       pwd = f$element(index, " ", owner)
$       if pwd .eqs. "" .or. pwd .eqs. " " then goto list_complete
$       index = index + 1
$       if f$length(pwd) .gt. 6 then pwd_list = pwd_list + ",""" + pwd + """"
$       goto get_pwds
$               !
$               ! Check the username against the whole list of paswords.
$               ! If it matches then take note if it is DISUSERed.
$               !
$ list_complete:
$       check 'username'/exclude=('pwd_list')
$       if VMS$SECURE .nes. "WEAK" then goto loop
$       check 'username'
$       disuser = VMS$SECURE .eqs. "DISUSER"
$       index = 0
$               !
$               ! If a match was found then loop through each item in the
$               ! passwords list until the weak password is found.
$               !
$ got_im_loop:
$       password = f$element(index, ",", pwd_list)
$       index = index + 1
$       check 'username'/exclude='password'
$       if VMS$SECURE .nes. "WEAK" then goto got_im_loop
$               !
$               ! Write the fact we got one to the logfile/console.
$               ! (Note that only the username is displayed at this point.)
$               ! Check if a page break is needed, print heading if so.
$               ! Update line & page counters.
$               ! Write record to report file.
$               ! Iterate main loop.
$               !
$       say "%CHECKPWD-I-FOUND, user ''username' has an insecure password"
$       if lines_printed .ne. lines_printed / 55 * 55 then goto print_record
$       pages_printed = pages_printed + 1
$       write out ff
$       write out -
"Report of usernames with insecure passwords         Date: ''date'   Page " + -
"''pages_printed'"
$       write out ""
$       write out -
   "       Owner         Username           UIC       Account  Privs  Password"
$ print_record:
$       lines_printed = lines_printed + 1
$       if disuser then password = password + "(D)"
$       write out f$extract(0, 66, line) + (password - """" - """")
$       goto loop
$               !
$               ! Come here on EOF.
$               ! Close files, delete temporary file etc.
$               !
$ all_done:
$       write out "''lines_printed' users matched."
$ abort:
$       close/nolog in
$       close/nolog out
$       delete/nolog 'uaf_tmp_file'
$       say "%CHECKPWD-S-FINISHED, insecure password search completed"
$       exit f$verify(verify)*0+1
--------------------------------cut-here--------------------------------

