March 2015 security vulnerability

From RavenWiki
Revision as of 10:37, 13 March 2015 by jw35 (talk | contribs) (Created)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search

In March 2015 a security vulnerability was discovered in both the Apache module (mod_ucam_webauth) and the example PHP code (ucam_webauth.php) used to interface to Raven. Similar vulnerabilities may exist in Raven agents for various environments which have been written outside UIS. The UIS's Raven Java Toolkit, the Raven support in the UIS Drupal module, and the Raven Shibboleth interface are not vulnerable.

The underlying problem is as follows. A Ucam WebAuth response message contains an identifier for the key used to sign the message. The affected code uses this identifier to construct the name of a file from which to read the key. The code doesn't apply sufficient checks the the ID, with the result that it could contain things like '\', '/', and '..' which allow directory traversal. In some circumstances an attacker could exploit this to create a forged response message signed with a key under their control which would still verify as correct. Such a forged message could contain any identity.

We believe this vulnerability would be difficult to exploit. mod_ucam_webauth does some checking which may mean that the vulnerability is limited to the Windows platform; ucam_webauth.php performs no checks other than those that might be implemented by PHP functionality such as the 'open_basedir' configuration setting.

Revised versions of mod_ucam_webauth and ucam_webauth.php are available and anyone relying on either of these is advised to upgrade. The revised mod_ucam_webauth is version 2.0.2 and is available from the Raven project site; the revised PHP library is version 0.52 and is available from the UCS git service. Please note that the PHP library is not part of the supported Raven service.

To help address this issue we've added a 'clarification' about the syntax of the key identifier to the Ucam Webauth specification, bringing it to version 4.0. This now requires that key identifiers consist only of a sequence of digits. The revised specification (v4.0) is available.

Ucam WebAuth modules for various environments which have been written outside UIS may have been based on the faulty code and may include the same vulnerability. Where we can identify faulty code we are attempting to contact relevant authors, but this is unlikely to be possible in all cases. Anyone depending on such modules is encouraged to review them.

UIS would like to thank Graham Rymer of the Cambridge Institute for Medical Research for identifying and reporting the problem. His original advisory, which contains additional details, appears below.

From: G. Rymer <gr348@cam.ac.uk>
To: cert@cam.ac.uk
Date: Sun, 08 Mar 2015 15:03:09 +0000
Subject: Vulnerability present in certain Raven WAAs.

Description:
----------------
Processing of WLS authentication response messages by some WAAs
introduces a path traversal vulnerability.

Impact:
------------
Under appropriate conditions, it is possible for an attacker to forge a
valid WLS authentication response which allows manipulation of all
response fields, including that Holy Grail, "principal". Owing to the
widespread deployment of various unregistered Raven WAAs, protecting a
variety of web applications and services, the impact of a successfull
exploit is hard to understand, but could of course in the worst case be
very severe.

Notes:
---------
This message has been sent to CamCERT so that they may issue an alert to
University technical staff who may have deployed vulnerable modules, and
also manage the remedition of the stated vulnerabilities. It has been
sent to the authors/maintainers of the affected code too, since I expect
they will be interested, even if they no longer plan to develop their
respective WAAs. It has also been copied to Dr Markus Kuhn of the
Computer Laboratory, who I noted has expressed an interest in augmenting
the WLS in the past, and might be interested in this sort of thing [9].
At the very least, it may provide for an interesting discussion at the
weekly Security Group meeting on Friday afternoon if there are no more
interesting topics for debate. I have decided not to publish this
information on the mailing list 'cs-raven-discuss' yet, as I simply
don't know who might subscibe to that list (such information only being
available to the list's administrators).

* * * * *

Case 1, The UcamWebauth PHP class[1]:
------------------------------------------------------

This WAA does not make any attempt to sanitise input, we used the
following PHP script as a target for testing:

<?php

include_once 'ucam_webauth.php';

$testhostname = 'arcane.local';

$webauth = new Ucam_Webauth(array(
        'auth_service' =>
'https://demo.raven.cam.ac.uk/auth/authenticate.html',
        'clock_skew' => 600,
        'cookie_key' => 'abcdefgh',
        'cookie_name' => 'Ucam-Webauth-Session-PHP',
         'hostname' => $testhostname,
         'key_dir' => '/srv/http'
));

$complete = $webauth->authenticate();

if(!$complete) exit();

if($webauth->success()) {
        echo 'SUCCESS - ' . $webauth->principal();
} else {
        echo 'FAIL - ' . $webauth->status() . ': ' . $webauth->msg();
}

?>

We also commented out the 'open_basedir' option from the file
'/etc/php/php.ini' on our test server (of course this is not
recommended, and should be considered in the documentation for deploying
this WAA), to demonstrate a more severe impact. A crafted WLS
authentication response similar to the following will allow an attacker
to select an alternative key on the target host's filesystem:

localhost/?WLS-Response=3!200!!20150308T120000Z!0123456789-01234-0!http:%3A%
2F%2Flocalhost%2F!test0001!current!pwd!!36000!!/../../etc/ssl/certs/mychoice
!SIG...

When the WAA constructs the path to pass to fopen(), it does the
following:

        $key_filename = $this->key_dir . '/' . $key_id . '.crt';

