Objectives About Us Sponsors News Past Events Contact Us
Login G-TEC CC Mirror Forums Links

 

 

SIG^2 Vulnerability Research Advisory

singapore Image Gallery Web Application v0.9.10 Multiple Vulnerabilities

by Tan Chew Keong
Release Date: 16 Dec 2004

Summary

singapore is yet another open source PHP based image gallery web application. What makes singapore different from the hundreds of other similar scripts is that it is specifically geared towards displaying art in an aesthetically pleasing fashion using a clean, uncluttered interface.

Multiple vulnerabilies were found in the image gallery web application including arbitrary file download, directory deletion and Cross-Site Scripting (XSS).

 
Tested System

singapore Image Gallery Web Application Version 0.9.10 on English Win2K IIS with PHP 4.3.4, 4.3.9
singapore Image Gallery Web Application Version 0.9.10 on Linux Apache/1.3.33 (Unix) PHP/4.3.9

 
Details

singapore is yet another open source PHP based image gallery web application. What makes singapore different from the hundreds of other similar scripts is that it is specifically geared towards displaying art in an aesthetically pleasing fashion using a clean, uncluttered interface.

Multiple vulnerabilies were found in the image gallery web application including arbitrary file download, directory deletion and Cross-Site Scripting (XSS).
 

1. Insufficient directory traversal check in thumb.php showThumb() method allows arbitrary file download.

The showThumb() method in thumb.php checks for directory traversal using the following code

  if(strpos($gallery.$image,'/../') !== false)
      die("Suspected security threat");

The following code is used to check that the requested file is an image file.

  //security check: make sure $image has a valid extension
  if(!$isRemoteFile && !preg_match("/.+\.(".$config->recognised_extensions.")$/i",$image))
      die("Specified file is not an image file");

Subsequently, the following code is used to construct the full pathname to the image file.

  $imagePath = $config->pathto_galleries."$gallery/$image";

It is possible to bypass these two checks to download the encrypted password file in /install_dir/data/users.csv.php. A demonstration URL is provided below.

   http://[hostname]/thumb.php?gallery=../data/users.csv.php%00&image=a.jpg

In this URL,

   $gallery = ../data/users.csv.php%00
   $image = a.jpg

This passes the first check since the concatenation of $gallery and $image does not contain '/../'. The image pathname is then "galleries/../data/users.csv.php%00/a.jpg". In this case, %00 is the NULL character and when this pathname is passed to readfile(), it is interpreted as "galleries/../data/users.csv.php".

Although PHP replaces the NULL character with '\0' (ASCII 0x5C, 0x30) when it is received in a GET/POST request, further analysis showed that in thumb.php, '\0' got translated back to the NULL character due to the use of stripslashes() before calling showThumb(). This is shown in the following code taken from thumb.php.

   //remove slashes
   if(get_magic_quotes_gpc())
     showThumb(stripslashes($_REQUEST["gallery"]),stripslashes($_REQUEST["image"]), $_REQUEST["width"], 
               $_REQUEST["height"], isset($_REQUEST["force"]));

On a Windows server, it is possible to bypass the directory traversal check by using blackward slashes for directory traversal. i.e. '\..\', or using triple-dots for directory traversal, '/.../'.

For example,

    http://[hostname]/thumb.php?gallery=..\..\winnt\setuplog.txt%00&image=a.jpg
http://[hostname]/thumb.php?gallery=../.../winnt/setuplog.txt%00&image=a.jpg

For these demonstration URL to work, you might need to set display_errors=off in php.ini

 
2. Insufficient filename check in admin.class.php addImage() function allows arbitrary file upload.

When performing a New Image upload, a logon user is allowed to specify the filename of the uploaded image file. This filename (sgFileName), together with the file data, is sent to the server via a POST request using multipart/form-data; The addImage() function checks that the specified filename is a valid image filename using the following code.

    //make sure file has a recognised extension
    if(!preg_match("/\.(".$this->config->recognised_extensions.")$/i",$image)) $image .= ".jpeg";

It is possible to bypass this check using NULL character in the filename. In addition, the code does not perform directory traversal checks. Hence, by using a specially crafted POST request, it is possible to upload a file with arbitrary extension to any writable directory on the web server. This may be exploited by a malicious logon user to upload arbitrary PHP scripts.

A sample of the POST request is located here.

Note that instead of sending the sgFileName parameter as part of the multipart form-data, it is sent as part of the URL (shown below). This allows the NULL character to be encoded using URL encoding.

    POST /admin.php?sgFileName=o.php%00.jpeg HTTP/1.0

This crafted filename satisfies the extension check, but is interpreted as o.php in the subsequent move_uploaded_file() call due to the NULL character. Although PHP will replace the NULL character with '\0', it was restored back to NULL due to the use of stripslashes() in the code.

 
3. Insufficient directory traversal check in admin.class.php allows deletion of arbitrary directory that the Windows web server has delete access to.

Before deleting a gallery, directory traversal is checked using the following code in deleteGallery().

    //check that there are no "../" references in the gallery name
    //this ensures that the gallery being deleted really is a 
    //subdirectory of the galleries directory 
    if(strpos($galleryId,"../") !== false) return false;

This function checks only for the forwardslash character. On Windows systems, backslashes are often used for directory traversal. It is possible for a user with gallery deletion rights to delete all files in the installation directory with the following request. Deletion of arbitrary directories that the web server has write access to is also possible.

    http://[hostname]/admin.php?action=deletegallery&gallery=.\..\.

 
4. Multiple Cross-Site Scripting (XSS) Vulnerabilities

Multiple XSS exists due to insufficient escaping of HTML special characters in various parts of the application.

a) Javascript may be supplied as the image name to index.php. Lack of escaping of HTML special characters when displaying the resulting error page causes the input to be interpreted as script on the victim's browser.

    http://[hostname]/index.php?gallery=.&image=<script>alert('XSS');</script>&lang=en_us

b) XSS also exists in the user management page. For example, a user may set his fullname to <script>alert('XSS');</script>. This script will execute when the admin user accesses the user management page. These javascripts may be crafted by a malicious user to steal the admin user's session cookie, etc.

Use htmlspecialchars() function to escape HTML special characters before displaying any user's input.
 

 
Patch

  1. Upgrade to version 0.9.11.

 
Disclosure Timeline

17 Nov 04 - Vulnerability Discovered.
17 Nov 04 - Initial Author Notification by Email.
17 Nov 04 - Initial Author Reply.
18 Nov 04 - Second Author Notification.
19 Nov 04 - Received patch from Author, but it does not work.
19 Nov 04 - Informed Author that patch does not work.
30 Nov 04 - Third Author Notification.
03 Dec 04 - Author provided fix.
16 Dec 04 - Public Release.

 

Contacts

For further questions and enquries, email them to the following.

Overall-in-charge: Tan Chew Keong


Updated: 16/12/2004
webmaster@security.org.sg