Automating UNIX Security Monitoring
Robert Geiger and John Schweitzer
It's no secret to anyone working in the IT business that security, while always a relevant concern, has reached a prominent position on most organizations' priority lists. At the same time, systems administrators continue to be among the most overworked IT people on a day-to-day basis. To be sure, the daily security management of any large network is an arduous task, with firewalls shouldering much of the burden and considered the front line in protecting a company's information assets. But the importance of providing rock-solid host security with stringent, daily monitoring cannot be overstated.
Most information security professionals concede that it is impossible to make a system 100-percent hacker proof. However, keeping a close eye on a system's security vital signs will allow a systems administrator to quickly catch hackers, or perhaps repel an attack in progress.
There are some relatively easy ways to automate monitoring, and this article will address ways in which a systems administrator can use scripts and other automated routines to watch a UNIX system for intrusions and attempts at system breaches. With moderate scripting ability, the accompanying code will illustrate a cheap, simple method of security monitoring.
All of the scripts listed in this article are meant to be run from cron on a regular basis -- daily or hourly, depending on the routine in question -- with the output going to either email or to the systems administrator's pager. However, none of the things described in this article are foolproof. UNIX security mechanisms are only relevant if the root account has not been compromised. For example, scripts run through crontab can be easily disabled or modified if the attacker has attained root access, and most log files can be manipulated to cover tracks if the intruder has control over the root account.
We will focus on some important facets of systems administration, including suspicious log entries, network adapters going into promiscuous mode, strange directories appearing, and the number of SUID root files mysteriously changing. While in most cases Tripwire would do a tremendous job of finding changes to the integrity of system files and directories, the software can sometimes take a long time to run, thus making it impractical to use many times in one day. Tripwire may also be overkill on many systems, and managing the output may become an untenable burden.
These scripts provide a poor-man's way of monitoring for key security events. One of the common themes in this article is that the systems administrator doesn't need to be bothered for normal operation. Therefore, these scripts don't make any noise when nothing is wrong.
Finally, these scripts cannot be all things to all people because of the differences in how some UNIX variants work, and because of the factors that affect what is a relevant security event in one systems environment versus another.
We hope that this is a good overview and that these scripts and their conceptual underpinnings will help in the daily monitoring of your systems.
What's your Operating System?
Although we knew it would be far easier to focus on one kind of UNIX for this article, we wanted to make this portable across a couple of UNIX types -- specifically Linux and Solaris, given their wide install base. Most of these scripts can be easily modified to run on other types of UNIX -- such as FreeBSD, OpenBSD, AIX, and HP-UX -- and may even run as-is on some.
Listing 1 shows os.sh, which determines the system's operating environment and is called by all other scripts included with this article. It's assumed location in all other scripts is /usr/local/bin. (All listings for this article are available from the Sys Admin Web site: http://www.sysadminmag.com.)
A key feature of os.sh is found in the ALARM_COMMAND variable, which drives how each script in this article will alert the systems administrator of security events. It simply emails the alert generated by each script to a local mail account, Internet email address, pager, or cell phone, assuming the system being monitored has Internet access.
Who's Watching Your Back?
Logs are truly the lifeblood of monitoring your system and, if they're implemented and watched closely, will give you a ton of important information. Watching system log files is much easier said than done. The majority of the time, they reflect perfectly normal system events and, at the very least, show anomalies that are usually hardware or software problems, rather than security related.
However, these logs can still show hackers knocking at your doors. For example, error messages from daemons like Sendmail and finger can signal break-in attempts, and repeated login failures could signal a brute-force effort to breach your systems.
check_logs.sh in Listing 2 checks common system logs and finds suspicious entries based on the values assigned to the REDFLAGS variable. This is done through a nested set of for loops checking each log file for each word defined in REDFLAG. The script outputs to a file and uses the diff command to discern the differences between the current output and a previous run, so problems are only reported once.
The LOGFILES variable, set in os.sh, determines the logs that are examined. syslog, the central logging facility in UNIX, typically defaults to either /var/adm/messages or /var/log/messages, depending on your UNIX variant. The LOGFILES variable can be customized to have check_logs.sh look at any log you choose.
The REDFLAG variable lists various keywords that, if found in logs, will make the script alert the systems administrator. It contains parts of several common error messages:
excessive -- This usually comes in the form of excessive login failures and could denote a brute-force password attack.
vrfy -- From the SMTP vrfy command for username identification.
expn -- From the SMTP expn command; also good for username identification.
snort -- Any alerts from the output of snort should alert the systems adminstrator.
portsentry -- Anything that portsentry finds could be bad, as well.
The REDFLAG variable can be modified in this script to contain as many words as the systems administrator believes are red flags in their environments. For example, the words failed or failure may be helpful to some administrators since they could help spot password attacks, but may result in too many pages due to simple login errors on multi-user machines. Having pop3 or fingerd as flagging words may alert you to attempts to exploit those services. There are many variations, and users should experiment with those most appropriate to their environments and their system's normal usage.
Are Filesystems Getting Overgrown?
An important component of the availability part of system security is ensuring that you know when filesystems are running out of disk space. Monitoring for filesystem growth will also allow you to notice a filesystem's free space shrinking -- through user or system error -- in time to investigate and correct the problem. Additionally, sudden increases in the amount of filesystem space used may alert you to someone storing unauthorized files on your network.
Listing 3 shows check_filesys.sh, which will watch all filesystems and send an alert when the space used exceeds the number defined with the MAX_PERCENT variable. The EXEMPT variable can be used to exclude filesystems from this scrutiny if they are static in size, but typically over the space usage limit set in MAX_PERCENT.
Mind Your crons and ats
Automated routines performed by the cron daemon, such as cron and at jobs, are an extraordinary convenience to systems administrators. They are also a devious place for an intruder to plant a regenerating backdoor that will keep duplicating itself at a set date and time if the systems administrator finds the original.
Listing 4 shows the script time_sync.sh, which will compare trusted copies of root's normal cron and at configuration, stored in /etc/master, against whatever is running as the current versions. So, why the odd filename time_sync.sh? If an intruder were to seize the root account, and thus have the ability to modify or delete any alarms in root's crontab, this may give the script a name that's innocuous enough not to draw the attacker's attention. There should never be changes of unknown origin on root-owned routines, and the existence of such changes may signal a system breach.
Things that Shouldn't Change Overnight
While there are things on a UNIX system that change constantly, certain key components don't change much and, when they do, the systems administrator should know when and why the changes occurred.
This certainly applies to the checks done in check_crit_files.sh (Listing 5), which monitors inetd.conf, the system startup directories, the number of users in /etc/passwd, and the system's supply of .rhosts files. check_crit_files.sh will constantly compare against trusted results stored in /etc/master and notify you of any sudden changes.
inetd.conf, which controls most running system services, should be watched carefully so that you know which services are running on your system. This script compares the current version of the file with a trusted version to verify that no unauthorized additions or changes have been made. This will allow you to notice anything suspicious, such as the appearance of new entries that execute shell programs.
System startup routines seldom change, except for installations of new software or invoking new services not started in inetd.conf. And, the contents of the /etc/rc* directory structure should certainly not be modified without your knowledge. This is because system boot routines will often be modified by intruders to install back doors each time a system boots, enabling them to renew their access or to alter the services running on the system.
Trusted host relationships are the double-edged sword of systems administration because they can make life very convenient when managing multiple systems, but they can also be a security nightmare. It's therefore important to occasionally sweep the system for all .rhosts files and pay special attention when new files suddenly appear.
Likewise, there's seldom a good reason for new user IDs to be generated without the systems administrator's knowledge, and this script will alert you to any added or deleted user IDs.
Is Your Network Adapter Promiscuous?
Having your system's network adapter suddenly go into promiscuous mode (in which it sniffs the entire network for packets and not just those bound for its address) is a good sign that your system has been hacked and that you should be notified immediately.
The script in Listing 6, check_promisc.sh, will tell you when your Linux system's adapter is promiscuous and will work for other UNIX variants whose ifconfig command reports promiscuous mode. This script can be easily modified to use other dedicated promiscuous mode detectors, such as ifstatus, cpm, and promisc, if your UNIX's ifconfig does not do it.
As we did with the script checking automated routines, you may want to rename this script or embed it in another script so that it is transparent to an attacker (who would have gotten root to run a sniffer on your system).
Who is su'ing to root?
Security-minded systems administrators should watch every avenue that an attacker could use to access the root account, and logging of the su command is one of the biggest. The check_su.sh script in Listing 7 does that by referencing os.sh for your UNIX variant's standard su logging mechanism, extracting root entries, and notifying you if unauthorized people have attempted (or succeeded) to access root via the su command.
The OK_TO_SU variable allows you to exempt user IDs that have a legitimate reason to su to root, and for which you do not wish to receive notification. The script also dumps the current su log contents elsewhere, and reinitializes the log so you aren't paged with the same event the next time this script runs.
Monitor Supply of SUID/SGID Files
The Set User ID (SUID) and Set Group ID (SGID) functions allow any user who is executing files set with such privileges to run the associated process with owner or group-owner privileges. This is especially dangerous when the owner of the file is root.
Because SUID root files are a major security exposure, most notably, with buffer overflow attacks, it's a good idea to remove this setting from all possible binaries. (It's not always possible because users are unable to log in if the login command is not SUID root, but many other commands that aren't accessed by the average non-root user can easily get by without that setting.)
Listing 8 shows check_suid_sgid.sh, which counts the system's inventory of these files and reports any discrepancy. It is especially important that the systems administrator be aware of any new SUID root files that suddenly appear, because this is a common mechanism used by intruders to leave back doors on a UNIX system.
This script assumes that there are no rogue SUID or SGID files on the system the first time it is run, stores that trusted output in /var/tmp, and then compares the number of files found the next time the script is run. It then notifies whoever is designated in ALARM_COMMAND in the os.sh script when variations are found.
Should That Account Have a UID Number of 0?
find_new_zeros.sh in Listing 9 simply looks at /etc/passwd and reports any new user IDs that have a UID number of zero in an entry's third field. This is important as UNIX systems recognize any UID number of zero as the root user, regardless of the English-language name of the user ID. For obvious reasons, a new root-equivalent user ID may be a bad sign for your system security efforts. Listing 9 allows you to exempt IDs other than root from this scrutiny via the TOOR_IS_OK and TOOR_USERIDS variables.
Watch for Nasty Hiding Places
No self-respecting attacker is going to leave files, back doors, or other evidence where a systems administrator can easily discover them and, because UNIX allows for so many unusual characters in file and directory names, it's important to watch for new ones on your system. Although there are some strange directory entries on any UNIX system, it is unusual to have the number of these increase overnight or in any short period of time.
check_odd_dirs.sh in Listing 10 keeps an eye out for odd directory entries, keeps a static list in /var/tmp and notifies the appropriate party of any unusual items found. Of course, any new such directories found should be investigated immediately.
There's always more than one way to do anything in UNIX, and we would never claim that these scripts are an exhaustive treatment of how to keep tabs on all facets of your system's security. Tripwire and TCP Wrappers are invaluable tools and will do a wonderful job on a good number of the things we have tried to highlight in our home-grown solutions.
However, if time is short and a quick security fix is required, these scripts will give you a quick way to get on the road to more proactive monitoring of your systems.
In addition to doing good backups, staying informed on UNIX security issues and vulnerabilities and maintaining good anecdotal knowledge of all systems you administer, and making sure you hear about bad things happening to your system before your co-workers or boss are also important aspects of the job.
About the Author
Bob Geiger is VP of Information Security Services for info-defense.com (www.info-defense.com), a network security consultancy. A popular speaker on the security conference circuit, Bob has been working in systems administration and security for 15 years. He lives in Westchester County, New York, with wife Sandi and raging toddler Sammy and can be reached at: email@example.com.
John Schweitzer is a Senior Security Consultant for the information security consultancy info-defense.com. He has been coding and securing UNIX variants for almost 10 years, and honestly can't believe that he gets paid to do this for a living. John lives in Herndon, Virginia with his amazingly tolerant wife Sonya, and their three cats, who are up-and-coming Linux zealots.