Tuesday, January 8, 2008

Simple Script To Generate COPS Filter Files

Hey There,

For those of us out there that still use COPS (Not the new Persistence Checker, but the good old Computer Oracle and Password System) for Unix or Linux, today's script should come in handy. The program, itself, is obsolete (replaced by other programs like Tiger, which we'll touch on in a future post), but it seems to pop up almost everywhere I go and, while it may not be able to identify the latest and greatest operating system exploits, it's still good for finding those bad things that remain constant.

Since this package is so hard to find nowadays, I've put it up here as cops.zip. As an added bonus (depending on how you look at it, I suppose), the version I put up there has the hack already built into the COPS script so it doesn't litter up your hard drive with .FILT files, there's a sample email output and I've also included today's script in the distribution. Hopefully, I'm not breaking any laws. If I find out I am, I'll pull it, but I don't think that will be necessary. The whole distro should be good to go. You'll just need to edit the lines that ask you to edit them in the COPS script . Oh yes, also extract it into its own folder :)

This script addresses the issue of how COPS makes use of filtering. When you first run COPS, you're basically taking a baseline reading. You'll get emailed a number of errors (or you can just have them dumped to an output file - the configuration preference is yours) on the initial run, with regards to problems the software finds on your system, which is executed like so:

./cops

Not very complicated, I know ;) Once done, you then correct all the errors you need (or want) to by running the script, checking output, running the script again, etc, etc, etc.

Now, with COPS (as with most security software), you're going to end up getting notified of any number of errors that you are willing to accept (For instance - if you run sendmail, it will always complain that the version you're running "may have a hole/bug"). And that's were the filter file comes in. With a COPS filter file all set up, you can run the program like this, and not get notified unless you have an issue you need to tend to:

./cops -f ./cops_filter <--- Note that the "-f" is the important flag here. You can call the filter whatever you want.

Simple enough, yes? In a way. The reason I wrote this script is that COPS' filter file is actually an awk script that it feeds its results through; after which it emails you if there's any output left. Outside of the main construct of the filter file, you don't really have to change much to augment the basic example filter that comes with the distribution. But, you do need to know enough about awk, to be able to extend the matching it does, to include the entries you don't want to be notified of. That, in my experience, is one of the leading causes of heartburn on the job ;)

And, so, here we have it. A little shell script (for Linux and/or Unix) which writes an awk file. I chose to call the output cops_filter, just based on the standard naming convention, but you can modify this as you need. Note that the script also backs up your current filter file and lets you know what it called it, just in case you lose track at some point. It accepts input from a file that you can create manually or by cutting and pasting a COPS email message directly (just the body; no headers please!)

This program can be run simply and requires no arguments, as it's all menu driven:

./cfm <--- Or whatever you want to call it.

Easy :)

Best Wishes,


Creative Commons License


This work is licensed under a
Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License

#!/bin/ksh
#
# CFM - COPS Filter Maker - 2008 Mike Golvach - eggi@comcast.net
# Works equally well with COPS-Produced Source Or a Saved COPS
# Mailing. Will create a new filter file or augment an existing one.
#
# Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License
#

trap 'echo;echo "Bailing Out and Cleaning Up...";echo;clean_up;exit 1' 1 2 3 15

function clean_up {
rm -f harpo zeppo tempo newtempo filterfile
}

function stand_err {
echo
echo "$1 doesn't seem to exist!"
echo "Put it in this directory or use"
echo "an absolute pathname!!"
echo
echo "(Hit Return To Continue)"
read OBLIGSTOP
echo
clean_up
exec ./cfm
}

function part_one {
echo "/Warning!/ {" >> filterfile
echo "if (warning) print warning_msg" >> filterfile
echo "warning = skip_next = 0" >> filterfile
echo >> filterfile
echo "if ((\$0 ~ /Warning! Opening Bracket, If this gets \
matched, you've got strange problems!/) || \\" >> filterfile
}

