首页
社区
课程
招聘
[旧帖] [分享]win 7 下shellcode查找kernelbase(通常版) 0.00雪花
发表于: 2009-12-31 13:43 1485

[旧帖] [分享]win 7 下shellcode查找kernelbase(通常版) 0.00雪花

2009-12-31 13:43
1485
前些天写了个shellcode注入进程。发现在自己机器上到可以跑。换到win7上却找不到kernelbase了加载user32也就失败。原来程序为:
pushad
        push ebp
        mov  ebp, esp
// ebp-0x04 ====> hmodkern32
// ebp-0x08 ====> dwAddrOfGetProcAddress
// ebp-0x0C ====> dwAddrOfLoadLibrary
// ebp-0x10 ====> hmoduser32
// ebp-0x14 ====> dwAddrOfMessageBoxA
        sub  esp, 0x14   
//hmodkern32 = _GetBaseKernel32();
        call _GetBaseKernel32
        mov [ebp - 0x04], eax // save Base Address of "Kernel32.dll"
//dwAddrOfGetProcAddress = _GetGetProcAddrBase(hmodkern32);
        push eax
        call _GetGetProcAddrBase
        mov [ebp - 0x08], eax  // save GetProcAddress
        add esp, 0x04
    //load user32.dll   
// dwAddrOfLoadLibrary = GetProcAddress(hmodkern32, "LoadLibrary")
        call _get_loadlibrary
        _emit 'L'
        _emit 'o'
        _emit 'a'
        _emit 'd'
        _emit 'L'
        _emit 'i'
        _emit 'b'
        _emit 'r'
        _emit 'a'
        _emit 'r'
        _emit 'y'
        _emit 'A'
        _emit 0x0
_get_loadlibrary:
        push [ebp - 0x04]
        call dword ptr [ebp - 0x08]
        mov [ebp - 0x0C], eax
// hmoduser32 = LoadLibraryA("user32.dll");
        call _load_user32
        _emit 'u'
        _emit 's'
        _emit 'e'
        _emit 'r'
        _emit '3'
        _emit '2'
        _emit '.'
        _emit 'd'
        _emit 'l'
        _emit 'l'
        _emit 0x0
_load_user32:
        call dword ptr [ebp - 0x0C]
        mov [ebp-0x10], eax
//GET  KERBASE SOURCE CODE
_GetBaseKernel32:
        push ebp
        mov ebp, esp
        push esi
        push edi
        mov eax, fs:[0x30]
        mov eax, [eax + 0x0c]
        mov esi, [eax + 0x1c]
        mov eax, [esi]
        mov edi, [eax + 0x08]
        mov eax, edi // eax = BaseAddress of "kernel32.dll"
        pop edi
        pop esi
        mov esp, ebp
        pop ebp
        ret
// ---------------------------------------------------------
// type : DWORD GetGetProcAddrBase(DWORD base)
_GetGetProcAddrBase:
        push ebp
        mov ebp, esp
        push edx
        push edi
        push esi

        mov ebx, [ebp+8]
        mov eax, [ebx + 0x3c] // edi = BaseAddr, eax = pNtHeader
        mov edx, [ebx + eax + 0x78]
        add edx, ebx          // edx = Export Table (RVA)
        mov ecx, [edx + 0x18] // ecx = NumberOfNames
        mov edi, [edx + 0x20] //
        add edi, ebx          // ebx = AddressOfNames

