Tipps & Tricks: Januar 2017 Bereich: Securtiy Erstellung: 01/2017 MP Versionsinfo: 11g, 12c Letzte Überarbeitung: 01/2017 MP Security Scoring In diesem Tipp zeigen wir eine Möglichkeit zur Bewertung verschiedener potentieller Gefahren in der Oracle Datenbank, welche individualisiert überprüft werden können. Da wären SQL-Injection-anfällige Eingaben oder auch die Gefährlichkeit der Rechte bzw. Rollen von Datenbank-Nutzern. SQL Injection Um SQL Injection-Angriffe abzuwehren bietet Oracle das Package "DBMS_ASSERT", welches Eingaben bzw. Strings auf Gültigkeit überprüft. Möchte man allerdings eine Unterscheidung bzw. Einschätzung der potentiellen Gefahr haben, hilft einem dieses Package nicht weiter. Deshalb erstellen wir die Funktion "get_score", die einen zu überprüfenden String entgegennimmt. Zurückgegeben wird ein Scoring-Wert. CREATE OR REPLACE FUNCTION get_score (p_text IN VARCHAR2) RETURN NUMBER IS TYPE wordsArray IS TABLE OF VARCHAR2(64); l_words wordsArray := wordsArray( 'WITH','SELECT','FROM','WHERE','LIKE','IN','UNION','OR','DUAL','CREATE', 'ALTER','DROP','GATHER','STATS','EXECUTE','GRANT','HOST','TABLE', 'TABLESPACE','DATABASE','INDEX','TRIGGER','REPLACE','DELETE','FUNCTION', 'PROCEDURE','BEGIN','RETURN','END','FOR','LOOP','IF','THEN','SYS','DBMS', 'UTL','DBA','ALL','PRIVS','WWV','v\$','SDO','UTIL','CHECK','SECURITY', 'MDSYS','JAVA',';','--','(1)=\1','[;].[--]'); v_pattern VARCHAR2(32700); v_score NUMBER:=0; BEGIN FOR i IN 1 .. l_words.count LOOP v_pattern:=v_pattern||'|'||l_words(i); END LOOP; v_score:=v_score+REGEXP_COUNT(p_text,LTRIM(v_pattern,'|'),1,'i'); RETURN v_score; END; Innerhalb dieser Funktion legen wir uns ein Array mit allen Schlüsselwörtern an, die als verdächtig erachtet werden. Da "REGEXP_COUNT" nur ein Schlüsselwort erwartet, konkatenieren wir die Schlüsselwörter jeweils mit einem Pipe "|". Der Parameter "1" legt den ersten Buchstaben als Start fest und "i" beachtet keinen Unterschied zwischen Groß- und Kleinschreibung. Sobald "REGEXP_COUNT" einen Match gefunden hat, wird der Score um eins erhöht. Die Scoring-Abfrage auf einen typischen SQL Injection-String sieht folgend aus: select GET_SCORE('falscher_nutzer'' OR 1=1 ; DROP TABLE users --') as score Muniqsoft GmbH Schulungszentrum, Grünwalder Weg 13a, 82008 Unterhaching, Tel. 089 / 679090-40 IT-Consulting & Support, Witneystraße 1, 82008 Unterhaching, Tel. 089 / 6228 6789-0 Seite 1 von 8 from dual; SCORE ---------6 Hinweis: Oracle kann nur einen Befehl dynamisch ausführen, der DROP TABLE würde sowieso nicht funktionieren. Aber manche Hacker gehen von SQL Server oder MYSQL Datenbanken aus, da geht so etwas. Folgende Schlüsselwort wurden also abgefangen: "OR", "1=1", "DROP", "TABLE", ";", "--" Regex aus dem oberen Beispiel für Schlüsselwörter erklärt: "(1)=\1": Wahrheitsvergleich 1=1 der sehr beliebt ist "[;].[--]": Typisches Ende einer SQL Injection: ";--" oder auch "; DROP TABLE wichtig -------" Da das Thema Reguläre Ausdrücke sehr komplex ist, verweisen wir auf eine gute Stelle im Internet: http://www.sqlsnippets.com/en/topic-10764.html Rechte & Rollen Das oben beschriebene Prinzip bleibt das selbe: In ein Array speichern wir potentiell gefährliche Rechte, die wir abfragen möchten. Die Funktion bekommt einen Benutzernamen übergeben, den es zu überprüfen gilt, und zurückgegeben wird ein Scoring-Wert. Es werden nicht nur direkte Rechte abgefragt, sondern auch Rechte die über eine Rolle erteilt wurden. create or replace PACKAGE priv_check IS /* Notwendige Rechte: grant select on sys.sysauth$ to system; grant select on sys.user$ to system; grant select on sys.system_privilege_map to system; grant select on sys.DBA_ROLE_PRIVS to system; */ FUNCTION get_syspriv_score (p_user IN VARCHAR2) RETURN NUMBER; END; / CREATE OR REPLACE PACKAGE BODY priv_check IS FUNCTION get_syspriv_score (p_user IN VARCHAR2) RETURN NUMBER IS TYPE privArray IS TABLE OF VARCHAR2(64); l_privs privArray := privArray( 'ALTER ANY LIBRARY', 'ALTER DATABASE', 'ALTER USER', 'BECOME USER', 'CREATE ANY LIBRARY', 'CREATE EXTERNAL JOB', 'CREATE LIBRARY', 'CREATE USER', 'DROP ANY INDEX', 'DROP ANY LIBRARY', 'DROP ANY PROCEDURE', 'DROP ANY ROLE', Muniqsoft GmbH Schulungszentrum, Grünwalder Weg 13a, 82008 Unterhaching, Tel. 089 / 679090-40 IT-Consulting & Support, Witneystraße 1, 82008 Unterhaching, Tel. 089 / 6228 6789-0 Seite 2 von 8 'DROP ANY SYNONYM', 'DROP ANY TABLE', 'DROP TABLESPACE', 'DROP ANY TRIGGER', 'DROP ANY VIEW', 'DROP PUBLIC DATABASE LINK', 'DROP USER', 'EXECUTE ANY LIBRARY', 'EXEMPT ACCESS POLICY', 'EXEMPT IDENTITY POLICY', 'EXPORT FULL DATABASE', 'GRANT ANY PRIVILEGE', 'GRANT ANY OBJECT PRIVILEGE', 'IMPORT FULL DATABASE', 'SYSDBA', 'SYSOPER', 'SYSBACKUP' ); v_score NUMBER:=0; begin -- Direkte Rechte FOR c IN ( select u.name username, spm.name privilege from sys.user$ u, sys.sysauth$ s, sys.system_privilege_map spm where u.user#=s.grantee# and s.privilege#=spm.privilege and U.NAME=p_user ) LOOP FOR i IN 1 .. l_privs.count LOOP IF l_privs(i)= c.privilege THEN v_score:=v_score+1; END IF; END LOOP; END LOOP; -- Rechte via Rollen FOR c IN ( SELECT u1.name USERNAME, U2.NAME ROLENAME, SUBSTR(SPM.NAME,1,27) PRIVILEGE FROM SYS.SYSAUTH$ SA1, SYS.SYSAUTH$ SA2, SYS.USER$ U1, SYS.USER$ U2, SYS.SYSTEM_PRIVILEGE_MAP SPM Muniqsoft GmbH Schulungszentrum, Grünwalder Weg 13a, 82008 Unterhaching, Tel. 089 / 679090-40 IT-Consulting & Support, Witneystraße 1, 82008 Unterhaching, Tel. 089 / 6228 6789-0 Seite 3 von 8 WHERE SA1.GRANTEE# = U1.USER# AND SA1.PRIVILEGE# = U2.USER# AND U2.USER# = SA2.GRANTEE# (+) AND SA2.PRIVILEGE# = SPM.PRIVILEGE (+) AND (U1.NAME IN ( SELECT GRANTEE FROM sys.DBA_ROLE_PRIVS connect by prior granted_role=GRANTEE start with GRANTEE IN ( SELECT NAME FROM sys.USER$ WHERE user# in ( select privilege# from sys.sysauth$ t1, sys.user$ t2 where t1.grantee#=t2.user# and t2.name=p_user ) ) UNION SELECT GRANTED_ROLE FROM DBA_ROLE_PRIVS connect by prior granted_role=GRANTEE start with GRANTEE IN ( SELECT NAME FROM sys.USER$ WHERE user# in ( select privilege# from sys.sysauth$ t1, sys.user$ t2 where t1.grantee#=t2.user# and t2.name=p_user ) ) ) OR U1.NAME=p_user ) ) Muniqsoft GmbH Schulungszentrum, Grünwalder Weg 13a, 82008 Unterhaching, Tel. 089 / 679090-40 IT-Consulting & Support, Witneystraße 1, 82008 Unterhaching, Tel. 089 / 6228 6789-0 Seite 4 von 8 LOOP FOR i IN 1 .. l_privs.count LOOP IF l_privs(i)= c.privilege THEN v_score:=v_score+1; END IF; END LOOP; END LOOP; RETURN v_score; EXCEPTION WHEN OTHERS THEN RETURN sqlcode; END get_syspriv_score; END; / Eine Abfrage des Scores selektiert man wie folgt: SELECT * FROM ( SELECT username, priv_check.get_syspriv_score(username) AS score FROM dba_users ) WHERE score>0 ORDER BY score DESC; USERNAME SCORE --------------------------- ---------SYS 140 SYSTEM 74 WMSYS 8 APEX_050000 5 APEX_040200 5 DVSYS 4 SPATIAL_CSW_ADMIN_USR 2 SPATIAL_WFS_ADMIN_USR 2 OLAPSYS 2 GSMADMIN_INTERNAL 2 SYSBACKUP 2 MDSYS 2 SYSDG 1 XDB 1 Der administrative Benutzer "SYS" besitzt logischerweise den höchsten Scoring-Wert. Um überhaupt herauszufinden welche Benutzer direkt oder über eine Rolle solche Rechte besitzen, kann man dies mithilfe von folgendem Statement herausfinden. Der SELECT listet alle betroffenen Benutzer und zeigt diese in hierachischer Struktur an. Muniqsoft GmbH Schulungszentrum, Grünwalder Weg 13a, 82008 Unterhaching, Tel. 089 / 679090-40 IT-Consulting & Support, Witneystraße 1, 82008 Unterhaching, Tel. 089 / 6228 6789-0 Seite 5 von 8 SELECT lpad(' ', 2*level) || c "Privilege, Roles and Users" FROM ( /* THE PRIVILEGES */ select null p, name c from system_privilege_map where name in ( 'DROP TABLESPACE', 'CREATE USER', 'BECOME USER', 'ALTER USER', 'DROP USER', 'DROP ANY TABLE', 'DROP ANY INDEX', 'DROP ANY SYNONYM', 'SYSDBA', 'SYSOPER', 'DROP ANY VIEW', 'DROP PUBLIC DATABASE LINK', 'DROP ANY ROLE', 'ALTER DATABASE', 'DROP ANY PROCEDURE', 'DROP ANY TRIGGER', 'GRANT ANY PRIVILEGE', 'CREATE LIBRARY', 'CREATE ANY LIBRARY', 'ALTER ANY LIBRARY', 'DROP ANY LIBRARY', 'EXECUTE ANY LIBRARY', 'EXEMPT ACCESS POLICY', 'EXPORT FULL DATABASE', 'IMPORT FULL DATABASE', 'EXEMPT IDENTITY POLICY', 'CREATE EXTERNAL JOB' ) /* THE ROLES TO ROLES RELATIONS */ UNION SELECT granted_role p, grantee c FROM dba_role_privs /* THE ROLES TO PRIVILEGE RELATIONS */ UNION SELECT privilege p, grantee c FROM Muniqsoft GmbH Schulungszentrum, Grünwalder Weg 13a, 82008 Unterhaching, Tel. 089 / 679090-40 IT-Consulting & Support, Witneystraße 1, 82008 Unterhaching, Tel. 089 / 6228 6789-0 Seite 6 von 8 dba_sys_privs ) START WITH p IS NULL CONNECT BY p = PRIOR c; Ein ebenfalls hilfreiches Statement um herauszufinden, welche Benutzer welche Rechte vererben dürfen: select privilege, grantee, admin_option from dba_sys_privs where privilege in ( 'DROP TABLESPACE', 'CREATE USER', 'BECOME USER', 'ALTER USER', 'DROP USER', 'DROP ANY TABLE', 'DROP ANY INDEX', 'DROP ANY SYNONYM', 'SYSDBA', 'SYSOPER', 'DROP ANY VIEW', 'DROP PUBLIC DATABASE LINK', 'DROP ANY ROLE', 'ALTER DATABASE', 'DROP ANY PROCEDURE', 'DROP ANY TRIGGER', 'GRANT ANY PRIVILEGE', 'CREATE LIBRARY', 'CREATE ANY LIBRARY', 'ALTER ANY LIBRARY', 'DROP ANY LIBRARY', 'EXECUTE ANY LIBRARY', 'EXEMPT ACCESS POLICY', 'EXPORT FULL DATABASE', 'IMPORT FULL DATABASE', 'EXEMPT IDENTITY POLICY', 'CREATE EXTERNAL JOB' ) ORDER BY 1; PRIVILEGE GRANTEE ADM ----------------------- ------------------- --ALTER ANY LIBRARY DBA NO ALTER ANY LIBRARY SYS NO ALTER DATABASE SYS NO ALTER DATABASE APEX_040200 NO ... Muniqsoft GmbH Schulungszentrum, Grünwalder Weg 13a, 82008 Unterhaching, Tel. 089 / 679090-40 IT-Consulting & Support, Witneystraße 1, 82008 Unterhaching, Tel. 089 / 6228 6789-0 Seite 7 von 8 Weitere Ideen und Konzepte erhalten Sie in einem unserer drei Security Kurse (DB Security I, DB Security II und APEX Security). Oder Sie fragen nach unserem Consulting Security Check bei Ihnen im Hause. Muniqsoft GmbH Schulungszentrum, Grünwalder Weg 13a, 82008 Unterhaching, Tel. 089 / 679090-40 IT-Consulting & Support, Witneystraße 1, 82008 Unterhaching, Tel. 089 / 6228 6789-0 Seite 8 von 8