You are on page 1of 39

Oracle Auditing

Natalka Roshak
Presented to ABCD-Oracle
4 March 2004
About me
• Oracle and Sybase Database Administrator,
Analyst and Architect
• Experienced database programmer
• Oracle Certified Professional (OCP)
• Regular columnist for Oracle trade magazine,
orafaq.com, and other trade publications
• Oracle consultant, serving customers across
North America
• Available for consulting engagements
• http://rdbms-insight.com

Oracle Auditing - Natalka Roshak - http://rdbms-insight.com


About this presentation
• Presentedto Oracle users’ group at
Harvard University, ABCD-Oracle
• 4 March 2004

Oracle Auditing - Natalka Roshak - http://rdbms-insight.com


Auditing

2 main types of auditing:


• Oracle-supplied auditing using AUD$
• Trigger-based DML auditing

Oracle Auditing - Natalka Roshak - http://rdbms-insight.com


Oracle vs. Trigger-based Auditing

Different scope & application:


• AUD$ does not record any of the data values
involved in a DML change; need to use trigger-
based auditing to capture this info
• Obviously, Oracle auditing allows auditing of
non-DML statements, eg. ALTER ROLE

Oracle Auditing - Natalka Roshak - http://rdbms-insight.com


Oracle Auditing

I. Overview of Oracle Auditing


II. Fun with AUDIT SESSION
III. Security considerations & AUD$ size

Oracle Auditing - Natalka Roshak - http://rdbms-insight.com


I. Overview of Oracle Auditing
Enabling Oracle Auditing

First step: set static initialization parameter


AUDIT_TRAIL in INIT.ORA

Values:
• DB/TRUE
• OS
• NONE/FALSE
Oracle Auditing - Natalka Roshak - http://rdbms-insight.com
OS Audit Trail

Even if OS audit trail is not enabled, Oracle


will still write default actions to OS audit
trail:
• instance startup
• instance shutdown
• connections to the database as SYSOPER
or SYSDBA

Oracle Auditing - Natalka Roshak - http://rdbms-insight.com


OS Audit Trail

Oracle Auditing - Natalka Roshak - http://rdbms-insight.com


DB trail

• Writes all audit information to


SYS.AUD$
• AUD$ installed by catalog.sql
• Create auditing data dictionary views by
running
$oracle_home\rdbms\admin\cataudit.sql
• Remove these views using catnoaud.sql

Oracle Auditing - Natalka Roshak - http://rdbms-insight.com


















SQL> desc aud$
Name
-----------------------------------------
SESSIONID
ENTRYID
STATEMENT
TIMESTAMP#
USERID
USERHOST
TERMINAL
ACTION#
RETURNCODE
OBJ$CREATOR
OBJ$NAME
AUTH$PRIVILEGES
AUTH$GRANTEE
Null? Type
-------- --------------
NOT NULL NUMBER
NOT NULL NUMBER
NOT NULL NUMBER
NOT NULL DATE
VARCHAR2(30)
VARCHAR2(128)
VARCHAR2(255)
NOT NULL NUMBER
NOT NULL NUMBER
VARCHAR2(30)
VARCHAR2(128)
VARCHAR2(16)
VARCHAR2(30)
SYS.AUD$
• NEW$OWNER VARCHAR2(30)
• NEW$NAME VARCHAR2(128)
• SES$ACTIONS VARCHAR2(19)
• SES$TID NUMBER
• LOGOFF$LREAD NUMBER
• LOGOFF$PREAD NUMBER
• LOGOFF$LWRITE NUMBER
• LOGOFF$DEAD NUMBER
• LOGOFF$TIME DATE
• COMMENT$TEXT VARCHAR2(4000)
• SPARE1 VARCHAR2(255)
• SPARE2 NUMBER
• OBJ$LABEL RAW(255)
• SES$LABEL RAW(255)
• PRIV$USED NUMBER

Oracle Auditing - Natalka Roshak - http://rdbms-insight.com


