Přes veškerá nastavení MS SQL serveru popisovaná v minulém díle, zůstává stále mnoho možných bezpečnostních rizik. Zneužití těchto skulin zvenku není tak snadné, ale průzkumy dokazují, že největší nebezpečí pro data většinou číhá uvnitř vlastní firmy.

BUILTINAdministrators

Administrátor vaší sítě nemusí být vždy administrátorem databázového serveru. Čím větší firma, čím důležitější databáze, tím větší pravděpodobnost dělby zodpovědnosti mezi více osob v IT oddělení. Bohužel SQL server při své instalaci vytvoří automaticky uživatelskou skupinu BUILTINAdministrators, která má roli „sysadmin“ u všech databází vašeho SQL serveru.

Přihlásí-li se tedy některý z administrátorů pomocí Windows autentizace k SQL serveru, automaticky získává nejvyšší úroveň oprávnění ke všem databázovým objektům, jak vidíme na dalším obrázku. V horní části jsou všechny používané databáze, v dolní najdete jednotlivé role uživatele pro danou databázi.

V případě, že tento stav z organizačních nebo bezpečnostních důvodů nevyhovuje, je možno provést následující:

  1. Odstraňte login BUILTINAdministrator
    • Tento krok je poměrně snadný.
  2. Ve Windows vytvořte novou uživatelskou skupinu „SQL Server Admins“. Přidejte do této skupiny účet, pomocí kterého startujete SQL server (viz předchozí článek). Dále můžete do této skupiny selektivně přidat všechny uživatele, kteří potřebují k SQL serveru přístup jako „sysadmin“.
    • Čím méně bude mít tato skupina uživatelů, tím lépe. Snáze se vám budou monitorovat veškeré změny. Plný administrativní přístup může být navíc pro neznalého administrátora i velmi nebezpečný.
    • Pro větší zmatení případného útočníka můžete skupinu pojmenovat krypticky, aby při napadení systému útočník nezjistil na první pohled, do které skupiny se má přidat.
  3. Předposledním krokem je opětovné vytvoření loginu, spojeného s touto uživatelskou skupinou. Skupinu pojmenujte odlišně (tedy v žádném případě ne BUILTINAdministrator)!
    • Proč? Tento login má defaultně přístup jako vlastník databáze („DBO“) do všech databází vašeho SQL serveru, i když byl odstraněn a znovu vytvořen. Jediným rozdílem je, že při opětovném vytvoření nebude mít tento login roli „sysadmin“. I tak ale zůstává vlastníkem všech objektů.
  4. Závěrem je třeba přenastavit účet pro běh SQL Server Agenta.
    • Úpravami vestavěného loginu můžete totiž zablokovat běh veškerých naplánovaných úkolů. Agent totiž standardně běží pod účtem „LocalSystem“ a využívá Windows autentizace. Zajímavostí celé věci je, že server ani agent do logu žádný problém nezapíší a vše se zdá být v pořádku. Úkoly ale neběží a datum dalšího spuštění (“next run date”) není známé („unknown“). Uživatelský účet pro spouštění SQL Agenta musí mít oprávnění „sysadmin“.

Účet SA

Účet SA je velkým lákadlem pro každého útočníka. Tento účet má oprávnění vlastníka databáze pro všechny databáze vašeho serveru, nezávisle na použitém autorizačním režimu. Získá-li někdo přístup k SA účtu, může v databázi úmyslně nebo neúmyslně způsobit velkou škodu. Ochrana tohoto účtu je proto jedním z hlavních kritérií zabezpečení serveru.

Jedno pravidlo týkající se SA účtu jsme si už říkali – nikdy nesmí být bez hesla. Když se ale rozhlédnu po internetu, mám pocit, že opakování tohoto pravidla je házením hrachu na zeď. Objevuji pořád mnoho serverů, které tuto základní klauzuli neustále porušují.

Heslo by samozřejmě nemělo být veřejné (nalepené post-it bločkem na monitor), ale současně by mělo být k dispozici pro případ nenadálých situací. Osobně jsem v praxi narazil na mnoho způsobů jak toto zabezpečit. Jako nejjednodušší se mi jeví po změně hesla napsat jej na papírek a zalepit do obálky. Ta může být uložena v trezoru, hned vedle zálohovacích médií.

Další dobrou obranou před útoky na váš server je změna „sa“ účtu. Většina útoků je podnikána proti účtu „sa“, když jej tedy přejmenujete, zbavíte se dalšího rizika. Změna sice není tak jednoduchá (spousta aplikací přestane fungovat), ale dá se provést například podobným skriptem:

EXEC sp_configure ‚allow updates‘, 1
GO
update sysxlogins set name=’admin‘ where name=’sa‘
GO
EXEC sp_configure ‚allow updates‘, 0
GO

