Thursday, June 26, 2008

I Knew What You Did In Your Sessions

This blog title sounds like the 1997 movie I Knew What You Did Last Summer. Yes indeed, but in Solaris operating system, not in cinema. By turning on the auditing feature in Solaris, you can really tell what the user did in all his/her sessions. However the default setting in audit_control does not capture the execve system call. In order to find out the command executed together with the argument supplied to it, you need to include the "ex" in the flags: in /etc/security/audit_control and include "/usr/sbin/auditconfig -setpolicy +argv" in /etc/security/audit_startup This is what I have in my demo server:
# egrep -v '^#' /etc/security/audit_control
dir:/var/audit
flags:lo,fc,fm,fd,ex,xp,xc,xs,xx,fa
minfree:20
naflags:lo

# egrep -v '^#' /etc/security/audit_startup
/usr/bin/echo "Starting BSM services."
/usr/sbin/auditconfig -setpolicy +cnt
/usr/sbin/auditconfig -setpolicy +arg
/usr/sbin/auditconfig -conf
/usr/sbin/auditconfig -aconf

Once that has been configured properly, you can start the auditing by rebooting the server.

# cd /etc/security

# ./bsmconv
This script is used to enable the Basic Security Module (BSM).
Shall we continue with the conversion now? [y/n] y
bsmconv : INFO : checking startup file .
bsmconv : INFO : turning on audit module .
bsmconv : INFO : initializing device allocation .
The Basic Security Module is ready .
If there were any errors , please fix them now .
Configure BSM by editing files located in /etc/ security .
Reboot this system now to come up with BSM enabled .

# reboot


----- wait for the system to boot up -----



# svcs | grep "auditd"
online 23:30:03 svc:/system/auditd:default

The default location for the audit trail is in /var/audit. It is best practice to ensure you have sufficient space in this directory and /var (or /var/audit) is a separate partition because the audit trail file grows very fast in a production system. The audit trail files are stored in binary format and the data structure is described in audit.log. Two built-in utilities are provided in Solaris to streamline the audit reporting, they are auditreduce and praudit. The praudit default output is pretty hard to understand and comma separated variable output is not in fix-field format

# auditreduce | praudit | head
file,2008-06-23 10:56:27.000 +08:00,
header,44,2,system booted,na,2008-06-23 10:56:27.330 +08:00
text,booting kernel
header,145,2,open(2) - read,,solaris11,2008-06-23 11:02:51.437 +08:00
path,/devices/pseudo/pool@0:pool
attribute,20666,root,sys,336,118489094,970662608897
subject,chihung,root,root,root,root,674,2971128068,787 65558 10.1.2.84
return,success,7
header,120,2,open(2) - read,write,sp,solaris11,2008-06-23 11:02:51.467 +08:00
path,/var/adm/lastlog

However, if you read the man page of praudit, you will realise that it can dump the audit trail in XML. Here is a sample dump:

# auditreduce | praudit -x | head -50
<?xml version='1.0' encoding='UTF-8' ?>
<?xml-stylesheet type='text/xsl' href='file:///usr/share/lib/xml/style/adt_record.xsl.1' ?>

<!DOCTYPE audit PUBLIC '-//Sun Microsystems, Inc.//DTD Audit V1//EN' 'file:///usr/share/lib/xml/dtd/adt_record.dtd.1'>