找了半天 终于找到个好的办法和大家share下。(高手飘过)
int main( void )
{
        OSVERSIONINFOEX VersionInfoEx = { 0 };
        DWORD dwBaseAddressA = 0;
        DWORD dwBaseAddressB = 0;
        DWORD dwBaseAddressC = 0;
        DWORD dwBaseAddressD = 0;

        VersionInfoEx.dwOSVersionInfoSize = sizeof( OSVERSIONINFOEX );

        GetVersionEx( (LPOSVERSIONINFO)&VersionInfoEx );

        if( VersionInfoEx.dwPlatformId != VER_PLATFORM_WIN32_NT )
                printf( "Warning: Not an NT based platform, YMMV!\n" );

        printf( "-------------------------------------------------------------\n" );
        printf( "Microsoft Windows [Version %d.%d.%d] %s\n", VersionInfoEx.dwMajorVersion, VersionInfoEx.dwMinorVersion, VersionInfoEx.dwBuildNumber, VersionInfoEx.szCSDVersion );
        printf( "-------------------------------------------------------------\n" );
        printf( "GetModuleHandleA( \"kernelbase.dll\" ) = 0x%08X\n", (DWORD)GetModuleHandleA( "kernelbase.dll" ) );
        printf( "GetModuleHandleA( \"kernel32.dll\" )   = 0x%08X\n", (DWORD)GetModuleHandleA( "kernel32.dll" ) );
        printf( "GetModuleHandleA( \"ntdll.dll\" )      = 0x%08X\n", (DWORD)GetModuleHandleA( "ntdll.dll" ) );
        printf( "-------------------------------------------------------------\n" );

        // Get the actual kernel32 base address...
        dwBaseAddressA = (DWORD)GetModuleHandleA( "kernel32.dll" );

        // Try the first method...
        __asm
        {
                xor ebx, ebx             ; // clear ebx
                mov ebx, fs:[ 0x30 ]     ; // get a pointer to the PEB
                mov ebx, [ ebx + 0x0C ]  ; // get PEB->Ldr
                mov ebx, [ ebx + 0x1C ]  ; // get PEB->Ldr.InInitializationOrderModuleList.Flink (1st entry)
                mov ebx, [ ebx ]         ; // get the next entry (2nd entry)
                mov ebx, [ ebx + 0x08 ]  ; // get the 2nd entries base address (kernel32.dll)

                mov dwBaseAddressB, ebx
        }

        printf( "Method 1: Kernel32 Base Address = 0x%08X (Correct: %s)\n", dwBaseAddressB, (dwBaseAddressA==dwBaseAddressB?"YES":"NO!") );

        // Try the second method...
        __asm
        {
                xor ebx, ebx               ; // clear ebx
                mov ebx, fs:[ 0x30 ]       ; // get a pointer to the PEB
                mov ebx, [ ebx + 0x0C ]    ; // get PEB->Ldr
                mov ebx, [ ebx + 0x14 ]    ; // get PEB->Ldr.InMemoryOrderModuleList.Flink (1st entry)
                mov ebx, [ ebx ]           ; // get the next entry (2nd entry)
                mov ebx, [ ebx ]           ; // get the next entry (3rd entry)
                mov ebx, [ ebx + 0x10 ]    ; // get the 3rd entries base address (kernel32.dll)

                mov dwBaseAddressC, ebx
        }

        printf( "Method 2: Kernel32 Base Address = 0x%08X (Correct: %s)\n", dwBaseAddressC, (dwBaseAddressA==dwBaseAddressC?"YES":"NO!") );
       
        // Try the third method...
        __asm
        {
                cld                       ; // clear the direction flag for the loop
                xor edx, edx              ; // zero edx

                mov edx, fs:[ 0x30 ]      ; // get a pointer to the PEB
                mov edx, [ edx+0x0C ]     ; // get PEB->Ldr
                mov edx, [ edx+0x14 ]     ; // get the first module from the InMemoryOrder module list
        next_mod:
                mov esi, [ edx+0x28 ]     ; // get pointer to modules name (unicode string)
                mov ecx, 24               ; // set ecx to this length for the loop
                xor edi, edi              ; // clear edi which will store the hash of the module name
        loop_modname:
                xor eax, eax              ; // clear eax
                lodsb                     ; // read in the next byte of the name
                cmp al, 'a'               ; // some versions of Windows use lower case module names
                jl not_lowercase
                sub al, 0x20              ; // if so normalise to uppercase
        not_lowercase:
                ror edi, 13               ; // rotate left our hash value
                add edi, eax              ; // add the next byte of the name
                loop loop_modname         ; // loop untill we have read enough
                cmp edi, 0x6A4ABC5B       ; // compare the hash with that of KERNEL32.DLL
                mov ebx, [ edx+0x10 ]     ; // get this modules base address
                mov edx, [ edx ]          ; // get the next module
                jne next_mod              ; // if it doesnt match, process the next module
                  
                mov dwBaseAddressD, ebx   ; // when we get here EBX is the kernel32 base (or change to suit).
        }

        printf( "Method 3: Kernel32 Base Address = 0x%08X (Correct: %s)\n", dwBaseAddressD, (dwBaseAddressA==dwBaseAddressD?"YES":"NO!") );

        printf( "-------------------------------------------------------------" );

        return 0;
}

[课程]Android-CTF解题方法汇总!

收藏
免费 0
支持
分享
最新回复 (2)
雪    币: 175
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
关于TEB和PEB结构。找了半天才搞清楚。以此为基础。在做PE文件注入是应该方便点。

关于此文站的详细数据介绍可以参考  www.rootkit.com 很变态的一个网站
2010-1-4 13:48
0
雪    币: 137
活跃值: (19)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
谢谢楼主分享
2010-1-5 12:14
0
游客
登录 | 注册 方可回帖
返回
//