Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement Exploit::Remote::LDAP::Server
In order for Framework to properly utlize Rex' internal services, they should be exposed into the namespace using a ServiceManager instance. Concurrently, called options need to be presented as configurable to modules mixing in the Ruby module. This commit implements the Exploit::Remote::LDAP::Server namespace with options for the TCP & UDP services along with an optional path for reading an LDIF file like the one provided in the testserver directory of the net-ldap source tree. Testing: None TODO: Test the code Integrate into @zeroSteiner's efforts
- Loading branch information
RageLtMan
committed
Dec 15, 2021
1 parent
37db90b
commit 9fc6e40
Showing
2 changed files
with
127 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
# -*- coding: binary -*- | ||
|
||
module Msf | ||
|
||
### | ||
# | ||
# This module exposes methods for querying a remote LDAP service | ||
# | ||
### | ||
module Exploit::Remote::LDAP | ||
module Server | ||
include Exploit::Remote::SocketServer | ||
|
||
# | ||
# Initializes an exploit module that serves LDAP requests | ||
# | ||
def initialize(info = {}) | ||
super | ||
|
||
register_options( | ||
[ | ||
OptPort.new('SRVPORT', [true, 'The local port to listen on.', 389]), | ||
OptPath.new('LDIF_FILE', [ false, "Directory LDIF file path"]), | ||
], Exploit::Remote::LDAP::Server | ||
) | ||
|
||
register_advanced_options( | ||
[ | ||
OptBool.new('LdapServerUdp', [true, "Serve UDP LDAP requests", true]), | ||
OptBool.new('LdapServerTcp', [true, "Serve TCP LDAP requests", true]) | ||
], Exploit::Remote::LDAP::Server | ||
) | ||
end | ||
|
||
attr_accessor :service # :nodoc: | ||
|
||
# | ||
# Read LDIF file - from net-ldap ldapserver.rb#L162 | ||
# | ||
# @ return [Hash] parsed ldif file | ||
def read_ldif | ||
if File.exists?(datastore['LDIF_FILE']) | ||
ary = File.readlines(datastore['LDIF_FILE']) | ||
ldif = {} | ||
while (line = ary.shift) && line.chomp! | ||
if line =~ /^dn:[\s]*/i | ||
dn = $' | ||
ldif[dn] = {} | ||
while (attrib = ary.shift) && attrib.chomp! && attrib =~ /^([\w]+)[\s]*:[\s]*/ | ||
ldif[dn][$1.downcase] ||= [] | ||
ldif[dn][$1.downcase] << $' | ||
end | ||
end | ||
end | ||
return ldif | ||
else | ||
nil | ||
end | ||
end | ||
|
||
# | ||
# Handle incoming requests | ||
# Override this method in modules to take flow control | ||
# | ||
def on_dispatch_request(cli, data) | ||
service.default_dispatch_request(cli,data) | ||
end | ||
|
||
# | ||
# Handle incoming requests | ||
# Override this method in modules to take flow control | ||
# | ||
def on_send_response(cli, data) | ||
cli.write(data) | ||
end | ||
|
||
# | ||
# Starts the server | ||
# | ||
def start_service | ||
begin | ||
comm = _determine_server_comm(datastore['SRVHOST']) | ||
self.service = Rex::ServiceManager.start( | ||
Rex::Proto::LDAP::Server, | ||
datastore['SRVHOST'], | ||
datastore['SRVPORT'], | ||
datastore['LdapServerUdp'], | ||
datastore['LdapServerTcp'], | ||
read_ldif, | ||
comm, | ||
{'Msf' => framework, 'MsfExploit' => self} | ||
) | ||
|
||
self.service.dispatch_request_proc = Proc.new do |cli, data| | ||
on_dispatch_request(cli,data) | ||
end | ||
self.service.send_response_proc = Proc.new do |cli, data| | ||
on_send_response(cli,data) | ||
end | ||
self.service.start | ||
|
||
rescue ::Errno::EACCES => e | ||
raise Rex::BindFailed.new(e.message) | ||
end | ||
end | ||
|
||
# | ||
# Stops the server | ||
# @param destroy [TrueClass,FalseClass] Dereference the server object | ||
def stop_service(destroy = false) | ||
Rex::ServiceManager.stop_service(self.service) if self.service | ||
if destroy | ||
self.service = nil if self.service | ||
end | ||
end | ||
|
||
# | ||
# Resets the LDAP server | ||
# | ||
def reset_service | ||
stop_service(true) | ||
start_service | ||
end | ||
|
||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters