[NEWS] Multiple Vulnerabilities in WASD HTTP Server for OpenVMS

From: support@securiteam.com
Date: 10/01/02


From: support@securiteam.com
To: list@securiteam.com
Date: Tue,  1 Oct 2002 20:46:01 +0200 (CEST)

The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com
- - promotion

When was the last time you checked your server's security?
How about a monthly report?
http://www.AutomatedScanning.com - Know that you're safe.
- - - - - - - - -

  Multiple Vulnerabilities in WASD HTTP Server for OpenVMS
------------------------------------------------------------------------

SUMMARY

WASD VMS Hypertext Services is a popular HTTP server for OpenVMS released
under the GNU GPL. See <http://wasd.vsm.com.au/WASD/>
http://wasd.vsm.com.au/WASD/ The default installation of the WASD server
allows:
 - Universal directory traversal.
 - Instant access to the entire web server tree.
 - Trivial bypassing of access control rules.
 - Getting the location of the document root.
 - Read access to the whole web server configuration.
 - Read access to all web server logs.
 - Disclosure of directories supposed to be hidden.
 - Getting the list of all CGI scripts.
 - Getting the sources of all CGI scripts.
 - Read access to OpenVMS system files.
 - User home directories might be readable.
 - One very serious flaw in a CGI script enabled by default.
 - Some problems with other cgi-scripts enabled by default.

DETAILS

Vulnerable versions:
 * WASD 7.1, 7.2 (up to 7.2.3), 8.0, and possibly earlier versions.

Immune systems:
WASD 8.1, and the update versions 8.0.1 and 7.2.4, will fix the known
vulnerabilities.

Severity:
Critical
When combining different vulnerabilities, a remote SYSTEM (root)
compromise is possible in a default installation of WASD versions up to
8.0.

Even without compromising the system, important files that are supposed to
stay confidential can easily be read remotely.

Description:
The main problems are:
 - The default configuration is much too liberal.
 - The access control rules can be trivially bypassed.
 - CGI scripts are run by default under the identity of the main server.

There are also problems with some CGI scripts provided by default, at
least one of which is very serious.

The default configuration is much too liberal
The built-in "tree" script
By default the entire directory tree of the web server can be seen with
http://webserver/tree/

Documentation: <http://wasd.vsm.com.au/ht_root/doc/env/env_0400.html#43>
http://wasd.vsm.com.au/ht_root/doc/env/env_0400.html#43

Example:
http://wasd.vsm.com.au/tree/

"/*.*" directory traversal
Universal directory traversal is built-in with
http://webserver/dirname/*.* even if there is a page /dirname/index.html

Documentation: <http://wasd.vsm.com.au/ht_root/doc/env/env_0400.html>
http://wasd.vsm.com.au/ht_root/doc/env/env_0400.html

The built-in "upd" script
A nice graphical interface for directory traversal is built-in with
http://webserver/upd/dirname/ even if there is a page /dirname/index.html

Documentation: <http://wasd.vsm.com.au/httpd/-/updhelp.html>
http://wasd.vsm.com.au/httpd/-/updhelp.html

The built-in search
All documents can be searched by default.

Documentation: <http://wasd.vsm.com.au/ht_root/doc/env/env_0700.html#97>
http://wasd.vsm.com.au/ht_root/doc/env/env_0700.html#97

Most of the server root is accessible by default
The document root is the main server root, which includes everything
(configuration files, scripts, executables, etc...). Directory traversal
is enabled on most of the directories and access to the other directories
is possible anyway (see later).

The WASD documentation states that the liberal option was on purpose:
<http://wasd.vsm.com.au/ht_root/doc/htd/htd_0600.html#98>
http://wasd.vsm.com.au/ht_root/doc/htd/htd_0600.html#98

"The default configuration is fairly liberal, providing information of use
in a technical environment, but that may be superfluous or
less-than-desirable in other, possibly commercial environments."

OpenVMS has a reputation of being a very secure operating system. This may
explain why VMS system administrators may have a false sense of security
when installing the WASD web server and leave the default configuration
almost untouched.

The default configuration in WASD 8.1 will be much more restrictive.