Audit Views
STMT_AUDIT_OPTION_MAP
Contains information about auditing option type codes.
AUDIT_ACTIONS
Contains descriptions for audit trail action type codes.
ALL_DEF_AUDIT_OPTS
Contains default object-auditing options that will be applied when objects are created.
DBA_STMT_AUDIT_OPTS
Describes current system auditing options across the system and by user.
DBA_PRIV_AUDIT_OPTS
Describes current system privileges being audited across the system and by user.
DBA_OBJ_AUDIT_OPTS, USER_OBJ_AUDIT_OPTS
Describes auditing options on all objects. USER view describes auditing options on all objects owned by the current user.
DBA_AUDIT_TRAIL, USER_AUDIT_TRAIL
Lists all audit trail entries. USER view shows audit trail entries relating to current user.
DBA_AUDIT_OBJECT,USER_AUDIT_OBJECT
Contains audit trail records for all objects in the system. USER view lists audit trail records for statements concerning objects that are
accessible to the current user.
DBA_AUDIT_SESSION, USER_AUDIT_SESSION
Lists all audit trail records concerning CONNECT and DISCONNECT. USER view lists all audit trail records concerning connections and
disconnections for the current user.
DBA_AUDIT_STATEMENT, USER_AUDIT_STATEMENT
Lists audit trail records concerning GRANT, REVOKE, AUDIT, NOAUDIT, and ALTER SYSTEM statements throughout the database, or for the
USER view, issued by the user.
DBA_AUDIT_EXISTS
Lists audit trail entries produced by AUDIT EXISTS and AUDIT NOT EXISTS.

Oracle Auditing - Natalka Roshak - http://rdbms-insight.com


3 levels of audit options

Statement
• Audits on the type of SQL statement used, such as any
SQL statement on a table (which records each
CREATE, TRUNCATE, and DROP TABLE statement)
Object
• Audits specific statements on specific objects, such as
ALTER TABLE on the EMP table
Privilege
• Audits use of a particular system privilege, such as
CREATE TABLE

Oracle Auditing - Natalka Roshak - http://rdbms-insight.com


Statement Auditing

• Eg. AUDIT SELECT BY SCOTT


audits all select statements performed by
SCOTT
• AUDIT SELECT TABLE, UPDATE
TABLE BY SCOTT, BLAKE;

Oracle Auditing - Natalka Roshak - http://rdbms-insight.com


Object Auditing

• Eg. AUDIT SELECT ON scott.emp;


• AUDIT SELECT ON scott.emp WHENEVER
NOT SUCCESSFUL;
• AUDIT SELECT ON scott.emp WHENEVER
SUCCESSFUL;
• AUDIT ALL ON scott.emp ;

Oracle Auditing - Natalka Roshak - http://rdbms-insight.com


Privilege Auditing

eg. AUDIT GRANT SEQUENCE audits any


statements of the type:
• GRANT privilege ON sequence ;
• REVOKE privilege ON sequence ;
AUDIT EXECUTE PROCEDURE audits
• CALL of any procedure
AUDIT SELECT TABLE audits
• SELECT FROM table/view/materialized view;

Oracle Auditing - Natalka Roshak - http://rdbms-insight.com


Privilege auditing, con’t

AUDIT INDEX audits any statements of the type:


• CREATE INDEX
• ALTER INDEX
• DROP INDEX
AUDIT NOT EXISTS audits all SQL stmts that fail
because an object doesn’t exist
AUDIT SYSTEM AUDIT audits all
AUDIT/NOAUDIT statments
*AUDIT SESSION audits logon/logoff

Oracle Auditing - Natalka Roshak - http://rdbms-insight.com


BY SESSION/ACCESS

• BY SESSION: One audit record is inserted for


one session, regardless of the number of times
the statement is executed
• BY ACCESS: One audit record is inserted
each time the statement is executed
• Default is BY SESSION

Oracle Auditing - Natalka Roshak - http://rdbms-insight.com


Further examples

• AUDIT SESSION BY JOHN, ALEX


WHENEVER NOT SUCCESSFUL;
• AUDIT UPDATE, DELETE ON
scott.emp BY ACCESS;
• NOAUDIT UPDATE, DELETE ON
scott.emp;

Oracle Auditing - Natalka Roshak - http://rdbms-insight.com


II. Fun with AUDIT SESSION
Fun with AUDIT SESSION
• Underappreciated fact: AUD$ records IP when
session auditing is enabled
• SQL> select timestamp#, userid, machine, action#, returncode, logoff$time, comment$text from
aud$ where action# in (100,101);
• TIMESTAMP USERID MACHINE ACTION# RETURNCODE LOGOFF$TI
COMMENT$TEXT
• --------- ---------- --------------- ------- ---------- -------
• 02-FEB-04 EREQ_USER GYPSY 101 0 02-FEB-04 Authenticated by: DATABASE;
Client address: (ADDRESS=(PROTOCOL=tcp)(HOST=140.247.232.23)(PORT=3406))
• 02-FEB-04 EREQ_USER GYPSY 100 0 Authenticated by: DATABASE;
Client address:
• (ADDRESS=(PROTOCOL=tcp)(HOST=140.247.232.23)(PORT=3427))
• 02-FEB-04 EREQ_USER GYPSY 101 0 02-FEB-04 Authenticated by: DATABASE;
Client address: (ADDRESS=(PROTOCOL=tcp)(HOST=140.247.232.23)(PORT=3432))
• 02-FEB-04 BULKLOAD SHALLOT 100 0 Authenticated by: DATABASE;
Client address: (ADDRESS=(PROTOCOL=tcp)(HOST=140.247.164.242)(PORT=2544))