In this case, our crafted '$key_id' parameter will force the WAA to
validate the signature trailing the WLS authentication response using
the certificate '/etc/ssl/certs/mychoice.crt'. This could be from a
"well known" certificate pair present on the target host (ie. the UIS
VPN service client certificate[2], or perhaps a test certificate
included with some other software distribution like Node.js[3]). If
fopen() is allowing the "http://" URL scheme, then an attacker could,
assuming that 'key_dir' was set to NULL, force the WAA to use a
certifcate provided by the attacker for download from an auxiliary
server! This circumstance is, of course, deeply undesirable.

It's also worth noting that NULL injection is possible, ie. adding a
trailing "%00" to the supplied "$key_id" parameter could allow for the
convenient removal of the trailing ".crt" which is appended to the path
by the WAA.

Mitigation for this attack is already present in the mod_ucam_webauth
module for Apache, but as we will discuss next, this implementation is
also flawed.

Case 2, The mod_ucam_webauth C module for Apache[4]:
----------------------------------------------------------------------------
-

Line number 2689 of mod_ucam_webauth.c looks like this:

        msg = apr_psprintf(r->pool,"WLS response contains invalid key ID
(contains '/') %s", kid);

Although some effort has clearly been made to mitigate the path
traversal vulnerability described earlier, this code is platform
specific, and will only work on platforms using a forward slash as a
directory seperator in paths. Additionally, this module is designed to
be portable to the Windows platform, which of course uses backward
slashes for seperating directories in paths. A pre-compiled Windows
binary is made available by UIS [5]. This WAA prepares the path to be
passed to fopen() like this:

        key_full_path = ap_make_full_path(r->pool, key_path,
apr_pstrcat(r->pool, "pubkey", key_id, NULL));

It is inconvenient for an attacker that 'pubkey' is prepended to the key
name. However, if (for the sake of a quick example) there is a directory
named pubkey, then path traversal is still trivial. It is not clear
whether this prepending of 'pubkey' is intended to help mitigate such
vulnerabilities, or if it is "a bit of luck". I choose to believe the
former, since the rest of the module is very well written.

We have tested mod_ucam_webauth on the Windows platform, and can confirm
that path traversal is indeed possible. In some ways, it is easier than
with PHP, as the C module can potentially trawl anywhere on the
filesystem readable by the webserver process, and is not inhibited by
PHPs 'open_basedir' option. As an example, a crafted WLS authentication
response similar to the following will allow an attacker to select an
alternative key on the target host's filesystem:

localhost/?WLS-Response=3!200!!20150308T120000Z!0123456789-01234-0!http:%3A%
2F%2Flocalhost%2F!test0001!current!pwd!!36000!!\\..\\..\\..\\mychoice!SIG...

Our test host has a directory named
"C:\Apache24\conf\webauth_keys\pubkey". Using the compiled defaults, the
key directory on our test host will be "C:\Apache24\conf\webauth_keys".
Our injected path will force the WAA to validate the signature trailing
the WLS authentication response using the certificate ''C:\mychoice".

Mitigation:
--------------

This is a well understood and documented class of attack [6]. It can be
mitigated with proper attention to input validation [7]. These results
were unexpected. We were actually researching poor security in session
management, and did not expect the discovery of vulnerabilties in the
initial authentication process to be so trivial.
I would like to suggest that it is not necessary, and potentially
hazardous, to allow the WLS authentication response to specify the key
to be used in validating its own message! This decision should ideally
be taken in a hard coded fashion by the WAA, and trust established
through some other mechanism. The documentation for the WAA->WLS
communication protocol imposes this unfortunate requirement:

"[REQUIRED if a signature is present] A string which identifies the RSA
key which will be used to form a signature supplied with the response.
Typically these will be small integers."[8]

Although any WAA is free to remain non-compliant, it would perhaps
benefit downstream security of poorly implemented WAAs if such a
requirement was not imposed by the official definition of the protocol.
One might naively believe that a negative aspect to this approach would
be that the WLS cannot "revoke" a compromised key, which could allow an
attacker a window of opportunity to attack a compromised system until a
local administrator removes such a key. However, this makes no
difference to an atttacker, since the WLS cannot automatically remove a
compromised key from a client system physically. The only advantage is
that an administrator might get a "heads up" from failing
authentications of legitmate users, who would presumably inform him/her
through some channel. One must certainly weigh up such considerations
before committing to the idea of a steckered Raven protocol.

Best,
Graham.

References:
----------------
[1] https://wiki.cam.ac.uk/raven/PHP_library, accessed 8th March 2015.
[2] http://www.ucs.cam.ac.uk/vpn/vpn-client-id.p12, accessed 8th March
2015.
[3] https://github.com/joyent/node/blob/master/test/fixtures/agent.crt,
accessed 8th March 2015.
[4] http://raven.cam.ac.uk/project/apache/, accessed 8th March 2015.
[5]
http://raven.cam.ac.uk/project/apache/files/Windows/mod_ucam_webauth-2.0.1.z
ip,
accessed 8th March 2015.
[6] https://www.owasp.org/index.php/Path_Traversal, accessed 8th March
2015.
[7] https://www.owasp.org/index.php/Category:Input_Validation, accessed
8th March 2015.
[8] http://raven.cam.ac.uk/project/waa2wls-protocol.txt, accessed 8th
[9] https://wiki.cam.ac.uk/raven/Automated_access_by_scripts, accessed
8th March 2015.