The access control rules can be trivially bypassed
All the liberal features described above can be used to bypass the few
restrictions set by the web server.

Bypassing access restrictions set by the web server
The configuration file httpd$map.conf contains rules such as:

 pass /ht_root/wwwroot*
 fail /ht_root/*
 fail /-/*

In this example, the server root is ht_root and the document root is
wwwroot. The "fail" rules attempt to restrict access to the server root
but can be trivially bypassed with:
http://theserver/ht_root/wwwroot/-/*.*

(Note: "-" is the VMS equivalent of ".."). So the only real protection
comes from the directory protections and ACLs (access control lists)
imposed by the operating system. (See section "Solutions" below.)

The location of the document root can easily be obtained
The location of the document root can easily be obtained with the "where"
built-in script.

Documentation: <http://wasd.vsm.com.au/ht_root/doc/htd/htd_2100.html#364>
http://wasd.vsm.com.au/ht_root/doc/htd/htd_2100.html#364

Even if the "where" script is not enabled, the "404 not found" message
gives away the document root. On a server where the document root was
(correctly) not the entire web server root (logical name HT_ROOT), the
real document root could still be obtained with http://theserver/notfound
which gives "Document not found ... /ht_root/wwwroot/notfound" This allows
getting the entire web server root with
http://theserver/ht_root/wwwroot/-/*.* as described above.

The full physical path may also be given hidden as a comment in the HTML
returned in the "404 not found" message:
         <!-- sts: %X00018292 "$1$DUA2:[HT_ROOT.][WWWROOT]NOTFOUND" -->

The full web server configuration can easily be obtained
The web server configuration file in ht_root/local/httpd$map.conf is
generally supposed to be protected by a fail rule:

 fail /ht_root/local/*

However, this can often be trivially bypassed as shown above:
http://theserver/ht_root/wwwroot/-/local/httpd$map.conf

On one of the machines tested, there was even no "fail" rule so the
configuration could be obtained directly as
http://theserver/local/httpd$map.conf

The configuration file httpd$map.conf gives a lot of information to
intruders, in particular all the access control rules, all the script
directories, all the virtual domains handled, all the accessible
directories not under ht_root, etc...

All the web server logs can easily be obtained
This is just a variation on the above. There is generally a rule

 fail /ht_root/log/*

However, all the logs can generally be obtained with
http://theserver/upd/ht_root/src/-/log/ unless they are protected with
adequate ACLs.

If the logs are protected by ACLs but you have a user account on the
machine hosting the web server, then some of the logs may still be
obtained because the last request may be available in the logical name
(environment variable) HTTPD80$REQUEST :

 $ show log HTTPD80$REQUEST
 "HTTPD80$REQUEST" = "08
11:56:42.200.430.5287.0.9000.http://theserver:80.ip.address.of.caller.GET
/filename"

The logical name is dynamically updated at each request. However, this was
observed on only one system with an old version of WASD so the problem may
be fixed in 8.0.

The "tree" built-in script shows directories supposed to be hidden
The server logs are actually in a subdirectory /ht_root/log/server/ Since
there is generally a fail rule for /ht_root/log/* the subdirectory server
is supposed to be hidden, but the "tree" built-in script happily shows it:
http://theserver/tree/ht_root/

Directory protection can be bypassed anyway
Some directories are better protected and are not even visible with the
"tree" built-in scripts. On one tested site, the directory
/ht_root/script_local/ exists but cannot be seen with
/ht_root/script_local/*.* or with /tree/. This site has probably used the
following configuration described in
<http://wasd.vsm.com.au/ht_root/doc/htd/htd_0600.html#99>
http://wasd.vsm.com.au/ht_root/doc/htd/htd_0600.html#99

[DirAccess] - Make "disabled" to completely remove the ability to generate
directory listings under any circumstances.

However the search feature comes to rescue, and the directory (together
will all its scripts, see next section) can still be seen with
http://theserver/.../*.com?search=$

If even the standard search feature has been disabled, one can also try
the default glist script, which is supposed to give only a list of images
but also gives all subdirectories:
http://theserver/cgi-bin/glist/ht_root/?list=now

In any case, on this particular server the directory script_local is given
in /robots.txt so it is not difficult to see that it exists.

The list of CGI scripts can easily be obtained
It is not possible to see the list of CGI scripts with the URL
http://theserver/cgi-bin/*.* however the scripts are generally in
ht_root/script/ or ht_root/script_local. If a configuration rule is
supposed to block access to these directories (either because the document
root is correctly separated from the server root, or because there is an
explicit rule blocking script/*), it is generally possible to get the list
of scripts and their sources with an URL such as:

http://theserver/ht_root/wwwroot/-/script_local/*.*

For CGI scripts of users, which can be run with URL
http://theserver/~username/cgi-bin/scriptname it is a bit less trivial to
obtain the list of scripts because the obvious attempts fail:
http://theserver/~username/cgi-bin/*.*

However, the following generally works:
http://theserver/~username/xxx/-/cgi-bin/*.*

Where xxx does not have to be an existing directory.

If it does not work, then the search feature can generally be used:
http://theserver/~username/.../*.com?search=$

(Note: on OpenVMS "..." indicates directory recursion). This searches all
the *.com scripts for the character $ which always starts a command on
OpenVMS, and so gives as a result the full list of all .com scripts under
all subdirectories of the home directory. It is even possible to search
*.* instead of *.com.

The sources of CGI scripts can easily be obtained
After the list of scripts has been obtained as above, it is trivial to get
the sources of the scripts by clicking on a link. For general server
scripts, the link can be of the form:
http://theserver/ht_root/wwwroot/-/script_local/scriptname

For user scripts obtained by the search feature, the link is:
http://theserver/extract/~username/cgi-bin/scriptname.com?highlight=$

Here "extract" is a script provided by default by WASD. It allows getting
the source of a script instead of executing it, even if the directory
containing the script is named cgi-bin.

OpenVMS system files can generally be read
On several tested sites, a configuration rule is supposed to give access
to only a selected portion of system files:
 pass /sys$common/syslib/* /sys$common/syslib/*

However other system files can easily be read, for example:
http://theserver/sys$common/syslib/-/sysmgr/systartup_vms.com

User home directories might be readable
It is common practice to map URL http://theserver/~username/ to a
subdirectory /user_disk/username/web/ of the home directory
/user_disk/username/. However, if the OpenVMS protections and ACLs on the
home directory are not set correctly, it is possible to traverse it with:
http://theserver/~username/-/*.*

Actually, this often returns an error because of a strange mapping rule:
 pass /*/-/* /ht_root/runtime/*/*