<audit>
<file iso8601="2008-06-24 13:14:44.000 +08:00"></file>
<record version="2" event="fcntl(2)" host="solaris11" iso8601="2008-06-24 13:14:44.536 +08:00">
<argument arg-num="2" value="0x4" desc="cmd"/>
<argument arg-num="1" value="0x6" desc="no path: fd"/>
<attribute mode="10000" uid="root" gid="root" fsid="344" nodeid="323" device="0"/>
<subject audit-uid="chihung" uid="root" gid="root" ruid="root" rgid="root" pid="704" sid="1932086420" tid="639 65558 10.1.2.84"/>
<return errval="success" retval="0"/>
</record>
<record version="2" event="fcntl(2)" host="solaris11" iso8601="2008-06-24 13:14:44.536 +08:00">
<argument arg-num="2" value="0x4" desc="cmd"/>
<argument arg-num="1" value="0x7" desc="no path: fd"/>
<attribute mode="10000" uid="root" gid="root" fsid="344" nodeid="323" device="0"/>
<subject audit-uid="chihung" uid="root" gid="root" ruid="root" rgid="root" pid="707" sid="1932086420" tid="639 65558 10.1.2.84"/>
<return errval="success" retval="0"/>
</record>
<record version="2" event="fcntl(2)" host="solaris11" iso8601="2008-06-24 13:14:44.542 +08:00">
<argument arg-num="2" value="0x3" desc="cmd"/>
<argument arg-num="1" value="0x5" desc="no path: fd"/>
<attribute mode="10000" uid="chihung" gid="other" fsid="344" nodeid="324" device="0"/>
<subject audit-uid="chihung" uid="chihung" gid="other" ruid="chihung" rgid="other" pid="707" sid="1932086420" tid="639 65558 10.1.2.84"/>
<return errval="success" retval="2"/>
</record>
<record version="2" event="fcntl(2)" host="solaris11" iso8601="2008-06-24 13:14:44.542 +08:00">
<argument arg-num="2" value="0x4" desc="cmd"/>
<argument arg-num="1" value="0x5" desc="no path: fd"/>
<attribute mode="10000" uid="chihung" gid="other" fsid="344" nodeid="324" device="0"/>
<subject audit-uid="chihung" uid="chihung" gid="other" ruid="chihung" rgid="other" pid="707" sid="1932086420" tid="639 65558 10.1.2.84"/>
<return errval="success" retval="0"/>
</record>
<record version="2" event="fcntl(2)" host="solaris11" iso8601="2008-06-24 13:14:44.542 +08:00">
<argument arg-num="2" value="0x3" desc="cmd"/>
<argument arg-num="1" value="0x6" desc="no path: fd"/>
<attribute mode="10000" uid="chihung" gid="other" fsid="344" nodeid="324" device="0"/>
<subject audit-uid="chihung" uid="chihung" gid="other" ruid="chihung" rgid="other" pid="707" sid="1932086420" tid="639 65558 10.1.2.84"/>
<return errval="success" retval="2"/>
</record>
<record version="2" event="fcntl(2)" host="solaris11" iso8601="2008-06-24 13:14:44.542 +08:00">
<argument arg-num="2" value="0x4" desc="cmd"/>
<argument arg-num="1" value="0x6" desc="no path: fd"/>
<attribute mode="10000" uid="chihung" gid="other" fsid="344" nodeid="324" device="0"/>
<subject audit-uid="chihung" uid="chihung" gid="other" ruid="chihung" rgid="other" pid="707" sid="1932086420" tid="639 65558 10.1.2.84"/>
<return errval="success" retval="0"/>
</record>
<record version="2" event="access(2)" host="solaris11" iso8601="2008-06-24 13:14:44.547 +08:00">
<path>/dev/pts/1</path>
<attribute mode="20620" uid="chihung" gid="tty" fsid="337" nodeid="5942560" device="103079215105"/>
<subject audit-uid="chihung" uid="chihung" gid="other" ruid="chihung" rgid="other" pid="707" sid="1932086420" tid="639 65558 10.1.2.84"/>
<return errval="success" retval="0"/>
</record>
<record version="2" event="stat(2)" host="solaris11" iso8601="2008-06-24 13:14:44.548 +08:00">
<path>/dev/pts/1</path>
<attribute mode="20620" uid="chihung" gid="tty" fsid="337" nodeid="5942560" device="103079215105"/>
<subject audit-uid="chihung" uid="chihung" gid="other" ruid="chihung" rgid="other" pid="707" sid="1932086420" tid="639 65558 10.1.2.84"/>
<return errval="success" retval="0"/>
</record>

"sid" is the session ID and it is not difficult to find out how many records for all the sessions using Tcl (with tDOM extension). Once we locate the session ID, we can dump out all the execve commands and there corresponding arguments. auditreduce is able merge and select audit records from audit trail files, -a and -b flags to dump audit records between two timestamps. See the man page for all other options to reduce the audit trail output before it is piped to praudit.

$ ./sid.tcl
Usage: ./sid.tcl <xmlfile> <user>

$ ./sid.tcl sample.xml chihung
3331057518=19
2156193989=19
2283295222=19
740162063=177
3244834577=22
1932086420=387

$ ./sid-exec.tcl
Usage: ./sid-exec.tcl <xmlfile> <sid>

