Freitag, 14. November 2014

Logins und Serverrollen ermitteln

Grundlage aller Serveranalysen im Rahmen von Sicherheitsüberprüfungen ist eine Übersicht über die verfügbaren Logins (Server Prinzipale) und ihre Gruppenzugehörigkeit. War es seit der Version 2005 bis zur Version 2008 R2 noch möglich, mit Hilfe einer PIVOT-Abfrage die Zugehörigkeiten zu festen Serverrollen abzufragen, wurde mit Version 2012 die erstmals die Möglichkeit gegeben, eigene Serverrollen zu definieren. Wie dennoch eine Übersicht aller Berechtigungen ausgegeben werden kann, zeigen die folgenden Skripte im Zusammenhang mit einer umfangreichen Erläuterung zu den festen Serverrollen in Microsoft SQL Server.

Sicherheitsinformationen < 2012

Die Rollen von Microsoft SQL Server bis zur Version 2008 (R2) waren vordefiniert und konnten nicht individuell erweitert werden. Von daher war eine Analyse der Rollenzugehörigkeit für die Versionen 2005 – 2008 R2 durch eine PIVOT-Abfragen möglich, wie das nachfolgende Skript zeigt:

SELECT  login_name,
        login_type,
        [public],
        [sysadmin],
        [securityadmin],
        [serveradmin],
        [setupadmin],
        [processadmin],
        [diskadmin],
        [dbcreator],
        [bulkadmin]
FROM
(
    SELECT  SP.name         AS  login_name,
            SP.type         AS  login_type,
            'public'        AS  server_role,
            sp.principal_id
    FROM    sys.server_principals AS SP
    WHERE   type != 'R'
 
    UNION
 
    SELECT  SP.name         AS  login_name,
            SP.type         AS  login_type,
            role_list.name  AS  server_role,
            SP.principal_Id
    FROM    sys.server_principals AS SP LEFT JOIN
            (
                SELECT  SRM.member_principal_id,
                        SR.name
                FROM    sys.server_role_members AS SRM INNER JOIN sys.server_principals AS SR
                        ON (SRM.role_principal_id = SR.principal_id)
            ) AS role_list ON
            (sp.principal_id = role_list.member_principal_id)
    WHERE    SP.type != 'R'
) AS SecList
PIVOT
(
    COUNT(principal_id)
    FOR  server_role
    IN
    (
        [public],
        [sysadmin],
        [securityadmin],
        [serveradmin],
        [setupadmin],
        [processadmin],
        [diskadmin],
        [dbcreator],
        [bulkadmin]    
    )
) AS pvt
ORDER BY
    login_type,
    login_name;

Das Skript sieht auf dem ersten Blick umständlich aus da es durch die Verwendung einer PIVOT-Abfrage recht umfangreich und kompliziert erscheint. Prinzipiell gilt jedoch die besondere Beachtung den fest definierten Serverrollen. Diese “festen Serverrollen” sind in Microsoft SQL Server Standard und konnten bis zur Version Microsoft SQL Server 2012 nicht erweitert werden.


Sicherheitsinformationen >= 2012


Mit Microsoft SQL Server 2012 war es erstmals möglich, eigene Serverrollen zu definieren. Diese Möglichkeit wurde schon seit vielen Jahren gefordert, um in Enterprise-Umgebungen Möglichkeiten zu haben, granulare Berechtigungskonzepte für Administratoren festzulegen. Bisher war es immer notwendig, DBAs mit [sysadmin]-Berechtigungen auszustatten. Mit Microsoft SQL Server 2012 könnten erstmals dedizierte Berechtigungen erteilt werden, die sich nicht nur auf vordefinierte Bereiche erstrecken.


Auf Grund der Variabilität der Serverrollen kann das zuvor verwendete Skript nicht mehr angewendet werden. Man kann nicht mehr von den fest definierten Serverrollen ausgehen sondern muss ebenfalls einkalkulieren, dass individuelle Serverrollen implementiert wurden. Das nachfolgende Skript reagiert auf diese Variabilität, indem eine Ergebnistabelle dynamisch erstellt wird.



/* wenn die Ausgabetabelle bereits existiert, muss sie erst gelöscht werden */
IF OBJECT_ID('tempdb..##Result') IS NOT NULL
    DROP TABLE ##Result;
    GO
 