However, it is easy to work around this rule with:
 http://theserver/~username/x/--/*.*

Where x does not have to be the name of an existing directory, and "--"
represents for VMS the equivalent of "../.."

In one of the sites tested, there was even no mapping to a subdirectory so
the whole user home directory was available with
http://theserver/~username/*.*

CGI scripts are run by default under the identity of the main server
By default the server runs the image httpd.exe (or httpd_ssl.exe) under
the identity of user http$server. CGI scripts are also run by default
under the same identity. Thus, a flaw in one CGI script can affect the
entire server.

On Unix, the main server is typically run as root but CGI scripts are
typically run under user "nobody". Thus, a bad script cannot affect the
entire server.

The WASD server allows running CGI scripts as a user other than
http$server. This will be the default in WASD 8.1.

Problems with some CGI scripts enabled by default
Jean-loup Gailly has not studied all scripts provided in a default
installation of WASD. But at least one is very dangerous and there are
some bugs in others.

Write to an arbitrary file on the web server
One script enabled by default allows writing contents of the attacker's
choice to an arbitrary file on the server, as long as the VMS ACLs allows
it. This flaw can be exploited to get a remote SYSTEM (root) compromise.

Given the severity of this flaw, no details are given here. See the
"Solutions" section below for temporary workarounds.

Severe leakage of information in cgi_process.com
Running http://theserver/cgi-bin/cgi_process gives a *lot* of useful
information for an intruder. In particular, it gives all the privileges
owned by the script while running. (For Unix users: a script run with
privileges is equivalent to a setuid or setgid program, but with much
finer control on the actions allowed for the program.)

On one system, the script could be run with the SETPRV privilege, which is
equivalent to setuid root on Unix. This tells an intruder that efforts
should be concentrated on this particularly vulnerable server.