$ ./sid-exec.tcl sample.xml 740162063
/usr/bin/bash  ; -bash  ; success
/usr/lib/fs/ufs/quota  ; /usr/sbin/quota  ; success
/usr/bin/cat  ; /bin/cat -s /etc/motd  ; success
/usr/bin/mail  ; /bin/mail -E  ; success
/usr/bin/hostname  ; hostname  ; success
/usr/bin/more  ; more audit_control  ; success
/usr/bin/cat  ; cat audit_startup  ; success
/usr/bin/man  ; man auditconfig  ; success
/sbin/sh  ; sh -c cd /usr/man; tbl /usr/man/man1m/auditconfig.1m |neqn /usr/share/lib/pub/eqnchar - |nroff -u0 -Tlp -man - | col -x > /tmp/mpTkaODb  ; success
/usr/bin/col  ; col -x  ; success
/usr/bin/tbl  ; tbl /usr/man/man1m/auditconfig.1m  ; success
/usr/bin/neqn  ; neqn /usr/share/lib/pub/eqnchar -  ; success
/usr/bin/nroff  ; nroff -u0 -Tlp -man -  ; success
/sbin/sh  ; sh -c trap '' 1 15; /usr/bin/mv -f /tmp/mpTkaODb /usr/man/cat1m/auditconfig.1m 2> /dev/null  ; success
/usr/bin/mv  ; /usr/bin/mv -f /tmp/mpTkaODb /usr/man/cat1m/auditconfig.1m  ; success
/sbin/sh  ; sh -c more -s /tmp/mpTkaODb  ; success
/usr/bin/more  ; more -s /tmp/mpTkaODb  ; success
/usr/bin/ls  ; ls  ; success
/usr/sbin/auditreduce  ; auditreduce  ; success
/usr/sbin/praudit  ; praudit  ; success
/usr/bin/su  ; su -  ; success
/sbin/sh  ; -sh  ; success
/usr/lib/fs/ufs/quota  ; /usr/sbin/quota  ; success
/usr/bin/cat  ; /bin/cat -s /etc/motd  ; success
/usr/bin/mail  ; /bin/mail -E  ; success
/usr/bin/hostname  ; hostname  ; success
/usr/sbin/auditreduce  ; auditreduce  ; success
/usr/bin/prstat  ; prstat -x  ; success
/usr/bin/sparcv9/prstat  ; prstat -x  ; success
/usr/sbin/auditreduce  ; auditreduce  ; success
/usr/sbin/praudit  ; praudit -x  ; success
/usr/sbin/auditreduce  ; auditreduce -a 20080624130000  ; success
/usr/sbin/praudit  ; praudit -x  ; success
/usr/bin/vi  ; vi /var/tmp/x  ; success
/usr/bin/grep  ; grep 2283295222 /var/tmp/x  ; success
/usr/sbin/auditreduce  ; auditreduce -a 20080624130000  ; success
/usr/sbin/praudit  ; praudit -x  ; success

Here is the sid.tcl and sid-exec.tcl

$ cat sid.tcl
#! /usr/local/bin/tclsh


if { $argc != 2 } {
        puts stderr "Usage: $argv0 <xmlfile> <user>"
        exit 1
}
set xmlfile [lindex $argv 0]
set uid [lindex $argv 1]


package require tdom


set nrec 0
set doc [dom parse [tDOM::xmlReadFile [lindex $argv 0]]]
set root [$doc documentElement]
foreach r [$root selectNodes "//subject\[@uid='$uid']"] {
        set sid [$r getAttribute sid]
        if { [info exist arraySid($sid)] } {
                incr arraySid($sid)
        } else {
                set arraySid($sid) 1
        }
}
foreach { n v } [array get arraySid] {
        puts "$n=$v"
}

$ cat sid-exec.tcl
#! /usr/local/bin/tclsh


if { $argc != 2 } {
        puts stderr "Usage: $argv0 <xmlfile> <sid>"
        exit 1
}
set xmlfile [lindex $argv 0]
set sid [lindex $argv 1]


package require tdom


set nrec 0
set doc [dom parse [tDOM::xmlReadFile [lindex $argv 0]]]
set root [$doc documentElement]
foreach r [$root selectNodes "//subject\[@sid='$sid']/.."] {
        set event [$r getAttribute event]
        if { ![string equal $event {execve(2)}] } { continue }
        foreach pNode [$r selectNodes {path/text()}] {
                puts -nonewline "[string trim [$pNode nodeValue]] "
        }
        puts -nonewline " ; "
        foreach argNode [$r selectNodes {exec_args/arg/text()}] {
                puts -nonewline "[string trim [$argNode nodeValue]] "
        }
        puts -nonewline " ; "
        puts "[[$r selectNodes {return}] getAttribute errval]"
}

Labels: , , , ,

0 Comments:

Post a Comment

<< Home