Active Directory 手動列舉之擴展

 Active Directory 手動列舉之擴展


列舉作業系統

環境說明 : 在 AD 相關的章節中,主要都是依據下列的 LAB 環境,IP 可能不同,但角色相同

攻擊機 192.168.45.248

靶機 

 - 192.168.203.70 DC

 - 192.168.203.72 web04 

 - 192.168.203.73 files04

 - 192.168.203.74 client74

 - 192.168.203.75 client75

 - 192.168.203.76 client76

已知一般使用者帳號密碼 stephanie / LegmanTeamBenzoin!!

網域名稱 corp.com

採用工具 PowerView,存放路徑 C:\Tools,匯入指令 Import-Module .\PowerView.ps1

kali 有內建位置在 /usr/share/windows-resources/powersploit/Recon/PowerView.ps1


第一步 RDP 進入到某一台 client,注意密碼因為有驚嘆號,所以要加上單引號

xfreerdp /u:stephanie /p:'LegmanTeamBenzoin!!' /d:corp.com /v:192.168.203.75

匯入 PowerView,記得要先 powershell -ep bypass




獲取網域電腦資訊 Get-NetComputer

LAB 很新,DC 都已經是 Windows Server 2022 Standard 版本





之前有提過 Powershell 的輸出可以使用跟資料庫一樣的 select 語法

若要列舉作業系統跟主機名可以使用 Get-NetComputer | select operatingsystem,dnshostname

如下圖列出現有網域的所有電腦作業系統與主機名稱,符合一開始的 LAB 環境定義




練習 1

DistinguishedName for the WEB04

語法 Get-NetComputer | select operatingsystem,dnshostname,distinguishedname

答案 : CN=web04,CN=Computers,DC=corp,DC=com





練習 2

FILES04 的確切作業系統版本是什麼?

指令 Get-NetComputer | select operatingsystem,dnshostname,operatingsystemversion

答案 10.0 (20348)





練習 3

使用 PowerView 枚舉修改後的 corp.com 網域中的作業系統 以取得標誌

指令 Get-NetComputer | select operatingsystem,dnshostname



這樣也可以 Get-NetComputer | findstr "OS{"



如果輸出在 Terminal 介面過長不好查看,可以透過輸出到檔案之後進行搜尋與查看

Powershell 結果輸出要檔案的指令範例 Get-NetComputer | Out-File -FilePath .\123.txt






枚舉權限和登入用戶

當使用者登入網域時,他們的憑證(credentials )將快取在他們登入的電腦的記憶體中

PowerView 的 Find-LocalAdminAccess 指令掃描網絡,嘗試確定目前使用者是否具有網域中任何電腦的管理權限。此命令依賴 OpenServiceW 函數,該函數將連接到目標電腦上的服務控制管理器(SCM)。SCM 基本上維護 Windows 電腦上已安裝服務和驅動程式的資料庫。PowerView 將嘗試使用 SC_MANAGER_ALL_ACCESS 存取權限開啟此資料庫,這需要管理權限,如果連線成功,PowerView 將認為目前的使用者在目標電腦上具有管理權限

下圖中可以看到目前登入的網域帳號是 corp\stephanie 與電腦為 client75

掃描結果顯示當前使用者對於 client74 也擁有管理權限




兩個最可靠的 Windows API 是 

 - NetWkstaUserEnum 需要管理者權限

 - NetSessionEnum 不需要管理者權限

PowerView 的 Get-NetSession 指令在底層使用 NetWkstaUserEnum 和 NetSessionEnum API

所以我們可以直接執行 Get-NetSession 會直接依據權限列出結果

指令需要指定要列舉的目標電腦名稱或 IP

指令 Get-NetSession -ComputerName files04 or Get-NetSession -ComputerName web04

如下圖沒有任何結果輸出,有可能真的沒有任何登入 Session 或是沒有權限查詢



此時可以加上參數 -Verbose 將會告知我們結果,同樣指令加上參數再來一次

如下圖可以明確得知是沒有權限




接著讓我們對本機採用相同的命令查詢,可以發現透過簡名或是網域完整名稱都沒有結果

但是透過 127.0.0.1 或是 192.168.203.75 則可以正常查詢




這是因為 LAB 環境中預設名稱的解析皆以 IPv6 來解析所造成




但 LAB 對其他機器預設是走 IPv4,這一點在探訪本機時要特別注意

