čtvrtek 22. května 2008

Audit report - script to format output (similar to Solaris audit)

If you do audit user actions (commands) on a Linux box via auditd, then following script could help you to go through the logged data. It will show you user actions in Linux system in human-readable form.

The example below shows the common user "chick" who switched to root and then created and deleted file "somefile" in the /etc/directory. As you can see, the auid is persistent across su command, so the user is still seen as "chick" under authentic auid even he/she switched to root to perform the touch and remove on file.

# audit_report /var/log/audit/audit.log | grep somefile


time="02/29/2008 09:21:31" cwd=/root syscall=execve success=yes exit=0 pid=17695 auid=chick gid=root euid=root suid=root fsuid=root egid=root sgid=root comm=touch exe=/bin/touch argv[0]="touch" argv[1]="/etc/somefile"
time="02/29/2008 09:21:32" cwd=/root syscall=execve success=yes exit=0 pid=17697 auid=chick gid=root euid=root suid=root fsuid=root egid=root sgid=root comm=rm exe=/bin/rm argv[0]="rm" argv[1]="-i" argv[2]="/etc/somefile"

Here is the script:

#!/bin/bash
# @(#) audit_report 1.1@(#) 25/05/07
# ---------------------------------------------------
#
# audit_report: prints out specified input audit file
# archieved or actual log in sol format
#
# warning: this parser works with audit-1.0.14-1.EL4
# future version of the autitd may have
# different output field naming or order
# ---------------------------------------------------

FSPEC="${1}"
TMP_FILE="/tmp/audit_log_tmp"

# check valid argument
if [ "$FSPEC" = "" ]; then
echo "parameters: audit_report input_file" 1>&2
exit
fi

# check if file exists
if [ ! -f "$FSPEC" ]; then
echo "error: can't access $FSPEC" 1>&2
exit
fi

# check, if $TMPFILE exists
if [ -f ${TMP_FILE} ]; then
echo "info: ${TMP_FILE} exists, someone can be using audit_report or process terminated" 1>&2
echo -n "do you want me to delete the file to proceed? (y/n): " 1>&2
read INPUT
if [ "${INPUT}" = "y" ]; then
/bin/rm ${TMP_FILE}
else
exit
fi
fi

# ausearch path
if [ -x /sbin/ausearch ]; then
AUSEARCH=/sbin/ausearch
else
AUSEARCH=ausearch
fi

# sed path
if [ -x /bin/sed ]; then
SED=/bin/sed
else
SED=sed
fi

# extract filename, remove path
FNAME="`basename $FSPEC`"

# check if zipped
GZIP=`echo $FNAME | egrep ".gz$"`

if [ "$GZIP" = "" ]; then
if [ "${FNAME}" = "audit.log" ]; then
/bin/cp ${FSPEC} ${TMP_FILE}
SRCFILE=${TMP_FILE}
else
SRCFILE=${FSPEC}
fi
else
echo "info: unzipping: ${FSPEC}"
cp ${FSPEC} ${TMP_FILE}.gz
gunzip ${TMP_FILE}.gz
SRCFILE=${TMP_FILE}
fi

# parse plain text audit file
# 1) add text fields instead of numbers where possible
# 2) one record per line

# loop - processing audit file to sol format

${AUSEARCH} -i -if ${SRCFILE} | while read SHORT_LINE
do
if [ "${SHORT_LINE}" != "----" ]; then

SYMBOL=`echo ${SHORT_LINE} | tr '= ' ' ' | awk '{ print $2 }'`

case ${SYMBOL} in

PATH)
;;
CWD)
# $2 - date part
# $3 - time part
# $5 - actual working dir, cwd

# put the date-time into quotes
TIME_STAMP=`echo ${SHORT_LINE} | tr '(' '.'`
TIME_STAMP=`echo ${TIME_STAMP} | awk -F"." '{ print $2 }'`
TIME_STAMP="time=\"${TIME_STAMP}\" "

LINE1=`echo ${SHORT_LINE} | \
awk '{ print $5 }'`

;;

EXECVE)
# $ 5 - argv[0]
# $ 6 - argv[1]
# $ 7 - argv[2]
# $ 8 - argv[3]

LINE3=`echo ${SHORT_LINE} | \
awk '{ print $5 " " $6 " " $7 " " $8 }'`
;;

SYSCALL)
# $ 6 - syscall
# $ 7 - success
# $ 8 - exit code
# $ 9 to 12 - pointers
# $13 - nr of args
# $14 - pid
# $15 - auid
# $16 - uid
# $17 - gid
# $18 - euid
# $19 - suid
# $20 - fsuid
# $21 - egid
# $22 - sgid
# $23 - fsgid
# $24 - command
# $25 - executable

LINE2=`echo ${SHORT_LINE} | \
awk '{ print $6 " " $7 " " $8 " " $14 " " $15 " " $17 " " $18 " " $19 " " $20 " " $21 " " $22 " "
$24 " " $25 }'`
;;
*)
;;
esac

else

echo -n "${TIME_STAMP} "
echo -n "${LINE1} "
echo -n "${LINE2} "
echo -n "${LINE3} "
echo

fi

done

# cleanup temporary file

if [ "${SRCFILE}" = "${TMP_FILE}" ]; then
/bin/rm ${TMP_FILE}
fi

# end

Žádné komentáře: