23.3. Common PHP-Nuke security vulnerabilities

It's instructive to take the time and have a look at PHP-Nuke's list of vulnerabilities (see Table 23-1). Even a superficial inspection reveals some common vulnerability patterns:

In the following we will examine them in more detail.

Table 23-1. List of PHP-Nuke security vulnerabilities

Description

Date

PHP-Nuke Path Disclosure Vulnerability

21.10.2003

Splatt Forum Cross-Site Scripting Vulnerability

19.07.2003

PHP-Nuke SQL injection

19.05.2003

Splatt Forum Cross Site Scripting

02.05.2003

PHP-Nuke Cross-Site Scripting

25.04.2003

PHP-Nuke Cross-Site Scripting

01.04.2003

PHP-Nuke SQL Injection

26.03.2003

PHP-Nuke Referer Cross-Site Scripting

19.03.2003

PHP-Nuke Path Disclosure

18.03.2003

PHP-Nuke Multiple SQL Injection Vulnerabilities

07.03.2003

PHP-Nuke Multiple SQL Injection Vulnerabilities

25.02.2003

PHP Nuke Avatar Scriptcode Injection

04.02.2003

PHP-Nuke mail CRLF injection

23.12.2002

PHP-Nuke execution of arbitrary code

17.12.2002

PHP-Nuke Cross Site Scripting

17.12.2002

PHP-Nuke Cross Site Scripting

25.11.2002

PHP-Nuke SQL injection resets passwords

01.11.2002

PHP-Nuke Cross Site Scripting

10.10.2002

Cross Site Scripting holes in Xoops, PHP-Nuke, NPDS, daCode, Drupal and phpWebSite

24.09.2002

23.3.1. Cross-site scripting with PHP-Nuke

A CSS vulnerability is caused by the failure of a site to validate user input before returning it to the client s web-browser. The essence of cross-site scripting is that an intruder causes a legitimate web server to send a page to a victim's browser that contains malicious script or HTML of the intruder's choosing. The malicious script runs with the privileges of a legitimate script originating from the legitimate web server (see Cross-Site Scripting Vulnerabilities). By failing to validate user input, the vulnerable site makes it possible for a malicious user to execute (“inject”) a script in the context of that site's process.

Here are some known examples of cross-site scripting with PHP-Nuke:

As you can see from the above examples, the only remedy to cross-site scripting problems is to write PHP code that validates user input (or, if you are the “viewer”, disable scripting altogether, although even this will not prevent the injection of malicious HTML, see Cross-Site Scripting Vulnerabilities).

23.3.2. SQL injection with PHP-Nuke

Interaction with relational databases takes place through a textual language, the Structured Query Language ('SQL'). The most recent standard is ANSI SQL-92 and forms the basis around which most SQL dialects are based today. See SQL syntax diagrams for a visualization of SQL syntax. Data extraction from the database takes place through a 'query', which is a collection of SQL statements. An SQL query returns the data in a so-called 'result set'.

SQL statements are divided into two general categories: those that can modify the structure (Data Definition Language statements, or 'DDL') and those that can manipulate the contents of databases (Data Manipulation Language statements, or 'DML'). SQL Injection occurs when an attacker is able to insert a series of SQL statements into a 'query' by manipulating data input into an application (see Advanced SQL Injection in SQLServer Applications).

The typical scenario of an SQL Injection goes like this: an SQL statement like (taken from mainfile.php)

SELECT active FROM ".$prefix."_modules WHERE title='$module'

is used to retrieve the 'active' column from the 'nuke_modules' table (assuming that $prefix is set to 'nuke' in config.php, see Section 3.7), returning in the 'result set' only the row that matches the module $module. An important point to note here is that the string literal '$module' is delimited with single quotes. Presuming that $module is taken from the URL or from user input and was not subjected to further scrutiny, one could use a “module name” of

' UNION ALL SELECT user_password FROM nuke_users WHERE "=' 

and the 'query string' would become:

SELECT active FROM ".$prefix."_modules 
WHERE title=" UNION ALL SELECT user_password FROM nuke_users WHERE "="

The database server would execute the first part

SELECT active FROM ".$prefix."_modules WHERE title="

and would find no modules with empty title. It would then combine[1] this empty result set with the outcome of

SELECT user_password FROM nuke_users WHERE "="

which selects all passwords (since the WHERE clause is tautologically true, comparing an empty string with itself), returning the “cartesian product” (UNION) of the two - i.e. the set of all passwords. If the outcome of such a query is supposed to be printed somewhere, the user will be able to see sensitive information.

If the “module name” passed on unchecked were

' ; DROP TABLES WHERE "='

the consequences would be catastrophic: the database server would execute

SELECT active FROM ".$prefix."_modules WHERE title=" ; DROP TABLES WHERE "="

Depending on the actual SQL query, you may have to try some of these possibilities for the WHERE clause:

' or 1=1--
" or 1=1--
or 1=1--
' or 'a'='a
" or "a"="a
') or ('a'='a

instead of

"='

The general rule is that to "break out" of the quotes and manipulate the SQL query, while maintaining valid SQL syntax, your query string must start with a quote and end in a WHERE clause that needs a query appended to it (see SQL Injection).

In PHP-Nuke, SQL injection has been reported in the following vulnerabilities:

23.3.3. Path disclosure with PHP-Nuke

Path disclosure is a vulnerability that enables a user to gain knowledge of the internal path structure of an installation. It affects not only PHP-Nuke, but almost all PHP scripts too. A typical path disclosure scenario goes as follows:

A user enters deliberately a value which is passed unchecked to the script. The value is crafted so as to cause an error in the PHP interpreter or the database server. The user's speculation is that the error message will contain valuable information about the paths of the given software installation.

As an example, the error could be something like:

Fatal error: Cannot redeclare theindex() in 
/mnt/be1/02/738/0004711/w3/htdocs/www.yoursite.net/index.php 
on line 7

Typically, error reporting is set to display the errors on the served page and the user would gain knowledge of the full path of the index.php script on the server. This may or may not worry you, but it is a good idea to keep undisclosed to malicious users. To achieve this, once a script is in production and displayed messages are no longer needed for debugging, they should be disabled.

Path disclosure with PHP-Nuke has been reported in the following cases:

23.3.4. Cross-site tracing with PHP-Nuke

A new vulnerability has been found in Microsoft's Internet Information Server (IIS) which allows the reading of cookies. This is potentially possible also on Apache. Since PHP-Nuke relies on the cookie mechanism (Section 23.4.5) for user authentication, it is important to know the risks emanating from this type of vulnerability. Here is the way it works, according a CERT advisory (see Microsoft Internet Information Server (IIS) vulnerable to cross-site scripting via HTTP TRACK method):

Microsoft IIS servers support the HTTP TRACK method. The HTTP TRACK method asks a web server to echo the contents of the request back to the client for debugging purposes. The TRACK request is not RFC compliant and not well documented.

The complete request, including HTTP headers, is returned in the entity-body of a TRACK response. This leads to a Cross-site Scripting attack. Using features that provide client-side HTTP protocol support, such as XMLHTTP ActiveX or XMLDOM scripting objects, a web site can cause browsers to issue TRACK requests. The site can read the TRACK response, including sensitive header information such as cookies or authentication data.

Because the TRACK method is similar to the TRACE method, when combined with cross-domain browser vulnerabilities (VU#244729, VU#711843, VU#728563), HTTP TRACK and client-side HTTP support can be leveraged by attackers to read sensitive header information from third-party domains. This technique has been termed "Cross-Site Tracing," or XST, in Cross-Site Tracing (XST), a report published by WhiteHat Security. Cross-site tracing is also described in a CERT advisory about Cross-Site-Tracing.

As noted in the report of WhiteHat, the technique can be used to bypass the HttpOnly cookie attribute introduced in Microsoft Internet Explorer 6.0 SP1. HttpOnly blocks script access to the cookie property (document.cookie), but does not prevent a scripting object from reading the cookie out of an HTTP TRACK response. In the White Paper of WhiteHat Security, this new method of Cross-Site-Scripting is explained in detail. The essence is that this technique

...is able not only to bypass the httpOnly mechanism present in i.e. 6 service pack 1, but in addition the ability to xss just about anything from just about anywhere. This technique allows client-side scripting languages, such as javascript, and possibly other client-side technologies like vbscript, flash, java, etc., the ability access http web authentication credentials, with the added bonus of achieving this result over ssl.

Normally, the cookie is sent back to the domain it belongs. But with this TRACE or TRACK HTTP method, it is possible to request a trace and the web server will send back all data, including the cookie! This is especially important for PHP-Nuke, since it relies on cookies for the authentication of its users.

To protect yourself, you should deactivate the TRACE HTTP method , if you are using Apache, and the TRACK HTTP method, if you are using IIS:

There is nothing you can do in the code of PHP-Nuke to avoid this vulnerability, however you should bear in mind when we talk about cookies Section 23.4.5 that a Cross-Site Tracing attack may steal the cookies of your PHP-Nuke too. See also Cross-site tracing attack via HTTP TRACK / TRACE method.

Notes

[1]

this kind of SQL injection needs a database capable of understanding the UNION clause (for MySQL at least v. 4.x)