Skip to content

Commit 70b1381

Browse files
committed
Adding Login Scanner for MyBook Live
This is a LoginScanner auxiliary module for Western Digital MyBook Live NAS devices as well as the spec for testing.
1 parent d1523c5 commit 70b1381

File tree

3 files changed

+144
-0
lines changed

3 files changed

+144
-0
lines changed
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
require 'metasploit/framework/login_scanner/http'
2+
3+
module Metasploit
4+
module Framework
5+
module LoginScanner
6+
7+
# Western Digital MyBook Live login scanner
8+
class MyBookLive < HTTP
9+
10+
# Inherit LIKELY_PORTS,LIKELY_SERVICE_NAMES, and REALM_KEY from HTTP
11+
CAN_GET_SESSION = true
12+
DEFAULT_PORT = 80
13+
PRIVATE_TYPES = [ :password ]
14+
15+
# (see Base#set_sane_defaults)
16+
def set_sane_defaults
17+
self.uri = "/UI/login" if self.uri.nil?
18+
self.method = "POST" if self.method.nil?
19+
20+
super
21+
end
22+
23+
def attempt_login(credential)
24+
result_opts = {
25+
credential: credential,
26+
host: host,
27+
port: port,
28+
protocol: 'tcp'
29+
}
30+
if ssl
31+
result_opts[:service_name] = 'https'
32+
else
33+
result_opts[:service_name] = 'http'
34+
end
35+
begin
36+
body = "data%5BLogin%5D%5Bowner_name%5D=admin&data%5BLogin%5D%5Bowner_passwd%5D=#{Rex::Text.uri_encode(credential.private)}"
37+
cli = Rex::Proto::Http::Client.new(host, port, {}, ssl, ssl_version)
38+
cli.connect
39+
req = cli.request_cgi({
40+
'method' => 'POST',
41+
'uri' => '/UI/login',
42+
'data' => body
43+
})
44+
res = cli.send_recv(req)
45+
print res
46+
if res && res.code == 302 && res.headers['location'] && res.headers['location'].include?('UI')
47+
result_opts.merge!(status: Metasploit::Model::Login::Status::SUCCESSFUL, proof: res.headers)
48+
else
49+
result_opts.merge!(status: Metasploit::Model::Login::Status::INCORRECT, proof: res)
50+
end
51+
rescue ::EOFError, Errno::ETIMEDOUT, Rex::ConnectionError, ::Timeout::Error
52+
result_opts.merge!(status: Metasploit::Model::Login::Status::UNABLE_TO_CONNECT)
53+
end
54+
Result.new(result_opts)
55+
end
56+
end
57+
end
58+
end
59+
end
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
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+
require 'metasploit/framework/credential_collection'
8+
require 'metasploit/framework/login_scanner/mybook_live'
9+
10+
class Metasploit3 < Msf::Auxiliary
11+
include Msf::Auxiliary::Scanner
12+
include Msf::Exploit::Remote::HttpClient
13+
include Msf::Auxiliary::Report
14+
include Msf::Auxiliary::AuthBrute
15+
16+
def initialize
17+
super(
18+
'Name' => 'Western Digital MyBook Live Login Utility',
19+
'Description' => 'This module simply attempts to login to a Western Digital MyBook Live instance using a specific user/pass.',
20+
'Author' => [ 'Nicholas Starke <starke.nicholas[at]gmail.com>' ],
21+
'License' => MSF_LICENSE
22+
)
23+
24+
register_options(
25+
[
26+
Opt::RPORT(80)
27+
], self.class)
28+
29+
register_autofilter_ports([ 80 ])
30+
31+
#username is hardcoded into application
32+
deregister_options('RHOST', 'USERNAME', 'USER_FILE', 'USER_AS_PASS', 'DB_ALL_USERS')
33+
end
34+
35+
def run_host(ip)
36+
cred_collection = Metasploit::Framework::CredentialCollection.new(
37+
blank_passwords: datastore['BLANK_PASSWORDS'],
38+
pass_file: datastore['PASS_FILE'],
39+
password: datastore['PASSWORD'],
40+
user_file: datastore['USER_FILE'],
41+
userpass_file: datastore['USERPASS_FILE'],
42+
username: 'admin',
43+
user_as_pass: datastore['USER_AS_PASS']
44+
)
45+
46+
scanner = Metasploit::Framework::LoginScanner::MyBookLive.new(
47+
host: ip,
48+
port: rport,
49+
proxies: datastore['PROXIES'],
50+
cred_details: cred_collection,
51+
stop_on_success: datastore['STOP_ON_SUCCESS'],
52+
connection_timeout: 10,
53+
user_agent: datastore['UserAgent'],
54+
vhost: datastore['VHOST']
55+
)
56+
57+
scanner.scan! do |result|
58+
credential_data = result.to_h
59+
credential_data.merge!(
60+
module_fullname: fullname,
61+
workspace_id: myworkspace_id
62+
)
63+
if result.success?
64+
credential_core = create_credential(credential_data)
65+
credential_data[:core] = credential_core
66+
create_credential_login(credential_data)
67+
68+
print_good "#{ip}:#{rport} - LOGIN SUCCESSFUL: #{result.credential}"
69+
else
70+
invalidate_login(credential_data)
71+
print_status "#{ip}:#{rport} - LOGIN FAILED: #{result.credential} (#{result.status})"
72+
end
73+
end
74+
end
75+
end
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
require 'spec_helper'
2+
require 'metasploit/framework/login_scanner/mybook_live'
3+
4+
describe Metasploit::Framework::LoginScanner::MyBookLive do
5+
6+
it_behaves_like 'Metasploit::Framework::LoginScanner::Base', has_realm_key: true, has_default_realm: false
7+
it_behaves_like 'Metasploit::Framework::LoginScanner::RexSocket'
8+
it_behaves_like 'Metasploit::Framework::LoginScanner::HTTP'
9+
10+
end

0 commit comments

Comments
 (0)