29th Nov 2001 [SBWID-4884]
COMMAND
wu-ftpd
SYSTEMS AFFECTED
All versions of wu-ftpd including and up to 2.6.1 are vulnerable.
Version 2.7.0 snapshots are also vulnerable.
Solaris is NOT vulnerable to this problem.
PROBLEM
A previous bug was found, regarding glob() function and FTP daemon (see http://www.securitybugware.org/mUNIXes/4249.html).
This is another aspect of the same trouble.
The bug was re-discovered independantly by Luciano Notarfrancesco and
Juan Pablo Martinez Kuhn from CORE Security Technologies. Wu-ftpd is
vulnerable, remote attacker (with a valid local ftp account) can
execute arbitrary code, with UID of the running ftp daemon (most of the
time : root)
The problem is due to a combination of bugs, one located within the
function responsible for the globbing feature, which fails to properly
signal an error to its caller under certain conditions. The glob
function does not properly handle the string \"~{\" as an illegal
parameter. The other bug is at the caller, a command parser function,
that incorrectly handles the error status returned by the glob function
allowing the corruption of the process memory space.
Technical Description - Exploit/Concept Code:
=============================================
Tests were performed using wu-ftp server versions 2.6.1 and 2.7.0
snapshots
WU-FTPD server features globbing capabilities, allowing a user to
search pathnames matching patterns according to the rules used by the
shell. The feature does not use the glibc implementation of the glob()
function, instead it implements its own in the the glob.c file
This implementation fails to set the globerr variable under certain
circunstances, bypassing error checking after the call, and trying to
free an uninitialized memory address. This memory address is located in
the process heap and can be manipulated by the user, issuing especially
crafted commands beforehand to the server. This issue was found twice
in the source code.
The handling of the globbing metacharacters is done by the ftpglob()
function included in the glob.c file. The function is called for
example from ftpcmd.y line 1277 and line 1303 while processing
pathnames for restricted and non-restricted users beggining with a
\'/\' or a \'~\' character respectively.
if (restricted_user && logged_in && $1 && strncmp($1, \"/\", 1) == 0){
[...]
globlist = ftpglob(t);
[...]
}
else if (logged_in && $1 && strncmp($1, \"~\", 1) == 0) {
char **globlist;
globlist = ftpglob($1);
[...]
}
After that, the variable globerr is checked to handle any possible
error that could had happened during the globbing process, setting this
variable is responsability of the ftpglob() function.
Under certain circunstances not properly handled by the function,
globerr is not set even though an error condition is present
Being not initialized explicitly, globlist contains what was in the
heap before, which can be properly set with specially crafted requests
to the server.
As the globerr was not set properly, the function attempts to free the
provided pointer in ftpcmd.y line 1282 and line 1288.
if (globerr) {
reply(550, globerr);
$$ = NULL;
if (globlist) {
blkfree(globlist);
free((char *) globlist);
}
}
else if (globlist) {
$$ = *globlist;
blkfree(&globlist[1]);
free((char *) globlist);
}
As shown, during the processing of a globbing pattern, the Wu-Ftpd
implementation creates a list of the files that match. The memory where
this data is stored is on the heap, allocated using malloc(). The
globbing function simply returns a pointer to the list. It is up to the
calling functions to free the allocated memory.
If an error occurs processing the pattern, memory will not be allocated
and a variable indicating this should be set. The calling functions
must check the value of this variable before attempting to use the
globbed filenames (and later freeing the memory).
Under certain circumstances, the globbing function does not set this
variable when an error occurs. As a result of this, Wu-Ftpd will
eventually attempt to free uninitialized memory.
If this region of memory contained user-controllable data before the
free call, it is possible to have an arbitrary word in memory
overwritten with an arbitrary value. This can lead to execution of
arbitrary code if function pointers or return addresses are
overwritten.
Details of hwo to exploit this type of problems are in the public
domain and can be found in Phrack Magazine #57 article 9:
http://www.phrack.org/show.php?p=57&a=9
Unsuccessful explotation of the problem does not lead to denial of service
attacks as the ftp server continues normal execution, only the thread
handling the request fails, helping the attacker to success.
The following excerpt is a sample verification of the existence of
the problem:
ftp> open localhost
Connected to localhost (127.0.0.1).
220 sasha FTP server (Version wu-2.6.1-18) ready.
Name (localhost:root): anonymous
331 Guest login ok, send your complete e-mail address as password.
Password:
230 Guest login ok, access restrictions apply.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls ~{
227 Entering Passive Mode (127,0,0,1,241,205)
421 Service not available, remote server has closed connection
1405 ? S 0:00 ftpd: accepting connections on port 21
7611 tty3 S 1:29 gdb /usr/sbin/wu.ftpd
26256 ? S 0:00 ftpd:
sasha:anonymous/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
26265 tty3 R 0:00 bash -c ps ax | grep ftpd
(gdb) at 26256
Attaching to program: /usr/sbin/wu.ftpd, process 26256
Symbols already loaded for /lib/libcrypt.so.1
Symbols already loaded for /lib/libnsl.so.1
Symbols already loaded for /lib/libresolv.so.2
Symbols already loaded for /lib/libpam.so.0
Symbols already loaded for /lib/libdl.so.2
Symbols already loaded for /lib/i686/libc.so.6
Symbols already loaded for /lib/ld-linux.so.2
Symbols already loaded for /lib/libnss_files.so.2
Symbols already loaded for /lib/libnss_nisplus.so.2
Symbols already loaded for /lib/libnss_nis.so.2
0x40165544 in __libc_read () from /lib/i686/libc.so.6
(gdb) c
Continuing.
Program received signal SIGSEGV, Segmentation fault.
__libc_free (mem=0x61616161) at malloc.c:3136
3136 in malloc.c
Note that the segmentation fault is generated because the program is
trying to free() a user provided (and in this case invalid) memory
chunk referenced by the value 0x61616161 (or its ASCII equivalent
\'aaaa\', sent earlier in the session as the user password), this
should be enough hint on the existence and exploitability of the bug.
SOLUTION
Workaround
==========
To prevent exploitation of this bug it is advised to disable anonymous
FTP access until patches are applied. Notice that legit users with FTP
accounts can still exploit the problem even if anonymous access is
disabled. If legit ftp accoutn posse a security risk, FTP service
should be disabled completly until fixed packages are deployed.
Patch
=====
Multiple vendors and linux distributions released patched versions.
check their web sites for further information.
Source Patch
=============
Mark Canter released a patch for wu-ftpd :
--- glob.c.orig Sat Jul 1 14:17:39 2000
+++ glob.c Wed Nov 28 00:43:38 2001
@@ -298,7 +298,7 @@
for (lm = restbuf; *p != \'{\'; *lm++ = *p++)
continue;
- for (pe = ++p; *pe; pe++)
+ for (pe = ++p; *pe; pe++) {
switch (*pe) {
case \'{\':
@@ -314,11 +314,19 @@
case \'[\':
for (pe++; *pe && *pe != \']\'; pe++)
continue;
+ if (!*pe) {
+ globerr = \"Missing ]\";
+ return (0);
+ }
continue;
}
+ }
pend:
- brclev = 0;
- for (pl = pm = p; pm <= pe; pm++)
+ if (brclev || !*pe) {
+ globerr = \"Missing }\";
+ return (0);
+ }
+ for (pl = pm = p; pm <= pe; pm++) {
switch (*pm & (QUOTE | TRIM)) {
case \'{\':
@@ -352,19 +360,18 @@
return (1);
sort();
pl = pm + 1;
- if (brclev)
- return (0);
continue;
case \'[\':
for (pm++; *pm && *pm != \']\'; pm++)
continue;
- if (!*pm)
- pm--;
+ if (!*pm) {
+ globerr = \"Missing ]\";
+ return (0);
+ }
continue;
}
- if (brclev)
- goto doit;
+ }
return (0);
}
@@ -416,11 +423,10 @@
else if (scc == (lc = cc))
ok++;
}
- if (cc == 0)
- if (ok)
- p--;
- else
- return 0;
+ if (cc == 0) {
+ globerr = \"Missing ]\";
+ return (0);
+ }
continue;
case \'*\':
TUCoPS is optimized to look best in Firefox® on a widescreen monitor (1440x900 or better).
Site design & layout copyright © 1986-2025 AOH