Mým dalším doporučením je nepoužívat SA účet pro spouštění DTS balíčků. Při manipulaci s DTS balíčky velmi často dochází k prozrazení hesla, protože spouštění balíčků je úkon, který velmi často neprovádí přímo správce, ale jiná osoba. Pro nepoužívání tohoto účtu pro DTS mluví ještě jeden argument, a to bezpečnostní univerzálnost SA účtu. DTS balíčky velmi často manipulují data, ale i mění struktury tabulek, odstraňují a vytvářejí databázové objekty a podobně. Když tyto činnosti budou vykonávány s SA oprávněním, můžete napáchat v databázi nedozírné škody.

Aplikace ani uživatelé by neměli tento účet používat, je proto možné vytvořit alert pro administrátora databáze, který mu nahlásí každé použití tohoto účtu:

–Vytvoříme si operátora (lze přeskočit, máte-li jej vytvořen)
EXECUTE msdb.dbo.sp_add_operator @name = N’Admin‘, @enabled = 1, @netsend_address = N'<vaše netsend adresa>‘,
@category_name = N'[Uncategorized]‘, @weekday_pager_start_time = 80000, @weekday_pager_end_time = 180000,
@saturday_pager_start_time = 80000, @saturday_pager_end_time = 180000, @sunday_pager_start_time = 80000,
@sunday_pager_end_time = 180000, @pager_days = 62
GO
–Vytvoříme si dva alerty: 1) pro událost 18454 2) pro událost 18455
–Událost 18454 – Login succeeded for user ‚%ls‘. Connection: Non-Trusted.
EXECUTE msdb.dbo.sp_add_alert @name = N’SA_Login_1′, @message_id = 18454, @severity = 0, @enabled = 1, @delay_between_responses = 60, @include_event_description_in = 5, @event_description_keyword = N“’sa“‘, @category_name = N'[Uncategorized]‘
GO
–Propojíme alert s operátorem
EXECUTE msdb.dbo.sp_add_notification @alert_name = N’SA_Login_1′, @operator_name = N’Admin‘, @notification_method = 4
GO
–Událost 18455 – Login succeeded for user ‚%ls‘.
EXECUTE msdb.dbo.sp_add_alert @name = N’SA_Login_2′, @message_id = 18455, @severity = 0, @enabled = 1, @delay_between_responses = 60, @include_event_description_in = 5, @event_description_keyword = N“’sa“‘, @category_name = N'[Uncategorized]‘
GO
–Propojíme alert s operátorem
EXECUTE msdb.dbo.sp_add_notification @alert_name = N’SA_Login_2′, @operator_name = N’Admin‘, @notification_method = 4
GO
–Jako bonus budeme chtít vědět, kdy se přihlásil uživatel Administrator (událost 18453)
EXECUTE msdb.dbo.sp_add_alert @name = N’SA_Login_3′, @message_id = 18453, @severity = 0, @enabled = 1, @delay_between_responses = 60, @include_event_description_in = 5, @event_description_keyword = N’Administrator‘, @category_name = N'[Uncategorized]‘
GO
EXECUTE msdb.dbo.sp_add_notification @alert_name = N’SA_Login_3′, @operator_name = N’Admin‘, @notification_method = 4
GO

Uživatelská hesla

Hesla jsem zatím zmínil pouze v souvislosti s účtem SA. Na heslo k tomuto účtu by se ale měla vztahovat stejná pravidla jako na ostatní hesla ve vaší síti. Měla by být pravidelně měněna, aby se předešlo „brute force“ útokům, měla by mít stanovenou minimální povinnou délku a podobně. Ve větších firmách tato celá agenda spadá do kompetence manažera bezpečnosti, proto než nasadíte svůj server do produkčního prostředí, přesvědčete se, že tím nevytváříte v síti ostrov s nižším zabezpečením.

Veškerá uživatelská jména a hesla jsou uložena v tabulce sysxlogins. Při práci s touto tabulkou můžete použít i pohled syslogins. Hesla jsou defaultně v tabulce šifrována, aby nemohlo dojít k jejich kompromitaci. Pro práci s hesly ale můžete využít nedokumentované funkce PWDCOMPARE(řetězec1,heslo v db), jak si ukážeme na příkladech.

Velice častým nešvarem jsou účty bez hesla. Kromě osvětové činnosti doporučuji jednoduchým způsobem kontrolovat, zda-li uživatelé heslo skutečně používají:

SELECT name FROM master.dbo.syslogins
WHERE password IS NULL
AND isntname = 0

Tímto dotazem snadno odhalíte uživatele bez hesla (password is null), připojená podmínka (isntname = 0) z výsledku dotazu odstraní uživatele používající Windows autentizaci, jejich hesla se totiž do tabulky sysxlogins neukládají.

Bohužel, uživatelé si často při zadávání hesla ulehčují práci, a nastavují si heslo stejné jako login. Hříšníky objevíme snadno:

–Nadefinujeme si proměnné
DECLARE @lngCounter INTEGER
DECLARE @lngLogCount INTEGER
DECLARE @strName VARCHAR(256)
–Vytvoříme si dočasnou tabulku
CREATE TABLE #tempLogin
(
LoginID INTEGER IDENTITY(1,1)
,LoginName SYSNAME NULL
,LoginWeak INTEGER NULL
)
–Naplníme jí uživateli
INSERT INTO #tempLogin (LoginName)
SELECT name FROM master.dbo.syslogins WHERE isntname = 0
SET @lngLogCount = @@ROWCOUNT
–Zjistíme, zda-li mají stejné jméno heslo
SET @lngCounter = @lngLogCount
WHILE @lngCounter <> 0
BEGIN
  SET @strName = (SELECT LoginName FROM #tempLogin WHERE LoginID = @lngCounter)
  UPDATE #tempLogin
  SET LoginWeak = (SELECT PWDCOMPARE (@strName,(SELECT password FROM master.dbo.sysxlogins
  WHERE name = @strName)))
  WHERE LoginID = @lngCounter
  SET @lngCounter = @lngCounter – 1
END
–Vypíšeme je
PRINT ‚Tito uživatelé mají stejné jméno heslo:‘
SELECT LoginName FROM #tempLogin WHERE LoginWeak = 1

Stejně tak jednoduchou modifikací výše uvedeného skriptu můžeme objevit uživatele, kteří používají jednoznaková hesla:

–Nadefinujeme si proměnné
DECLARE @lngCounter INTEGER
DECLARE @lngCounter1 INTEGER
DECLARE @lngLogCount INTEGER
DECLARE @strName VARCHAR(256)
–Vytvoříme si dočasnou tabulku
CREATE TABLE #tempLogin2
(
LoginID INTEGER IDENTITY(1,1)
,LoginName SYSNAME NULL
,LoginWeak INTEGER NULL
)
–Naplníme jí uživateli
INSERT INTO #tempLogin2 (LoginName)
SELECT name FROM master.dbo.syslogins WHERE isntname = 0
SET @lngLogCount = @@ROWCOUNT
–Zjistíme, kteří uživatelé mají jednopísmenné heslo
SET @lngCounter = @lngLogCount
WHILE @lngCounter <> 0
BEGIN
  SET @lngCounter1 = 1
  SET @strName = (SELECT LoginName FROM #tempLogin2 WHERE LoginID = @lngCounter)
    WHILE @lngCounter1 < 256
    BEGIN
    UPDATE #tempLogin2
    SET LoginWeak = (SELECT PWDCOMPARE (CHAR(@lngCounter1),(SELECT password FROM master.dbo.sysxlogins
    WHERE name = @strName)))
    WHERE LoginID = @lngCounter
    AND LoginWeak <> 1
    SET @lngCounter1 = @lngCounter1 + 1
  END
  SET @lngCounter = @lngCounter – 1
END
–Vypíšeme je
PRINT ‚Tito uživatelé mají jednopísmenné heslo‘
SELECT LoginName FROM #tempLogin2 WHERE LoginWeak = 1

Poté, co jsme získali seznam uživatelů se slabými hesly, nezbývá než zjistit, proč taková používají. Během této investigativní činnosti přijdete na mnohé účty, které by v databázi dávno být neměly. U všech ostatních nastavte kvalitní heslo. Připravte se ale na situaci, kdy vás bude nenávidět celá firma, protože přestanou fungovat různé aplikace, DTS balíčky, replikace SQL serverů, DSN spojení a podobně. Když se kácí les, lítají třísky.

Při správě hesel si dejte pozor na uloženou proceduru sp_addlogin. Tuto uloženou proceduru lze spouštět s parametrem @encryptopt = ‚skip_encryption‘ a hesla pak nejsou v tabulce sysxlogins šifrována:

EXEC sp_addlogin @loginame = ‚pokus‘, @passwd = ‚password‘, @encryptopt = ‚skip_encryption‘

Stejně tak je třeba dát si pozor na „trojského koně“ v podobě procedury, která by teoreticky mohla heslo před zašifrováním odeslat nebo uložit do tabulky. Stejný problém se týká i procedury sp_password, pomocí které dochází ke změně hesel.

Doufám, že i tento článek přispěl k lepšímu zabezpečení vašeho serveru, ale bohužel pořád nemáme vyhráno. Vedeme ale 2:0 a příště se naučíme, jak vstřelit další branku.

Starší komentáře ke článku

Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.

Žádný příspěvek v diskuzi

Odpovědět