hacking contest

hacking exploits security forum
hacking
compliance articles
upgrade backup exec
information security consultant

sPiKie
Release Date: 2004-03-04


Critical:
Highly critical
Impact: System access

Where: From remote



Software: ProFTPD 1.2.x




Description:
Phantasmal Phantasmagoria has reported a vulnerability in ProFTPD, which potentially can be exploited by malicious users to compromise a vulnerable system.

The vulnerability is caused due to two off-by-one errors in the "_xlate_ascii_write()" function. These can be exploited by sending a specially crafted "RETR" FTP command with a 1023 bytes long argument starting with a linefeed character.

Successful exploitation may allow execution of arbitrary code with the privileges of ProFTPD.

The vulnerability has been reported in the following versions:
* 1.2.7/1.2.7p
* 1.2.8/1.2.8p
* 1.2.9rc1/1.2.9rc1p
* 1.2.9rc2/1.2.9rc2p

Solution:
The vulnerabilities are reportedly not present in version 1.2.9rc3 and later.
http://www.proftpd.org/download.html

Provided and/or discovered by:
Phantasmal Phantasmagoria




Please note: The information, which this Secunia Advisory is based upon, comes from third party unless stated otherwise.

Secunia collects, validates, and verifies all vulnerability reports issued by security research groups, vendors, and others.
bitwild
Date: Mon, 1 Mar 2004 21:37:36 -0800
To: full-disclosure@lists.netsys.com
"The Cult of a Cardinal Number"

...
---- Technical Details -------------

As in the case of the ISS bug this issue resides in the _xlate_ascii_write()
function, used to insert a preceeding CR for every LF. It can be triggered
by the RETR ftp command.

CODE

static void _xlate_ascii_write(char **buf, unsigned int *buflen,
   unsigned int bufsize) {
 char *tmpbuf = *buf;
 unsigned int tmplen = *buflen;
 unsigned int lfcount = 0;
 unsigned int added = 0;
 int res = 0;
 register unsigned int i = 0;


 if (tmpbuf[0] == '\n')
   lfcount++;


..


 if ((res = (bufsize - tmplen - lfcount)) <= 0) { /* [A] */
   pool *copy_pool = make_sub_pool(session.xfer.p);
   char *copy_buf - pcalloc(copy_pool, tmplen);


   memmove(copy_buf, tmpbuf, tmplen);


   session.xfer.bufsize = tmplen + lfcount; /* [B] */
   session.xfer.buf = pcalloc(session.xfer.p,session.xfer.bufsize);


   session.xfer.buf++; /* [C] */
   session.xfer.bufstart = session.xfer.buf;


   memmove(session.xfer.buf, copy_buf, tmplen); /* [D] */
   destroy_pool(copy_pool);


   tmpbuf = session.xfer.buf;
   bufsize = session.xfer.bufsize;
 }


 if (tmpbuf[0] == '\n') {
   memmove(&(tmpbuf[1]), &tmpbuf[0], bufsize); /* [E] */
   tmpbuf[0] = '\r';


   added++;
   lfcount--;
 }


..


 tmpbuf[tmplen+added] = '\0'; /* [F] */
 *buf = tmpbuf;
 *buflen = tmplen + added;
}


These flaws are made possible at a number of stages. Firstly, we need
to get into the if statement at [A]. This is easy enough to do. The variable
bufsize is the actual size of the buffer we are attacking, which when
using the RETR command is 1024. For the sake of the overflows, we want
to get 'res' to exactly 0. There are a number of possible combinations
to do this, the simplest of which is passing a 1023 byte long buffer
containing a single LF in the first character to the _xlate_ascii_write()
function.


Knowing that we can trigger the if statement we can shift our attention
to session.xfer.buf, the buffer we will be overflowing. The first important
mistake occurs when session.xfer.bufsize is set to 1024 at [B], where
it should actually be 1025 (1023 + CR + NULL). This is followed by the
crux of the overflows at [C]. It is entirely unnessecary to increase
session.xfer.buf here. It essentialy reduces the amount of valid space
in the buffer to 1023. The final significant event leading to the overflows
is at [D], where 1023 bytes of our buffer (including the starting LF)
is moved to session.xfer.buf. Due to the slip-up at [C], we lose our
NULL terminating byte; our buffer is exactly contiguous to the end of
valid space.


The first off-by-one overflow occurs at [E]. The last character of our
1023 byte long argument to _xlate_ascii_write() is moved past the boundary
of allocated space for session.xfer.buf to make room for the preceeding
CR to our LF. We can control this value. We can't, however, control the
next off-by-one at [F]. Due to [C], the line at [F] should be setting
tmpbuf[1022] to NULL. The value at tmpbuf[1023] is what we just oveflowed.
Instead, tmpbuf[1023 + 1] gets set to NULL. Perhaps it would be more
accurate to call this an off-by-two, but as the overflow at [F] existed
even before the ISS bug was patched that would only introduce confusion.
pr0t0type
Is this the same one as sept last year? if so securityfocus.com has 3 exploits for it http://www.securityfocus.com/bid/8679/exploit/

If not this looks so simmilar that it should be easy to mod the exploits to fit this one.

EDIT: Ah thanks bitwild, so it is a different bug and it looks like this one doesn't need upload perms like the iss one before.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.

 
Invision Power Board © 2001-2005 Invision Power Services, Inc.