Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 71 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
71
Dung lượng
406,19 KB
Nội dung
475 In most large shops there is a need, at least occasionally, to monitor a user’s actions. You may even want to audit the keystrokes of anyone with root access to the system or other administration type accounts, such as oracle. Contractors on site can pose a par- ticular security risk. Typically when a new application comes into the environment one or two contractors are on site for a period of time for installation, troubleshooting, and training personnel on the product. I always set up contractors in sudo (see Chapter 14 for more details on sudo) to access the new application account, after I change the pass- word. sudo tracks only the commands that were entered with a date/time stamp. The detail of the command output from stdout and stderr does not get logged so you do not have a complete audit trail of exactly what happened if a problem arises. To get around this dilemma you can track a user’s keystrokes from the time he or she accesses a user account until the time he or she exits the account, if you have the space for the log file. This little feat is accomplished using the script command. The idea is to use sudo to kick off a shell script that starts a script session. When the script session is running, all of the input and output on the terminal is captured in the log file. Of course, if the user goes into some menus or programs the log file gets a little hard to read, but we at least have an idea what happened. This monitoring is not done surrep- titiously because I always want everyone to know that the monitoring is taking place. When a script session starts, output from the script command informs the user that a session is running and gives the name of the session’s log file. We can also set up mon- Monitoring and Auditing User Key Strokes CHAPTER 19 itoring to take place from the time a user logs in until the user logs out. For this moni- toring we do not need sudo, but we do need to edit the $HOME/.profile or other login configuration file for the particular user. Syntax Using the script command is straightforward, but we want to do a few more things in the shell script. Giving a specific command prompt is one option. If you are auditing root access you need to have a timeout set so that after about five minutes (see the TMOUT environment variable) the shell times out and the root access ends. On a shell timeout, the session is terminated and the user is either logged out or presented with a command prompt, but we can control this behavior. We have many options for this set of shell scripts. You are going to need to set up sudo, super-user-do, on your machine. The full details for installing and configuring sudo are in Chapter 14. We want sudo to be configured with the names of each of the shell scripts that are used for this moni- toring effort, as well as the specific users that you will allow to execute them. We will get to these details later. The script command works by making a typescript of everything that appears on the terminal. The script command is followed by a filename that will contain the cap- tured typescript. If no filename is given the typescript is saved in the current directory in a file called typescript. For our scripting we will specify a filename to use. The script session ends when the forked shell is exited, which means that there are two exits required to completely log out of the system. The script command has the follow- ing syntax: script [filename] As the script session starts, notification is shown on the terminal and a time stamp is placed at the top of the file, indicating the start time of the session. Let’s look at a short script session as used on the command line in Listing 19.1. [root:yogi]@/# more /usr/local/logs/script/script_example.out Script command is started on Wed May 8 21:35:27 EDT 2002. [root:yogi]@/# cd /usr/spool/cron/crontabs [root:yogi]@/usr/spool/cron/crontabs# ls adm root sys uucp [root:yogi]@/usr/spool/cron/crontabs# ls -al total 13 drwxrwx 2 bin cron 512 Feb 10 21:36 . drwxr-xr-x 4 bin cron 512 Jul 26 2001 -rw-r r 1 adm cron 2027 Feb 10 21:36 adm -rw 1 root cron 1125 Feb 10 21:35 root -rw-r r 1 sys cron 864 Jul 26 2001 sys Listing 19.1 Command-line script session. 476 Chapter 19 -rw-r r 1 root cron 703 Jul 26 2001 uucp [root:yogi]@/usr/spool/cron/crontabs# cd / [root:yogi]@/usr/spool# ls -l total 12 drwxrwsrwt 2 daemon staff 512 Sep 17 2000 calendar drwxr-xr-x 4 bin cron 512 Jul 26 2001 cron drwxrwxr-x 7 lp lp 512 Mar 23 15:21 lp drwxrwxr-x 5 bin printq 512 May 01 20:32 lpd drwxrwxr-x 2 bin mail 512 May 06 17:36 mail drwxrwx 2 root system 512 May 06 17:36 mqueue drwxrwxr-x 2 bin printq 512 Apr 29 11:52 qdaemon drwxr-xr-x 2 root system 512 Jul 26 2001 rwho drwxrwsrwx 2 bin staff 512 Jul 26 2001 secretmail drwxr-xr-x 11 uucp uucp 512 Mar 13 20:43 uucp drwxrwxrwx 2 uucp uucp 512 Sep 08 2000 uucppublic drwxrwxr-x 2 root system 512 Apr 16 2001 writesrv [root:yogi]@/usr/spool# exit Script command is complete on Wed May 8 21:36:11 EDT 2002. [root:yogi]@/# Listing 19.1 Command-line script session. (continued) Notice that every keystroke is logged as well as all of the command output. At the beginning and end of the log file a script command time stamp is produced. These lines of text are also displayed on the screen as the script session starts and stops. These are the user notifications given as the monitoring starts and stops. Scripting the Solution There are three different situations in which you want to use this type of monitor- ing/auditing. In this first instance we have users that you want to monitor the entire session. In the next situation you want to monitor activity only when a user wants root access to the system. Our systems have direct, remote, and su root login disabled, so to gain root access the user must use sudo to switch to root using the broot script. The third script is a catch-all for other administrative user accounts that you want to audit. The first script is covering end-to-end monitoring with the script execution starting at login through the user’s $HOME/.profile. Before we actually start the script session, there are some options to consider. Because we are executing a shell script from the user’s .profile we need to ensure that the script is the last entry in the file. If you do not want the users to edit any .profile files, then you need to set the ownership of the file to root and set the user to read-only access. Monitoring and Auditing User Key Strokes 477 Logging User Activity We are keeping log files so it is a good idea to have some kind of standard format for the log filenames. You have a lot of options for filenames, but I like to keep it simple. Our log files use the following naming convention: [hostname].[user $LOGNAME].[Time Stamp] We want the hostname because most likely you are monitoring users on multiple systems and using a central repository to hold all of the log files. When I write a shell script I do not want to execute a command more times than necessary. The hostname command is a good example. Assigning the system’s hostname to a variable is a good idea because it is not going to change, or it should not change, during the execution of the script. To assign the hostname of the system to a variable use the following syntax: THISHOST=$(hostname) For the date/time stamp a simple integer representation is best. The following date command gives two digits for month, day, year, hour, minute, and second: TS=$(date +%m%d%y%H%M%S) Now we have to reference only the $TS variable for the date/time stamp. Because the user may change we can find the active username with either of the following envi- ronment variables: echo $LOGNAME echo $USER echo $LOGIN As you change user IDs by using the switch user command (su), all of these envi- ronment variables change accordingly. However, if a user does a switch user using sudo, then the $LOGIN environment variable carries over to the new user while the $LOGNAME and $USER environment variables gain the new user ID. Now we have everything to build a log filename. A good variable name for a log file is LOGFILE, unless this variable is used by your system or another application. On my systems the LOGFILE variable is not used. Not only do we need to create the name of the $LOGFILE, but we need to create the file and set the permissions on the file. The ini- tial permissions on the file need to be set to read/write by the owner, chmod 600 $LOGFILE. The following commands set up the log file: TS=$(date +%m%d%y%H%M%S) # Create a time stamp THISHOST=$(hostname) # Query the system for the hostname LOGFILE=${THISHOST}.${LOGNAME}.$TS # Name the log file touch ${LOGDIR}/$LOGFILE # Create an empty log file chmod 600 ${LOGDIR}/${LOGFILE} # Set the file permissions 478 Chapter 19 A sample filename is shown here: yogi.randy.05110274519 The filename is good, but where do we want to store the file on the system? I like to use a separate variable to hold the directory name. With two separate variables repre- senting the directory and filename, you can move the log directory to another location and have to change just one entry in the script. I set up a log directory on my system in /usr/local/logs. For these script log files I added a subdirectory called script. Then I set a LOGDIR variable to point to my logging directory, as shown here: LOGDIR=/usr/local/logs/script Starting the Monitoring Session With the logging set up we are ready to start a script session. We start the session using the following syntax: script ${LOGDIR}/${LOGFILE} When the script session starts, a message is displayed on the screen that informs the user that a script session has started and lists the name of the script log file, as shown here: Script command is started. The file is /usr/local/logs/script/yogi.randy.051102174519. If the user knows that monitoring is going on and also knows the name of the file, what is to keep the user from editing or deleting the log? Usually directory permissions will take care of this little problem. During the script session the actual log file is an open file—that is, actually a system temporary file that cannot be accessed directly by the user. But if the user is able to delete the $LOGFILE then you have lost the audit trail. This is one problem that we will discuss later. Where Is the Repository? So far here is the scenario. A user has logged into the system. As the user logs in, a mon- itoring session is started using the script command, which logs all of the terminal output in a log file that we specify. During the time that the session is active the log file is open as a system temporary file. When the session ends, by a user typing exit or CTRL-D or by an exit signal, the log file is closed and the user is notified of the session ending, and again the name of the log file is displayed. For security and auditing purposes we need to have a central repository for the logs. The method I like to use is email. When the session ends we want to set the file permis- sions on the log file to read only by the owner. Then we email the log to another machine, ideally, which is where the repository is located. Once the email is sent I compress the local file and exit the script. Monitoring and Auditing User Key Strokes 479 With two copies of the user session existing on two different machines, an audit will easily detect any changes. In fact, if a user tries to change the log these commands will also be logged. You may have different ideas on handling the repository, but I set up a user on a remote machine that I use as a log file manager, with a name logman. The logman user’s email is the repository on the audit machine. For simplicity in this shell script we are going to email the logs to the local logman user. To send mail, I use the mailx command on all Unix flavors except Linux, where I use the mail command, as shown here: mailx -s “$TS - $LOGNAME Audit Report” $LOG_MANAGER < ${LOGDIR}/${LOGFILE} In the shell script the $LOG_MANAGER is defined as logman. The nice thing about having a variable hold the mail recipients is that you can add a second repository or other people to receive email notifications. By using the local logman account you have other options. You can set up mail aliases; one of my favorites is to use the logman account as a bounce account. By adding a .forward file in the $HOME directory for the logman user, you can redirect all of the email sent to the logman user to other destina- tions. If a .forward file exists in the user’s home directory, the mail is not delivered to the user but instead is sent to each email address and alias listed in the .forward file. A sample .forward file is shown here. yogibear@cave.com booboo@cave.com dino@flintstones.org admin With the previous entries in the $HOME/.forward file for the logman user, all mail directed to logman is instead sent to the three email address and all of the addresses pointed to by the admin email alias. The Scripts We have covered all of the basics for the shell scripts. We have three different shell scripts that are used in different ways. The first script is intended to be executed at login time by being the last entry in the user’s $HOME/.profile. The second shell script is used only when you want to gain root access, which is done through sudo, and the third script is a catch-all for any other administration-type accounts that you want to audit, which also use sudo. Let’s first look at the login script called log_keystrokes.ksh, shown in Listing 19.2. #!/bin/ksh # # SCRIPT: log_keystrokes.ksh # # AUTHOR: Randy Michael Listing 19.2 log_keystrokes.ksh shell script listing. 480 Chapter 19 # DATE: 05/08/2002 # REV: 1.0.P # PLATFOEM: Any Unix # # PURPOSE: This shell script is used to monitor a login session by # capturing all of the terminal data in a log file using # the script command. This shell script name should be # the last entry in the user’s $HOME/.profile. The log file # is both kept locally and emailed to a log file # administrative user either locally or on a remote machine. # # REV LIST: # # # set -n # Uncomment to check syntax without any execution # set -x # Uncomment to debug this shell script # ############# DEFINE AUDIT LOG MANAGER ################### # # This user receives all of the audit logs by email. This # Log Manager can have a local or remote email address. You # can add more than one email address if you want by separating # each address with a space. LOG_MANAGER=”logman” # List to email audit log ########################################################## ################ DEFINE FUNCTIONS HERE ################### ########################################################## cleanup_exit () { # This function is executed on any type of exit except of course # a kill -9, which cannot be trapped. The script log file is # emailed either locally or remotely, and the log file is # compressed. The last “exit” is needed so the user does not # have the ability to get to the command line without logging. if [[ -s ${LOGDIR}/${LOGFILE} ]] then case `uname` in Linux) # Linux does not have “mailx” mail -s “$TS - $LOGNAME Audit Report” $LOG_MANAGER < ${LOGDIR}/${LOGFILE} ;; *) mailx -s “$TS - $LOGNAME Audit Report” $LOG_MANAGER < ${LOGDIR}/${LOGFILE} ;; Listing 19.2 log_keystrokes.ksh shell script listing. (continues) Monitoring and Auditing User Key Strokes 481 esac compress ${LOGDIR}/${LOGFILE} 2>/dev/null fi exit } # Set a trap trap ‘cleanup_exit’1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 26 ########################################################## ################ DEFINE VARIABLES HERE ################### ########################################################## TS=$(date +%m%d%y%H%M%S) # File time stamp THISHOST=$(hostname|cut -f1-2 -d.) # Host name of this machine LOGDIR=/usr/local/logs/script # Directory to hold the logs LOGFILE=${THISHOST}.${LOGNAME}.$TS # Creates the name of the log file touch $LOGDIR/$LOGFILE # Creates the actual file set -o vi 2>/dev/null # Previous commands recall stty erase ^? # Set the backspace key # Set the command prompt export PS1=”[$LOGNAME:$THISHOST]@”’$PWD> ‘ #################### RUN IT HERE ########################## chmod 600 ${LOGDIR}/${LOGFILE} # Change permission to RW for the owner script ${LOGDIR}/${LOGFILE} # Start the script monitoring session chmod 400 ${LOGDIR}/${LOGFILE} # Set permission to read-only for # the owner cleanup_exit # Execute the cleanup and exit function Listing 19.2 log_keystrokes.ksh shell script listing. (continued) The log_keystrokes.ksh script in Listing 19.2 is not difficult when you look at it. At the top we define the cleanup_exit function that is used when the script exits to email and compress the log file. In the next section we set a trap and define and set some variables. Finally we start the logging activity with a script session. In the cleanup_exit function notice the list of exit codes that the trap command will exit on. This signal list ensures that the log file gets emailed and the file gets compressed. 482 Chapter 19 The only exit signal we cannot do anything about is a kill -9 signal because you cannot trap kill -9. There are more exit signals if you want to add more to the list in the trap statement, but I think the most captured are listed. The last command executed in this shell script is exit because in every case the cleanup_exit function must execute. If exit is not the last command, then the user will be placed back to a command prompt without any logging being done. The reason for this behavior is that the script session is really a fork of the original shell. Therefore, when the script command stops executing, one of the shells in the fork terminates, but not the original shell. This last exit logs out of the original shell. You may want to replace this last exit, located in the cleanup_exit function, with logout, which will guarantee the user is logged out of the system. Logging root Activity In some shops there is a need to log the activity of the root user. If you log the root activity, then you have an audit trail, and it is much easier to do root cause analysis on a root user booboo. We can use the same type of shell that we used in the previous sec- tions, but this time we will use sudo instead of a .profile entry. I call this script broot because it is a short name for “I want to be root”. In this section let’s look at the shell script in Listing 19.3 and go through the details at the end. #!/bin/ksh # # SCRIPT: broot # # AUTHOR: Randy Michael # DATE: 05/08/2002 # REV: 1.0.P # PLATFOEM: Any Unix # # PURPOSE: This shell script is used to monitor all root access by # capturing all of the terminal data in a log file using # the script command. This shell script is executed from the # command line using sudo (Super User Do). The log file # is kept locally and emailed to a log file administrative # user either locally or on a remote machine. Sudo must be # configured for this shell script. Refer to your sudo notes. # # USAGE: sudo broot # # REV LIST: # # # set -n # Uncomment to check syntax without any execution # set -x # Uncomment to debug this shell script # Listing 19.3 broot shell script listing. (continues) Monitoring and Auditing User Key Strokes 483 [...]... pdisk8 pdisk9 pdisk10 pdisk11 pdisk12 pdisk13 pdisk14 pdisk15 Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available Available 34- 08- 5B91-01-P 34- 08- 5B91-02-P 34- 08- 5B91-03-P 34- 08- 5B91-04-P 24- 08- 5B91-05-P 24- 08- 5B91-07-P 24- 08- 5B91-06-P 24- 08- 5B91- 08- P 24- 08- 5B91-09-P 24- 08- 5B91-10-P 24- 08- 5B91-11-P 24- 08- 5B91-12-P... a look at this shell script in Listing 19.5, and pay particular attention to the boldface type #!/bin/ksh # # SCRIPT: “Banybody” boracle - This time # # AUTHOR: Randy Michael # DATE: 05/ 08/ 2002 # REV: 1.0.P # PLATFOEM: Any Unix # # PURPOSE: This shell script is used to capture all “$EFF_USER” # access by capturing all of the terminal data in a log # file using the script command This shell script is... COMPLETE \n” } Listing 20 .8 list_of_disks function listing (continued) Notice in the boldface text in Listing 20 .8 where we do the test to see if the pdisk listed is a real pdisk by using the -c switch in the if statement We have covered the rest of the function, so let’s move on to the main body of the shell script The Full Shell Script This is a good point to show the entire shell script and go through... Listing 19.5 boracle shell script listing (continues) 489 490 Chapter 19 # accounts by just changing the EFF_USER variable # and the script name # # set -n # Uncomment to check syntax without any execution # set -x # Uncomment to debug this shell script # # ################# DEFINE EFFECTIVE USER ################## # This EFF_USER is the username you want to be to execute # a shell in An su command... KILL=/usr/bin/kill ORACLE_SU=/usr/bin/su - oracle TCPDUMP=/usr/sbin/tcpdump ERRPT=/usr/bin/errpt SVRMGRL=/oracle/product /8. 0.5/bin/svrmgrl # User privilege specification root ALL=(ALL) ALL ROOTADMIN LOCAL=BROOT NORMAL LOCAL=MNT,UMNT,EXP_FS Listing 19.4 Example /etc/sudoers file (continues) 487 488 Chapter 19 ADMIN LOCAL=BROOT,MNT,UMNT,KILL,ORACLE_SU,TCPDUMP,ERRPT: \ LOCAL=EXP_FS ORACLE LOCAL=SVRMGRL # Override... 34- 08- 5B91-02-P 34- 08- 5B91-03-P 34- 08- 5B91-04-P 24- 08- 5B91-05-P 24- 08- 5B91-07-P 24- 08- 5B91-06-P 24- 08- 5B91- 08- P 24- 08- 5B91-09-P 24- 08- 5B91-10-P 24- 08- 5B91-11-P 24- 08- 5B91-12-P 34- 08- 5B91-13-P 34- 08- 5B91-14-P 34- 08- 5B91-16-P 34- 08- 5B91-15-P SSA160 SSA160 SSA160 SSA160 SSA160 SSA160 SSA160 SSA160 SSA160 SSA160 SSA160 SSA160 SSA160 SSA160 SSA160 SSA160 Physical Physical Physical Physical Physical Physical... specified on the command line when the shell script is executed In the main body of the shell script we do all of the parsing of the command-line arguments because if you tried to parse the command line inside a function the parsing would act on the function’s argument, not the shell script’s arguments Therefore this is a short function In the main body of the shell script a variable, PDISKLIST, is... this entry beginning with a “dot”, which means to execute the following file, as the last entry in the $HOME/.profile If you added execution of $HOME/ profile into the shell script you end up executing the log_keystrokes.ksh shell 485 486 Chapter 19 script recursively When you run the script like this you fill up the buffers and you get an error message similar to the following output: ksh: : 0403-059... 2>/dev/null & fi exit } # Set a trap trap ‘cleanup_exit’1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 26 ########################################################## ################ DEFINE VARIABLES HERE ################### ########################################################## TS=$(date +%m%d%y%H%M%S) # File time stamp Listing 19.3 broot shell script listing (continued) Monitoring and Auditing User... pointed to by the TWIRL_PID variable Life, though, is not always normal In the top of the main body of the shell script we set a trap The trap is used to execute one or more commands, programs, or shell scripts when a specified exit code is captured Of course, you cannot trap a kill -9! In this shell script we execute the cleanup function on exit codes 1, 2 ,3, 5, and 15 You can add more exit codes . Randy Michael Listing 19.2 log_keystrokes.ksh shell script listing. 480 Chapter 19 # DATE: 05/ 08/ 2002 # REV: 1.0.P # PLATFOEM: Any Unix # # PURPOSE: This shell script is used to monitor a login session. the original shell. Therefore, when the script command stops executing, one of the shells in the fork terminates, but not the original shell. This last exit logs out of the original shell. You. log_keystrokes.ksh shell script listing. (continues) Monitoring and Auditing User Key Strokes 481 esac compress ${LOGDIR}/${LOGFILE} 2>/dev/null fi exit } # Set a trap trap ‘cleanup_exit’1 2 3 4 5 6 7 8 9