On three separate occasions this summer, our PIKT PasswdChkWarning alarm detected security break-ins, at least one telltale sign of which was the appending of a new account line to the passwd file with uid 0 (i.e., with root privileges).
All well and good, except that we run the Warning alarms just once nightly, so there would be as much as 24 hours before PIKT would report this serious passwd problem.
This has bothered me for some time, and I have finally done something about it. I have created a new PasswdChkUrgent alarm which copies the PasswdChkWarning alarm but excludes the non-critical problems. We run our Urgent alarms hourly. So, if passwd problems of an urgent nature happen again, we will get a much more timely report of them.
The PasswdChkUrgent alarm follows. (If you use this, be sure to register it in the Urgent stanza in alerts.cfg. Also, I have retained the critical stuff in PasswdChkWarning just in case.)
/////////////////////////////////////////////////////////////////////////////// PasswdChkUrgent init status active level urgent task "Report passwd problems/anomalies" input proc "=sort -t: +2n =passwd" seps ":" dat $username  dat $password  dat $uid  dat $gid  dat $gcos  dat $homedir  dat $shell  begin // assume no crisis (yet) set #crisis = #false() rule // nis? set $fc = $left($username,1) set #nis = ( $fc eq "+" ) || ( $fc eq "-" ) rule // system account? set #sysacct = ! #nis && ( #value($uid) < 100 ) rule // magic cookie? if #nis && #length($username) == 1 output mail "Illegal magic cookie line: $inline" next endif rule // set $uname, stripping off "+" or "-", if present set $uname = $substr($username,#if(#nis,2,1)) rule // non-root uid 0's if $uid eq "0" && ! #nis && ( $uname !~ "^(root|sundiag|sysdiag|smtp)$" || ( $uname =~ "^(sundiag|sysdiag)$" && $password ne "*" ) ) output mail "User $uname has UID OF 0!" output syslog "User $uname has UID OF 0!" set #crisis = #true() endif rule // no password if $password eq "" && ! #nis output mail "User $uname has NO PASSWD!" output syslog "User $uname has NO PASSWD!" if $uname eq "root" set #crisis = #true() endif endif end // drastic change in passwd file size set #lines = #innum() if #defined(%lines) && ((%lines != 0 && (#lines - %lines)/%lines >= 20% ) || (%lines != 0 && (#lines - %lines)/%lines <= -25% )) output mail "the size of /etc/passwd has changed by >= 20%, was $text(%lines) lines, is now $text(#lines)" set #crisis = #true() endif // we have paging capabilities available, but i haven't had // time yet to implement this; wam, how about it? // if #crisis // page if crisis //#ifdef doexec // exec wait "=page =crisispagers =passwdchkpagecode" //#endifdef // endif ///////////////////////////////////////////////////////////////////////////////
For more examples, see Developer's Notes.