Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

RedHat Security Audit

by redleg7 (Initiate)
on Feb 18, 2009 at 14:17 UTC ( [id://744764]=sourcecode: print w/replies, xml ) Need Help??
Category: Networking
Author/Contact Info
Description: Recently went thru a security audit and used this script to check some basic secuity issues on the RedHat boxes.

use strict;
use warnings;


# $user, $passwd, $uid, $gid, $gecos, $homedir,  $shell
my ($sysShells, $badShells, $passwds, $uid, $gid, $wheel, $ssh);
$sysShells = "\nUSER:PASSWD:USERID:GROUPID:GECOS:HOMEDIR:SHELL";
$badShells = "\nBAD SHELLS \n(except for root, system user shells shou
+ld be /sbin/nologin)\nuser|uid|shell";
$passwds = "\nCLEAR or EMPTY PASSWORDS\n(password field not set to x, 
+should see no output)";
$uid = "\nUSERS with UID of ZERO \n(should only be root)\nuser|uid|gid
+|shell";
$gid = "\nUSERS with GID of ZERO \n(should be root plus all members of
+ root group)\nuser|uid|gid|shell";
$wheel = "\nUsers in WHEEL GROUP:\n";
$ssh = "\nSSH CONFIG (selected options)\n";

# copy the password file
my $passwdFile = 't_e_s_t_passwd';
my $copy = `cp -pf /etc/passwd $passwdFile`;

unless(open(READFILE, "<$passwdFile"))
{
    print "Error opening file $passwdFile\n";
    die;
}
my @userIDsShells = <READFILE>;
close(READFILE);

# delete the copy of password file
my $remove = `rm -f $passwdFile`;


my $run = 1;
while($run)
{
    print "\nPlease enter a selection from the list below:\n";
    print "users    :     all users, paswords, user IDs, group IDs, co
+mments, home directory, and shells.\n";
    print "passwds  :     all users with Empty passwords, enter passwd
+s.\n";
    print "uid      :     all users with UID 0 (root access).\n";
    print "gid      :     all users with GID 0 (root access).\n";
    print "shells   :     system users, who do not have \/sbin\/nologi
+n as their shell.\n";
    print "wheel    :     users in wheel group.\n";
    print "sshd     :     selected sshd_config options.\n";
    print "exit     :     to exit.\n";
    print "\n*********************************************************
+**********************\n";

    chomp(my $choice = <STDIN>);

    if($choice eq 'users')            { showUsers($sysShells, @userIDs
+Shells);}
    elsif($choice eq 'passwds')       { showEmptyPasswds($passwds, @us
+erIDsShells);}
    elsif ($choice eq 'uid')          { showUsersWithUIDofZero($uid, @
+userIDsShells);}
    elsif ($choice eq 'gid')          { showUsersWithGIDofZero($gid, @
+userIDsShells);}
    elsif($choice eq 'shells')        { showSystemUsersWithBadShells($
+badShells, @userIDsShells);}
    elsif($choice eq 'wheel')         { limitSUcmdToWheel($wheel);}
    elsif($choice eq 'sshd')           { selectedSSH_ConfigOptions($ss
+h);}
    elsif ($choice eq 'exit')         { print "Goodbye!!!\n"; $run=0;}
    else                              { print "Bad choice.  Try again.
+\n"; message();}
}

######################################################################
+##################################

sub showUsers
{
    my $header = shift;
    my @array = @_;
    print "\n*********************************************************
+**********************\n";
    print "$header\n\n";
    for(my $index=0; $index<@array; $index++)
    {
         print "$array[$index]\n";
    }
    print "\n*********************************************************
+**********************\n";
    
    return;
}


sub showEmptyPasswds
{
    my $header = shift;
    my @array = @_;
    print "\n*********************************************************
+**********************\n";
    print "$header\n\n";
    if(@array == 0)
    {
        print "NONE\n";
    }
    else
    {
        for(my $index=0; $index<@array; $index++)
        {
          chomp($array[$index]);
          my ($user, $passwd, $uid, $gid, $gecos, $homedir,  $shell) =
+ split/:/, $array[$index];
             if($passwd ne 'x')
             {
                 print "$user|$passwd\n";
             }    
         }
    }

    print "\n*********************************************************
+**********************\n";

    return;
}


sub showUsersWithUIDofZero
{
    my $header = shift;
    my @array = @_;
    my $nologin = '/sbin/nologin';
    print "\n*********************************************************
+**********************\n";
    print "$header\n\n";
    if(@array == 0)
    {
       print "NONE\n";
    }
    else
    {
        for(my $index=0; $index<@array; $index++)
        {
          chomp($array[$index]);
          my ($user, $passwd, $uid, $gid, $gecos, $homedir,  $shell) =
+ split/:/, $array[$index];
          if($uid == 0)
          {
              print "$user|$uid|$gid|$shell\n";
          }
        }
    }

    print "\n*********************************************************
+**********************\n";

    return;
}


sub showUsersWithGIDofZero
{
    my $header = shift;
    my @array = @_;
    my $nologin = '/sbin/nologin';
    print "\n*********************************************************
+**********************\n";
    print "$header\n\n";
    if(@array == 0)
    {
       print "NONE\n";
    }
    else
    {
        for(my $index=0; $index<@array; $index++)
        {
          chomp($array[$index]);
          my ($user, $passwd, $uid, $gid, $gecos, $homedir,  $shell) =
+ split/:/, $array[$index];
          if($gid == 0)
          {
              print "$user|$uid|$gid|$shell\n";
          }
        }
    }

    print "\n*********************************************************
+**********************\n";

    return;
}


sub showSystemUsersWithBadShells
{
    my $header = shift;
    my @array = @_;
    my $nologin = '/sbin/nologin';
    print "\n*********************************************************
+**********************\n";
    print "$header\n\n";
    if(@array == 0)
    {
       print "NONE\n";
    }
    else
    {
        for(my $index=0; $index<@array; $index++)
        {
          chomp($array[$index]);
          my ($user, $passwd, $uid, $gid, $gecos, $homedir,  $shell) =
+ split/:/, $array[$index];

          #print "\n\n$array[$index]\n";
          #print "**shell=$shell***     ***nologin=$nologin***\n";
          if($uid < 500  && $shell ne $nologin)
          {
              print "$user|$uid|$shell\n";
          }
        }
    }

    print "\n*********************************************************
+**********************\n";

    return;
}


sub limitSUcmdToWheel
{
    my $header = shift;
    my $wheel = `grep -i wheel /etc/group`;
    my $suConfig = `grep -i pam /etc/pam.d/su`;
    print "\n*********************************************************
+**********************\n";
    print "$header";
    print "$wheel\n";
    print "(\/etc\/pam.d\/su:  auth required \/lib\/security\/pam_whee
+l.so use_id)\n";
    print "$suConfig\n";
    print "\n*********************************************************
+**********************\n";
    
    return;

}


