With builtin and free of charge database features
Database Consult Aalderks http://www.db-consult-aalderks.de
Preliminary Notes Non Recommendations Awareness The Answer Secure Database Activities
Players :
IT/DB Security DBA‘s Appication Owner Data Security Officer Work council
Attacker‘s
12/3/2013 Database Consult Karsten Aalderks 2
Oracle Core Databases
are dangerous !
12/3/2013 Database Consult Karsten Aalderks 3
Why ?
TNS-Poison vulnerability not fixed
Oradebug ( code remains after ‘fix‘ )
O5LOGON Crypto. Flaw (not fixed for 11g)
Tools like BBED ( block browser and editor)
Alter system dump datafile block feature
Builtin privilege escalation features
http://blog.red-database-security.com/
Decryption of DB_LINK Passwords with python
http://soonerorlater.hu/index.khtml?article_id=1
Presentation DerbyCon 3.0 - 28.09.2013 - Page 164
12/3/2013 Database Consult Karsten Aalderks 4
Situation of many companies A lot of databases - up to 30.000 !
Optimized, outsourced DBA activities
No independant Database Security Group
A lot of critical data
Mostly non well organized and insecure development/test/integration environments
No SIEM ( Security Information and Event System )
Database cloning pandemia
12/3/2013 Database Consult Karsten Aalderks 5
Oracle DB has several thousands functions
Patching could be dangerous, cause new errors and leaks, possible downtimes and costs
Passwords are stored on several places in and around Databases ( interfaces, agents, applications ) in (config_files, pwd_stores, …)
Username/Password is default authentication
Privileges are mostly not well adjusted and sensitive in case of changes ( cascading roles, dynamic privileges, dynamic synonyms, indirect privileges )
12/3/2013 Database Consult Karsten Aalderks 6
Whole Auth via Kerberos,Radius, … Install all Oracle Patches ( security, functional)* Change all Passwords in DB >10 digits +
complexity If a privileg is not used, Revoke it Audit all ( DB System, DB Applications) Store Audit Data in /dev/null Use SecurityBaselines with hundred‘s of Queries Use security tools for all databases
• *Patch 11.2.0.4 : 9000 documented/undocumented bugfixes and • estimated 5000-7000 hidden bugfixes
12/3/2013 Database Consult Karsten Aalderks 7
Desaster
for
Availability
and
Performance
12/3/2013 Database Consult Karsten Aalderks 8
Companies
are
attached
12/3/2013 Database Consult Karsten Aalderks 9
Soft adaptive
Hardening Concept
12/3/2013 Database Consult Karsten Aalderks 10
User Management /Passwords
Config Parameters
Privileges
Auditing /DB –Hardening
Database Scanning
Database Monitoring
Secure Database Code
Encryption / Hashing
Data Masking
Advanced Techniques
12/3/2013 Database Consult Karsten Aalderks 11
Deactivating sqlplus / as sysdba Change Default Passwords Deactivating Oracle Users Delete DES Hashes Drop Oracle Users Drop Oracle Features/Options and Users Create User Profiles Use password verification functions
Strong Weak
Use secure password store http://www.oracle-base.com/articles/10g/secure-external-
password-store-10gr2.php Metalink /MyOracle Support (Doc ID 340559.1)
12/3/2013 Database Consult Karsten Aalderks 12
Step 1: sqlnet.ora SQLNET.AUTHENTICATION_SERVICES=(NONE)
Step 2: sec_case_sensitive_logon=false cause O5LOGON Cryp. Flaw
Step 3: Create your own high privileged accounts and one emergency user
Privs for emergency user create session update in sys.user$ Step 4 : Impossible Password for sys, system , all sysdba‘s , … Alter user x identified by values “ 666666.... “ Step 5 : Audit 'Alter User'
12/3/2013 Database Consult Karsten Aalderks 13
Alter user sys identified by ka ; -- possible! Alter user sys identified by “Rayna#*övp“ ; possible ? First : use SQLPLUS > password !
It depends from login method
O3LOGON via DES Hashes (10g) -- no O5LOGON via SHA1 Hashes with Cryptogr. Flaw (11g) -- yes, but it depends from character Set
Tip :
Use SEC_CASE_SENSITIVE_LOGON=FALSE ( O3LOGON ), if you can‘t change all clients to Authentication Protocol of 12c
Use special characters if possible and no migration to other character sets is likely Password length >= 12 ( if possible and tested) via pwd verify function Password complexity via pwd verify function ( strong/weak )
12/3/2013 Database Consult Karsten Aalderks 14
How ?
Table sys.user$ SPARE4 : SHA-1( password||salt)||salt - length 62 Password : DES(username||password) - length 16
Alter user xdb identified by values “66666666666666666666666666666666666666666666666666666666666666666666666666“
Two ways:
Blind generated complex password with length 30 Use a few characters which can‘t be entered --chr(398)||“66666666666.. “
12/3/2013 Database Consult Karsten Aalderks 15
If you use SEC_CASE_SENSITIVE_LOGON=TRUE
( O5LOGON authentication protocol -11g )
Delete DES Hashes
update sys.user$ set password=‘‘ where password is not null;
Regular password change only via
Sqlplus > password
after check of glogin.sql
12/3/2013 Database Consult Karsten Aalderks 16
How ?
Drop user dbmsnmp cascade;
Which users ?
http://www.orafaq.com/wiki/List_of_default_database_users
If you are not sure deactivate user !
12/3/2013 Database Consult Karsten Aalderks 17
Java :
cd $ORACLE_HOME/javavm
sqlplus "SYS/ AS SYSDBA" @rmjvm.sql
Xdb :
SQL> set echo on
SQL> spool xdb_removal.log
SQL> @?/rdbms/admin/catnoqm.sql
12/3/2013 Database Consult Karsten Aalderks 18
SQL> CREATE PROFILE restrictive
LIMIT FAILED_LOGIN_ATTEMPTS 1
PASSWORD_LIFE_TIME 30
PASSWORD_LOCK_TIME 7
PASSWORD_GRACE_TIME 0;
12/3/2013 Database Consult Karsten Aalderks 19
FAILED_LOGIN_ATTEMPTS
if a user attempts to login more than the specified number of times the account will be locked. Default is 10 days.
PASSWORD_LIFE_TIME
number of days the same password can be used unless a grace period is specified. Default is 108 days.
PASSWORD_REUSE_TIME
number of days that must pass before the same password can be used again. Default is unlimited.
PASSWORD_REUSE_MAX
number of times a password must be changed before a previous password can be used again. Default is unlimited.
PASSWORD_LOCK_TIME
number of days an account will remain locked after failed login attempts has been triggered. Default is 1 day.
PASSWORD_GRACE_TIME
number of grace days for user to change password. Default is 7 days.
PASSWORD_VERIFY_FUNCTION
allows you to define PL/SQL that can be used for password verification.
12/3/2013 Database Consult Karsten Aalderks 20
Weak pwd verify function with logging of all pwd policy violations, but ever true!
Code insert procedure with pragma autonumous_transaction
Indirect ( execute immediate) and exeception handler with write call to alert.log for exception and data !
SQL> exec dbms_system.ksdwrt(2, 'This message goes to the alert log');
PL/SQL procedure successfully completed.
12/3/2013 Database Consult Karsten Aalderks 21
CREATE OR REPLACE FUNCTION verify_function_11G (username varchar2, password varchar2, old_password varchar2) RETURN boolean IS n boolean; m integer; differ integer; …
BEGIN digitarray:= '0123456789'; chararray:= 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; -- Check for the minimum length of the password IF length(password) < 8 THEN
Execute immediate (store_dll_cmd ( username,maschine, session, q ‘ #Password length less than 8‚systimestamp#‘)); -- weak
-- or
raise_application_error(-20001, 'Password length less than 8'); -- strong
END IF;
12/3/2013 Database Consult Karsten Aalderks 22
Question :
How many config parameters , documented and undocumented, are available in the database ?
12/3/2013 Database Consult Karsten Aalderks 23
Oracle 11g XE
Documented > 340
Undocumented > 2300
Additional hidden and unknown parameters ?
I think – yes! e.g. Parameter _fifteenth_spare_parameter allows to disable
Oradebug undocumented commands like poke, …
12/3/2013 Database Consult Karsten Aalderks 24
The problem :
Some undocumented parameters override official parameters.
Examples of security related parameters The good for security )
_CLOSE_CACHED_OPEN_CURSORS
The bad for security
_UTL_FILE_FOLLOW_SYMLINK
_ORACLE_BASE -- Database identity change
…
12/3/2013 Database Consult Karsten Aalderks 25
Tip : Save original config settings via
checksum complete and check the settings every day via lookup ( system level , session level )
Columns of interest. Isdefault
Session
Comprehension Question : Is it possible to manipulate the value of isdefault ? ( important for security baseline‘s)
Which tools would you use?
12/3/2013 Database Consult Karsten Aalderks 26
Questions : Who can select SPARE4/PASSWORD from v$users direct/indirect ? Who can determine SPARE4/Password from sys.link$ direct/indirect ? Does the role creater have implicit admin privileges (10g/11g) ? Where can you find all this privileges in the oracle universe ? Are you sure, you know all privileges in your databases?
12/3/2013 Database Consult Karsten Aalderks 27
Compound Effective Privileges System dba_sys_privs, dba_role_privs,…
Object dba_tab_privs, dba_col_privs,…
Public union as user /role
Sysdba v$pwfile_users
ACL‘s ( XDB/JAVA) dba_network_acl_privileges,…
VPD/OLS dba_policies,..
External Procedures listener/Library
OS Permissions filesystem
Privileges via privilege escalation
12/3/2013 Database Consult Karsten Aalderks 28
Granting modes : Direct
Indirect
Direct : Direct Grant , via Role (cascading), via db_links,
via Policy,via ACL‘s, VPD, …
Indirect : via privilege escalation
via identity change
Via intermediate steps - packages dbms_metadata, virtual column functions,…
OS Permissions via os exit
12/3/2013 Database Consult Karsten Aalderks 29
Concept : Identify all effective privileges for all Users including sys/system/public, … Sysdba and implict schema privileges must be generated !
This is a lot of work !
Detect and analyze some/all changes including typical patterns Revoke, re-grant Revoke, new grant, revoke, old grant ...
Some changes can be detected with Rowid‘ s – use base table x$... All changes ( if we trust Oracle ) , can be detected with a DDL/DCL Trigger.
12/3/2013 Database Consult Karsten Aalderks 30
DDL/DCL Capture via System Trigger
Comment Create Alter Truncate Drop
Rename Grant Revoke
Audit Noaudit
Analyze
ASSOCIATE STATISTICS
DISASSOCIATE STATISTICS
12/3/2013 Database Consult Karsten Aalderks 31
create or replace trigger trigger1 after grant or revoke on database declare priv dbms_standard.ora_name_list_t; who dbms_standard.ora_name_list_t; npriv pls_integer; nwho pls_integer; begin npriv := ora_privilege_list(priv); if (ora_sysevent = 'GRANT') then nwho := ora_grantee(who); else nwho := ora_revokee(who); end if; for i in 1..npriv loop for j in 1..nwho loop insert into log values ( systimestamp, ora_sysevent, who(j), priv(i), ora_dict_obj_owner, ora_dict_obj_name ); end loop; end loop; end;
12/3/2013 Database Consult Karsten Aalderks 32
SQL> grant select on log to bar;
Grant succeeded.
SQL> revoke select on log from bar;
Revoke succeeded.
SQL> select * from log; DT WHAT WHO PRIV OWN OBJ
25-NOV-12 05.29.19.095403 PM GRANT BAR SELECT MAT LOG 25-NOV-12 05.29.27.004610 PM REVOKE BAR SELECT MAT LOG
12/3/2013 Database Consult Karsten Aalderks 33
Number of effective privileges
with public and implicit privileges of every user
50.000 – up to more than 100.000.000 !
Identify all effective privileges via recursive sql dba_sys_privs,tba_tab_privs, dba_role_privs,dba_role_roles,
dba_col_privs, …
Better solution : Use base tables of dba_xxx_views without filter and with rowid!
12/3/2013 Database Consult Karsten Aalderks 34
Import all effective privs in a master privilege table initial
changes e.g. every day
Consolidate cascading role privs to flat direct privileges!
Use a simple provisioning system for direct privs
from master privilege db to slave db‘s.
Maintain your role concept on the master privilege database , but work with direct privileges !
12/3/2013 Database Consult Karsten Aalderks 35
Now, you can change a single privilege with limited impact and less dependancies.
Secure Approach for changing privileges
in Test Enviroments and please work step by step ( one logical change )!
Before : Select any table
After : select all on hr via generated direct privileges
Detecting ORA -01031 insufficient privileges via System Error Trigger / manual or automatic controlled privilege escalation
12/3/2013 Database Consult Karsten Aalderks 36
Avoid Oracle default roles
Resource role includes : Alter user …
Use create session instead of connect,resource
Use set role concept, if it‘s possible and tested!
Check if role creater has implicit admin option
(depends from Oracle version)
12/3/2013 Database Consult Karsten Aalderks 37
Standard Auditing AUDIT_TRAIL = { none | os | db | db,extended | xml | xml,extended }
SQL> ALTER SYSTEM SET audit_trail=db,extended SCOPE=SPFILE;
SYSDBA / SYSOPER Auditing
audit_sys_operations = TRUE
SQL> ALTER SYSTEM SET audit_trail=db,extended SCOPE=SPFILE;
Differences Windows - Linux/Unix
Windows : All audit entries are stored in Event Log
Linux : Standard audit often in database tables , sydba audit always in native os files ( .aud)
12/3/2013 Database Consult Karsten Aalderks 38
Helpful Triggers based on internal events/sys events System Database Trigger
After Login Before Logoff After Error After DDL External table on listener.log
Schema Level Trigger
Before/After Drop Before/After Alter Before/After Drop Before/After Revoke Before/After Truncate and some undocumented
Table Triggers
Row Level Triggers
Instead of Triggers
12/3/2013 Database Consult Karsten Aalderks 39
For System and Schema Level Triggers you can choose between two methods for storing the events /commands in your own tables
1. Direct insert in Trigger code or via procedure call
2. Indirect / async insert code via dbms_scheduler after sys events notification !
Method 1 is possible, but you are in context of the trigger transaction. In our example a direct revoke dba from … as activity of ‘grant dba to ka‘ is not possible. Use indirect calls via execute immediate after checking if insert_proc exists is valid and accessible.
Method 2 is smart, because you are not inside the transaction of the trigger. After inserting the events/commands in a table, you can e.g. revoke illegal grant commands just in time !
12/3/2013 Database Consult Karsten Aalderks 40
Audit Data Transport
Why syslog isn‘t a good solution
No PCI,SOX, ISO, COBIT compliance No transactional protocol No encryption options No failover capabilities ( memory, harddisc) No advanced filter options
Tip : Write your own audit transport solution or use products like syslog-ng How to audit sysdba into an os file owned by root - from Uwe Hesse http://uhesse.com/2010/02/02/how-to-audit-sys-into-an-os-file-owned-by-root/ Works also with syslog-ng !
12/3/2013 Database Consult Karsten Aalderks 41
Audit Transport
A lot of security experts recommends a solution with control from outside the database.
This is true, but not realistic.
Why ?
In every comany the database group uses tested proceedings for rollout–remember up to 30.000 databases!
Rollout a database centric audit data transport solution with existing infrastructure is more practical. It is also true, that the most complicated part in such database centric solutions, is to make them acceptably safe!
12/3/2013 Database Consult Karsten Aalderks 42
Conclusion
It is better to have a database centric audit data transport solution in place of no solution !
12/3/2013 Database Consult Karsten Aalderks 43
How avoiding personalized audit data ? Event/Actor Model
One Auditrecord describes the event without data of user,machine, …
One Auditrecord describes the user, machine,…
Create your join criteria (1=1, 1:n) (database,rac_id, application,timestamp, …)
Use filters, groupings, codes for identical command sequences to reduce the amount of audit data.
But limit optimisation :
revoke, grant, revoke ,grant in a sequence, should create four audit records!
12/3/2013 Database Consult Karsten Aalderks 44
Small Audit Comand Set by Red Database Security audit ALTER ANY PROCEDURE BY ACCESS; audit ALTER ANY TABLE BY ACCESS; audit ALTER DATABASE BY ACCESS; audit ALTER PROFILE BY ACCESS; audit ALTER SYSTEM BY ACCESS; audit ALTER USER BY ACCESS; audit CREATE ANY JOB BY ACCESS; audit CREATE ANY LIBRARY BY ACCESS; audit CREATE ANY PROCEDURE BY ACCESS; audit CREATE ANY TABLE BY ACCESS; audit CREATE EXTERNAL JOB BY ACCESS; audit CREATE PUBLIC DATABASE LINK BY ACCESS; audit CREATE SESSION BY ACCESS; audit CREATE USER BY ACCESS; audit DATABASE LINK BY ACCESS; audit DROP ANY PROCEDURE BY ACCESS; audit DROP ANY TABLE BY ACCESS; audit DROP PROFILE BY ACCESS; audit DROP USER BY ACCESS; audit EXEMPT ACCESS POLICY BY ACCESS; audit GRANT ANY OBJECT PRIVILEGE BY ACCESS;
12/3/2013 Database Consult Karsten Aalderks 45
audit GRANT ANY PRIVILEGE BY ACCESS; audit GRANT ANY ROLE BY ACCESS; audit PROFILE BY ACCESS; audit CREATE PUBLIC SYNONYM BY ACCESS; audit ROLE BY ACCESS; audit SYSTEM audit BY ACCESS; audit SYSTEM GRANT BY ACCESS; audit create any table by access; audit alter any table by access; audit drop any table by access; audit CREATE ROLE by access; audit CREATE JOB BY ACCESS; audit CREATE ANY JOB BY ACCESS; audit audit SYSTEM BY ACCESS; audit ALTER DATABASE BY ACCESS; audit CREATE ANY DIRECTORY BY ACCESS; audit CREATE PUBLIC SYNONYM BY ACCESS; audit EXECUTE ON DBMS_FGA BY ACCESS; audit EXECUTE ON DBMS_RLS BY ACCESS; audit EXECUTE ON DBMS_FILE_TRANSFER BY ACCESS; audit EXECUTE ON DBMS_SCHEDULER BY ACCESS; audit EXECUTE ON DBMS_JOB BY ACCESS; audit EXECUTE ON DBMS_IJOB BY ACCESS; audit EXECUTE ON KUPP$PROC BY ACCESS; audit SELECT ON SYS.V_$SQL; audit create session;
12/3/2013 Database Consult Karsten Aalderks 46
Housekeeping of Auditdata in Tables / Files
via DBMS_AUDIT_MGMT ( tables / os files)
or
use a job /cqn based
Housekeeping as part of your
Auditdata transport solution
12/3/2013 Database Consult Karsten Aalderks 47
Database System Baselines CIS Benchmarks ( updated by experts in 2012) http://benchmarks.cisecurity.org/downloads/show-single/?file=oracle11g.110
BSI Checkliste https://www.bsi.bund.de/SharedDocs/Downloads/DE/BSI/Grundschutz/Hilfsmittel/Extern/orcl-chk_pdf.html
McAfee Database Security Scanner ( all inclusive ) http://www.mcafee.com/de/products/security-scanner-for-databases.aspx
12/3/2013 Database Consult Karsten Aalderks 48
Types of monitoring
Classical Monitoring
Acitivity Monitoring
Virtual Patching
Classical Monitoring - activity after event completes
Activity Monitoring - activity before event completes
Virtual Patching - activity after detection the usage of database leaks
12/3/2013 Database Consult Karsten Aalderks 49
What ?
Classical Database Monitoring : Objects (Tables,Views, Data, …)
Activity Monitoring
All of classical monitoring
Event/Commands detecting
Rule/Event based activity !
12/3/2013 Database Consult Karsten Aalderks 50
Application Security
Monitor the truth …
Network scanning :
select * from scott.gender;
But “gender“ is a view based on “creditcard“!
Monitor all modify and select operations on “creditcard“
12/3/2013 Database Consult Karsten Aalderks 51
Points of interest :
Which appliation exports and imports data ?
Which foreign applications select‘s critical data?
Which foreign application modifies user
management, application config, … ?
Which application users works with critical data?
Is it possible to create a whitelist with machine names, ip‘s , … for users of critical data ?
…
12/3/2013 Database Consult Karsten Aalderks 52
Example activity monitoring solution by yourself
Encrypts/Decrypts creditcard numbers and audit every select on column “CREDIT_CARD_NR“
Concept :
virtual columns + autonomous transaction deterministic pl/sql function
12/3/2013 Database Consult Karsten Aalderks 53
Possible Activities with functions, used in virtual columns ( critical columns) :
Encrypt /Decrypt functionality
Monitoring and logging of modify and select operations
Data masking
Masking decision via session information Time
Machine
…
12/3/2013 Database Consult Karsten Aalderks 54
CREATE TABLE creditcard ( id NUMBER, -- persistent card_nr_ecrypt RAW(400) , -- persistent credit_card_nr AS (dcrypt(card_nr_ecrypt) ) -- flüchtig ); /
INSERT INTO creditcard ( id, card_nr_ecrypt ) VALUES ( 1, ecrypt('5554334334453344') ); COMMIT;
12/3/2013 Database Consult Karsten Aalderks 55
CREATE OR REPLACE FUNCTION dcrypt( eingabe IN RAW) RETURN VARCHAR2 DETERMINISTIC IS PRAGMA AUTONOMOUS_TRANSACTION; v_os VARCHAR2(30); v_schem VARCHAR2(30); v_mach VARCHAR2(100); v_prg VARCHAR2(100); v_daten RAW(200); v_schluessel RAW(32); v_verschluesselung PLS_INTEGER := DBMS_CRYPTO.ENCRYPT_AES256 + DBMS_CRYPTO.CHAIN_CBC + DBMS_CRYPTO.PAD_ZERO; BEGIN SELECT schluessel INTO v_schluessel FROM schluesseltabelle WHERE sysdate BETWEEN startdatum AND NVL(enddatum, sysdate); v_daten := DBMS_CRYPTO.DECRYPT( src => eingabe, typ => v_verschluesselung, KEY => v_schluessel); SELECT osuser, schemaname, machine, program INTO v_os, v_schem, v_mach, v_prg FROM v$session WHERE sid IN (SELECT sys_context('USERENV','SID') FROM dual );
12/3/2013 Database Consult Karsten Aalderks 56
INSERT INTO audit_select VALUES ( 'CREDITCARD', 'CREDITCARD_NR', v_os, v_schem, v_mach, v_prg, systimestamp ); COMMIT; RETURN UTL_I18N.RAW_TO_CHAR(v_daten, 'AL32UTF8'); END; /
12/3/2013 Database Consult Karsten Aalderks 57
To make it transparent for your application
Add your virtual columns to original table
Rename your base table to table_name_base
Create updatable view on that original table 1:1
Write instead of trigger on updatable view which redirects org_column insert‘s via ecrypt function in encrypted column.
12/3/2013 Database Consult Karsten Aalderks 58
CREATE OR REPLACE TRIGGER scott.trg_instof_creditcard
INSTEAD OF INSERT ON SCOTT.creditcard_v FOR EACH ROW
BEGIN
INSERT INTO creditcard ( id,card_nr_ecrypt) values (:new.id,ecrypt(:new.credit_card_nr));
END;
/
12/3/2013 Database Consult Karsten Aalderks 59
Is execute immediate ‘grant dba to ka‘ in your deterministic function and used in virtual columns a bomb , if executed with authid current as high privileged user?
Actually we discuss this point and want to find some indirect dba executions
in real life examples.
A DDL Defense makes sense
Store DDL/DCL commands e.g. oramon.oraddl ( Grant, Revoke, .... )
CQN Event on Resultset change of oramon.oradll ( SQL with Select e.g. filter - Grant dba to ... - additional conditions
Function, triggered by CQN event excutes a procedure ( just in time ) with
replace(replace(sql_text,'grant','revoke'),'to', 'from);'
12/3/2013 Database Consult Karsten Aalderks 60
Applications have their own universe in database userschema‘s
A lot of infrastructure components exists once more.
User Management/Password Management
Privilegemanagement
History Management
…
12/3/2013 Database Consult Karsten Aalderks 61
Example Passwords : You can find Application Passwords in cleartext or hashed in tables like “MyKillerApp.Passwords“ and not in sys.user$. Points of interest :
Detection of database objects with passwords over Object_name, object_column_names, Procedures with parameter like Pwd , … Detection of cleartext passwords Detection of pasword complexity with length Detection of password life time Detection of encryption/hash algorithm, perhaps with salt History of all password changes via other applications
12/3/2013 Database Consult Karsten Aalderks 62
Starting with a simple approach : Write your detection sql statements as a union view.
Use - like and regexp
Use packages /java code ( as stored procedures ) for algos / detection
Use the union view for insert/merge in your master table for all monitoring objects ( Master Monitoring Object Table)
Customize the master table with monitoring features ( logging, send email, revoke privilege, kill session, null, … ) based on a single object - manually !
Start your monitoring package via database job and a time interval and this package fills up your Master Logging Table
Start a second reporting job against the Master Logging Table with statistics and alerts/notifications based on multiple entries.
12/3/2013 Database Consult Karsten Aalderks 63
Which Oracle system information can help to find attackers in context application ?
v$session columns : machine, Program , module, module_hash First save all values from regular and allowed programs including
a whitlist of machines Check with the logon trigger if module_hash,machine is member
of whitelist and if program and module are equal and module_hash is correct for a specific application!
SQLPLUS module_hash ( 11xe windows) 254292535
12/3/2013 Database Consult Karsten Aalderks 64
V$sqlarea : columns of interest
Sql_text ( select with no where clause ! )
Row_processed ( detection for logical export )
Interest on high and 0 values
Parsing_user_id not equal parsing_schema_id !
Module and module_hash not in whitelist
Remote not equal ‘N‘
12/3/2013 Database Consult Karsten Aalderks 65
v$db_object_cache columns of interest :
owner of application or application schema‘s
Name of object with sql statement object
Db_link not null
Type of object ( table,view, cursor, package, …)
Executions high values and 0
Pin_mode value != ‘NONE‘ - shareable,…
12/3/2013 Database Consult Karsten Aalderks 66
Activity Monitoring with commercial software
McAfee Database Actvitiy Monitoring (McDAM)
formerly Hedgehog
Concept :
‘connect‘s‘ direct on oracle sga and reads every statement before execution and after execution plan creation with an merge option based on network scanning
So , this is the truth!
Via rules you can define the activity :
Logging, alerting, send email, … ,kill session
12/3/2013 Database Consult Karsten Aalderks 67
Preventing SQL Injection : Questions for verfing input/parameter (pl/sql)
Correct usage of dbms_assert
Write your own input validation building set
Questions : Which result do you expect (Single row or multiple rows ) ?
Can you limit the input length ?
Can you limit the count of spaces ?
Can you enumerate a fixed whitelist for values ?
Can you write a static select with all possible values?
Are special character‘s valid and how much
Enumerate a blacklist ( union, -- , ‘‘ , q , … )
12/3/2013 Database Consult Karsten Aalderks 68
Input validation – The old style :
You have two pages with several input fields.
Use plausibility methods based on association of preceding input and often only a few values remains.
Benefits : Preventing SQL Injection
High data qualitiy
12/3/2013 Database Consult Karsten Aalderks 69
Preventing SQL Injection with dbms_assert
First check if dbms_assert is not a public synonym for an empty package ( null;)
Check if users like OLAP_USER can‘t create public synonyms for ORACLE PACKAGES.
Do not use the sys.dbms_assert.noop function
Use all Packages full qualified user.package.function/procedure
12/3/2013 Database Consult Karsten Aalderks 70
DBMS_ASSERT functions :
Verify if Schemaname exists SCHEMA_NAME
Verify if Objects or Sqlnames exists SQL_OBJECT_NAME,
SIMPLE_SQL_NAME,
QUALIFIED_SQL_NAME
Enqotes literals with double quotes ENQUOTE_LITERAL
Enquotes names with double quotes ENQUOTE_NAME
No operation NOOP
12/3/2013 Database Consult Karsten Aalderks 71
Advanced example from Alexander Kornbrust
CREATE OR REPLACE PROCEDURE test (TABLENAME IN VARCHAR2) IS
VERIFY_TAB VARCHAR2(64);
num1 number;
BEGIN
VERIFY_TAB := DBMS_ASSERT.QUALIFIED_SQL_NAME(TABLENAME);
dbms_output.put_line('ASSERT result='||VERIFY_TAB);
EXECUTE IMMEDIATE 'select count(*) from all_tables where table_name='''||VERIFY_TAB||'''';
END test;
/
12/3/2013 Database Consult Karsten Aalderks 72
SQL> exec test('ALEX'' or 1=1--');
BEGIN test('ALEX'' or 1=1--'); END;
*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error
ORA-06512: at "SYS.DBMS_ASSERT", line 234
ORA-06512: at "HACKER.TEST", line 6
ORA-06512: at line 1
12/3/2013 Database Consult Karsten Aalderks 73
Cool idea!
create table "' or 1=1--'" (a varchar2(1));
SQL> exec test('"'' or 1=1--''"');
ASSERT result="' or 1=1--'"
PL/SQL procedure successfully completed.
12/3/2013 Database Consult Karsten Aalderks 74
In the background Oracle concatenates the sanitized input into the SQL command EXECUTE IMMEDIATE 'select count(*) from all_tables
where table_name='''||VERIFY_TAB||'''';
and constructs and executes the following SQL statement
select count(*) from all_tables where table_name='"' or 1=1 --'""'
12/3/2013 Database Consult Karsten Aalderks 75
CREATE OR REPLACE PROCEDURE test (TABLENAME IN VARCHAR2) IS
VERIFY_TAB VARCHAR2(64);
num1 number;
BEGIN
VERIFY_TAB := DBMS_ASSERT.ENQUOTE_LITERAL(DBMS_ASSERT.QUALIFIED_SQL_NAME(TABLENAME));
dbms_output.put_line('ASSERT result='||VERIFY_TAB);
EXECUTE IMMEDIATE 'select count(*) from all_tables where table_name='||VERIFY_TAB;
END test;
/
12/3/2013 Database Consult Karsten Aalderks 76
Best solution, if possible, bind variables
Use double quotes for names, literals,passwords,
...
Develop ‘create object wrapper‘ with checks aginst real life names, better policies !
Use q function instead of ‘‘‘‘‘
12/3/2013 Database Consult Karsten Aalderks 77
declare
v_sql varchar2(32767);
begin
v_sql := 'declare ' ||
' v_sql varchar2(32767); ' ||
'begin ' ||
' v_sql := ''select ''''Hello World'''' from dual'''||
' end;';
end;
12/3/2013 Database Consult Karsten Aalderks 78
declare v_sql varchar2(32767);
begin
v_sql := q'#declare #' ||
q'# v_sql varchar2(32767); #' ||
q'#begin #' ||
q'# v_sql := q'{select q'[Hello World]' from dual}'#' ||
q'# end;#';
end;
12/3/2013 Database Consult Karsten Aalderks 79
Check your PL/SQL Code via dba_source -column TEXT or via unwrapper tools ( Python).
Dynamic SQL : execute immediate, dbms_sql, dbms_sys_sql, oci_calls via external procedure
Dangerous functions : translate, replace, converting functions, unions, ….
Wrapped code, which is not from Oracle and from Oracle …
12/3/2013 Database Consult Karsten Aalderks 80
Use AES-256 via java stored prodedure for critical columns
Add new hash algorithm via java stored procedure ( SHA-3,Keccak )
Use BBS Pseudo Random Generator via Java Stored Procedures instead of dbms_random and dbms_crypto !
http://code.google.com/p/randomness-framework/source/browse/trunk/csprng/org/randomness/BBS.java
12/3/2013 Database Consult Karsten Aalderks 81
Good News - October 2013:
'Network encryption (native network encryption and SSL/TLS) and strong authentication services (Kerberos, PKI, and RADIUS) are no longer part of Oracle Advanced Security and are available in all licensed editions of all supported releases of the Oracle database.
12/3/2013 Database Consult Karsten Aalderks 82
Activate network encryption : Client - $ORACLE_HOME/network/admin/sqlnet.ora
Fast !
SQLNET.CRYPTO_CHECKSUM_TYPES_CLIENT = (MD5) SQLNET.ENCRYPTION_TYPES_CLIENT = (RC4_256) SQLNET.ENCRYPTION_CLIENT = required SQLNET.CRYPTO_CHECKSUM_CLIENT = required
Safe!
SQLNET.CRYPTO_CHECKSUM_TYPES_CLIENT = (SHA1) SQLNET.ENCRYPTION_TYPES_CLIENT = (AES_256) SQLNET.ENCRYPTION_CLIENT = required SQLNET.CRYPTO_CHECKSUM_CLIENT = required
Multiple entries für types_client are possible: (RC4_256,AES256)
12/3/2013 Database Consult Karsten Aalderks 83
For all enviroments including production data masking make sense!
Why production ?
Because cloning and full database exports starts in reality on production
You can store the original and a masked version of your data in production
12/3/2013 Database Consult Karsten Aalderks 84
How on production ?
One solution based on VPD predicates
Where role is in ‚‘DEV‘,TEST‘,‘INT‘,‘CLONER‘
or
Where role = ‘PROD‘
Other solutions uses partitioning and deternministic functions for dynamic partiton keys
12/3/2013 Database Consult Karsten Aalderks 85
PL/SQL Treasure Steps in development :
Mark criticial source code lines Start the treasure package with param ‘Transform‘
Encrypts marked source code in a table Sets marked lines to null; null Integrates a call execute immediate
gen_blk(‘account_mgmt’,p_name,p_pwd); -->~~< SIGNATUR_1
Recompiles your procedure/function
What happens during runtime ? Call your native procedure/function The integrated remarked call generates an anonymous block with merged code ( decrypted , native code) and executes this block. Last statement in this pl/sql block destroys code and data in memory. Way back to original sourcecode via param ‘Original‘ for developers
12/3/2013 Database Consult Karsten Aalderks 86
Detecting file changes on Linux/Unix
Use auditd, audist, auditctl, audit.rules
or if possible, inotify to detect modifications and read operations for selected files ( oracle user ) with non default processes.
Config files ( sqlnet, tnsnames, listener | .ora, …)
Log files ( alert.log, audit files, listener.log,….
12/3/2013 Database Consult Karsten Aalderks 87
With simple concepts you can effect a lot
12/3/2013 Database Consult Karsten Aalderks 88