測試另外一台 Client74 可以發現是走 IPv4





剛剛前面一開始跑 Find-LocalAdminAccess 有列舉出 Client74 有權限

所以這一次讓我們直接針對 Client74 進行 NetSession 列舉

指令 Get-NetSession -ComputerName client74

注意 CNAME 顯示的 IP 是我們用來查詢的 Client75,這表示顯示的該 Session 就是我們用來查詢 Get-NetSession 使用的 Session




根據 NetSessionEnum 的文檔有五種可能的查詢等級:0,1,2,10,502。等級 0 僅傳回建立會話的電腦的名稱。等級 1 和等級 2 傳回更多信息,但需要管理權限。

留下了 10 和 502 級。兩者都應該返回諸如電腦名稱和建立連接的用戶名稱之類的資訊。預設情況下,PowerView 使用 NetSessionEnum 的查詢等級 10 

使用 NetSessionEnum 列舉工作階段所需的權限在 SrvsvcSessionInfo 登錄項目中定義

此登錄項目位於 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\DefaultSecurity

可以使用 Get-Acl 查看該登錄檔設定
Get-Acl -Path HKLM:SYSTEM\CurrentControlSet\Services\LanmanServer\DefaultSecurity\ | fl

有 fl 表示一條一條列出,沒有的話將無法透過 Terminal 介面閱讀,如下範例

其中有一條 [ BUILTIN\Users Allow ReadKey ] 這表示所有使用者都可以讀取該設定

即便有許多其他群組可以讀取與擁有控制權,但不包含遠端讀取


根據微軟的文檔,輸出末尾的長字串是 a Capability SID。事實上,文檔引用了我們輸出中的確切 SID。

功能 SID 是不可偽造的授權令牌,它授予 Windows 元件或通用 Windows 應用程式對各種資源的存取權。但是,它不會讓我們遠端存取感興趣的註冊表項。

在舊版 Windows 版本中(Microsoft 未指定), 經過驗證的使用者可以存取註冊表設定單元並從SrvsvcSessionInfo項目取得資訊。但是,遵循最小權限原則,常規網域使用者應該無法在網域內獲取此信息,這也可能是註冊表配置單元的權限發生變更的部分原因。在這種情況下,由於權限的原因,我們可以確定 NetSessionEnum 在預設的 Windows 11 上將無法取得此類資訊。

幸運的是,我們還可以使用其他工具,例如 SysInternals Suite 中的 PsLoggedOn 應用程式。文件指出,PsLoggedOn 將列舉 HKEY_USERS 下的註冊表項,以檢索 登入使用者的安全識別碼(SID) 並將 SID 轉換為使用者名稱。PsLoggedOn 也會使用 NetSessionEnum API 來查看誰透過資源共享登入電腦。

然而一個限制是 PsLoggedOn 依賴遠端註冊表服務來掃描關聯的金鑰。自 Windows 8 以來,Windows 工作站上預設未啟用遠端登錄服務,但係統管理員可以啟用它來執行各種管理任務、向後相容或安裝監視、部署工具、腳本、代理程式等。

在較高版本的 Windows Server 作業系統(例如 Server 2012 R2、2016 (1607)、2019 (1809) 和 Server 2022 (21H2))上,它也預設為啟用。如果啟用,該服務將在十分鐘不活動後停止以節省資源,但一旦我們與 PsLoggedOn 連接,它將重新啟用(使用自動觸發器)。

現在理論已經完成,讓我們嘗試對我們之前嘗試枚舉的計算機(從 FILES04 和 WEB04 開始)運行 PsLoggedOn。

該工具包含在微軟提供的好用 Powershell 工具包 PSTools 中,可以透過下列網址下載

https://learn.microsoft.com/zh-tw/sysinternals/downloads/pstools




直接使用 PsLoggedon.exe 針對 files04、web04 進行列舉

files04 有一個登入的 Session 帳號名稱是 CORP\jeff

web04 沒有顯示任何登入的 Session,記得上述理論也有可能是遠端註冊表服務沒有運行




接著重新列舉 client74,發現除了我們的帳號外還有一個 jeffadmin

但時間顯示 <unknown time> 表示該 Session 可能已經中斷但憑證(credentials )仍舊在

也發現另外一件事是 PsLoggedon 可以列舉出 Get-NetSession 無法列舉的使用者 Session




練習

