From:	CRDGW2::CRDGW2::MRGATE::"SMTP::CRVAX.SRI.COM::RELAY-INFO-VAX" 10-MAR-1991 09:33:09.99
To:	MRGATE::"ARISIA::EVERHART"
CC:	
Subj:	Checksum program -was anti-virus for VMS

Received:  by crdgw1.ge.com (5.57/GE 1.80)
	 id AA08874; Fri, 8 Feb 91 11:08:12 EST
Message-Id:  <9102081608.AA08874@crdgw1.ge.com>
Received: From SCFB.NWC.NAVY.MIL by CRVAX.SRI.COM with TCP; Fri,  8 FEB 91 07:43:10 PST
Date: 8 Feb 91 07:24:00 PDT
From: "FIDLER::LEVINE" <levine%fidler.decnet@scfb.nwc.navy.mil>
Subject: Checksum program -was anti-virus for VMS
To: "wlbaker" <wlbaker@relay.nswc.navy.mil>
Cc: "info-vax" <info-vax@crvax.sri.com>

>IS there any Anti-Virus software for the VAX, like McAfee for the PC. 
>Also would a program that calculates two different CRCs help to identify
>viruses??   I am asking this for my ADP Security Officer.  Please E-Mail
>to me & I will sumarize to the Net.  MilNet E-Mail:
>wlbaker@relay.nswc.navy.mil   (703)663-8594                               

	Here is a program that I use for checks. In share format in 2 parts.

Michael N. LeVine  Naval Weapons Center, China Lake, Ca 93555, USA
Internet: levine%fidler.decnet@nwc.navy.mil,levine%fidler.decnet@26.3.0.85
(619) 939-2614  avn  437-2614 

 "Waiter, there's a bug in my soup!"        
 "No, Sir, it's not a bug, it's a feature!" 