/*
    Erstellung der Ausgabetabelle basierend auf den vorhandenen Serverrollen
*/
DECLARE    @stmt        NVARCHAR(4000);
DECLARE    @col_enum    NVARCHAR(1000) = N'';
SET        @stmt  =    'CREATE TABLE ##Result([PrincipalName] nvarchar(128) NOT NULL PRIMARY KEY CLUSTERED, login_type CHAR(5) NOT NULL $Column_Names);';
 
SELECT  @col_enum = @col_enum + ', ' + QUOTENAME(name) + ' TINYINT NOT NULL DEFAULT (0)'
FROM    sys.server_principals AS SP
WHERE   type_desc = 'SERVER_ROLE'
ORDER BY
        principal_id;
 
/* Ersetzen der Textkomponente durch die tatsächlich zu erstellenden Attribute */
SET   @stmt =  REPLACE(@stmt, '$Column_Names', @col_enum);
EXEC  sp_executeSQL @stmt;
 
/* Eintragen aller vorhandenen Logins des Servers */
INSERT INTO ##Result ([PrincipalName], [login_type], [public])
SELECT  name, type, ISNULL(IS_SRVROLEMEMBER('public', name), 0)
FROM    sys.server_principals
WHERE   type_desc != 'SERVER_ROLE';
 