以 stephanie 身分登入 CLIENT75 。找出 Stephanie 在哪台新電腦上具有管理權限,然後登入該電腦並從管理員桌面取得標誌

登入 75 後 Find-LocalAdminAccess 看一下結果有 web04 & client74 有權限




使用相同帳號密碼 RDP 進入到 web04 在 Administrator 使用者桌面找到 proof.txt









透過服務主體名稱進行枚舉

攻擊機 IP 更換為 192.168.45.172

靶機第三碼換為 250

SPN 全名 : Service Principal Name 服務主體名稱

所有網域中的 SPN 都會註冊到 AD,故可以直接查詢 AD 詢問所有 SPN

指令 setspn -L iis_service

IP 已改變換成登入到 192.168.250.74 RDP

└─$ xfreerdp /u:stephanie /p:'LegmanTeamBenzoin!!' /d:corp.com /v:192.168.250.74

這兩行不要忘記 powershell -ep bypass & Import-Module .\PowerView.ps1
雖然等等要用到的指令是內建的,但靶機的環境還是可以先準備起來



因為之前有 web04 所以我們直接列舉 IIS 服務帳號,指令 setspn -L iis_service




另一種列舉 SPN 帳號的方式是先列舉出所有網域帳號,然後用 select 輸出帳號與 SPN 欄位

指令 Get-NetUser -SPN | select samaccountname,serviceprincipalname

可以看到 iis_service 綁在了 HHTP/web04 上




練習

用於關聯到 Active Directory 中特定服務的唯一服務識別碼的名稱是什麼?

Ans : SPN




枚舉物件權限

ACE 全名 : Access Control Entries 存取控制條目

ACL 全名 : Access Control List 存取控制清單

ACL 由 ACE 所構成,每個 ACE 定義是否允許或拒絕對特定物件的存取

相關權限的描述清單

GenericAll: Full permissions on object
GenericWrite: Edit certain attributes on the object
WriteOwner: Change ownership of the object
WriteDACL: Edit ACE's applied to object
AllExtendedRights: Change password, reset password, etc.
ForceChangePassword: Password change for object
Self (Self-Membership): Add ourselves to for example a group

最強大的 ACL 為第一個 GenericAll


可以使用 Get-ObjectAcl 來列舉 ACE (PS: Get-ObjectAcl 隸屬 PowerView)

先看看自己的帳號擁有那些 ACE,指令 Get-ObjectAcl -Identity stephanie



可以存取的物件是以 SID 的方式顯示,這個雖然是 AD 物件唯一值但卻不易閱讀

一樣透過 PowerView 中的 Convert-SidToName 來顯示成易閱讀的值

例如 : Convert-SidToName S-1-5-21-1987370270-658905905-1781884369-1104




一般我們感興趣的值是 ActiveDirectoryRights 和 SecurityIdentifier 這兩個

下圖為例,RAS and IAS Servers 對使用者物件 stephanie 擁有 ReadProperty 權限




接著讓我們針對群組 "Management Department" 查看誰擁有最大權限 GenericAll

指令 Get-ObjectAcl -Identity "Management Department" | ? {$_.ActiveDirectoryRights -eq "GenericAll"} | select SecurityIdentifier,ActiveDirectoryRights

並將條列出的 SID 一一做 convert 成 name




在轉換 SID to Name 時可以一個一個轉換或是一次輸入所有的 SID 進行轉換

指令 "S-1-5-21-1987370270-658905905-1781884369-512","S-1-5-21-1987370270-658905905-1781884369-1104","S-1-5-32-548","S-1-5-18","S-1-5-21-1987370270-658905905-1781884369-519" | Convert-SidToName




上圖中可以看到我們目前的使用者 stephanie 對管理部門群組擁有 GerericAll 權限,這個在一般網域管理中不常見,因為一般使用者帳號不會對 AD 相關物件擁有過大的權限,會出現如此的權限一般是設定錯誤或是擁有特殊的含意,這個就是在枚舉階段的精隨發現

接著查看該群組的成員 Get-NetGroup "Management Department" | select member

發現僅有一個網域使用者 jen 隸屬該群組




但既然現在的使用者帳號 stephanie 對該群組有最大權限,接著就是將自己的帳號加入該群組

指令 net group "Management Department" stephanie /add /domain

再列舉一次群組 member,現有帳號已隸屬該群組了




要清除帳號使用指令 net group "Management Department" stephanie /del /domain

再列舉一次群組成員,確認剩下 jen 一個帳號,確認現有帳號對該群組擁有權限



練習 1 : ACL 由哪些條目組成?

Ans : ACE

練習 2 : 對於 Active Directory 中的對象,我們可以擁有的最強大的 ACL 是什麼?

Ans : GerericAll




探索域名共享

一樣使用 PowerView 中的 Find-DomainShare 來尋找網域中的共用

使用 Find-DomainShare 列舉網域中的共享資源時需要一段時間,請耐心等候




練習 1 : 在corp.com網域中共用SYSVOL資料夾的伺服器的主機名稱是什麼 ?

Ans : DC1



SYSVOL 預設是 DC 上的 GPO 與腳本共享資料夾路徑,對應到 DC 上的路徑如下

%SystemRoot%\SYSVOL\Sysvol\domain-name,預設每個帳號都可以存取

所以可以先行查看該分享中的內容,ls \\dc1.corp.com\sysvol\corp.com\

跟預設一樣,一個 GPO 一個腳本資料夾




繼續查看資料夾 ls \\dc1.corp.com\sysvol\corp.com\Policies\

Policies 資料夾中有一個資料夾 oldpolicy,光看名稱就應該懷疑是否是梗,所以接著看




ls \\dc1.corp.com\sysvol\corp.com\Policies\oldpolicy,裡面有個 old-policy-backup.xml 檔案




查看一下內容 cat \\dc1.corp.com\sysvol\corp.com\Policies\oldpolicy\old-policy-backup.xml

看到有個 password = "+bsY0V3d4/KgX3VJdO/vyepPfAN1zMFTiQDApgR92JE"

帳號是 Administrator,看來是修改 Client 本機管理員密碼的一個腳本




從密碼來看是一個雜湊值,讓我們使用 kali 內建的 gpp-decrypt 來解密

指令 gpp-decrypt "+bsY0V3d4/KgX3VJdO/vyepPfAN1zMFTiQDApgR92JE"

密碼是 P@$$w0rd



GPP 詳細說明 https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2012-r2-and-2012/dn581922(v=ws.11)

gpp-decrypt 指令說明 https://www.kali.org/tools/gpp-decrypt/

一個簡單的 ruby​​ 腳本,用於解密給定的 GPP 加密字串。

GPP 全名 :  Group Policy Preferences 群組原則首選項

該密碼通常可以在名為 groups.xml 的檔案中找到

該檔案通常位於 SMB 共享資源的目錄中,名為SYSVOL,如果您找到該目錄並且您對其具有讀取權限,請利用它,並尋找名為 groups.xml 的檔案

在檔案內部,我們唯一感興趣的是名為 cpassword 的參數中存在的雜湊值

至於 GPP 怎麼加密密碼的呢,微軟有發布在此 https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-gppref/2c15cbf0-f086-4c74-8b70-1f2fa45dd4be?source=post_page-----4edb9a1663c4-------------------------------- 直接告訴你怎麼加密的




在 payload all the thing 中也有提到如何解密 AD Group Policy 的密碼

https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Active%20Directory%20Attack.md#passwords-in-sysvol-&-group-policy-preferences




另一個透過 Powershell 尋找 AD GPO 中的密碼好用指令

findstr /S /I cpassword \\<FQDN>\sysvol\<FQDN>\policies\*.xml

本例中 FQDN 就是 "corp.com"

findstr /S /I cpassword \\dc1.corp.com\sysvol\corp.com\policies\*.xml




回到一開始列舉的 docshare ,發現在 files04 的共享有一個名稱為 docshare






只要是非 Windows 預設 Share 的名稱建議都可以查看 ls \\FILES04.corp.com\docshare

有個資料夾叫 docs




繼續 ls \\FILES04.corp.com\docshare\docs





檔案 environment.txt 內容看來僅是說明,沒有甚麼幫助





查看另一個有趣的資料夾 do-not-share,裡面有個 start-email.txt 文件





查看內容後拿到了帳號密碼 jeff / HenchmanPutridBonbon11





練習 : 使用 PowerView 找到修改後的 corp.com 網域中的共用並列舉它們以取得標誌

看到 files04 有一個叫做 Important Files 資料夾裡面有個 proof.txt,cat 後就發現 flag





留言

這個網誌中的熱門文章

Challenge 0 - Secura(2)

Challenge 0 - Secura(1)

Challenge 8 - Poseidon(0)