$! ------------------ CUT HERE -----------------------
$ v='f$verify(f$trnlnm("SHARE_VERIFY"))'
$!
$! This archive created by VMS_SHARE Version 7.2-007  22-FEB-1990
$!   On  8-FEB-1991 06:53:58.95   By user LEVINE 
$!
$! This VMS_SHARE Written by:
$!    Andy Harper, Kings College London UK
$!
$! Acknowledgements to:
$!    James Gray       - Original VMS_SHARE
$!    Michael Bednarek - Original Concept and implementation
$!
$!+ THIS PACKAGE DISTRIBUTED IN 2 PARTS, TO KEEP EACH PART
$!  BELOW 30 BLOCKS
$!
$! TO UNPACK THIS SHARE FILE, CONCATENATE ALL PARTS IN ORDER
$! AND EXECUTE AS A COMMAND PROCEDURE  (  @name  )
$!
$! THE FOLLOWING FILE(S) WILL BE CREATED AFTER UNPACKING:
$!       1. CHECK.DOC;7
$!       2. CHECK.COM;20
$!       3. CHECK.MAR;31
$!
$set="set"
$set symbol/scope=(nolocal,noglobal)
$f=f$parse("SHARE_TEMP","SYS$SCRATCH:.TMP_"+f$getjpi("","PID"))
$e="write sys$error  ""%UNPACK"", "
$w="write sys$output ""%UNPACK"", "
$ if f$trnlnm("SHARE_LOG") then $ w = "!"
$ ve=f$getsyi("version")
$ if ve-f$extract(0,1,ve) .ges. "4.4" then $ goto START
$ e "-E-OLDVER, Must run at least VMS 4.4"
$ v=f$verify(v)
$ exit 44
$UNPACK: SUBROUTINE ! P1=filename, P2=checksum
$ if f$search(P1) .eqs. "" then $ goto file_absent
$ e "-W-EXISTS, File ''P1' exists. Skipped."
$ delete 'f'*
$ exit
$file_absent:
$ if f$parse(P1) .nes. "" then $ goto dirok
$ dn=f$parse(P1,,,"DIRECTORY")
$ w "-I-CREDIR, Creating directory ''dn'."
$ create/dir 'dn'
$ if $status then $ goto dirok
$ e "-E-CREDIRFAIL, Unable to create ''dn'. File skipped."
$ delete 'f'*
$ exit
$dirok:
$ w "-I-PROCESS, Processing file ''P1'."
$ if .not. f$verify() then $ define/user sys$output nl:
$ EDIT/TPU/NOSEC/NODIS/COM=SYS$INPUT 'f'/OUT='P1'
PROCEDURE Unpacker ON_ERROR ENDON_ERROR;SET(FACILITY_NAME,"UNPACK");SET(
SUCCESS,OFF);SET(INFORMATIONAL,OFF);f:=GET_INFO(COMMAND_LINE,"file_name");b:=
CREATE_BUFFER(f,f);p:=SPAN(" ")@r&LINE_END;POSITION(BEGINNING_OF(b));
LOOP EXITIF SEARCH(p,FORWARD)=0;POSITION(r);ERASE(r);ENDLOOP;POSITION(
BEGINNING_OF(b));g:=0;LOOP EXITIF MARK(NONE)=END_OF(b);x:=ERASE_CHARACTER(1);
IF g=0 THEN IF x="X" THEN MOVE_VERTICAL(1);ENDIF;IF x="V" THEN APPEND_LINE;
MOVE_HORIZONTAL(-CURRENT_OFFSET);MOVE_VERTICAL(1);ENDIF;IF x="+" THEN g:=1;
ERASE_LINE;ENDIF;ELSE IF x="-" THEN IF INDEX(CURRENT_LINE,"+-+-+-+-+-+-+-+")=
1 THEN g:=0;ENDIF;ENDIF;ERASE_LINE;ENDIF;ENDLOOP;t:="0123456789ABCDEF";
POSITION(BEGINNING_OF(b));LOOP r:=SEARCH("`",FORWARD);EXITIF r=0;POSITION(r);
ERASE(r);x1:=INDEX(t,ERASE_CHARACTER(1))-1;x2:=INDEX(t,ERASE_CHARACTER(1))-1;
COPY_TEXT(ASCII(16*x1+x2));ENDLOOP;WRITE_FILE(b,GET_INFO(COMMAND_LINE,
"output_file"));ENDPROCEDURE;Unpacker;QUIT;
$ delete/nolog 'f'*
$ CHECKSUM 'P1'
$ IF CHECKSUM$CHECKSUM .eqs. P2 THEN $ EXIT
$ e "-E-CHKSMFAIL, Checksum of ''P1' failed."
$ ENDSUBROUTINE
$START:
$ create 'f'
X
X
X
X
X
X
X
X`09`09`09Check Files for Tampering
X
X
X
X
XMichael N. LeVine
XCode 3514
XNaval Weapons Center
XChina Lake
XCa 93555
X(619) 939-3970
X avn 437-3970
XLEVINE%FIDLER.DECNET@NWC.ARPA
X
X`0C
X`09In various discussions in the PAGESWAPPER, and in various trade
Xpublications, one of the tools mentioned for the detection of possible break
V-in
Xis the un-documented VAX/VMS utility CHECKSUM. But in most discussions it is
Xalso recognized that CHECKSUM can be easily fooled and that it can be patche
Vd
Xto give wrong answers. In looking at this problem, I thought that it would b
Ve
Xmuch more difficult for a hacker to do an undetected tamper of critical syst
Vem
Xfiles if more than one type of check was made on the target files. As a firs
Vt
Xcut, I wrote the following program with its driving command file. CHECK will
V,
Xfor each file specified, calculate the following information about the file:
X
X`09Checksum`098 bit`20
X`09Checksum`0916 bit
X`09Checksum`0932 bit
X`09CRC`09`09CRC-16
X`09CRC`09`09CCITT
X`09CRC`09`09AUTODIN-II
X`09CRC`09`09CRC-12
X
Xand then output it with the file name on a single line.
X
XThe program can be executed by either
X
X$ RUN CHECK
X
Xor
X
X$ CHECK := $'F$LOGICAL("SYS$DISK")''F$DIRECTORY()'CHECK
X$ CHECK  file name
X
Xor
X
X$ CHECK := $'F$LOGICAL("SYS$DISK")''F$DIRECTORY()'CHECK
X$ CHECK
X
X
Xthe program will repeatedly prompt for file names until an empty line or EOF
V is
Xencountered. The file names specified can contain wild cards, and all matchi
Vng
Xfiles will be checked before the program prompts for a new file.`20
X
X$ RUN CHECK
XFile name ? sys$library:*.exe;*
XFile name ? sys$system:link.exe;*
X
X`0C
X`09As an example of how a system check would be done, I have provided a
Xcommand file CHECK.COM that would do the required checks. The command file
Xassumes that a file containing the valid check information exists in the
Xinvoking directory using the name CHECKSUMS.DAT, if this is not true such as
Xthe case of the first time the program has been run on the system or there h
Vas
Xbeen an upgrade or a new layered product has been installed then invoke the
Xcommand file`20
X
X$ @CHECK FIRST
X
Xotherwise to do a normal check just do
X
X$ @CHECK
X
Xthe command file does the following:
X
X.
X.
XCompletely rebuild the program from sources so any tampering has to be done
V to
Xthe source where a quick visual check can be made.`20
X.
X.
X$ mac check
X$ link/notrace check
X.
X.
XThen the checks are run on the critical files-redirecting the results to a
Xtemporary file. The files checked includes itself.`20
X.
X.
X$ define/usermode sys$output checksums.acc
X$ run check
Xsys$system:checksum.exe;*
Xsys$system:diff.exe;*
X.
X.
Xsys$library:*.tlb;*
Xcheck.*
X.
X.
XThen a comparison is done checking the results against the data file contain
Ving
Xthe correct results. Any differences could mean tampering.`20
X.
X.
X$ diff checksums.acc checksums.dat
X.
X.
XOne last check is made of the master data file letting the output go to the
Xterminal where the user can then check the master data file's integrity agai
Vnst
Xa hard copy value.`20
X.
X.
X$ run check
Xchecksums.dat
X.
X.
XWhen completed, the command file cleans up including deleting the .EXE and
X.OBJ.`20
X
X`0C
X`09In writing this program, one objective I had was to keep it simple so
Xthat a user checking the source could easily spot any changes that had been
Xmade or so that the users could make mods that they felt necessary.`20
X`09No special privileges are needed to run CHECK, only read access to the
Xfiles to be checked. This permits the user to keep and run this program from
Xany account.`20
X`09If you have any feedback on this program, I can be contacted at the
Xaddress, phone or E-Mail address show above (E-Mail preferred).`20
X
$ CALL UNPACK CHECK.DOC;7 1717457451
$ create 'f'
X$ iv='f$verify(0)'
X$ set noon`09! nomatter what the error-continue
X$ !
X$ ! command file to check critical files for tampering
X$ !
X$ ! if p1 ="FIRST" this is the first time through and
X$ ! we are building the template for the compares
X$ !
X$ set terminal /width=132`09! for output-use a wide screen
X$ write sys$output "Building fresh copy of check program"
X$ mac check`09! rebuild program from source so hacker does not have .EXE
X$ link/notrace check`09! to tamper with
X$ write sys$output "Starting checks"
X$ define/usermode sys$output checksums.acc !redirect output to a file
X$ ! run checks on the most critical files
X$ run check
Xsys$common:`5Bsysexe`5Dchecksum.exe;*
Xsys$common:`5Bsysexe`5Ddiff.exe;*
Xsys$common:`5Bsysexe`5Ddirectory.exe;*
Xsys$common:`5Bsysexe`5Dmonitor.exe;*
Xsys$common:`5Bsysexe`5Dlink.exe;*
Xsys$common:`5Bsysexe`5Dloginout.exe;*
Xsys$common:`5Bsysexe`5Dmacro32.exe;*
Xsys$common:`5Bsys$ldr`5D*.exe;*
Xsys$system:*.stb;*
Xsys$library:*.exe;*
Xsys$library:*.mlb;*
Xsys$library:*.olb;*
Xsys$library:*.tlb;*
Xcheck.*
Xchecks.*
X$ ! if this is the forst time-we are building the template date file
X$ if p1 .eqs. "FIRST" then copy checksums.acc checksums.dat
X$ purge checksums.*
X$ write sys$output "Check file generated-compareing to template
X$ ! any error messages here mean possable tampering
X$ diff checksums.acc checksums.dat
X$ write sys$output -
X "Compare checksum of template checksum file with your hard copy value"
X$ write sys$output "Any difference signifies possable tampering"
X$ !check the master copy of the checks to see it has not been tamered with
X$ run check
Xchecksums.dat
X$ inquire ready "Hit <CR> to continue "
X$ !clean up
X$ delete/noconf/nolog checksums.acc;*
X$ delete/noconf/nolog check.obj;*
X$ delete/noconf/nolog check.exe;*
X$ set term/width=80
X$ ivv=f$verify(iv)
$ CALL UNPACK CHECK.COM;20 254702048
$ create 'f'
X`09.title`09check_images
X`09.subtitle`09declarations
X;
X;`09program to check selected files for different checksums and
X;`09crc's to see if they have been mofified. This program is
X;`09an advancement over CHECKSUM in that it does more than one
X;`09type of check and it would be extreamly difficult for a
X;`09hacker to make a modification that could still match
X;`09all seven different checks.
X;
X;`09Michael N. LeVine
X;`09Code 3514
X;`09Naval Weapons Center
X;`09China Lake
X;`09Ca 93555
X;`09(619) 939-3970
X;`09 avn  437-3970
X;
X;`09to add a new crc calc to list-modify the declaration
X;`09of "number_of_crc" below to the new value
X;`09then add to the end of each list below the required
X;`09information as noted
X;
X`09.enable`09debug
Xnumber_of_crc=4
X`09$rmsdef
X`09.page
X`09.subtitle`09pure data
X`09.psect`09pure_data,rd,nowrt,noexe,shr,page,gbl,novec
X;
X;`09CRC polynomial is specified as outlined in the VAX Architecture
X;`09reference manual entry on the CRC instruction
X;
X;`09add new crc polynomial to end of this table
Xcrc_poly:`09
X`09.long`09`5Eo00120001`09; CRC-16
X`09.long`09`5Eo00102010`09; CCITT
X`09.long`09`5Exedb88320`09; AUTODIN-II
X`09.long`09`5Eo00007401`09; CRC-12
X;
X;`09this table is used when the final CRC is to be extracted from the
X;`0932 bit long word. This is the length of the CRC (highest order
X;`09element of the CRC polynomial).
X;
X;`09add bit length of new crc polynomial to end of this table
Xcrc_length:
X`09.long`0916`09; CRC-16
X`09.long`0916`09; CCITT
X`09.long`0932`09; AUTODIN-II
X`09.long`0912`09; CRC-12
X;
X;`09What is the starting value of the CRC ?
X;`09usually 0 or -1
X;
X;`09add inital value of new crc polynomial to end of this table
Xcrc_init:
X`09.long`090`09; CRC-16
X`09.long`09-1`09; CCITT
X`09.long`09-1`09; AUTODIN-II
X`09.long`090`09; CRC-12
X;
X;`09output is to sys$output- a single line generated by SYS$FAO
X;`09useing the format string below
X;
X;`09add name of new crc to strings below. Modify list to keep length
X;`09132 chars or less.
Xformat_string:
X;`09`09`09`09`09item`09`09length`09ending byte
X`09.ascii`09?!20<!AD!> ?`09`09;name`09`0921`0921
X`09.ascii`09?Cksum8=%X!XB ?`09`09;chksum8`0912`0933
X`09.ascii`09?Cksum16=%X!XW ?`09;chksum16`0915`0948
X`09.ascii`09?Cksum32=%X!XL ?`09;chksum32`0919`0967
X`09.ascii`09?CRC16=%X!XW ?`09`09;CRC 16`09`0913`0980
X`09.ascii`09?CCITT=%X!XW ?`09`09;CCITT`09`0913`0993
X`09.ascii`09?AUTODIN-II=%X!XL ?`09;AUTODIN-II`0922`09115
X`09.ascii`09?CRC12=%X!3XW ?`09`09;CRC-12`09`0912`09127
X;
X;`09no more additions are needed for a new CRC calculation
X;
Xformat_length=.-format_string`09`09; descripter for FAO format string
Xformat:`09.long`09format_length
X`09.address`09format_string
X
Xget_file_arg:`09`09`09`09; argument used for LIB$GET_COMMAND
X`09.long`094`09`09`09; to input name of next file
X`09.address`09file_name`09; or files (wild card) to check
X`09.address`09file_prompt
X`09.address`09file_length
X`09.address`09force
Xfile_prompt:
X`09.ascid`09/File name ? /
X
Xff_arg:`09.long`093`09`09`09; argument list for LIB$FIND_FILE
X`09.address`09file_length`09; to step thorough a list of files
X`09.address`09ff_name`09`09; specified by a wild card
X`09.address`09ff_context
X
Xffe_arg:`09`09`09`09; arguemnt list to LIB$END_FIND_FILE
X`09.long`091`09`09`09; when done with one file spec
X`09.address`09ff_context`09; with all its wild card permutations
X
X`09.page
X`09.subtitle`09impure data
X`09.psect`09impure_data,rd,wrt,noexe,noshr,page,gbl,novec
X;
X;`09The CRC tables used by the CRC inst. are built at run time
X;`09and stored here
X;
Xcrc_tables:
X`09.blkl`09<16*number_of_crc>
X;
X;`09the current value of each CRC is stored in this table while
X;`09not in use
X;
Xcrc_value:
X`09.blkl`09number_of_crc
X;
X;`09the file name specification input via the LIB$GET_FOREIGN
X;`09stored below useing 2 descripters, one passing the full
X;`09length of the buffer available, the other getting the
X;`09length of the string read for further processing
X;
Xfile_name:
X`09.long`091024
X`09.address`09file_string
Xfile_length:
X`09.long`090
X`09.address`09file_string
Xfile_string:
X`09.blkb`091024
X;
X;`09LIB$FIND_FILE found name returned here
X;
Xff_name:
X`09.long`091024
X`09.address`09ff_string
Xff_length:
X`09.long`090
X`09.address`09ff_string
Xff_string:
X`09.blkb`091024`20
Xff_context:
X`09.long`090
X;
X;`09the results of the calculation are converted to ascii string
X;`09and stored in the string below. two descripters are used, one
X;`09to pass to FAO the size of the buffer available, the other to receive
X;`09the length actually used and to pass on the actuall string to be printed
X;
Xoutput_buffer:
X`09.long`09132
X`09.address`09output_string
Xoutput_length:
X`09.long`090
X`09.address`09output_string
Xoutput_string:
X`09.blkb`09132
X;
X;`09all checksums are stored below between update calc's
X;
Xchecksum_8:
X`09.long`090
Xchecksum_16:
X`09.long`090
Xchecksum_32:
X`09.long`090
X;
X;`09used by LIB$GET_FOREIGN to force prompt on prompts 2..n
X;
Xforce:`09.long`090
X
X`09.page
X`09.subtitle`09io data structures
X`09.psect`09io_data_structures,rd,wrt,page,noshr,noexe,gbl,novec
X;
X;`09for more info-read RMS reference manual
X;
X`09.align`09long
Xfab:`09$fab
X`09.align`09long
Xrab:`09$rab
X`09.align`09long
Xnam:`09$nam`09`09`09; Name block is used to extract full name
X`09.align`09long`09`09; of file to be checked
Xnam_work:
X`09.blkb`09256
Xnam_exp:
X`09.blkb`09256
Xio_buffer:
X`09.blkb`0916384`09`09; buffer to hold part of file for check
X
X`09.page
X`09.subtitle`09once only init
X`09.psect`09code,rd,nowrt,exe,shr,gbl,novec,long
X`09.entry`09check,`5Em<r2,r3,r4,r5,r6,r7,r8,r9,r10,r11>
X`09clrl`09force`09;first read-prompt is optional
X;
X;`09rebuild the CRC tables for each CRC
+-+-+-+-+-+-+-+-  END  OF PART 1 +-+-+-+-+-+-+-+-