Oracle Auditing - Natalka Roshak - http://rdbms-insight.com


AUD$ fields

For 100/101 events (ACTION# IN (100,101)):


• col SPARE1 = OS username
• col RETURNCODE = ora-xxxx returncode
• col TERMINAL = terminal name (eg. ttyp3 in
UNIX, machine name in Windows)
• col COMMENT$TEXT = IP and port of client
-- very useful!

Oracle Auditing - Natalka Roshak - http://rdbms-insight.com


Extracting the IP

select userid, terminal, spare1, substr(s1,1,instr(s1,')')-1)


IP,
returncode, timestamp#
from
(select A.*,
substr(comment$text,instr(comment$text,'HOST=')
+5,100) s1
from aud$ a where action# in (100,101) )
order by IP;

Oracle Auditing - Natalka Roshak - http://rdbms-insight.com


Sample output
USERID TERMINAL SPARE1 IP RETURNCODE TIMESTAMP#
-------------------------------------------------------------------------------------------
HERS MARS apacheco 128.103.231.86 0 02/24/2004 3:08:36 PM
HERS oracle 128.103.231.86 0 01/25/2004 11:14:11 AM
EREQ_USER MRUTENBUR mrutenburg 140.247.10.130 0 01/30/2004 4:42:52 PM
BULKLOAD CJTRU cjtru 140.247.10.132 0 02/05/2004 4:26:41 PM
BULKLOAD ttyp3 oracle 140.247.10.132 0 02/09/2004 10:42:13 AM
SYS ttyp3 oracle 140.247.10.132 0 02/09/2004 11:55:56 AM
BULKLOAD ROBIN michael 140.247.10.135 0 01/29/2004 7:59:49 AM
SYSTEM JB Jen?Braster 140.247.10.135 0 01/28/2004 8:34:31 PM
EREQ_USER JB Jen?Braster 140.247.10.135 0 01/28/2004 8:39:07 PM

Oracle Auditing - Natalka Roshak - http://rdbms-insight.com


Returncodes

• Indicates ora-XXXX if logon failed


• Common returncodes:
• 0 – successful
• 1017 – invalid username/password
• 1005 – null password given
• 1035 – RESTRICTED SESSION enabled
• Eg. Add “where” clause to query to filter on
ora-1017s
Oracle Auditing - Natalka Roshak - http://rdbms-insight.com
Other possibilities

• Create table of known IPs expected to connect,


query for other IPs
• Alert when there’s a connection attempt from a
new or non-Harvard IP
• Create table of known terminals expected to
connect over VPN (140.247.10/11.0/255),
query for other terminals (or terminal &
username combo) connecting over VPN

Oracle Auditing - Natalka Roshak - http://rdbms-insight.com


Filtering on known IPs/terminals
select * from (
select userid, terminal, spare1, substr(s1,1,instr(s1,')')-1) IP,
k.hostname, str.returncode, count(*) from
(select A.*, substr(comment$text,instr(comment$text,'HOST=')+5,100) s1
from aud$ a
) str, system.known_ips k
where 1=1
and (substr(s1,1,instr(s1,')')-1) not in (select ip from system.known_ips)
and NOT ( (substr(s1,1,instr(s1,')')-1) like '140.247.10%'
OR substr(s1,1,instr(s1,')')-1) like '140.247.11%' )
AND str.terminal in (select terminal from system.known_terminals)
)
)
and str.terminal NOT in (select terminal from system.known_terminals)
and substr(s1,1,instr(s1,')')-1)=k.ip(+)
and timestamp# > sysdate-20
group by userid, terminal, spare1, substr(s1,1,instr(s1,')')-1), hostname, returncode
) where IP not like '140.247.164.%' and IP not in ('140.247.232.22','140.247.232.23')
order by IP

Oracle Auditing - Natalka Roshak - http://rdbms-insight.com


Filtering on known IPs/terminals

USERID TERMINAL SPARE1 IP RETURNCOD COUNT(*)


------------------------------------------------------------------------------
SYS unknown n_user 140.247.10.149 0 1
UTILITY LOKI dfaux 140.247.10.150 0 1
BULKLOAD CLIENT1 kyu 140.247.11.20 0 3
SYS ttyp2 oracle 140.247.11.20 0 1
SYS ttyp2 oracle 140.247.11.20 1017 1
ASPERIN CLIENT1 kyu 140.247.11.9 0 5
HR_DATA CLIENT1 kyu 140.247.11.9 0 8
FIN_OFFIC UHALL-TEMP5 hadass 140.247.70.24 0 7
FIN_OFFIC IBM-5F0826A1BDE nasson 140.247.70.28 0 5
FIN_OFFIC IBM-5F0826A1BDE nasson 140.247.70.28 1017 4

Oracle Auditing - Natalka Roshak - http://rdbms-insight.com


III. Security Considerations
Too Much AUD$

• Problem: AUD$ is located in SYSTEM


tablespace
• If AUDIT SESSION is enabled, DOS attack
can fill up SYSTEM tablespace, bringing
database to a complete halt
• An untended AUD$ can do the same thing over
time
• Solution: Monitor size of AUD$
Oracle Auditing - Natalka Roshak - http://rdbms-insight.com
MANAGE_AUD$ package

• Job to check size of AUD$ and move rows out


of SYS tablespace if AUD$ too large
• Write to alert log if AUD$ has to be cleaned
out
• Procedures for quarterly log rotation

Oracle Auditing - Natalka Roshak - http://rdbms-insight.com


Create tables to archive AUD$
• SYSTEM.AUD$_BU
• SYSTEM.AUD$_PREV_QUARTER

drop table system.aud$_bu;

create table system.aud$_bu


tablespace tools
as (select * from sys.aud$ where 1=2);

drop table system.aud$_prev_quarter;

create table system.aud$_prev_quarter


tablespace tools
as (select * from sys.aud$ where 1=2);

Oracle Auditing - Natalka Roshak - http://rdbms-insight.com


Rotate AUD$ quarterly
procedure quarterly_rotation
is

/* Procedure quarterly_rotation
* Cleans out table system.aud$_prev_quarter
* and repopulates it with the previous quarter's worth of audit info
* Should be scheduled to run every quarter
*/

begin
commit;
set transaction use rollback segment rbs_bulk;
delete from system.aud$_prev_quarter;
insert into system.aud$_prev_quarter
( select * from sys.aud$ au
where au.timestamp# < trunc(sysdate,'Q'));
delete from sys.aud$ where timestamp# < trunc(sysdate,'Q') ;
commit;
end quarterly_rotation;

Oracle Auditing - Natalka Roshak - http://rdbms-insight.com


Use dbms_system.kdswrt() to log


delete from sys.aud$ where timestamp# < trunc(sysdate,'Q') ;
commit;

sys.dbms_system.ksdwrt(3,'ORA-AUDIT
TRAIL: Quarterly rotation COMPLETE');
sys.dbms_system.ksdwrt(3,'ORA-AUDIT
TRAIL: This message brought to you by
sys.manage_aud$');
end quarterly_rotation ;

Oracle Auditing - Natalka Roshak - http://rdbms-insight.com


Check AUD$ size
procedure
keep_size_in_check
is
rowCount number;
begin
select count(*) into rowCount from sys.aud$ ;
if rowCount > 50000
then
commit;
set transaction use rollback segment rbs_bulk;
insert into system.aud$_bu (select * from sys.aud$);
delete from sys.aud$ ;
commit;
sys.dbms_system.ksdwrt (3,'ORA-AUDIT TRAIL: POSSIBLE DOS
ATTACK!!!! AUD$ rows moved to AUD$_BU');
end if;
end keep_size_in_check;

Oracle Auditing - Natalka Roshak - http://rdbms-insight.com


Poll AUD$ table regularly

declare
myjob number;
begin
dbms_job.submit(myjob,
what => ‘manage_aud$.keep_size_in_check;’,
interval => ‘trunc(sysdate)+1/96’);
End;

Oracle Auditing - Natalka Roshak - http://rdbms-insight.com


Summary

• Oracle Auditing is good for auditing non-DDL


events, and auditing DDL where a record of the
data changed is not important
• AUDIT SESSION lets you track connections
by IP, OS username, & terminal
• If DB audit trail is enabled, the size of AUD$
must be managed

Oracle Auditing - Natalka Roshak - http://rdbms-insight.com


Natalka Roshak
Oracle and Sybase Database
Administrator, Architect and Analyst

http://rdbms-insight.com
http://toolkit.rdbms-insight.com

You might also like