[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Proftpd v1.3.5a ZERODAY - Heap Overflows due to zero length mallocs. Advanced Information Security Corporation

                              Date: 22/11/2015
                      Credit: Nicholas Lemonias

             .::PROFTPD  v1.3.5a  HEAP OVERFLOWS ::.


                                                    Keeping Things Simple!


               888' _`888'_  `88888
               888 888 888  88888
              .888  `::::'    8:88.
             8888            `8:888.
           .8888'             `888888.
          .8888:..  .::.  ...:'8888888:.
         .8888.'     :'     `'::`88:88888
        .8888        '         `.888:8888.
       888:8         .           888:88888
     .888:88        .:           888:88888:
     8888888.       ::           88:888888
     `.::.888.      ::          .88888888
    .::::::.888.    ::         :::`888'.:.
   ::::::::::.888   '         .::::::::::::
   ::::::::::::.8    '      .:8::::::::::::.
 .::::::::::::::.        .:888:::::::::::::
         `':::_:' -- '' -'-' `':_::::'`.

 ProFTPD is Free and open-source software, compatible with Unix-like
 systems and Microsoft Windows (via Cygwin). Along with vsftpd and
 Pure-FTPd, ProFTPD is among the most popular FTP servers in Unix-like
 environments today. Compared to those, which focus e.g. on simplicity,
 speed or security, ProFTPD's primary design goal is to be a highly
 feature rich FTP server, exposing a large amount of configuration
 options to the user

 Description: During a manual source code audit of ProFTPD latest,
 various security issues were discovered.



 (Heap Overflow due to zero length malloc allocation)


 Code Snippet:

     ret = malloc(size);
   if (ret == NULL) {
     pr_log_pri(PR_LOG_ALERT, "Out of memory!");
 #ifdef PR_USE_DEVEL
     if (debug_flags & PR_POOL_DEBUG_FL_OOM_DUMP_POOLS) {
   return ret;

 The return value of malloc can be set to null for zero size allocs,
 and this would return a NULL pointer on certain implementations of
 MIPS32 and ARM architectures, or cause a SIGSEGV.  Despite the exit()
 function call, the memory allocation would be attempted.

 Embedded platforms such as OpenWRT could be targeted and this defect
 can be taken advantage of, depending on where the swap is, this can be

 This would have critical impact on architectures such as ARM and
 MIPS32  used in embedded platforms, to cite as an example, and thus
 the impact is implementation specific.


 Line: 371-379
 CERT MEM04-C; CWE-131

 static cmd_rec *fxp_cmd_alloc(pool *p, const char *name, char *arg) {
   cmd_rec *cmd;

   cmd = pr_cmd_alloc(p, 2, pstrdup(p, name), arg ? arg : "");
   cmd->arg = arg;

   return cmd;

 fxp_cmd_alloc() can be a cause for unspecified behavior.

 Furthermore there is a memory pool management issue, which can result
 to heap overflows and DoS attacks.

 ../src/pool.c:128-160, 771, 811

 There is a defect in the way the memory pool is organized. The issue
 itself is that the pool relies on malloc returning truly aligned
 memory; and explicitly freeing/allocating memory. The impact is that
 you can overwrite random memory.

 Behavior and impact of this reliance on aligned memory is
 implementation specific.

 Reading USER_AUTH_INFO_RESP messages from client
 ../mod_sftp/kbdint.c#L297 Denial of Service

 According to RFC 4256 Section 3.2 The server may send as many requests
 as are necessary to authenticate the client; the client MUST be
 prepared to handle multiple exchanges.
 According to RFC 4256 Section 3.2 The server may send as many requests
 as are necessary to authenticate the client; the client MUST be
 prepared to handle multiple exchanges.

 kbdint.c: 209-210


 IF multiple clients send multiple requests and where each request
 (resp_count in code) is thus not greater than SFTP_KBDINT_MAX_RESPONSE
 LIMIT (500) per user, this would cause significant problems to the
 aforementioned memory allocation pool defect.

 I could find no plausible MAX LIMIT on the size of the pool, nor any
 controls to restrict that apart from a buffer which is equal to
 3072 in sinze, in kbdint.c ; in context  of the created pool, which
 can be allocated on a per connection basis.

   kbdint.c: 209-210

   buflen = bufsz = 3072;
   buf = ptr = palloc(pkt->pool, bufsz);


 PacketStorm Security
 TEAM TESO, w00w00, Netric, b0iler (eyeonsecurity), wootehfoot,
 badpack3t (SP), Vandal (Vic), s0kket, mantis,  Big_Al , ELFQrin, bob
 (dtors),  epic  for their ~ legendary mark.

 Advanced Information Security Corporation, 2015