sub selectedSSH_ConfigOptions
{
    my $header = shift;
    my $allowedUsers = `grep -i allowusers /etc/ssh/sshd_config`;
    my $permitRootLogin = `grep -i permitrootlogin /etc/ssh/sshd_confi
+g`;
    my $permitEmptyPasswords = `grep -i permitemptypasswords /etc/ssh/
+sshd_config`;
    my $protocol = `grep Protocol /etc/ssh/sshd_config`;
    my $ignore = `grep -i ignorerhosts /etc/ssh/sshd_config`;
    my $client = `grep -i client /etc/ssh/sshd_config`;

    print "\n*********************************************************
+**********************\n";
    print "$header\n";
    print "$allowedUsers\n";
    print "$permitRootLogin\n";
    print "$permitEmptyPasswords\n";
    print "$protocol\n";
    print "$ignore\n";
    print "$client\n";
    print "$allowedUsers\n";
    print "\n*********************************************************
+**********************\n";
    
    return;
}


sub message
{
   print "\n\nPress enter to continue.\n";
   <STDIN>;
}
Replies are listed 'Best First'.
Re: RedHat Security Audit
by Your Mother (Archbishop) on Feb 18, 2009 at 17:34 UTC

    I'm not a sysadmin guy at all so I have no content feedback but I can suggest a little style to make this sort of script more maintainable and easier to read. So a big bunch of printing from your script looks like this-

    sub line { ( "*" x 70 ) . "\n" } print join("\n", line(), $header, $allowedUsers, $permitRootLogin, $permitEmptyPasswords, $protocol, $ignore, $client, $allowedUsers, line() ); # Update: I know someone will suggest it if I don't. # Instead of "sub line" you could do- # use constant LINE => ( "*" x 70 ) . "\n"; # -or- # my $Line = ( "*" x 70 ) . "\n";

    Though if this is something you really care about, I'd skip this intermediate step and use Template. Then you could have a plain text/terminal template, an HTML template, and whatever subsets you wanted.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: sourcecode [id://744764]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others examining the Monastery: (5)
As of 2024-03-28 16:06 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found