如何屏蔽一组用户的数据值?

时间:2017-11-06 13:52:14

标签: sql sql-server tsql sql-server-2016

我是(初级)DWH / BI开发人员,想要删除查看整个组的未屏蔽数据的权限(但仍可以随时撤销)。 我用

创建了一个表格
MASKED WITH (FUNCTION   =  'partial(1,"xxxx",0)')

- 类似定义的列,现在想要设置权限。 我试过了:

DENY UNMASK TO PCCZ\CZ_GBUS_ITD_BI
EXECUTE AS USER = 'PCCZ\CZ_GBUS_ITD_BI'
SELECT * FROM dim.MaskingTest
REVOKE UNMASK TO PCCZ\CZ_GBUS_ITD_BI;  

1 个答案:

答案 0 :(得分:0)

您无法DENY UNMASKsysadmin db_owner。这是内置限制。此外,如文档中所述,如果用户可以查询表,则这不是安全功能。

enter image description here

如您所见,您可以查询表格,lie系统。实际上,您不应该在SQL Server的上下文中依赖所有这些功能。它主要是client-side设置(并且在T-SQL的上下文中几乎不执行任何操作)。

我参加了一个名为"Hacking SQL Server"的SQL周六会话,其中André Melancia显示了为什么动态数据屏蔽不能用于保护数据(同样不是安全功能)。

在这里你可以找到他演示的可用黑客。我会鼓励你检查一下。此外,here您可以找到他已经入侵的其他Microsoft安全功能。

/* 
    SQL Saturday #667 Oslo 2017
    Hacking SQL Server
    2017-09-02 (version 1.33)
    Demo - Dynamic Data Masking Hacking
    André Melancia
    http://Andy.PT

    (C) 2015-2017, André Melancia

    For more information on DDM please visit
    https://msdn.microsoft.com/library/mt130841.aspx

           ________   ________    _________  ____________;_
          - ______ \ - ______ \ / _____   //.  .  ._______/
         / /     / // /     / //_/     / // ___   /
        / /     / // /     / /       .-'//_/|_/,-'
       / /     / // /     / /     .-'.-'
      / /     / // /     / /     / /
     / /     / // /     / /     / /
    / /_____/ // /_____/ /     / /
    \________- \________-     /_/

*/

--  +----------------------------------------------------------------+
--  | MISSION BRIEFING                                               |
--  +----------------------------------------------------------------+

    -- WARNING: Run these scripts on an EMPTY database!

    -- INSTRUCTIONS: Run one statement at a time.


--  +----------------------------------------------------------------+
--  | MISSION PREPARATION                                            |
--  +----------------------------------------------------------------+

    USE SQLSatOslo;         -- Or whatever database you created!
                            -- Please don't run this on the Master, that's
                            -- just ugly!
    GO

    -- Things an MI6 agent with Licence to KILL has to do
    -- Note: "IF EXISTS" are ugly. First time these will generate errors
    --       Just accept the errors as part of an agent's life ;)
    DROP USER M;
    DROP USER Q;
    DROP USER Sean;
    DROP USER David;
    DROP USER George;
    DROP USER Roger;
    DROP USER Timothy;
    DROP USER Pierce;
    DROP USER Daniel;
    GO

    DROP SECURITY POLICY AgentValidationPolicy
    GO
    DROP FUNCTION MI6_Access.FN_MI6_AgentValidationPredicate;
    GO
    DROP SCHEMA   MI6_Access;
    GO

    DROP VIEW     dbo.VIEW_BondFilms;
    GO
    DROP TABLE    dbo.BondFilms;
    GO
    DROP TABLE    dbo.Agents;
    GO
    DROP TABLE    dbo.Letters;
    GO


--  +----------------------------------------------------------------+
--  | CREATE USERS                                                   |
--  +----------------------------------------------------------------+

    CREATE USER M       WITHOUT LOGIN;
    CREATE USER Q       WITHOUT LOGIN;
    CREATE USER Sean    WITHOUT LOGIN;
    CREATE USER David   WITHOUT LOGIN;
    CREATE USER George  WITHOUT LOGIN;
    CREATE USER Roger   WITHOUT LOGIN;
    CREATE USER Timothy WITHOUT LOGIN;
    CREATE USER Pierce  WITHOUT LOGIN;
    CREATE USER Daniel  WITHOUT LOGIN;


--  +----------------------------------------------------------------+
--  | CREATE TABLE dbo.BondFilms                                     |
--  +----------------------------------------------------------------+

    CREATE TABLE dbo.BondFilms
    (
        FilmID       INT           NOT NULL,
        FilmTitle_EN NVARCHAR(64)  NOT NULL,
        FilmTitle_NO NVARCHAR(64)  NOT NULL,
        FilmYear     INT           NOT NULL, 
        BondActor    NVARCHAR(64)  NOT NULL,
        Agent        SYSNAME       NOT NULL,
        Payment      INT           NOT NULL,
        CONSTRAINT PK_BondFilms PRIMARY KEY CLUSTERED  ( FilmID ASC ) 
    );


    -- Insert some REAL top secret for-your-eyes-only information
    -- Leaked from here: https://en.wikipedia.org/wiki/List_of_James_Bond_films
    -- And fom here:     https://no.wikipedia.org/wiki/James_Bond
    INSERT INTO dbo.BondFilms
    (FilmID, FilmTitle_EN, FilmTitle_NO, FilmYear, BondActor, Agent, Payment) 
    VALUES 
    ( 1, 'Dr.No',                            'Dr.No',                          1962, 'Sean Connery',   'Sean',      10000),
    ( 2, 'From Russia with Love',            'Med hilsen fra Russland',        1963, 'Sean Connery',   'Sean',      10000),
    ( 3, 'Goldfinger',                       'Goldfinger',                     1964, 'Sean Connery',   'Sean',      10000),
    ( 4, 'Thunderball',                      'Operasjon Tordensky',            1965, 'Sean Connery',   'Sean',      10000),
    ( 5, 'Casino Royale',                    'Casino Royale',                  1967, 'David Niven',    'David',     10000),
    ( 6, 'You Only Live Twice',              'James Bond i Japan',             1967, 'Sean Connery',   'Sean',      10000),
    ( 7, 'On Her Majesty''s Secret Service', 'James Bond i hemmelig tjeneste', 1969, 'George Lazenby', 'George',    10000),
    ( 8, 'Diamonds Are Forever',             'Diamanter varer evig',           1971, 'Sean Connery',   'Sean',      10000),
    ( 9, 'Live and Let Die',                 'Å leve og la dø',                1973, 'Roger Moore',    'Roger',     10000),
    (10, 'The Man with the Golden Gun',      'Mannen med den gyldne pistol',   1974, 'Roger Moore',    'Roger',     10000),
    (11, 'The Spy Who Loved Me',             'Spionen som elsket meg',         1977, 'Roger Moore',    'Roger',     10000),
    (12, 'Moonraker',                        'Måneraketten',                   1979, 'Roger Moore',    'Roger',     10000),
    (13, 'For Your Eyes Only',               'Kun for dine øyne',              1981, 'Roger Moore',    'Roger',     10000),
    (14, 'Octopussy',                        'Octopussy',                      1983, 'Roger Moore',    'Roger',     10000),
    (15, 'Never Say Never Again',            'Aldri si aldri',                 1983, 'Sean Connery',   'Sean',    3552822), /* 3552822 = 0x363636 = "36 36 36 00" little endian */
    (16, 'A View to a Kill',                 'Med døden i sikte',              1985, 'Roger Moore',    'Roger',     10000),
    (17, 'The Living Daylights',             'I skuddlinjen',                  1987, 'Timothy Dalton', 'Timothy',   10000),
    (18, 'Licence to Kill',                  'Med rett til å drepe',           1989, 'Timothy Dalton', 'Timothy',   10000),
    (19, 'GoldenEye',                        'GoldenEye',                      1995, 'Pierce Brosnan', 'Pierce',    10000),
    (20, 'Tomorrow Never Dies',              'Tomorrow Never Dies',            1997, 'Pierce Brosnan', 'Pierce',    10000),
    (21, 'The World Is Not Enough',          'The World Is Not Enough',        1999, 'Pierce Brosnan', 'Pierce',    10000),
    (22, 'Die Another Day',                  'Die Another Day',                2002, 'Pierce Brosnan', 'Pierce',    10000),
    (23, 'Casino Royale',                    'Casino Royale',                  2006, 'Daniel Craig',   'Daniel',  3552822), /* 3552822 = 0x363636 = "36 36 36 00" little endian */
    (24, 'Quantum of Solace',                'Quantum of Solace',              2008, 'Daniel Craig',   'Daniel',    10000),
    (25, 'Skyfall',                          'Skyfall',                        2012, 'Daniel Craig',   'Daniel',    10000),
    (26, 'Spectre',                          'Spectre',                        2015, 'Daniel Craig',   'Daniel',    10000);


    -- Super advanced top secret spying technique
    SELECT * FROM dbo.BondFilms;

    GO


--  +----------------------------------------------------------------+
--  | CREATE TABLE dbo.BondActors                                    |
--  +----------------------------------------------------------------+

    CREATE TABLE dbo.Agents
    (
        Agent      SYSNAME       NOT NULL,
        BondActor  NVARCHAR(64)  NOT NULL,
        CONSTRAINT PK_Agents PRIMARY KEY CLUSTERED  ( Agent ASC ) 
    );


    -- Insert some REAL top secret for-your-eyes-only information
    -- Leaked from here: https://en.wikipedia.org/wiki/List_of_James_Bond_films
    INSERT INTO dbo.Agents 
    (Agent, BondActor) 
    SELECT DISTINCT Agent, BondActor
    FROM dbo.BondFilms;


    -- Super advanced top secret spying technique
    SELECT * FROM dbo.Agents;

    GO


--  +----------------------------------------------------------------+
--  | MASK COLUMN WITH DYNAMIC DATA MASKING                          |
--  +----------------------------------------------------------------+

    -- Mask the Agent column with DDM.
    ALTER TABLE dbo.BondFilms
    ALTER COLUMN BondActor ADD MASKED WITH (FUNCTION = 'Partial(2, "▪▪▪", 1)');
    GO

    -- We are so confident in our security that we're assigning read permissions
    --     to everyone.
    --     /!\ Please don't do this in a production environment, assign 
    --     permissions to the group(s) or role(s) the users belong
    GRANT SELECT ON dbo.BondFilms TO Public;
    GRANT SELECT ON dbo.Agents    TO Public;

    GRANT UNMASK TO M; -- M is allowed to see masked fields

    -- Super advanced top secret spying technique
    SELECT *, 'Seen as DBO using DDM'  AS Who FROM dbo.BondFilms; -- Returns unmasked

    EXECUTE AS USER = 'M';
    SELECT *, 'Seen as M using DDM'    AS Who FROM dbo.BondFilms; -- Returns unmasked 
    REVERT; -- Go back to connection default user

    EXECUTE AS USER = 'Sean';
    SELECT *, 'Seen as Sean using DDM' AS Who FROM dbo.BondFilms; -- Returns masked  
    REVERT;

    GO


--  +----------------------------------------------------------------+
--  | DYNAMIC DATA MASKING EXPLOIT - "0. Mission preparation"        |
--  +----------------------------------------------------------------+

    REVERT; REVERT; REVERT; REVERT; REVERT; REVERT; 

    -- Turn on viewing of Execution Plan (Ctrl-M)

    -- Allow everyone to see Execution Plan
    GRANT SHOWPLAN TO Public; -- NEVER do this in production!!!


--  +----------------------------------------------------------------+
--  | DYNAMIC DATA MASKING EXPLOIT - "1. WHERE HACK"                 |
--  +----------------------------------------------------------------+

    EXECUTE AS USER = 'Sean';
    SELECT *, 'Seen as Sean using DDM with WHERE hack' AS Who 
    FROM dbo.BondFilms
    WHERE BondActor Like '%Roger%' -- Hack: infer the content of the field
    REVERT;


--  +----------------------------------------------------------------+
--  | DYNAMIC DATA MASKING EXPLOIT - "2. EXACT JOIN HACK"            |
--  +----------------------------------------------------------------+

    EXECUTE AS USER = 'Sean';
    SELECT b.*, a.BondActor AS AGENTS_BondActor, 'Seen as Sean using DDM with EXACT JOIN hack' AS Who 
    FROM dbo.BondFilms b
         INNER JOIN
         dbo.Agents a
         ON b.BondActor = a.BondActor -- Hack: infer the content with JOIN
    REVERT;