/* Ermittlung aller verfügbaren Serverrollen für jedes Login */
DECLARE c CURSOR
FOR
    SELECT  N'UPDATE ##Result SET ' + QUOTENAME (R.name) + ' = 1 WHERE [PrincipalName] = '+ QUOTENAME(L.name, '''') + ';'
    FROM    sys.server_principals AS L INNER JOIN sys.server_role_members AS SRM
            ON (l.principal_id = SRM.member_principal_id) INNER JOIN sys.server_principals AS R
            ON (SRM.role_principal_id = R.principal_id);
 
OPEN c;
 
FETCH NEXT FROM c INTO @stmt;
WHILE @@FETCH_STATUS != -1
BEGIN
    EXEC sp_executeSQL @stmt;
    FETCH NEXT FROM c INTO @stmt;
END
 
CLOSE c;
DEALLOCATE c;
 
/* Ausgabe des Ergebnisses */
SELECT * FROM ##Result
ORDER BY
    [login_type],
    [PrincipalName];

Das Skript wirkt ebenfalls recht umfangreich, ist aber auf Grund seiner modularen Schritte recht einfach zu lesen. Im ersten Schritt wird eine globale temporäre Tabelle erstellt, die später für die Ausgabe vorgesehen ist. Die Besonderheit dieser Ausgabetabelle besteht aus drei Dingen:



  • es handelt sich um eine globale temporäre Tabelle, da später mit sp_executeSQL befüllt und aktualisiert wird. Da sp_executeSQL in einem eigenen Kontext ausgeführt wird, kann die Ausführung nur auf globale Objekte zugreifen, die vorhanden sind.
  • Im Ausführungsstring für die Erstellung der Tabelle [##Result] befindet sich ein Textelement “$Column_Names”. Dieses Textelement wird vor der Ausführung des Codes durch die Namen der vorhandenen Serverrollen ersetzt. Dadurch wird in der Tabelle für jede Serverrolle ein eigenes Attribut erzeugt.
  • SQL Injection kann mit großer Wahrscheinlichkeit ausgeschlossen werden, da die Attribute mit QUOTENAME() in eckige Klammern eingeschlossen werden und damit nicht als Codestrukturen erkannt werden.

Ist die temporäre Tabelle ##Result erstellt, werden alle vorhandenen Logins in die Tabelle eingetragen. Da für alle Attribute, die Serverrollen repräsentieren der Standardwert 0 gilt, müssen abschließend die vorhandenen Zuordnungen von Serverlogins und Serverrollen ausgewertet und aktualisiert werden. Die Ermittlung dieser Informationen wird mit einem Cursor durchgeführt. Sobald die Evaluierungsphase abgeschlossen ist, werden die Informationen ausgegeben.


Feste Serverrollen


Für die Bewertung der Sicherheit eines vorhandenen Microsoft SQL Server ist diese Auswertung ein erster wichtiger Schritt, der jedoch noch weitere Prüfungen nach sich zieht. Hierzu zählen insbesondere die dedizierten Serverberechtigungen für jeden einzelnen Login. Microsoft SQL Server verfügt über Standardrollen für die Administration des Servers, die über unterschiedliche Berechtigungen verfügen. Die nachfolgende Liste beschreibt die festen Serverrollen in einem Microsoft SQL Server.


sysadmin


Die Mitglieder der festen Serverrolle [sysadmin] verfügen über ALLE Berechtigungen. Rechte von Mitgliedern der Serverrolle [sysadmin] können nicht eingeschränkt werden. Grundsätzlich sollten weder Applikationskonten noch Logins von Standardbenutzern über diese Rechte verfügen! Leider kommt es immer wieder vor (<=90%), dass Applikationen, die durch Softwarehersteller auf den Kundenservern implementiert werden, Logins verwenden, die Mitglied der festen Serverrolle [sysadmin] sind. Wenn ein Softwarehersteller nach diesen Rechten für seine Applikation fragt, sollte Vorsicht angebracht sein und in einer Gegenfrage die speziellen Berechtigungen für die Anwendung angefordert werden, die eine Mitgliedschaft in der Serverrolle [sysadmin] berechtigen. Ebenfalls impliziert die Mitgliedschaft in der festen Serverrolle [sysadmin] den Zugang zu allen Datenbanken und ihre Inhalte (Daten)!


serveradmin


Die Mitglieder dieser festen Serverrolle können – wie sich aus dem Namen der Serverrolle bereits ableiten lässt – die Konfiguration eines Servers ändern. Weiterhin besteht für Mitglieder der festen Serverrolle [serveradmin] die Möglichkeit, die Dienste des Microsoft SQL Server neu zu starten. Die Mitglieder der festen Serverrolle [serveradmin] sind trotz des Namens SEHR eingeschränkt. Ihre Berechtigungen erstrecken sich ausschließlich auf die Konfiguration von Einstellungen, die mittels sp_configure abgerufen werden können. Ein Mitglied der festen Serverrolle [serveradmin] kann weder Einstellungen für den SQL Agent konfigurieren noch Datenbanken oder neue Logins / Benutzer anlegen. Außerdem können keine globalen oder temporären Traceflags gesetzt werden.


securityadmin


Mitglieder der festen Serverrolle [securityadmin] können die Eigenschaften von Logins modifizieren. Jedoch können Mitglieder der festen Serverrolle [securityadmin] ein Login nicht einer Serverrollen zuweisen,  der er nicht selbst als Mitglied zugeordnet ist.


Dennoch ist vor der Vergabe dieser Privilegien sorgfältig abzuwägen! Als Mitglied der festen Serverrolle [securityadmin] besteht die Möglichkeit, weitreichende Berechtigungen “durch die Hintertür” an andere Logins zu vergeben. Das nachfolgende Skript – ausgeführt als ein Mitglied der festen Serverrolle [securityadmin] – verdeutlicht die Problematik.



-- Erstellen eines neuen Logins
CREATE LOGIN TEST WITH PASSWORD = 'abc$123', CHECK_EXPIRATION = OFF, CHECK_POLICY = OFF;
GO
 
-- Hinzufügen zur Serverrolle [securityadmin] funktioniert
ALTER SERVER ROLE [securityadmin] ADD MEMBER [TEST];
 
-- Hinzufügen zu Serverrolle [processadmin schlägt fehl,
-- da nicht selbst Mitglied
ALTER SERVER ROLE [processadmin] ADD MEMBER [TEST];
GO
 
-- Zuweisung von Berechtigungen auf Serverebene, die weit
-- über die Berechtigungen der eigenen Serverrolle hinausgehen
GRANT ALTER ANY DATABASE TO [TEST];
GRANT ADMINISTER BULK OPERATIONS TO [TEST];
GRANT CONTROL SERVER TO [TEST];
GO

Das Skript erstellt ein neues Login mit dem Namen [Test]. Anschließend sollen diesem neuen Login zwei Serverrollen zugewiesen werden. Die Zuweisung zur ersten Gruppe funktioniert einwandfrei, da der ausführende Benutzer selbst Mitglied der Serverrolle [securityadmin] ist. Der zweite Aufruf schlägt fehl, da der ausführende Benutzer nicht selbst über die notwendigen Berechtigungen verfügt.


Problematisch wird die Zuweisung von serverweiten Berechtigungen. Die letzten drei Befehle können von einem Mitglied der festen Serverrolle [securityadmin] ausgeführt und umgesetzt werden. Somit verfügt der neue Login z. B. über die Möglichkeit der Serverkontrolle und somit über die Möglichkeit der Verwendung von “Dynamic Management Objects”, die einem Mitglied der festen Serverrolle [securityadmin] versagt sind. Da ein Mitglied der festen Serverrolle [securityadmin] das Login selbst erstellt hat, kann er sich nun mit diesem Konto anmelden und anschließend die Serverinformationen abfragen oder aber – wie das obige Beispiel zeigt – mit diesem Konto den SQL Server kontrollieren. Microsoft verweist ausdrücklich auf die erweiterten Sicherheitsbedenken in der OH:


Durch die Möglichkeit, Zugriff auf Database Engine (Datenbankmodul) zu gewähren und Benutzerberechtigungen zu konfigurieren, kann der Sicherheitsadministrator die meisten Serverberechtigungen zuweisen.Die Rolle securityadmin muss als Entsprechung der Rolle sysadmin behandelt werden.


processadmin


Den Mitgliedern der festen Serverrolle [processadmin] ist es erlaubt, aktive Prozesse (Threads) zu beenden indem Sie mit KILL die entsprechende Session beenden. Diese Berechtigung hört sich zunächst recht harmlos an, hat aber – aus meiner Sicht – erhebliche Mankos in Bezug auf die Datensicherheit. Mit der Mitgliedschaft in der festen Serverrolle [processadmin] geht einher, dass das Login nicht nur Prozesse beenden kann sondern mittels “Dynamic Management Objects” ebenfalls Möglichkeiten besitzt, bestehende Sessions zu überwachten und zu analysieren! Das nachfolgende Skript kann ein Mitglied der festen Serverrolle [processadmin] ohne Probleme ausführen:



SELECT  DES.session_id,
        DEC.last_read,
        DEC.last_write,
        DEST.text            AS last_command,
        req_command.text     AS current_command,
        DEQP.query_plan      AS current_plan,
        DER.last_wait_type
FROM    sys.dm_exec_connections AS DEC INNER JOIN sys.dm_exec_sessions DES
        ON (DEC.session_id = DES.session_id) LEFT JOIN sys.dm_exec_requests AS DER
        ON (
             DEC.connection_id = DER.connection_id AND
             DEC.most_recent_session_id = DER.session_id
           )
        CROSS APPLY sys.dm_exec_sql_text(DEC.most_recent_sql_handle) AS DEST
        OUTER APPLY sys.dm_exec_sql_text(DER.sql_handle) AS req_command
        OUTER APPLY sys.dm_exec_query_plan(DER.plan_handle) AS DEQP
WHERE   DES.is_user_process = 1;

Das ein Mitglied der festen Serverrolle [processadmin] überprüfen muss, wann eine Session zum letzten Mal aktiv war oder worauf eine aktive Sitzung zuletzt gewartet hat, ist unbestreitbar eine Grundvoraussetzung für ein verantwortliches Handeln. Problematisch wird es – aus meiner Sicht – jedoch, wenn es darum geht, auch die Ausführungsbefehle sichtbar zu machen. Hier geht die Berechtigung eines Mitglieds der festen Serverrolle [processadmin] zu weit, da durch die Auswertung von SQL Befehlen Informationen preis gegeben werden, die u. U. nicht für Dritte zugänglich sein sollten (z. B. ein UPDATE einer Mitarbeitertabelle, in der Gehälter gespeichert werden).


setupadmin


Die Mitglieder der festen Serverrollen [setupadmin] haben die Möglichkeit, Verbindungsserver (“Linked Server”) hinzuzufügen.


bulkadmin


Auch hier ist der Name selbst erklärend. Mitglieder dies festen Serverrolle [bulkadmin] verfügen über die Berechtigung, BULK INSERT Operationen ausführen zu können. In Seminaren taucht immer wieder die Frage auf, warum es diese Rolle überhaupt gibt. Die Antwort ist recht einfach: Mit BULK INSERT werden externe Datendateien in Datenbanken importiert. Ein Mitglied der festen Serverrolle [bulkadmin] erhält – indirekt – einen Zugriff auf Ressourcen, die sich außerhalb von Microsoft SQL Server befinden.


diskadmin


Mitglieder der festen Serverrolle [diskadmin] verfügen über die Berechtigung zur Verwaltung von Datenträgerdateien. Diese Serverrolle ist aus meiner Sicht wertlos, da sie einzig die Berechtigung zur Verwaltung von BACKUP-Medien erteilt. Sollte man Mitglied der festen Serverrolle [diskadmin] sein, so sollte man bereits einige Erfahrung mit T-SQL haben; die Verwendung von SQL Server Management Studio (SSMS) ist trotz Mitgliedschaft in der festen Serverrolle [diskadmin] nicht möglich! Das SSMS in Bezug auf Verwaltung seine Tücken hat, habe ich bereits im Artikel “GUI vs. T-SQL – trotz dbo / db_owner keine Berechtigungen?” beschrieben.


Versucht man, als Mitglied der festen Serverrolle [diskadmin] über SSMS ein neues BACKUP Medium anzulegen, erhält man die folgende Fehlermeldung:


CREATE NEW BACKUP MEDIA


Auch die Verwaltung bereits bestehender Backupmedien gestaltet sich schwierig, wenn nicht zusätzlich zur bestehenden Mitgliedschaft in der festen Serverrolle [diskadmin] die Mitgliedschaft in der festen Serverrolle [dbcreator] besteht!


CHECK BACKUP MEDIA


Um ein Backupmedium zu erstellen, muss also mit T-SQL gearbeitet werden



EXEC sp_addumpdevice @devtype = 'disk', @logicalname = 'DB_BACKUP', @physicalname = 'S:\backup\db_backup.med';

Mit sp_addumpdevice ist es möglich, ein BACKUP-Medium zu erstellen; auf Grund der Voraussetzung weiterer Berechtigungen sind weitere Operationen wie BACKUP und RESTORE nicht möglich! Hierzu bedarf es mindestens der Zugehörigkeit zur festen Serverrolle [dbcreator].


dbcreator


Mitglieder der festen Serverrolle [dbcreator] können beliebige Datenbanken erstellen, ändern, löschen und wiederherstellen. Diese – eher unscheinbare – Berechtigung sollte mit Sorgfalt zugeteilt werden. Ein Mitglied der festen Datenbankrolle [dbcreator] kann von JEDER Datenbank eine Datensicherung machen. Insbesondere bei Datenbanken, die im vollständigen Wiederherstellungsmodus laufen, sollte ein Mitglied der festen Datenbankrolle [dbcreator] darauf aufmerksam gemacht werden, dass BACKUP-Befehle immer mit der Option COPY_ONLY ausgeführt werden sollten um die Sicherungskette der Protokollsicherungen nicht zu unterbrechen.


Ein zusätzliches Manko der festen Serverrolle [dbcreator] ist die fehlende Möglichkeit, den Eigentümer einer neu angelegten Datenbank nachträglich zu ändern. Diese Berechtigung fehlt einem Mitglied der festen Datenbankrolle [dbcreator] nämlich trotz “... beliebige Datenbanken erstellen, ändern, löschen ...”.


Einen Vorteil hat die feste Serverrolle [dbcreator] im Zusammenhang mit der Wiederherstellung von Datenbanken jedoch... führt ein Mitglied der festen Serverrolle [sysadmin] eine Wiederherstellung einer Datenbank von einer Datensicherung aus, so wird – automatisch – der ausführende Benutzer zum Eigentümer der Datenbank. Führt ein Mitglied der festen Datenbankrolle [dbcreator] eine Wiederherstellung einer Datenbank aus einer Datensicherung aus, so bleibt der ursprüngliche Eigentümer der Datenbank erhalten. Sehr bedauerlich, dass diese Einstellung nicht grundsätzlich die Standardeinstellung ist. Unabhängig davon, ob ein Mitglied der festen Serverrolle [sysadmin] oder ein Mitglied der festen Serverrolle [dbcreator] die Wiederherstellung initiiert sollte der ursprüngliche Eigentümer einer Datenbank bei einer Wiederherstellung erhalten bleiben.


Herzlichen Dank fürs Lesen!

Keine Kommentare :

Kommentar veröffentlichen