0x00 前言利用TabShell可以使用普通用戶逃避沙箱並在Exchange Powershell中執行任意cmd命令,本文將要介紹利用TabShell執行cmd命令並獲得返回結果的方法,分享通過Python編寫腳本的細節。
0x01 簡介本文將要介紹以下內容:
執行cmd命令並獲得返回結果的方法
Python實現
0x02 執行cmd命令並獲得返回結果的方法testanull公開了一個利用的POC,地址如下:https://gist.github.com/testanull/518871a2e2057caa2bc9c6ae6634103e
為了能夠支持更多的命令,POC需要做簡單修改,細節如下:
某些命令無法執行,例如netstat -ano或者systeminfo
解決方法:
去掉命令:$ps.WaitForExit()
執行cmd命令並獲得返回結果的方法有以下兩種:
1.使用Powershell連接Exchange服務器,實現TabShellPowershell命令示例:
需要注意以下問題:
需要域內主機上執行
需要fqdn,不支持IP
連接url可以選擇http或https
認證方式可以選擇Basic或Kerberos
2.通過SSRF漏洞調用Exchange Powershell,實現TabShell這裡需要通過Flask建立本地代理服務器,方法可參考之前的文章《ProxyShell利用分析3——添加用户和文件写入》
Powershell命令示例:
0x03 Python實現這裡需要考慮兩部分,一種是通過SSRF漏洞調用Exchange Powershell實現TabShell的Python實現,另一種是通過Powershell Session實現TabShell的Python實現,後者比前者需要額外考慮通信數據的編碼和解碼,具體細節如下:
1.通過SSRF漏洞調用Exchange Powershell實現TabShell的Python實現為了分析中間的通信數據,抓取明文數據的方法可參考上一篇文章《渗透技巧——Exchange Powershell的Python实现》 中的0x04,在Flask中輸出中間的通信數據
關鍵代碼示例:
通過分析中間的通信數據,我們可以總結出以下通信過程:
(1)creationXml
初始化,構造原始數據
(2)ReceiveData
循環多次執行,返回結果中包含'RunspaceState'作為結束符
(3)執行命令;/./././Windows/Microsoft.NET/assembly/GAC_MSIL/Microsoft.PowerShell.Commands.Utility/v4.0_3.0.0.0__31bf3856ad364e35/Microsoft.PowerShell.Commands.Utility.dll\Invoke-Expression
在返回數據中獲得CommandId
(4)讀取輸出結果
通過CommandId讀取命令執行結果
(5)執行命令$ExecutionContext.SessionState.LanguageMode='FullLanguage'
在返回數據中獲得CommandId
(6)讀取輸出結果
通過CommandId讀取命令執行結果
(7)執行命令並獲得返回結果
依次執行以下命令:
在返回數據中獲得CommandId,並通過CommandId讀取命令執行結果,這些命令的格式相同,發送數據的格式如下:
(8)執行命令並獲得最終返回結果
發送數據的格式同(7)一致,執行的命令為:$Out,在返回數據中獲得CommandId,並通過CommandId讀取最終的命令執行結果,提取執行結果的示例代碼:
2.通過Powershell Session實現TabShell的Python實現這裡可以藉鑑上一篇文章《渗透技巧——Exchange Powershell的Python实现》 得出的經驗:兩者通信過程一致,只是通過Powershell Session實現TabShell的Python實現需要額外考慮通信數據的編碼和解碼
通信數據的編碼和解碼可參考上一篇文章《渗透技巧——Exchange Powershell的Python实现》 中的0x03
數據的編碼和解碼示例代碼如下:
0x04 小結本文介紹了利用TabShell執行cmd命令並獲得返回結果的方法,改進POC,分享通過Python編寫腳本的細節。