 |
|
 |
by Tan Chew Keong
Release Date: 16 Dec 2004
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).
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
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.
- Upgrade to version 0.9.11.
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.
For further questions and enquries, email them to the following.
Overall-in-charge: Tan Chew Keong
webmaster@security.org.sg
|
 |