針對新型程式注入技術Ctrl-Inject原理分析
概述
在本文中,我們將主要介紹一種新型的程式注入方法,我們稱之為“Ctrl-Inject”,它利用控制檯應用程式中處理Ctrl訊號的機制實現注入。在研究的過程中,我們在瀏覽MSDN時發現有一條關於Ctrl訊號處理的相關評論:“這是一個與SetConsoleCtrlHandler函式( )一起使用的函式,由應用程式定義。控制檯程式使用此函式來處理程式收到的控制訊號。當收到訊號後,系統會在程式中啟動一個新的執行緒來執行該函式。”這也就意味著,每次我們觸發一個訊號到一個基於控制檯的程式時,系統都會呼叫一個在新執行緒中呼叫的處理函式。正因如此,我們可以藉助這一特點,來實現一個不同於以往的程式注入。
控制訊號處理
當使用者或程式向基於控制檯的程式(例如cmd.exe或powershell.exe)傳送Ctrl + C(或Break)訊號時,系統程式csrss.exe將會在目標程式中建立一個新的執行緒來呼叫函式CtrlRoutine。CtrlRoutine函式負責包裝使用SetConsoleCtrlHandler的處理程式。接下來,我們深入研究一下CtrlRoutine,首先注意到了下面這段程式碼:
該函式使用名為HandlerList的全域性變數來儲存回撥函式列表,在該函式中會迴圈執行,直到其中一個處理程式返回TRUE(通知該訊號已被處理)為止。為了使處理程式成功執行,它必須滿足以下條件:1、函式指標必須正確編碼。處理程式列表中的每個指標都使用RtlEncodePointer進行編碼,並在執行之前使用RtlDecodePointer API進行解碼。因此,未經編碼的指標很有可能會導致程式崩潰。2、指向有效的CFG(Control Flow Guard,控制流防護)目標。CFG透過驗證間接呼叫的目標是否為有效函式,來嘗試對間接呼叫進行保護。我們來看一下SetConsoleCtrlHandle,看看它如何設定一個Ctrl處理程式,以便我們以後可以模仿其方式。在下圖中,我們可以看到各個指標在新增到HandlerList之前是如何編碼的。
接下來,我們看到了一個名為SetCtrlHandler的內部函式呼叫。該函式更新了兩個變數:一個是HandlerList,用於新增一個新的指標;另一個全域性變數是HandlerListLength,增加了它的長度以適應新的列表大小。
現在,由於HandlerList和HandlerListLength變數駐留在kernelbase.dll模組中,並且該模組會對映到所有程式的相同地址,所以我們可以在程式中找到它們的地址,然後使用WriteProcessMemory在遠端程式中更新它們的值。我們的工作還沒有完成,考慮到CFG和指標編碼的存在,我們需要找到一種方法來繞過它們。
繞過指標編碼
在Windows 10之前的版本中,我們需要理解指標編碼、解碼的工作原理,從而應對指標編碼保護。接下來,我們一起深入瞭解一下EncodePointer的工作原理。
開始,存在一個對NtQueryInformationProcess的呼叫,其定義如下:
NTSTATUS WINAPI NtQueryInformationProcess(
_In_HANDLE ProcessHandle,
_In_PROCESSINFOCLASS ProcessInformationClass,
_Out_ PVOIDProcessInformation,
_In_ULONGProcessInformationLength,
_Out_opt_ PULONG ReturnLength
);
根據上述定義,我們可以做出以下假設:1、ProcessHandle:當傳遞-1的值時,它代表引用呼叫程式的函式。2、ProcessInformationClass:該引數的值為0x24,這是一個未公開的值,要求核心檢索程式加密Cookie。Cookie本身駐留在EPROCESS結構中。在檢索加密Cookie後,我們可以看到幾個涉及輸入指標和加密Cookie的操作。具體為:
EncodedPointer = (OriginalPointer ^ SecretCookie) >> (SecretCookie & 0x1F)
一種繞過的方法,是使用CreateRemoteThread執行RtlEncodePointer,並將NULL作為引數傳遞給它,如下所示:1) EncodedPointer = (0 ^ SecretCookie) >> (SecretCookie & 0x1F)2) EncodedPointer = SecretCookie >> (SecretCookie & 0x1F)這樣一來,返回值將被Cookie旋轉的值增加到31倍(在64位Windows 10環境上該值為63,即0x3f)。如果我們在目標程式上使用已知的編碼地址,就能夠暴力猜測出原始Cookie值。以下程式碼展示瞭如何對Cookie進行暴力猜測:
在Windows 10及以上版本中,微軟非常慷慨地為我們提供了一組新的API,稱為RtlEncodeRemotePointer和RtlDecodeRemotePointer。顧名思義,我們傳遞一個程式控制程式碼和一個指標,該API將會為目標程式返回一個有效的編碼後指標。此外,還有另一種提取Cookie的技術,請參考: %20Process%20Cookie%20for%20Windows%207/main.cpp 。
繞過CFG
到目前為止,我們已經將我們的程式碼注入到目標程式,並修改了HandlerList和HandlerListLength的值。如果我們現在嘗試傳送Ctrl+C訊號來觸發程式碼,該程式會引發異常,最終自行終止。其原因在於,CFG會注意到我們正在嘗試跳轉到一個非有效呼叫目標的指標。幸運的是,微軟對我們一直非常友善,他們釋出了另外一個有用的API,名為SetProcessValidCallTargets。
WINAPI SetProcessValidCallTargets(
_In_HANDLEhProcess,
_In_PVOID VirtualAddress,
_In_SIZE_TRegionSize,
_In_ULONG NumberOfOffsets,
_Inout_ PCFG_CALL_TARGET_INFO OffsetInformation
);
簡而言之,我們傳遞程式控制程式碼和指標後,該API會將其設定為有效的呼叫目標。此外,如果使用我們此前介紹過的( https://blog.ensilo.com/documenting-the-undocumented-adding-cfg-exceptions )未記錄的API也可以實現這一點。
觸發Ctrl+C事件
現在一切準備就緒,我們需要做的就是在目標程式上觸發Ctrl + C,以呼叫我們的程式碼。有幾種方法可以觸發它。在這種情況下,我們可以使用SendInput的組合,來觸發系統範圍的Ctrl鍵按鍵,以及用於傳送C鍵的PostMessage。同樣,也適用於隱藏或不可見的控制檯視窗。以下是觸發Ctrl-C訊號的函式:
揭秘底層
從實質上來說,在這個程式注入技術中,我們將程式碼注入到目標程式中,但是我們從不直接呼叫它。也就是說,我們從來沒有自己呼叫CreateRemoteThread或使用SetThreadContext改變執行流。相反,我們正在讓csrss.exe為我們呼叫它,這樣一來就顯得是一個正常的行為,不會被懷疑。其原因在於,每次將Ctrl + C訊號傳送到基於控制檯的應用程式時,conhost.exe會呼叫類似於呼叫堆疊的內容,如下所示:
其中,CsrClientCallServer會傳遞一個唯一索引識別符號(0x30401),然後將其傳遞給csrss.exe服務。在其中,會從排程表中呼叫一個名為SrvEndTask的函式。呼叫鏈具體如下:
在這個呼叫鏈的最後,我們看到了RtlCreateUserThread,它負責在目標程式上執行我們的執行緒。注意:儘管Ctrl-Inject技術僅針對於控制檯應用程式,但也可能會在很多控制檯應用程式上被濫用,最值得注意的就是cmd.exe。
總結
現在,我們已經瞭解了這個新型的程式注入方法,掌握了該方法的工作原理以及其背後到底發生了什麼。在最後,我們可以總結一下Ctrl-Inject技術。這種技術與傳統執行緒注入技術相比,主要優點是遠端執行緒是由可信的Windows程式csrss.exe建立,這使得它得隱蔽性更強。但同樣存在缺點,就是這種方法僅適用於控制檯應用程式。
要進行這種程式注入技術,所需的步驟如下:1、將OpenProcess附加到控制檯程式。2、透過呼叫VirtualAllocEx,為惡意負載分配一個新的緩衝區。3、使用WriteProcessMemory將資料寫入分配的緩衝區。4、使用目標程式cookie將指標指向指定的緩衝區。透過呼叫帶有空指標的RtlEncodePointer並手動編碼指標或透過呼叫RtlEncodeRemotePointer來實現。5、通知遠端程式,新指標是可以使用SetProcessValidCallTargets的有效指標。6、最後,使用PostMessage和SendInput的組合觸發Ctrl + C訊號。7、恢復原始處理程式列表。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31510736/viewspace-2154492/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 技術分享 | 一種針對PHP物件注入漏洞的新型利用方法PHP物件
- COM 程式注入技術
- 最新堆疊查詢注入攻擊和注入程式碼分析技術
- 最新二次注入攻擊和程式碼分析技術
- 最新寬位元組注入攻擊和程式碼分析技術
- 最新Base64注入攻擊和程式碼分析技術
- [精華] RDMA技術原理分析、主流實現對比和解析
- WIFI探針技術WiFi
- 專門針對SQL Server的注入手段SQLServer
- Elasticsearch核心技術(四):索引原理分析Elasticsearch索引
- 蘋果和新型可穿戴技術蘋果
- 對於搞技術的人怎樣針對自己看什麼書
- Java技術開發專題系列之【Guava RateLimiter】針對於限流器的入門到精通(針對於原始碼分析介紹)JavaGuavaMIT原始碼
- IOC注入技術之編譯時注入編譯
- 技術分享 | Linux 環境下針對程式維度的監控實現Linux
- SQL 注入技術詳解SQL
- C# DLL注入技術C#
- 新型Windows惡意軟體正在針對Linux、macOS裝置WindowsLinuxMac
- 【Netty技術專題】「原理分析系列」Netty強大特性之ByteBuf零拷貝技術原理分析Netty
- Java 遠端通訊技術及原理分析Java
- 技術分享 | DLL注入之遠執行緒注入執行緒
- 基於軟體分析的智慧化開發新型服務與技術
- 模板引擎注射:針對現代web應用的新型命令執行Web
- 針對Office 365的新型網路釣魚詐騙之音訊郵件音訊
- FBI針對Tor網路的惡意程式碼分析
- ?【Java技術專區】「探針Agent專題」Java Agent探針的技術介紹(1)Java
- typedef分析(針對ccColor4B)
- Mysql報錯注入原理分析(count()、rand()、group by)MySql
- 技術原理:Python中range和xrange對比Python
- Apache Flink CDC 批流融合技術原理分析Apache
- Spring 原始碼分析之 bean 依賴注入原理(注入屬性)Spring原始碼Bean依賴注入
- KVM虛擬化新型漏洞CVE-2015-6815技術分析
- 大資料分析技術在新型智慧能源建設中的應用大資料
- 針對macOS的新型加密貨幣挖礦木馬OSX.CpuMeanerMac加密
- 資料庫注入技術小結資料庫
- McAfee針對GandCrab勒索軟體的分析
- 低程式碼的技術原理是什麼?
- 對話式互動技術原理及流程揭祕