`From: [email protected] [mailto:[email protected].
edu] On Behalf Of Gregory A Lundberg
Sent: Tuesday, March 23, 1999 10:44 AM
To: Russ Allbery
Cc: [email protected]; [email protected]
Subject: Re: FW: ftp exploit
>
>
On 23 Mar 1999, Russ Allbery wrote:
>
> > any comments?
>
> It's an exploit script for the path overflow bug that's already been
> announced by CERT, been on all the security lists, and has already
> been fixed in the latest version of every wu-ftpd variant that I'm
> aware of as well as being the impetus for the final mainline wu-ftpd
> release?
>
Correct. This is a full exploit against Redhat 5.2 (the original advisory
was based upon a test, not an exploit).
>
My comment: This posting proves why you need to keep up with the CERT
mailing list, if not Bugtraq and other lists. As often heppens, the
exploit followed the discovery of the vulnerability by several weeks.
While it sometimes happens that exploits are distributed before the daemon
authors are notified and public security announcement made, this was not
the case here.
>
>
>
My testing shows:
>
This is an exploit using the buffer overflow described in
>
CERT Advisory CA-99.03 - FTP-Buffer-Overflows
>
Available from htp://www.CERT.org/
>
It is directed solely at Redhat CD 4.2 Linux systems running a clean,
default install. It was not successfull on unclean 5.2 systems, the
pre-5.2 systems I tested on, or when I built the daemon by-hand instead of
using a Redhat (S)RPM. My testing showed, while none of the systems I
have available were exploitable, the exploit WOULD HAVE WORKED but failed
for identifiable reasons.
>
Given working code for Redhat 4.2, it should be a fairly simply matter to
port to non-Linux or non-5.2 systems.
>
>
>
WHO IS VULNERABLE
-----------------
>
- Systems running ALL versions of WU-FTPD _prior_ to 2.4.2 (final),
including all 2.4.2-beta versions, ARE VULNERABLE, except as noted
below:
>
- Systems with proper upload clauses are partially protected. Many
systems do not use proper upload clauses for real/guest users and are
NOT protected from abuse by their local users.
>
- Systems with proper permissions are partially protected. Most systems
do not use proper permissions for real/guest users since they would
prevent use by Telnet/SSH/Shell .. such systems are NOT protected from
their local users.
>
>
>
WHO IS NOT VULNERABLE
---------------------
>
- Systems running 2.4.2 (final) are protected against _this_ bug. Such
systems should upgrade to VR16 for maximum security; a number of other
bugs and security problems have been fixed in VR16.
>
- Systems running 2.4.2-beta-18-VR10 or later are protected. Anyone
running VR10 through VR13 should upgrade to VR14 or later at your
earliest convenience.
>
- Systems running BeroFTPD 1.2.0 or later are NOT vulnerable. All
BeroFTPD systems should upgrade to the current version (1.3.4) at their
earliest conenience. Anyone running a vulnerable system with NEWVIRT,
will want to immedeately upgrade to BeroFTPD.
>
>
>
The location of the latest version of wu-ftpd can be found in the
directory
>
ftp://ftp.vr.net/pub/wu-ftpd/
>
>wu-ftpd Resource Center: http://www.landfield.com/wu-ftpd/
>wu-ftpd FAQ: http://www.cetis.hvu.nl/~koos/wu-ftpd-faq.html
>wu-ftpd list archive: http://www.landfield.com/wu-ftpd/mail-archive/
>
>--
>
>Gregory A Lundberg Senior Partner, VRnet Company
>1441 Elmdale Drive [email protected]
>Kettering, OH 45409-1615 USA 1-800-809-2195
------------------------------------------------------------------------------
Date: Thu, 25 Mar 1999 22:17:33 -0500
From: Gregory A Lundberg <[email protected]>
To: [email protected]
Subject: Re: wu-ftpd overflow.
On Sun, 21 Mar 1999, CyberPsychotic wrote:
> (cc'ed to bugtraq since I haven't seen yet any patches fixing this
> problem were posted there)
Yes, the exploit recently posted to Bugtraq takes advantage of the
realpath() buffer overflows .. as they exist in the Redhat RPM version
shipped on their 5.<something> CD. The exploit may require some
modification to be successfully used against other Linux/Intel systems
and, of course, will need major changes to be used against other hardware
or software platforms.
About the exploit posted on Bugtraq: my read-through of the shows it does
use the vulnerability through the MKD command. You are correct that some
Academ beta versions do not use the source-provided vulnerable realpath()
function for MKD. ISTM it should be fairly easy to modify the exploit to
make use of other commands where a given Academ beta version _does_ use
realpath(). Remember, the exploit is an _example_ of the problem, it does
not reveal the true magnetude of the vulnerability. A positive test
proves vulnerability while a negative test proves nothing.
The vulnerable and non-vulnerable versions were outlined in the advisories
which _were_ posted on Bugtraq.
The realpath() problem was openly discussed on Bugtraq weeks (months? ..
I'd have to look through the Bugtraq archives again) before the release of
the advisories. The actively maintained versions of the wu-ftpd daemon
were immedeately corrected as a result of the realpath() vulnerability
discussions on Bugtraq, so they had been corrected for quite some time
prior to Netect's research indicating there may be a problem.
At the time of publication of the Netect/CERT Advisories, patches for
wu-ftpd were unnecessary since the current, maintained, versions were not
vulnerable.
My patch file for wu-ftpd, which corrects the problem, is presently 644162
bytes in length, fixes several hundred other problems with the daemon, and
is available via FTP from ftp://ftp.vr.net/pub/wu-ftpd/ for those silly
enough to want it (I rather doubt it Aleph would allow it through to the
Bugtraq the mailing list). I am not inclined to pull out the patches for
realpath() because the entire pile of male bovine by-product was replaced.
A patch file for the other major, maintained, version of wu-ftpd
(BeroFTPD) is not available at all. Since today it would probably run
well over 1 Meg, the maintainer sees no point in the fiction of
'patching'. He is also dis-inclined to pull out the realpath() changes
since he and I co-operated on the complete replacement of the function
(actually he did most of the initial work; I just debugged it).
At about the time of the Netect/CERT Advisorie Redhat released updated
RPMs for the vulnerable Academ 2.4.2-betas they distribute. I don't know
whether they released before or after, but I do recall it was just a few
hours before their availability was discussed on Bugtraq.
Other versions (from wu-stl and academ) are not actively maintained and
should not be used in production environments. Anyone running versions of
wu-archive / the wu-ftpd daemon older than Academ's 2.4.2-beta-18 has more
severe problems than this buffer overrun, so I see no point posting the
patch. For them the correct solution is either updating to a more current
version or manual operation of the power switch.
The only current version still vulnerable when the CERT advisory was
issued the Academ version 2.4.2-beta-18, which is (almost) not actively
maintained. A week or two following the CERT advisory Academ silently
released 2.4.2 (final).
My knowledge of the code, and my direct research indicates:
The 2.4.2 (final) version does not completely solve the problem. Nor
does your patch. (Nor, for that matter, does the Redhat patch but
that's a moot point since their patch does fix the problem for their
Linux systems.)
For systems using the realpath() function supplied with the source kit,
a patch will work to correct, or at least hide, most, if not all, of
the vulnerability. For other systems, whether or not the daemon is
vulernable depends upon whether or not your vendor-supplied realpath()
function is vulnerable (back to the original discussion on Bugtraq).
The only change here from my recommendations appearing in the Netect
and CERT advisories is that the number of potentially vulnerable
systems has been reduced by those using the daemon-supplied realpath()
function to only those with vendor-supplied vulnerable realpath()
functions.
To determine if your daemon uses the supplied function, look in
<wuftpd>/src/config/config.<ostype> for a line reading something like:
#define realpath realpath_on_steroids
If this #define does NOT appear, contact your vendor concerning the
vulnerability of the realpath() function, or upgrade to a more-current
version of the daemon (yes, there are versions much more current that
Academ's 2.4.2/final).
Those wishing further information may contact me via the wu-ftpd support
mailing list at mailto:[email protected] .. subscription and
unsubscription information for that mailing list are in the FAQ.
The location of the latest versions of wu-ftpd can be found in the
directory
ftp://ftp.vr.net/pub/wu-ftpd/
wu-ftpd Resource Center: http://www.landfield.com/wu-ftpd/
wu-ftpd FAQ: http://www.cetis.hvu.nl/~koos/wu-ftpd-faq.html
wu-ftpd list archive: http://www.landfield.com/wu-ftpd/mail-archive/
(The html version of the wu-ftpd list archive is
currently not working, use the Unix mailbox
format instead.)
--
Gregory A Lundberg Senior Partner, VRnet Company
1441 Elmdale Drive [email protected]
Kettering, OH 45409-1615 USA 1-800-809-2195
------------------------------------------------------------------------------
Date: Sun, 21 Mar 1999 18:21:22 +0500
From: CyberPsychotic <[email protected]>
To: [email protected]
Subject: wu-ftpd overflow.
~ Has some1 located the file/function where
~ the overflow takes place ?
Yes. I think overflow takes place is function realpath.c:
look at the end of the function realpath(), which first concatinates
everything together and then just does strcpy into result variable, which is
pointer to buffer sized of MAXPATHLEN. You could either owerflow workpath
variable in realpath, or, if your buffer is not too fat, it will be
overflowed later, when function makedir returns (called from ftpcmd).
in either case return address gets overflowed and it returns
nowhere (or to your exploit code if you put there such, no big deal).
I've made a couple of fixes to ftpd daemon to generate debugging info via
syslog, so here's what I have:
Mar 21 12:21:46 gear ftpd[21737]: ftpcmd:1294 (ftpcmd called makedir)
Mar 21 12:21:46 gear ftpd[21737]: before 3180 (calling realpath line 3128)
Mar 21 12:21:46 gear ftpd[21737]: overflow:180 (here overflow takes place)
Mar 21 12:21:46 gear ftpd[21737]: overflow:210 (again. It's being copied twice)
Mar 21 17:21:47 gear syslogd: Cannot glue message parts together
Mar 21 12:21:46 gear ftpd[21737]: after 3180 (realpath line 3128 returns)
/foo/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/AAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/AAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Mar 21 17:21:47 gear
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/AAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Mar 21 12:21:47 gear ftpd[21737]: exiting on signal 11
oops..... now it attempted to execute piece at 0x41414141 addy..
Some previous beta releases of wu-ftpd are NOT vulneriable
to this thing because they just don't call realpath function (which does
overflow) from makedir() function. Here's quick patch I've done to this
piece (cc'ed to bugtraq since I haven't seen yet any patches fixing this
problem were posted there):
--/cut here/--
--- ftpd.c.orig Mon Jul 6 15:14:25 1998
+++ ftpd.c Sun Mar 21 18:17:52 1999
@@ -3146,19 +3146,24 @@
if (mkdir(name, 0777) < 0) {
if (errno == EEXIST){
- realpath(name, path);
- reply(521, "\"%s\" directory exists", path);
+ if(realpath(name, path))
+ reply(521, "\"%s\" directory exists.", path);
+ else reply(521,"path too long.");
}else
perror_reply(550, name);
return;
}
- realpath(name, path);
/* According to RFC 959:
* The 257 reply to the MKD command must always contain the
* absolute pathname of the created directory.
* This is implemented here using similar code to the PWD command.
* XXX - still need to do `quote-doubling'.
*/
+ if(!realpath(name, path))
+ if (strlen(path)!=0)
+ reply(257,"\"%s\" directory created name truncated.",path);
+ else reply(500,"no directory created. Path too long.");
+ else
reply(257, "\"%s\" new directory created.", path);
}
--- realpath.c.orig Sun Mar 21 17:29:42 1999
+++ realpath.c Sun Mar 21 18:08:28 1999
@@ -40,6 +40,7 @@
#include <sys/stat.h>
#include <sys/param.h>
#include <string.h>
+#include <syslog.h>
#ifndef HAVE_SYMLINK
#define lstat stat
@@ -55,10 +56,10 @@
#endif
{
struct stat sbuf;
- char curpath[MAXPATHLEN],
- workpath[MAXPATHLEN],
- linkpath[MAXPATHLEN],
- namebuf[MAXPATHLEN],
+ char curpath[MAXPATHLEN+1],
+ workpath[MAXPATHLEN+1],
+ linkpath[MAXPATHLEN+1],
+ namebuf[MAXPATHLEN+1],
*where,
*ptr,
*last;
@@ -75,7 +76,7 @@
return(NULL);
}
- strcpy(curpath, pathname);
+ strncpy(curpath, pathname,MAXPATHLEN);
if (*pathname != '/') {
uid_t userid;
@@ -93,7 +94,7 @@
#else
if (!getwd(workpath)) {
#endif
- strcpy(result, ".");
+ strncpy(result, ".",MAXPATHLEN);
seteuid(userid);
enable_signaling(); /* we can allow signals once again: kinch */
return (NULL);
@@ -142,9 +143,13 @@
for (last = namebuf; *last; last++)
continue;
if ((last == namebuf) || (*--last != '/'))
- strcat(namebuf, "/");
- strcat(namebuf, where);
-
+ strncat(namebuf, "/",MAXPATHLEN-strlen(namebuf));
+ strncat(namebuf, where,MAXPATHLEN-strlen(namebuf));
+ if (strlen(namebuf)+strlen(where)>=MAXPATHLEN) {
+ syslog(LOG_DAEMON|LOG_NOTICE,"possible buffer overflow attempt");
+ return(NULL);
+ }
+
where = ++ptr;
if (lstat(namebuf, &sbuf) == -1) {
strcpy(result, namebuf);
@@ -163,8 +168,13 @@
if (*linkpath == '/')
*workpath = '\0';
if (*where) {
- strcat(linkpath, "/");
- strcat(linkpath, where);
+ strncat(linkpath, "/",MAXPATHLEN-strlen(linkpath));
+ strncat(linkpath, where,MAXPATHLEN-strlen(linkpath));
+ if (strlen(namebuf)+strlen(where)>=MAXPATHLEN) {
+ syslog(LOG_DAEMON|LOG_NOTICE,
+ "possible buffer overflow attempt");
+ return(NULL);
+ }
}
strcpy(curpath, linkpath);
goto loop;
`