Format string bug in PerlRTE_example1.pl
See <http://wasd.vsm.com.au/ht_root/src/perl/readmore.html>
http://wasd.vsm.com.au/ht_root/src/perl/readmore.html for a description of
this script and its sources. It contains in particular:
    printf ("$name=\"$ENV{$name}\"\n");

The variable $name comes from the user and is not filtered, so a classic
format string attack is possible. For example:
  http://wasd.vsm.com.au/plrte/PerlRTE_example1/%25x%25x%25x

(where %25 is the hex encoding of the character '%') gives:

   PATH_INFO="/000"
   PATH_TRANSLATED="HT_ROOT:[000000]000"
   REQUEST_URI="/plrte/PerlRTE_example1/ 0 0 0"

Where the number of zeroes is the number of %x format indicators. This bug
is probably not exploitable, but this should be checked.

This script also gives away a lot of potentially useful information for an
intruder (all logical names).

Potential denial of service in print.com
The CGI script print.com allows printing a file on the server from a
remote location. This script is enabled by default. The source is
available at http://wasd.vsm.com.au/script/print.com This script attempts
to restrict the IP addresses allowed to print:

 $ HPRINTS_ALLOWED = "131.185.250.*"

Anyone in this IP range can force the printer to run out of paper. Anyway,
it should be fairly easy to spoof the source IP address.

Solutions:
The WASD documentation has a section "Securing the site":
<http://wasd.vsm.com.au/ht_root/doc/htd/htd_0600.html#98>
http://wasd.vsm.com.au/ht_root/doc/htd/htd_0600.html#98

This is essential reading for any administrator of a WASD server. However,
some of the recommendations are not effective. In particular the example
given in section "Package tree" to block all access to the /ht_root/ tree
except for selected areas, does not work correctly for WASD versions up to
8.0.

Here is a list of minimum recommendations, which can be put in place even
with the existing versions WASD (up to 8.0). Such recommendations might
seem obvious for Apache users, but unfortunately, many of the WASD sites
that were tested did not follow these basic recommendations.

Check for new WASD versions at <http://wasd.vsm.com.au/WASD/>
http://wasd.vsm.com.au/WASD/

At the time of writing this advisory, version 8.1 of WASD is in
preparation. It will fix all the known security problems, provide from
installation a directory structure and associated permissions facilitating
minimum necessary upward security adjustments, and use much more
restrictive default access rules than previous versions.

An advisory written by the WASD author should be available at
<http://wasd.vsm.com.au/ht_root/doc/misc/wasd_advisory_020925.txt>
http://wasd.vsm.com.au/ht_root/doc/misc/wasd_advisory_020925.txt

Existing versions 8.0 and 7.2 will each have an update kit available
(8.0.1 and 7.2.4 or later). These will include a server with fixes for all
known security issues and a script install_secure.com that adjusts the
existing directory structure and permissions to conform to that
implemented for 8.1.

If these updates and/or version 8.1 or later is not available or not
applicable to a given site, then check for a kit that provides just the
install_secure.com script. This can be used standalone on 7.x and 8.0
installations for significant improvements to site security.

If none of these are available or applicable to a given site, then take at
least the minimum precautions described below in sections 5.2 to 5.6.

Use a separate document root, not the whole web server root
Put the document root in /ht_root/wwwroot, not /ht_root, with mapping
rules such as:
 pass /* /ht_root/wwwroot/*
 fail /ht_root/*

You can add a rule such as
 fail /-/*
But unfortunately, it will not be very effective because it can be
trivially bypassed with all versions of the WASD server up to 8.0.

Use a subdirectory for a user document root, not the home directory
Use rules such as:
 user /~*/* /user_disk/*/web/*
 redirect /~* /~*/

Set files protections and ACLs correctly
Since the WASD access restrictions can be bypassed, the only effective
protection is that provided by the system itself, OpenVMS. The web server
runs by default as user http$server, so make sure that directories
supposed to be protected are not readable by this user. Take at least the
following minimum precautions:

 . Make sure that all directories under ht_root are owned by user SYSTEM,
