2015-04-30 19:57:30 +00:00
|
|
|
module Metasploit
|
|
|
|
module Framework
|
|
|
|
module NTDS
|
|
|
|
require 'metasploit/framework/ntds/account'
|
|
|
|
# This class respresent an NTDS parser. It interacts with the Meterpreter Client
|
|
|
|
# to provide a simple interface for enumerating AD user accounts.
|
|
|
|
class Parser
|
|
|
|
|
|
|
|
# The size, in Bytes, of a batch of NTDS accounts
|
2015-06-02 17:46:21 +00:00
|
|
|
BATCH_SIZE = (Metasploit::Framework::NTDS::Account::ACCOUNT_SIZE * 20)
|
2015-04-30 19:57:30 +00:00
|
|
|
|
2015-05-11 16:17:58 +00:00
|
|
|
#@return [Rex::Post::Meterpreter::Channels::Pool] The Meterpreter NTDS Parser Channel
|
2015-04-30 19:57:30 +00:00
|
|
|
attr_accessor :channel
|
2015-05-11 16:17:58 +00:00
|
|
|
#@return [Msf::Session] The Meterpreter Client
|
2015-04-30 19:57:30 +00:00
|
|
|
attr_accessor :client
|
2015-05-11 16:17:58 +00:00
|
|
|
#@return [String] The path to the NTDS.dit file on the remote system
|
2015-04-30 19:57:30 +00:00
|
|
|
attr_accessor :file_path
|
|
|
|
|
|
|
|
def initialize(client, file_path='')
|
|
|
|
raise ArgumentError, "Invalid Filepath" unless file_path.present?
|
|
|
|
@file_path = file_path
|
|
|
|
@channel = client.priv.ntds_parse(file_path)
|
|
|
|
@client = client
|
|
|
|
end
|
|
|
|
|
|
|
|
# Yields a [Metasploit::Framework::NTDS::Account] for each account found
|
|
|
|
# in the remote NTDS.dit file.
|
|
|
|
#
|
2015-05-11 16:17:58 +00:00
|
|
|
# @yield [account]
|
2015-04-30 19:57:30 +00:00
|
|
|
# @yieldparam account [Metasploit::Framework::NTDS::Account] an AD user account
|
2015-05-11 16:17:58 +00:00
|
|
|
# @yieldreturn [void] does not return a value
|
2015-04-30 19:57:30 +00:00
|
|
|
def each_account
|
|
|
|
raw_batch_data = pull_batch
|
|
|
|
until raw_batch_data.nil?
|
|
|
|
batch = raw_batch_data.dup
|
|
|
|
while batch.present?
|
2015-06-02 17:46:21 +00:00
|
|
|
raw_data = batch.slice!(0,Metasploit::Framework::NTDS::Account::ACCOUNT_SIZE)
|
2015-04-30 19:57:30 +00:00
|
|
|
# Make sure our data isn't all Null-bytes
|
|
|
|
if raw_data.match(/[^\x00]/)
|
|
|
|
account = Metasploit::Framework::NTDS::Account.new(raw_data)
|
|
|
|
yield account
|
|
|
|
end
|
|
|
|
end
|
|
|
|
raw_batch_data = pull_batch
|
|
|
|
end
|
|
|
|
channel.close
|
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
def pull_batch
|
|
|
|
if channel.cid.nil?
|
|
|
|
reopen_channel
|
|
|
|
end
|
|
|
|
begin
|
|
|
|
raw_batch_data = channel.read(BATCH_SIZE)
|
|
|
|
rescue EOFError
|
|
|
|
raw_batch_data = nil
|
|
|
|
end
|
|
|
|
raw_batch_data
|
|
|
|
end
|
|
|
|
|
|
|
|
def reopen_channel
|
|
|
|
@channel = client.priv.ntds_parse(file_path)
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|