Bugtraq mailing list archives

Re: Checking for most recent Solaris Security Patches


From: waider () SCOPE IE (Ronan Waide)
Date: Thu, 7 Jan 1999 09:41:00 +0000


--wXN96xPRKk
Content-Type: text/plain; charset=us-ascii
Content-Description: message body text
Content-Transfer-Encoding: 7bit

On January 6, spamhater () GRYMOIRE COM said:
Enclosed is a script that checks if your Solaris system has the
latest security patches applied.

It FTP's the status file from Sun's site, caches a local copy, does a
"showrev -a", compares the two, and reports out-of-date patches.
This is not a perfect test, but it is quick and easy, and some might find
it useful.

If the local copy is old, you either get a warning, or a forced update
of the patch information file. (A configuration option).

The package requires expect and perl 5 (no perl modules need be
installed).

Funnily enough... :)

I've a version of a similar program sitting on one of the Solaris
boxen here for the last few months, which I hacked together after
getting fed up with doing the job manually. It's almost purely perl;
no expect, no variable settings. It's not got commandline switches
either, since I wrote it for my own use.

Module-wise, it uses Net::FTP to do the fetching, and POSIX (part of
the core distribution anyway) to get your OS details.

Anyway, here it is. YMMV. It's only been used on 2.4 and 2.6, so if it
catches fire, lemme know what broke.

Cheers,
Waider.

--wXN96xPRKk
Content-Type: text/plain
Content-Description: patch checker in Perl
Content-Disposition: inline;
        filename="patchcheck.pl"
Content-Transfer-Encoding: 7bit

#!/usr/local/bin/perl -w

use Net::FTP;
use POSIX; # for uname

$ftp = undef;

# You may wish to edit these
$PATCHHOST='sunsolve1.Sun.COM';
$PATCHDIR='/pub/patches';
$SHOWREV='/usr/bin/showrev -p';

# Check OS version
$os = (uname)[0];
$osver = (uname)[2];

# Gah. SunOS $osver is 5.x instead of Solaris' 2.x. I guess subtract 3...
$osver = $osver - 3 if ( $os eq 'SunOS' );

$RECOMMENDED=$osver.'_Recommended.README';

$|=1;

print "Fetching $RECOMMENDED from Sun...";
maybe_fetch_file( $RECOMMENDED );
print "done.\n";

open( PLIST, "$SHOWREV|" ) || die $!;
open( RECOM, "<$RECOMMENDED" ) || die $!;

while( <PLIST> )
{
        (undef, $patch, undef) = split;
        ($id, $rev) = split(/-/, $patch);
        $erev = $installed{ $id };
        $erev ||= '00';
        print STDERR "already: $erev\n";
        $installed{ $id } = $rev if $rev > $erev;
}
%recommended = map
{
        if ( /^[0-9][0-9][0-9][0-9][0-9][0-9]\-[0-9][0-9]\s+/ )
        {
                chomp;
                ($patch, undef) = split;
                ($id, $rev) = split(/-/, $patch);
                $id => $rev ;
        }
        else
        {
                'dud' => 'dud';
        }
} <RECOM>;

close( RECOM );
close( PLIST );

%patches = map { $_ => $_ } keys %installed;
for( keys %recommended )
{
        $patches{ $_ } = $_ unless $_ =~ /dud/;
}
@patches = keys %patches;

print "Patch Report\nID\tInstalled\tRecommended\tAction\n";

for( @patches )
{
        $inst = $installed{ $_ };
        $rec = $recommended{ $_ };
        $inst ||= '00';
        $rec ||= '00';

        $action = ( $inst < $rec ) ? "fetching..." : "installed\n";

        printf "$_ \t%s\t\t%s\t\t%s", $inst, $rec, $action;
        if ( $action eq "fetching..." )
        {
                maybe_fetch_file( "$_-$rec.tar.Z" );
                print "done.\n";
        }
}

if ( $ftp )
{
        $ftp->close();
}

sub maybe_fetch_file()
{
        $file = shift;

        # check for local copy of the file
        if ( -r $file )
        {
                # stat local copy, get mtime & size
                (undef, undef, undef, undef, undef, undef, undef, $locsz,
                 undef, $loctm, undef, undef, undef ) = stat( $file );
        }
        else
        {
                $locsz = 0;
                $loctm = 0;
        }

        # check if ftp connection is live, reopen if necessary
        if ( !defined( $ftp ) || !ref( $ftp ) || !$ftp->pwd )
        {
                $ftp = Net::FTP->new( $PATCHHOST );
                $ftp->login( 'anonymous', 'waider () scope ie' );
                $ftp->cwd( $PATCHDIR );
                $ftp->pasv();
                $ftp->binary();
        }

        # check mtime & size of remote copy
        $remsz = $ftp->size( $file ) || die $!;

        # if mtime of local is more recent & sizes match, return
        if ( $remsz == $locsz )
        {
                $remtm = $ftp->mdtm( $file );
                if ( $remtm <= $loctm )
                {
                        return;
                }
        }

        # fetch file
        $ftp->get( $file );
}

--wXN96xPRKk
Content-Type: text/plain; charset=us-ascii
Content-Description: .signature
Content-Transfer-Encoding: 7bit


--
waider () scope ie / Scope Communications / +353-1-8303455 / +353-1-8300888 (Fax)
"When you say `I wrote a program that crashed Windows', people just stare
 at you blankly and say `Hey, I got those with the system, *for free*'"
                                                   - Linus Torvalds

--wXN96xPRKk--



Current thread: