首页
社区
课程
招聘
[求助]内核注入R3执行代码
发表于: 2012-7-23 22:10 6547

[求助]内核注入R3执行代码

2012-7-23 22:10
6547
http://bbs.pediy.com/showthread.php?t=104069按这个来写的,
RtlCopyMemory(pBuffer,ShellCode,size);到这一句就蓝了,找不到原因。。

sp3测试,
FuncType KeSuspendThread = NULL;
FuncType KeResumeThread = NULL;   都直接赋值了,就地windbg改下把。。

#include "ntifs.h"

typedef struct _X86_KTRAP_FRAME {
        ULONG   DbgEbp;
        ULONG   DbgEip;
        ULONG   DbgArgMark;
        ULONG   DbgArgPointer;
        ULONG   TempSegCs;
        ULONG   TempEsp;
        ULONG   Dr0;
        ULONG   Dr1;
        ULONG   Dr2;
        ULONG   Dr3;
        ULONG   Dr6;
        ULONG   Dr7;
        ULONG   SegGs;
        ULONG   SegEs;
        ULONG   SegDs;
        ULONG   Edx;
        ULONG   Ecx;
        ULONG   Eax;
        ULONG   PreviousPreviousMode;
        ULONG   ExceptionList;
        ULONG   SegFs;
        ULONG   Edi;
        ULONG   Esi;
        ULONG   Ebx;
        ULONG   Ebp;
        ULONG   ErrCode;
        ULONG   Eip;
        ULONG   SegCs;
        ULONG   EFlags;
        ULONG   HardwareEsp;
        ULONG   HardwareSegSs;
        ULONG   V86Es;
        ULONG   V86Ds;
        ULONG   V86Fs;
        ULONG   V86Gs;
} X86_KTRAP_FRAME, *PX86_KTRAP_FRAME;

typedef struct _MODULE_ENTRY {
        LIST_ENTRY le_mod;
        ULONG  unknown[4];
        ULONG  base;
        ULONG  driver_start;
        ULONG  unk1;
        UNICODE_STRING driver_Path;
        UNICODE_STRING driver_Name;
        //.......
} MODULE_ENTRY, *PMODULE_ENTRY;

typedef ULONG (*FuncType)(PETHREAD Thread);

FuncType KeSuspendThread = NULL;
FuncType KeResumeThread = NULL;

_declspec (naked) void ShellCode()
{
        _asm
        {
                push eax
                push 0
                push 0
                push 0
                push 0
                mov eax,0x77D66534        // jmp ds:12345678H, 绝对地址跳转
                call eax
                pop eax

                // jmp ds:12345678H, 绝对地址跳转
                _emit 0xEA
                _emit 0x78
                _emit 0x56
                _emit 0x34
                _emit 0x12
                _emit 0x1B
                _emit 0x00

        }
}

VOID InjectShellCode(PETHREAD pThread,PEPROCESS pProcess)
{
       
        ULONG i;
        PX86_KTRAP_FRAME pTrapFrame;
        PCLIENT_ID pCid;
        OBJECT_ATTRIBUTES oa;
        HANDLE hProcess;
        NTSTATUS ntStatus;

        _asm int 3

        KeSuspendThread(pThread);

        pTrapFrame = *(PX86_KTRAP_FRAME*)((ULONG)pThread + 0x134);

        for (i=(ULONG)ShellCode; i<=(ULONG)ShellCode+0x20; ++i)                //先修改好shellcode,在把它复制到进程的用户空间
        {
                if (  MmIsAddressValid((PVOID)i)
                                &&
                          MmIsAddressValid((PVOID)(i+3)) )
                {
                        if ( *(PULONG)i == 0x12345678)
                        {
                                *(PULONG)i = pTrapFrame->Eip;
                                break;
                        }
                }

        }

        //分配空间,复制shellcode到指定进程的用户空间
        InitializeObjectAttributes(&oa,0,0,0,0);
        pCid = (CLIENT_ID *)((ULONG)pThread + 0x1ec);//不用加4,或者->                //ntdll!_CLIENT_ID
                                                                                                                                                //+0x000 UniqueProcess    : Ptr32 Void
                                                                                                                                                //+0x004 UniqueThread     : Ptr32 Void
                                                                                       
        ntStatus = ZwOpenProcess(&hProcess,                                //hProcess是返回的句柄
                                                                PROCESS_ALL_ACCESS,
                                                                &oa,                //要么指定oa,要么指定pCid
                                                                pCid);                //这里指定了pCid的地址,就是进程ID的地址
        if (NT_SUCCESS(ntStatus))
        {
                PVOID pBuffer = NULL;
                SIZE_T size = 0x20;
                ntStatus = NtAllocateVirtualMemory(hProcess,//hProcess是ZwOpenProcess的返回值
                                                                                        &pBuffer,//返回分配的地址值的指针
                                                                                        0,
                                                                                        &size,        //返回实际分配的大小
                                                                                        MEM_RESERVE | MEM_COMMIT,
                                                                                        PAGE_EXECUTE_READWRITE);
                if (NT_SUCCESS(ntStatus))
                {
                        KAPC_STATE kapc;
                        KeStackAttachProcess(pProcess,&kapc);
                        RtlCopyMemory(pBuffer,ShellCode,size);
                        KeUnstackDetachProcess(&kapc);

                        pTrapFrame->Eip = (ULONG)pBuffer;       
                        //修改用户空间的EIP为分配的shellcode地址
                }
                ZwClose(hProcess);
        }
        KeResumeThread(pThread);

}

VOID Inject(char* strProc, int len) {
        PEPROCESS pProcess;
        PETHREAD pThread;
        PLIST_ENTRY pListHead, pNextEntry;
        PLIST_ENTRY pThListHead, pThNextEntry;

        _asm int 3;

        pProcess = PsGetCurrentProcess();
        pListHead = (PLIST_ENTRY)((ULONG)pProcess + 0x88);                //ActiveProcessLinks
        pNextEntry = pListHead;

        // 先找到要注入的进程,通过ZwQuerySystemInformation来查找更稳定一些
        // 不过本人很讨厌那个繁琐的函数……
        do {
                pProcess = (PEPROCESS)((ULONG)pNextEntry - 0x88);
                if ( !_strnicmp((char*)pProcess + 0x174, strProc, len) ) {
                        DbgPrint("find process\n");
                        pThListHead = (PLIST_ENTRY)((ULONG)pProcess + 0x190);                // ThreadListHead, XP SP2
                        pThNextEntry = pThListHead->Flink;
                        while ( pThNextEntry != pThListHead) {
                                // 接着查找符合条件的线程
                                UCHAR SuspendCount;
                                ULONG CrossThreadFlags;

                                pThread = (PETHREAD)((ULONG)pThNextEntry - 0x22c);                // ThreadListEntry, XP SP2

                                SuspendCount = *(PUCHAR)((ULONG)pThread + 0x1b9);
                                CrossThreadFlags = *(PULONG)((ULONG)pThread + 0x248);

                                if( !SuspendCount && !(CrossThreadFlags & 0x13) )
                                {                // 非Suspend,非退出态,非内核线程
                                        DbgPrint("find thread\n");

                                        // 注入找到的线程
                                        InjectShellCode(pThread,pProcess);
                                        break;
                                }
                                pThNextEntry = pThNextEntry->Flink;
                        }
                        break;
                }
                pNextEntry = pNextEntry->Flink;
        } while(pNextEntry != pListHead);
}

VOID OnUnload(IN PDRIVER_OBJECT o){
        DbgPrint("unload!\n");
        return;
}

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath)
{
        char *strProc = "try.exe";
        _asm int 3
        DriverObject->DriverUnload = OnUnload;

        KeSuspendThread = (FuncType)0x804fcbdc;
        KeResumeThread        = (FuncType)0x804fc806;

        Inject(strProc,strlen(strProc));
        return STATUS_SUCCESS;

}

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (4)
雪    币: 239
活跃值: (133)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
2
try。exe 随便弄个进程。。。
2012-7-23 22:11
0
雪    币: 40
活跃值: (14)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
还不如贴上dump信息
2012-7-23 23:15
0
雪    币: 257
活跃值: (67)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
4
RtlCopyMemory(pBuffer,ShellCode,size);
这里蓝的话,会不会是缓冲区溢出?或者长度超出?
2012-7-24 03:32
0
雪    币: 239
活跃值: (133)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
5
我也迷茫,传入的Size是0X20,ntAllo。。后就返回一个页面的大小0x1000,而且我按照之前写的那个源码弄的。。目的缓冲区时0x1000,源地址是Shellcode的。。估计size=0x1000超过了shellcode的范围,。。我把RtlCopyMemory的size改成0x20试试
2012-7-24 09:38
0
游客
登录 | 注册 方可回帖
返回
//