Tuesday, November 2, 2010

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' 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



No comments:

Post a Comment