/ Bug 3521 – Telnet IAC processing stack overflow
Bug 3521 - Telnet IAC processing stack overflow
: Telnet IAC processing stack overflow
Status: CLOSED FIXED
Product: ProFTPD
core
: 1.3.3
: All All
: P1 blocker
Assigned To: proftpd development group
:
: Backport
:
:
  Show dependency treegraph
 
Reported: 2010-10-29 12:15 UTC by TJ Saunders
Modified: 2010-12-18 12:51 UTC (History)
4 users (show)

See Also:


Attachments
Prevent underflows of the buflen variable to avoid the stack overflow (771 bytes, patch)
2010-10-29 12:22 UTC, TJ Saunders
Details

Note You need to log in before you can comment on or make changes to this bug.
Description TJ Saunders 2010-10-29 12:15:13 UTC
ZDI-CAN-925: ProFTPD TELNET_IAC Remote Code Execution Vulnerability

-- CVSS ----------------------------------------------------------------
10, (AV:N/AC:L/Au:N/C:C/I:C/A:C)

-- ABSTRACT ------------------------------------------------------------

TippingPoint has identified a vulnerability affecting the following 
products:

    ProFTPD FTP Server

-- VULNERABILITY DETAILS -----------------------------------------------

This vulnerability allows remote attackers to execute arbitrary code on
vulnerable installations of ProFTPD. Authentication is not required to
exploit this vulnerability. 

The flaw exists within the proftpd server component which listens by
default on TCP port 21. When reading user input if a TELNET_IAC escape
sequence is encountered the process miscalculates a buffer length
counter value allowing a user controlled copy of data to a stack buffer.
 A remote attacker can exploit this vulnerability to execute arbitrary
code under the context of the proftpd process.

Tested on proftpd-1.3.3a.
[Switching to process 31268]
0x0806d498 in pr_netio_telnet_gets (buf=0xbf979ffc 'A' <repeats 200
times>..., buflen=4294963202, in_nstrm=0x97d77e4, out_nstrm=0x97d79f4)
at netio.c:1103
1103          *bp++ = cp;

FTP commands are read by function pr_cmd_read() of file
src/main.c (line 566).

The function pr_cmd_read() uses a local buffer (line 568):
  char buf[PR_DEFAULT_CMD_BUFSZ+1] = {'\0'};

At line 582, pr_cmd_read() calls pr_netio_telnet_gets():
  if (pr_netio_telnet_gets(buf, sizeof(buf)-1, [...]

The second parameter of pr_netio_telnet_gets() is "sizeof(buf)-1",
so its value is :
  sizeof(buf)-1 =
  (PR_DEFAULT_CMD_BUFSZ+1)-1 =
  PR_DEFAULT_CMD_BUFSZ =          [defined in src/main.c]
  PR_TUNABLE_PATH_MAX + 7 =       [defined in include/options.h]
  MAXPATHLEN + 7 =                [on Linux, MAXPATHLEN==4096]
  4096 + 7 =
  4103

The function pr_netio_telnet_gets() is defined in src/netio.c
(line 991):
  pr_netio_telnet_gets(char *buf, size_t buflen, [...]

We have buflen==4103. It is first decremented, and then
each read character decrements it. This is inside a loop
which stops when buflen==0, or when a '\n' character
is found (line 1039).

However, on line 1073, there is:
  buflen--;
So, buflen can be decremented by TWO inside the loop. This
case occurs because the function processes TELNET_IAC
escape characters followed by a TELNET_xyz character.

So, successive buflen values can be :
  4103
  4102
  ...
  3
  2
  1 (here we manage to decrement by TWO, by putting
     a TELNET_IAC character at this location)
  -1
  -2
  ...
So, the loop never stops because buflen is never zero.
The loop will only stop when a '\n' character is found
(line 1039).

So, every character between the TELNET_IAC and the
'\n' will overflow the stack buffer. This is a classical
stack overflow.


-- CREDIT --------------------------------------------------------------

This vulnerability was discovered by:
    * Anonymous
Comment 1 TJ Saunders 2010-10-29 12:17:40 UTC
There is no effective workaround to prevent this bug.  At best, admins can use
different CommandBufferSize values in their proftpd.conf to avoid having the
same default buffer size and thus make it harder for automated scripts, using
the same default values.  Thus something like:

  CommandBufferSize 1037

or

  CommandBufferSize 3983

or other odd but perfectly functional values.
Comment 2 TJ Saunders 2010-10-29 12:22:04 UTC
Created attachment 3436 [details]
Prevent underflows of the buflen variable to avoid the stack overflow
Comment 3 TJ Saunders 2010-10-29 12:23:31 UTC
Ignore the comments about using CommandBufferSize to attempt to mitigate this
vulnerability; they will NOT work.  The CommandBufferSize directive is used on
commands read from clients *after* they have been processed by the vulnerable
NetIO processing of Telnet characters.
Comment 4 TJ Saunders 2010-10-29 12:37:18 UTC
Other considerations for this issue: it affects both FTP and FTPS (FTP over
SSL/TLS) connections, but does NOT affect SSH/SFTP/SCP connections (i.e. it
does not apply to the mod_sftp module).
Comment 5 TJ Saunders 2010-10-29 13:30:39 UTC
Patch committed to CVS with accompanying regression test, and backported to
1.3.3 branch.
Comment 6 TJ Saunders 2010-10-29 18:04:29 UTC
The initial report from TippingPoint did not indicate the range of versions of
ProFTPD with this vulnerability.  Inspecting the sources of versions past
indicates that this vulnerability has been present since at least
proftpd-1.2.0pre10.
Comment 7 TJ Saunders 2010-10-29 18:18:24 UTC
Correction:

The initial report from TippingPoint did not indicate the range of versions of
ProFTPD with this vulnerability.  Inspecting the sources of versions past
indicates that this vulnerability has been present since proftpd-1.3.2rc3.  The
vulnerability was inadvertently added as part of the fix for Bug#3131.
Comment 8 TJ Saunders 2010-11-12 19:35:30 UTC
For future reference, this has been issued a CVE:

  http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2010-4221
Comment 9 TJ Saunders 2010-11-16 17:14:14 UTC
And the published ZDI advisory for this:

  http://www.zerodayinitiative.com/advisories/ZDI-10-229/
Comment 10 TJ Saunders 2010-12-18 12:51:31 UTC
Resolved in 1.3.4rc1.