From f91c0cc226f126f456699e41bb78e72b9a7fcfc8 Mon Sep 17 00:00:00 2001 From: Spencer McIntyre Date: Wed, 9 Oct 2024 15:28:45 -0400 Subject: [PATCH] Add the ldapwhoami command support See RFC4532 and ruby-ldap/ruby-net-ldap#425 --- .../ui/console/command_dispatcher/client.rb | 9 ++++- lib/rex/proto/ldap.rb | 39 +++++++++++++++++++ lib/rex/proto/ldap/client.rb | 10 +++++ 3 files changed, 57 insertions(+), 1 deletion(-) diff --git a/lib/rex/post/ldap/ui/console/command_dispatcher/client.rb b/lib/rex/post/ldap/ui/console/command_dispatcher/client.rb index 4935207cb2e68..6b74c09c7a3d2 100644 --- a/lib/rex/post/ldap/ui/console/command_dispatcher/client.rb +++ b/lib/rex/post/ldap/ui/console/command_dispatcher/client.rb @@ -32,7 +32,8 @@ class Console::CommandDispatcher::Client # def commands cmds = { - 'query' => 'Run an LDAP query' + 'query' => 'Run an LDAP query', + 'getuid' => 'Get the user that the connection is running as' } reqs = {} @@ -102,6 +103,12 @@ def cmd_query_help print @@query_opts.usage end + def cmd_getuid + username = client.ldapwhoami + username.delete_prefix!('u:') + print_status("Server username: #{username}") + end + private def parse_scope(str) diff --git a/lib/rex/proto/ldap.rb b/lib/rex/proto/ldap.rb index 3ac3ff6e85c4d..a851bac39f190 100644 --- a/lib/rex/proto/ldap.rb +++ b/lib/rex/proto/ldap.rb @@ -9,6 +9,11 @@ # Update Net::LDAP's initialize and new_connection method to honor a tracking proxies setting class Net::LDAP + WhoamiOid = '1.3.6.1.4.1.4203.1.11.3'.freeze + + # fix the definition for ExtendedResponse + AsnSyntax[Net::BER::TAG_CLASS[:universal] + Net::BER::ENCODING_TYPE[:constructed] + 107] = :string + # Reference the old initialize method, and ensure `reload_lib -a` doesn't attempt to refine the method alias_method :_old_initialize, :initialize unless defined?(_old_initialize) @@ -457,6 +462,40 @@ def modify(args) pdu end + + # Monkeypatch upstream library to support the extended Whoami request. Delete + # this after https://github.com/ruby-ldap/ruby-net-ldap/pull/425 is landed. + # This is not the only occurrence of a patch for this functionality. + def ldapwhoami + ext_seq = [Net::LDAP::WhoamiOid.to_ber_contextspecific(0)] + request = ext_seq.to_ber_appsequence(Net::LDAP::PDU::ExtendedRequest) + + message_id = next_msgid + + write(request, nil, message_id) + pdu = queued_read(message_id) + + if !pdu || pdu.app_tag != Net::LDAP::PDU::ExtendedResponse + raise Net::LDAP::ResponseMissingOrInvalidError, "response missing or invalid" + end + + pdu + end +end + +class Net::LDAP::PDU + # Monkeypatch upstream library to support the extended Whoami request. Delete + # this after https://github.com/ruby-ldap/ruby-net-ldap/pull/425 is landed. + # This is not the only occurrence of a patch for this functionality. + def parse_extended_response(sequence) + sequence.length.between?(3, 5) or raise Net::LDAP::PDU::Error, "Invalid LDAP result length." + @ldap_result = { + :resultCode => sequence[0], + :matchedDN => sequence[1], + :errorMessage => sequence[2], + } + @extended_response = sequence.last + end end module Rex diff --git a/lib/rex/proto/ldap/client.rb b/lib/rex/proto/ldap/client.rb index 608edaa84770b..5ff6fa01b1147 100644 --- a/lib/rex/proto/ldap/client.rb +++ b/lib/rex/proto/ldap/client.rb @@ -98,6 +98,16 @@ def discover_base_dn dlog("#{peerinfo} Discovered base DN: #{base_dn}") base_dn end + + # Monkeypatch upstream library to support the extended Whoami request. Delete + # this after https://github.com/ruby-ldap/ruby-net-ldap/pull/425 is landed. + # This is not the only occurrence of a patch for this functionality. + def ldapwhoami(args = {}) + instrument "ldapwhoami.net_ldap", args do |payload| + @result = use_connection(args, &:ldapwhoami) + @result.success? ? @result.extended_response : nil + end + end end end end