function part_two {
sed -e 's/^X/(\$0 ~ \//' tempo >> newtempo
sed -e 's/.$/\/) || \\/' newtempo > tempo
sed -e 's/\//\\\//g' tempo > newtempo
sed -e 's/\\\/W/\/W/' -e 's/\\\/)/\/)/' -e 's/\\\/bug *.*\//\//' -e 's/\\\/ftp-Warning/\/ftp-Warning/' newtempo > tempo
sed -e 's/(/\\(/g' -e 's/)/\\)/g' tempo > newtempo
sed -e 's/\\(\$/(\$/' -e 's/\\) |/) |/' newtempo > tempo
cat tempo >> filterfile
echo "(\$0 ~ /Warning! Thanks for the ride!/)) {" >> filterfile
echo "skip_next = 1" >> filterfile
echo "next" >> filterfile
echo "}" >> filterfile
echo >> filterfile
echo "warning = 1" >> filterfile
echo "warning_msg = \$0" >> filterfile
echo "}" >> filterfile
echo >> filterfile
echo "! /Warning!/ {" >> filterfile
echo "if (warning)" >> filterfile
echo "print warning_msg" >> filterfile
echo "warning = 0" >> filterfile
echo "if (!skip_next && \$0 !~ /\*\*\*\*/)" >> filterfile
echo "print \$0" >> filterfile
echo "}" >> filterfile
echo "/\*\*\*\*/ {" >> filterfile
echo "print \$0" >> filterfile
echo "}" >> filterfile
echo
}

if [[ $# -ne 0 ]]
then
echo
echo "Ooops! Usage: cfm ...and that's all"
echo
exit 1
fi
clear
typeset -x COLUMNS=1
echo
echo " COPS FILTER MAKER"
echo "---------------------------------"
echo " Are You..."
select ANSWER in "Creating A New Filter?" "Adding To An Existing Filter?" "Ending It All?"
do
case $REPLY in
1 )
echo
echo "What file are you creating the filter from?"
echo
read COPSOURCE
if [[ ! -f $COPSOURCE ]]
then
stand_err $COPSOURCE
fi
part_one
sed -e '/^ *$/d' -e 's/^Warning/XWarning/' -n -e '/^XWarning/p' -e 's/^ftp-Warning/Xftp-Warning/' -n -e '/^Xftp-Warning/p' $COPSOURCE >> tempo
part_two
echo "Filter file \"cops_filter\" created successfully!"
echo
break;;
2 )
echo
echo "What's the name of the existing filter?"
echo
read COPSORIG
if [[ ! -f $COPSORIG ]]
then
stand_err $COPSORIG
fi
part_one
sed -n -e '/^(\$/p' $COPSORIG >> harpo
sed -e '/)) {/d' harpo >> zeppo
cat zeppo >> filterfile
echo
echo "What file are you adding from?"
echo
read ADDFILE
if [[ ! -f $ADDFILE ]]
then
stand_err $ADDFILE
fi
sed -e '/^ *$/d' -e 's/^Warning/XWarning/' -n -e '/^XWarning/p' -e 's/^ftp-Warning/Xftp-Warning/' -n -e '/^Xftp-Warning/p' $ADDFILE >> tempo
part_two
echo "Augmented filter file \"cops_filter\" created successfully!"
echo
break;;
3 )
clean_up
echo
echo "Cleaning up Temp Files..."
echo
echo "All gone!"
echo
exit 1;;
* )
echo
echo "$REPLY, huh?"
echo
echo "Press Return to Get On With It..."
read OBLIGSTOP
exec ./cfm;;
esac
done
rm -f harpo zeppo tempo newtempo
if [[ $COPSORIG == COPS_filter ]]
then
SIGN=$$
mv cops_filter cops_filter.$SIGN
echo "The original has been copied to \"cops_filter.$SIGN\"!"
echo
fi
if [[ -f cops_filter ]]
then
SIGN=$$
echo "Other COPS_filter file found! Copied to cops_filter.$SIGN!"
echo
mv cops_filter cops_filter.$SIGN
fi
mv filterfile cops_filter
exit


, Mike