--  +----------------------------------------------------------------+
--  | DYNAMIC DATA MASKING EXPLOIT - "3. PARTIAL JOIN HACK"          |
--  +----------------------------------------------------------------+

    -- Special thanks to 
    --     Dmitri V. Korotkevitch
    --     http://aboutsqlserver.com
    --     dk@aboutsqlserver.com  


    -- Create a table with single letters 
    -- (let's assume it's case INsensitive)
    CREATE TABLE dbo.Letters
    (
        Letter NVARCHAR(1)  NOT NULL,
        CONSTRAINT PK_Letters PRIMARY KEY CLUSTERED  ( Letter ASC ) 
    );

    INSERT INTO dbo.Letters (Letter)
    VALUES ('A'), ('B'), ('C'), ('D'), ('E'), ('F'), ('G'), ('H'), ('I'), 
           ('J'), ('K'), ('L'), ('M'), ('N'), ('O'), ('P'), ('Q'), ('R'),
           ('S'), ('T'), ('U'), ('V'), ('W'), ('X'), ('Y'), ('Z'), (' ');

    GRANT SELECT ON dbo.Letters TO Public; -- Very safe!

    -- Spies don't call it stalking...
    SELECT * FROM dbo.Letters;


    -- Get letter by letter (here using subqueries)...
    EXECUTE AS USER = 'Sean';
    SELECT b.*, 
           k01.Letter AS L01,
           k02.Letter AS L02,
           k03.Letter AS L03,
           k04.Letter AS L04,
           k05.Letter AS L05,
           k06.Letter AS L06,
           k07.Letter AS L07,
           k08.Letter AS L08,
           k09.Letter AS L09,
           k10.Letter AS L10,
           k11.Letter AS L11,
           k12.Letter AS L12,
           k13.Letter AS L13,
           k14.Letter AS L14,
           'Seen as Sean using DDM with PARTIAL JOIN hack' AS Who 
    FROM dbo.BondFilms b
         INNER JOIN dbo.Letters AS k01 ON (k01.Letter = SUBSTRING(b.BondActor,01,1))
         INNER JOIN dbo.Letters AS k02 ON (k02.Letter = SUBSTRING(b.BondActor,02,1))
         INNER JOIN dbo.Letters AS k03 ON (k03.Letter = SUBSTRING(b.BondActor,03,1))
         INNER JOIN dbo.Letters AS k04 ON (k04.Letter = SUBSTRING(b.BondActor,04,1))
         INNER JOIN dbo.Letters AS k05 ON (k05.Letter = SUBSTRING(b.BondActor,05,1))
         INNER JOIN dbo.Letters AS k06 ON (k06.Letter = SUBSTRING(b.BondActor,06,1))
         INNER JOIN dbo.Letters AS k07 ON (k07.Letter = SUBSTRING(b.BondActor,07,1))
         INNER JOIN dbo.Letters AS k08 ON (k08.Letter = SUBSTRING(b.BondActor,08,1))
         INNER JOIN dbo.Letters AS k09 ON (k09.Letter = SUBSTRING(b.BondActor,09,1))
         INNER JOIN dbo.Letters AS k10 ON (k10.Letter = SUBSTRING(b.BondActor,10,1))
         INNER JOIN dbo.Letters AS k11 ON (k11.Letter = SUBSTRING(b.BondActor,11,1))
         INNER JOIN dbo.Letters AS k12 ON (k12.Letter = SUBSTRING(b.BondActor,12,1))
         INNER JOIN dbo.Letters AS k13 ON (k13.Letter = SUBSTRING(b.BondActor,13,1))
         INNER JOIN dbo.Letters AS k14 ON (k14.Letter = SUBSTRING(b.BondActor,14,1))
    REVERT;

    -- Missing some characters? Create a bigger Unicode table...


--  +----------------------------------------------------------------+
--  | DYNAMIC DATA MASKING EXPLOIT - "4. PARTIAL SUBQUERY HACK"      |
--  +----------------------------------------------------------------+

    -- This WILL NOT WORK. Why? 
    -- Because you are getting the "BondActor" column at the SELECT
    -- stage, not the FROM or WHERE stages! 

    -- Get letter by letter (here using subqueries)...
    EXECUTE AS USER = 'Sean';
    SELECT b.*, 
           (SELECT Letter FROM dbo.Letters AS k01 WHERE k01.Letter = SUBSTRING(b.BondActor,1,1)) AS L01,
           (SELECT Letter FROM dbo.Letters AS k02 WHERE k02.Letter = SUBSTRING(b.BondActor,2,1)) AS L02,
           (SELECT Letter FROM dbo.Letters AS k03 WHERE k03.Letter = SUBSTRING(b.BondActor,3,1)) AS L03,
           'Seen as Sean using DDM with PARTIAL FIND hack' AS Who 
    FROM dbo.BondFilms b
    REVERT;


--  +----------------------------------------------------------------+
--  | DYNAMIC DATA MASKING EXPLOIT - "..."                           |
--  +----------------------------------------------------------------+

    -- (Your exploit here)
    -- Found more exploits? Let me know!


--  +----------------------------------------------------------------+
--  | Mission is now over.                                           |
--  | You can't run away with the Bond Girl because you're an NSA    |
--  | agent, not an MI6 agent.                                       |
--  | Consider changing sides: MI6 has better... eh... cars...       |
--  +----------------------------------------------------------------+