/
Bugzilla – Bug 3521
Telnet IAC processing stack overflow
Last modified: 2010-12-18 12:51:31 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
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.
Created attachment 3436 [details] Prevent underflows of the buflen variable to avoid the stack overflow
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.
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).
Patch committed to CVS with accompanying regression test, and backported to 1.3.3 branch.
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.
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.
For future reference, this has been issued a CVE: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2010-4221
And the published ZDI advisory for this: http://www.zerodayinitiative.com/advisories/ZDI-10-229/
Resolved in 1.3.4rc1.