not by user HTTP$SERVER. Add specific ACLs for directories and files that
must be readable or writable by HTTP$SERVER, but only these:

$ set file /owner=system /prot=(s:rwed,o:rwed,g,w) -
 ht_root:[000000]local.dir, ht_root:[local...]*.*;* , -
 ht_root:[000000]http$server.dir, ht_root:[http$server...]*.*;*

$ set security /acl=((ident=http$server,access=e) /delete=all -
 ht_root:[000000]local.dir

$ set security /acl=((ident=http$server,access=r+e) /delete=all -
 ht_root:[local]*.com;*

$ set security /acl=((ident=http$server,access=r+e) /delete=all -
 ht_root:[http$server]*.com;*

Be particularly careful about ACLs on files in directory [local]. Only the
com files there should be readable by http$server; the rest contains very
sensitive information.

 . To prevent all the different ways of reading scripts, set protection
Execute only instead of Read+Execute on all essential scripts (and delete
all other scripts as described below). Check at least the directories
/script, /script_local, /vax and /axp, plus any other directories
mentioned in the logical name CGI-BIN.

$ set file /owner=system /prot=(s:rwed,o:rwed,g,w) -
 ht_root:[000000]script*.dir, ht_root:[script*...]*.*;* , -
 ht_root:[000000]axp.dir, ht_root:[axp...]*.*;* , -
 ht_root:[000000]vax.dir, ht_root:[vax...]*.*;*

$ set security /acl=((ident=http$server,access=e) /delete=all -
 ht_root:[000000]script*.dir

$ set security /acl=((ident=http$server,access=e) /delete=all -
 ht_root:[script*]*.*;*

$ set security /acl=((ident=http$server,access=e) /delete=all -
 ht_root:[000000]axp.dir ! or vax.dir depending on architecture

$ set security /acl=((ident=http$server,access=e) /delete=all -
 ht_root:[axp]*.*;* ! or [vax]*.*;* depending on architecture

 . To prevent reading the web server logs, set ACLs to allow write-only
access for user http$server on directory [log] and its subdirectories.

 . To prevent all the forms of directory traversal, set protection Execute
only instead of Read+Execute for directories that must be protected from
traversal. You can also add rules in httpd$map.conf

 fail /tree/
 fail /tree/*
 fail /upd/*
 fail /where/*
 fail /query/*
 fail /extract/*

But do not rely only on these rules, set ACLs correctly first.

Remove all unused CGI programs
This is a basic principle, but unfortunately, it was not followed in any
of the tested sites: remove *all* unused CGI scripts and executables. Some
of the programs provided by default with the WASD server are very
dangerous. So check at least the directories script, script_local, axp and
vax (all under ht_root) and move anything that is unused somewhere outside
ht_root, with very strict ACLs.

If the machine hosting the web server has some untrusted users with local
accounts on the machine, then forbid execution of arbitrary CGI scripts in
~untrusted/cgi-bin with a rule such as:
 fail /~untrusted/cgi-bin/*

Put before the rule:
 exec /~*/cgi-bin/* /user_disk/*/cgi-bin/*

Or better, block CGI access to all local users.

Never run CGI scripts under the account of a privileged user
If you really need privileges in your CGI script, then force the https
protocol and force user authentication. Read the WASD documents
<http://wasd.vsm.com.au/ht_root/doc/htd/htd_1200.html>
http://wasd.vsm.com.au/ht_root/doc/htd/htd_1200.html

Never do user authentication without SSL (the https protocol).

Do not run CGI scripts as user http$server. Strictly speaking, this
account is not privileged, but since it is also used to run the main
server, faulty CGI scripts can cause more harm than unprivileged users.

If the machine hosting the web servers has untrusted local users with a
~username/cgi-bin directory, then it is preferable to either remove the
ability to run scripts there, or at least run the scripts as the user.
Running those scripts as user http$server lets the untrusted users do many
things to the web server, such as reading the server logs if ACLs are not
set correctly, or killing the main server process; it would be the
equivalent of giving the additional right [http$server] to the untrusted
users.

Examples of site weaknesses
Several WASD sites were used for testing the various weaknesses. An actual
intrusion was made on two systems only to check that it was indeed
feasible. The system administrators were warned immediately. On other
systems, the presence of the vulnerabilities was checked but was not used
for intrusion.

Site A
The first system compromise was not entirely due to weaknesses in WASD and
was only possible because of a flaw in an independent CGI script that is
not part of the WASD distribution. However, without the WASD
vulnerabilities, the faulty script would not have been found and its
source analyzed to find the weakness.

The system was rather well (but not perfectly) configured. But the system
administrator had left a faulty script in his cgi-bin directory. The home
directory was correctly protected by ACLs so even the WASD vulnerabilities
did not allow reading it. The list of scripts and their sources were
supposed to be protected by the WASD configuration, but it was very easy
to work around this using the "upd" and the "extract" built-in scripts as
described before.

There was another weakness in the WASD configuration: the script was run
under the identity of the owner of the script, which was the system
administrator. This account was not the predefined SYSTEM account but
still had many privileges. It was then possible to remotely run any
command with those privileges. The system administrator was told how the
compromise was done and how to fix the server.

Site B
The story is very similar, but in this case, a flaw in one of the scripts
provided by WASD was used. The flaw was particularly severe because the
particular configuration used at this site allowed some scripts to be run
under the identity of a system administrator, who had all privileges
(SETPRV, which is the equivalent of root). The system administrators were
warned about the flaw and fixed it immediately.

Sites C,D,E
On three different sites, all directories and files were owned by the user
that runs all CGI scripts. So these sites were particularly vulnerable:
any flaw in a script can immediately lead to a SYSTEM compromise because
the script has write access to everything. The system administrators have
been warned and the sites have been fixed.

Almost all sites
In almost all tested sites, it was very easy to be read access to
important configuration files that are supposed to stay confidential, and
to get the list and sources of all CGI scripts, including site-specific
scripts.

Conclusion
Do not blindly believe that, if something runs on OpenVMS, then it must be
secure. Common sense precautions such as not giving away the entire server
tree or all script sources, and checking user input in all CGI scripts,
must be taken even on OpenVMS.

If you are using WASD 8.0 or earlier, fix your configuration
*immediately*.

ADDITIONAL INFORMATION

This document is available at
 <http://jl.gailly.net/security/wasd-vuln-2002-09.txt>
http://jl.gailly.net/security/wasd-vuln-2002-09.txt

The information has been provided by Jean-loup Gailly.

========================================

This bulletin is sent to members of the SecuriTeam mailing list.
To unsubscribe from the list, send mail with an empty subject line and body to: list-unsubscribe@securiteam.com
In order to subscribe to the mailing list, simply forward this email to: list-subscribe@securiteam.com

====================
====================

DISCLAIMER:
The information in this bulletin is provided "AS IS" without warranty of any kind.
In no event shall we be liable for any damages whatsoever including direct, indirect, incidental, consequential, loss of business profits or special damages.



Relevant Pages

  • remote SYSTEM compromise in WASD OpenVMS http server
    ... WASD VMS Hypertext Services is a popular http server for OpenVMS ... - getting the sources of all cgi scripts ...
    (Bugtraq)
  • Re: Restrict FileSystemObject to its virtual dir
    ... not scripts run by the Web Server. ... Creating an Application Pool for each application, with a unique AppPool ... If you allow users to upload and run arbitrary code on the server, ...
    (microsoft.public.inetserver.iis)
  • Re: Restrict FileSystemObject to its virtual dir
    ... not scripts run by the Web Server. ... Creating an Application Pool for each application, with a unique AppPool ... If you allow users to upload and run arbitrary code on the server, ...
    (microsoft.public.inetserver.iis.security)
  • Re: Phishing - Linux boxes are vulnerable
    ... that they can notify their customers each time a security fix is made. ... People are trying to do complex things on the cheap. ... developed a web server architecture for customers, ... will need to inspect many scripts before making them executable. ...
    (Fedora)
  • Re: Advice on distutils and distribution policies
    ... These might be scripts that are modified as a ... > HTML and CSS files that are to be handled directly by the web browser is ... > directly by the web server) van be anywhere under /var, ... And this is the HTML one (which is a template that is used by the python ...
    (comp.lang.python)